This commit is contained in:
QAston
2011-06-28 16:18:42 +02:00
37 changed files with 679 additions and 615 deletions
-26
View File
@@ -562,7 +562,6 @@ INSERT INTO `command` VALUES
('npc move',2,'Syntax: .npc move [#creature_guid]\r\n\r\nMove the targeted creature spawn point to your coordinates.'),
('npc playemote',3,'Syntax: .npc playemote #emoteid\r\n\r\nMake the selected creature emote with an emote of id #emoteid.'),
('npc say',1,'Syntax: .npc say $message\nMake selected creature say specified message.'),
('npc set deathstate',2,'Syntax: .npc set deathstate on/off\r\n\r\nSet default death state (dead/alive) for npc at spawn.'),
('npc set link',2,'Syntax: .npc set link $creatureGUID\r\n\r\nLinks respawn of selected creature to the condition that $creatureGUID defined is alive.'),
('npc set model',2,'Syntax: .npc set model #displayid\r\n\r\nChange the model id of the selected creature to #displayid.'),
('npc set movetype',2,'Syntax: .npc set movetype [#creature_guid] stay/random/way [NODEL]\r\n\r\nSet for creature pointed by #creature_guid (or selected if #creature_guid not provided) movement type and move it to respawn position (if creature alive). Any existing waypoints for creature will be removed from the database if you do not use NODEL. If the creature is dead then movement type will applied at creature respawn.\r\nMake sure you use NODEL, if you want to keep the waypoints.'),
@@ -822,7 +821,6 @@ CREATE TABLE `creature` (
`currentwaypoint` mediumint(8) unsigned NOT NULL DEFAULT '0',
`curhealth` int(10) unsigned NOT NULL DEFAULT '1',
`curmana` int(10) unsigned NOT NULL DEFAULT '0',
`DeathState` tinyint(3) unsigned NOT NULL DEFAULT '0',
`MovementType` tinyint(3) unsigned NOT NULL DEFAULT '0',
`npcflag` int(10) unsigned NOT NULL DEFAULT '0',
`unit_flags` int(10) unsigned NOT NULL DEFAULT '0',
@@ -27885,30 +27883,6 @@ LOCK TABLES `vehicle_accessory` WRITE;
/*!40000 ALTER TABLE `vehicle_accessory` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `vehicle_scaling_info`
--
DROP TABLE IF EXISTS `vehicle_scaling_info`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `vehicle_scaling_info` (
`entry` mediumint(8) unsigned NOT NULL default '0',
`baseItemLevel` float NOT NULL default '0',
`scalingFactor` float NOT NULL default '0',
PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `vehicle_scaling_info`
--
LOCK TABLES `vehicle_scaling_info` WRITE;
/*!40000 ALTER TABLE `vehicle_scaling_info` DISABLE KEYS */;
/*!40000 ALTER TABLE `vehicle_scaling_info` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `version`
--
+7
View File
@@ -1927,6 +1927,7 @@ INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,
/* SPELLS */
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
-- generic
( 66218, 'spell_gen_launch'),
( 39228, 'spell_gen_absorb0_hitlimit1'),
( 60218, 'spell_gen_absorb0_hitlimit1'),
( 6962, 'spell_gen_pet_summoned'),
@@ -1987,6 +1988,12 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
( 12749, 'spell_gen_allow_cast_from_item_only'),
( 13258, 'spell_gen_allow_cast_from_item_only'),
( 13166, 'spell_gen_allow_cast_from_item_only'),
(65266, 'spell_gen_vehicle_scaling'),
(65635, 'spell_gen_vehicle_scaling'),
(65636, 'spell_gen_vehicle_scaling'),
(66666, 'spell_gen_vehicle_scaling'),
(66667, 'spell_gen_vehicle_scaling'),
(66668, 'spell_gen_vehicle_scaling'),
-- instances
-- Black Temple
( 41475, 'spell_boss_lady_malande_shield'),
@@ -0,0 +1,2 @@
DELETE FROM `spell_script_names` WHERE `spell_id`=66218;
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES (66218,'spell_gen_launch');
@@ -0,0 +1,13 @@
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (33354,33355,33430,33431,33525,33526,33527,33528);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (33354,33355,33430,33431,33525,33526,33527,33528) AND `event_type`=6;
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
(33354,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Corrupted Servitor - on death set instance data for achievement Con-Speed-Atory'),
(33355,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Misguided Nymph - on death set instance data for achievement Con-Speed-Atory'),
(33430,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Guardian Lasher - on death set instance data for achievement Con-Speed-Atory'),
(33431,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Forest Swarmer - on death set instance data for achievement Con-Speed-Atory'),
(33525,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Mangrove Ent - on death set instance data for achievement Con-Speed-Atory'),
(33526,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Ironroot Lasher - on death set instance data for achievement Con-Speed-Atory'),
(33527,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Natures\'s Blade - on death set instance data for achievement Con-Speed-Atory'),
(33528,0,0,0,6,0,100,0,0,0,0,0,34,2,1,0,0,0,0,19,32906,0,0,0,0,0,0,'Guardian of Life - on death set instance data for achievement Con-Speed-Atory');
@@ -0,0 +1,8 @@
DELETE FROM `spell_script_names` WHERE `spell_id` IN(65266,65635,65636,66666,66667,66668);
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(65266,'spell_gen_vehicle_scaling'),
(65635,'spell_gen_vehicle_scaling'),
(65636,'spell_gen_vehicle_scaling'),
(66666,'spell_gen_vehicle_scaling'),
(66667,'spell_gen_vehicle_scaling'),
(66668,'spell_gen_vehicle_scaling');
@@ -0,0 +1 @@
DROP TABLE `vehicle_scaling_info`;
@@ -0,0 +1,21 @@
DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10447,10448,10449,10459,10460,10461) AND `type` IN (11,12,18);
INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`)
VALUES
(10447,11,0,0,'achievement_knock_on_wood'),
(10447,12,0,0,''),
(10448,11,0,0,'achievement_knock_knock_on_wood'),
(10448,12,0,0,''),
(10449,11,0,0,'achievement_knock_knock_knock_on_wood'),
(10449,12,0,0,''),
(10459,11,0,0,'achievement_knock_on_wood'),
(10459,12,1,0,''),
(10460,11,0,0,'achievement_knock_knock_on_wood'),
(10460,12,1,0,''),
(10461,11,0,0,'achievement_knock_knock_knock_on_wood'),
(10461,12,1,0,'');
UPDATE `creature_template` SET `AIName`='' WHERE `entry` IN (33354,33355,33430,33431,33525,33526,33527,33528);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (33354,33355,33430,33431,33525,33526,33527,33528);
@@ -0,0 +1,11 @@
DELETE FROM `disables` WHERE `entry` IN (10088,10089,10418,10419,10420,10421);
DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10088,10089,10418,10419,10420,10421) AND `type`=11;
INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`)
VALUES
(10088,5,58501,0,''),
(10089,5,58501,0,''),
(10418,5,58501,0,''),
(10419,5,58501,0,''),
(10420,5,58501,0,''),
(10421,5,58501,0,'');
@@ -0,0 +1 @@
UPDATE `areatrigger_teleport` SET `target_orientation`= 3.30496 WHERE `id`=922;
@@ -0,0 +1 @@
DELETE FROM `command` WHERE `name`= 'npc set deathstate';
@@ -0,0 +1,4 @@
-- Drop DeathState column
ALTER TABLE `creature` DROP COLUMN `DeathState`;
-- Remove spawns for Kologarn (not boss) and Focused Eyebeam (summoned).
DELETE FROM `creature` WHERE `id` IN (34297,33632,33802);
@@ -0,0 +1,14 @@
DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (7709,7710,7711,7712,7713,7714,7715,7716,7718,7719);
DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (7709,7710,7711,7712,7713,7714,7715,7716,7718,7719);
INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
(7709,6,4575,0, ''), -- killed player in Wintergrasp Fortress
(7710,6,4612,0, ''), -- killed player in Eastspark Workshop
(7711,6,4539,0, ''), -- killed player in The Broken Temple
(7712,6,4538,0, ''), -- killed player in The Sunken Ring
(7713,6,4611,0, ''), -- killed player in Westspark Workshop
(7714,6,4581,0, ''), -- killed player in Flamewatch Tower
(7715,6,4583,0, ''), -- killed player in Shadowsight Tower
(7716,6,4582,0, ''), -- killed player in Winter's Edge Tower
(7718,6,4584,0, ''), -- killed player in The Cauldron of Flames
(7719,6,4589,0, ''); -- killed player in The Chilled Quagmire
+2 -2
View File
@@ -311,8 +311,8 @@ void VehicleAI::CheckConditions(const uint32 diff)
{
if (!conditions.empty())
{
for (SeatMap::iterator itr = m_vehicle->m_Seats.begin(); itr != m_vehicle->m_Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*m_vehicle->GetBase(), itr->second.passenger))
for (SeatMap::iterator itr = m_vehicle->Seats.begin(); itr != m_vehicle->Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*m_vehicle->GetBase(), itr->second.Passenger))
{
if (Player* plr = passenger->ToPlayer())
{
+8 -34
View File
@@ -142,9 +142,8 @@ lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGrou
m_PlayerDamageReq(0), m_lootMoney(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_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_creatureInfo(NULL), m_creatureData(NULL),
m_formation(NULL)
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
@@ -229,7 +228,7 @@ void Creature::SearchFormation()
void Creature::RemoveCorpse(bool setSpawnTime)
{
if ((getDeathState() != CORPSE && !m_isDeadByDefault) || (getDeathState() != ALIVE && m_isDeadByDefault))
if (getDeathState() != CORPSE)
return;
m_corpseRemoveTime = time(NULL);
@@ -471,9 +470,6 @@ void Creature::Update(uint32 diff)
}
case CORPSE:
{
if (m_isDeadByDefault)
break;
if (m_groupLootTimer && lootingGroupLowGUID)
{
// for delayed spells
@@ -504,15 +500,6 @@ void Creature::Update(uint32 diff)
}
case ALIVE:
{
if (m_isDeadByDefault)
{
if (m_corpseRemoveTime <= time(NULL))
{
RemoveCorpse(false);
sLog->outStaticDebug("Removing alive corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY));
}
}
Unit::Update(diff);
// creature can be dead after Unit::Update call
@@ -1082,7 +1069,6 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
data.currentwaypoint = 0;
data.curhealth = GetHealth();
data.curmana = GetPower(POWER_MANA);
data.is_dead = m_isDeadByDefault;
// prevent add data integrity problems
data.movementType = !m_respawnradius && GetDefaultMovementType() == RANDOM_MOTION_TYPE
? IDLE_MOTION_TYPE : GetDefaultMovementType();
@@ -1114,7 +1100,6 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< (uint32) (0) << ", " //currentwaypoint
<< GetHealth() << ", " //curhealth
<< GetPower(POWER_MANA) << ", " //curmana
<< (m_isDeadByDefault ? 1 : 0) << ", " //is_dead
<< GetDefaultMovementType() << ", " //default movement generator type
<< npcflag << ", "
<< unit_flags << ", "
@@ -1292,8 +1277,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
m_respawnradius = data->spawndist;
m_respawnDelay = data->spawntimesecs;
m_isDeadByDefault = data->is_dead;
m_deathState = m_isDeadByDefault ? DEAD : ALIVE;
m_deathState = ALIVE;
m_respawnTime = sObjectMgr->GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
if (m_respawnTime) // respawn on Update
@@ -1404,7 +1388,7 @@ bool Creature::isVisibleForInState(WorldObject const* seer) const
if (!Unit::isVisibleForInState(seer))
return false;
if (isAlive() || (m_isDeadByDefault && m_deathState == CORPSE) || m_corpseRemoveTime > time(NULL))
if (isAlive() || m_corpseRemoveTime > time(NULL))
return true;
return false;
@@ -1495,7 +1479,9 @@ float Creature::GetAttackDistance(Unit const* pl) const
void Creature::setDeathState(DeathState s)
{
if ((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault))
Unit::setDeathState(s);
if (s == JUST_DIED)
{
m_corpseRemoveTime = time(NULL) + m_corpseDelay;
m_respawnTime = time(NULL) + m_respawnDelay + m_corpseDelay;
@@ -1503,11 +1489,7 @@ void Creature::setDeathState(DeathState s)
// always save boss respawn time at death to prevent crash cheating
if (sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss())
SaveRespawnTime();
}
Unit::setDeathState(s);
if (s == JUST_DIED)
{
SetUInt64Value(UNIT_FIELD_TARGET, 0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState)
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
@@ -1608,14 +1590,6 @@ void Creature::Respawn(bool force)
CreatureTemplate const *cinfo = GetCreatureInfo();
SelectLevel(cinfo);
if (m_isDeadByDefault)
{
setDeathState(JUST_DIED);
i_motionMaster.Clear();
ClearUnitState(uint32(UNIT_STAT_ALL_STATE));
LoadCreaturesAddon(true);
}
else
setDeathState(JUST_ALIVED);
uint32 displayID = GetNativeDisplayId();
@@ -254,7 +254,6 @@ struct CreatureData
uint32 currentwaypoint;
uint32 curhealth;
uint32 curmana;
bool is_dead;
uint8 movementType;
uint8 spawnMask;
uint32 npcflag;
@@ -603,7 +602,6 @@ class Creature : public Unit, public GridObject<Creature>
void SetCurrentCell(Cell const& cell) { m_currentCell = cell; }
void RemoveCorpse(bool setSpawnTime = true);
bool isDeadByDefault() const { return m_isDeadByDefault; };
void ForcedDespawn(uint32 timeMSToDespawn = 0);
void DespawnOrUnsummon(uint32 msTimeToDespawn = 0);
@@ -656,7 +654,6 @@ class Creature : public Unit, public GridObject<Creature>
void SetFormation(CreatureGroup *formation) {m_formation = formation;}
Unit *SelectVictim();
void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;}
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
bool IsReputationGainDisabled() { return DisableReputationGain; }
@@ -713,7 +710,6 @@ class Creature : public Unit, public GridObject<Creature>
bool m_AlreadySearchedAssistance;
bool m_regenHealth;
bool m_AI_locked;
bool m_isDeadByDefault;
SpellSchoolMask m_meleeDamageSchoolMask;
uint32 m_originalEntry;
@@ -179,7 +179,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
if (!goinfo)
{
sLog->outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f) ang: %f rotation0: %f rotation1: %f rotation2: %f rotation3: %f", guidlow, name_id, map->GetId(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3);
sLog->outErrorDb("Gameobject (GUID: %u Entry: %u) not created: non-existing entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f)", guidlow, name_id, map->GetId(), x, y, z);
return false;
}
@@ -189,7 +189,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
if (goinfo->type >= MAX_GAMEOBJECT_TYPE)
{
sLog->outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist GO type '%u' in `gameobject_template`. It's will crash client if created.", guidlow, name_id, goinfo->type);
sLog->outErrorDb("Gameobject (GUID: %u Entry: %u) not created: non-existing GO type '%u' in `gameobject_template`. It will crash client if created.", guidlow, name_id, goinfo->type);
return false;
}
+5 -5
View File
@@ -3480,7 +3480,7 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
return false;
}
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled)
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled, bool loading /*=false*/)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
@@ -3720,7 +3720,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
// cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned)
// note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive
if (talentCost > 0 && IsSpellHaveEffect(spellInfo, SPELL_EFFECT_LEARN_SPELL))
if (!loading && talentCost > 0 && IsSpellHaveEffect(spellInfo, SPELL_EFFECT_LEARN_SPELL))
{
// ignore stance requirement for talent learn spell (stance set for spell only for client spell description show)
CastSpell(this, spell_id, true);
@@ -4405,7 +4405,7 @@ bool Player::resetTalents(bool no_cost)
if (const SpellEntry *_spellEntry = sSpellStore.LookupEntry(talentInfo->RankID[rank]))
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) // search through the SpellEntry for valid trigger spells
if (_spellEntry->EffectTriggerSpell[i] > 0 && _spellEntry->Effect[i] == SPELL_EFFECT_LEARN_SPELL)
removeSpell(_spellEntry->EffectTriggerSpell[i]); // and remove any spells that the talent teaches
removeSpell(_spellEntry->EffectTriggerSpell[i], true); // and remove any spells that the talent teaches
// if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
if (plrTalent != m_talents[m_activeSpec]->end())
@@ -17739,7 +17739,7 @@ void Player::_LoadSpells(PreparedQueryResult result)
if (result)
{
do
addSpell((*result)[0].GetUInt32(), (*result)[1].GetBool(), false, false, (*result)[2].GetBool());
addSpell((*result)[0].GetUInt32(), (*result)[1].GetBool(), false, false, (*result)[2].GetBool(), true);
while (result->NextRow());
}
}
@@ -24289,7 +24289,7 @@ void Player::ActivateSpec(uint8 spec)
if (const SpellEntry *_spellEntry = sSpellStore.LookupEntry(talentInfo->RankID[rank]))
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) // search through the SpellEntry for valid trigger spells
if (_spellEntry->EffectTriggerSpell[i] > 0 && _spellEntry->Effect[i] == SPELL_EFFECT_LEARN_SPELL)
removeSpell(_spellEntry->EffectTriggerSpell[i]); // and remove any spells that the talent teaches
removeSpell(_spellEntry->EffectTriggerSpell[i], true); // and remove any spells that the talent teaches
// if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
//PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
//if (plrTalent != m_talents[m_activeSpec]->end())
+1 -1
View File
@@ -1598,7 +1598,7 @@ class Player : public Unit, public GridObject<Player>
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask);
void SendInitialSpells();
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled, bool loading = false);
void learnSpell(uint32 spell_id, bool dependent);
void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true);
void resetSpells(bool myClassOnly = false);
+17 -7
View File
@@ -15630,7 +15630,12 @@ void Unit::SetStunned(bool apply)
SetUInt64Value(UNIT_FIELD_TARGET, 0);
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
// AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
// MOVEMENTFLAG_ROOT cannot be used in conjunction with
// MOVEMENTFLAG_FORWARD, MOVEMENTFLAG_BACKWARD, MOVEMENTFLAG_STRAFE_LEFT, MOVEMENTFLAG_STRAFE RIGHT (tested 3.3.5a)
// this will freeze clients. That's why we remove any current movement flags before
// setting MOVEMENTFLAG_ROOT
RemoveUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
// Creature specific
if (GetTypeId() != TYPEID_PLAYER)
@@ -15662,7 +15667,7 @@ void Unit::SetStunned(bool apply)
data << uint32(0);
SendMessageToSet(&data, true);
// RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
}
}
}
@@ -15674,7 +15679,12 @@ void Unit::SetRooted(bool apply)
if (m_rootTimes > 0) // blizzard internal check?
m_rootTimes++;
// AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
// MOVEMENTFLAG_ROOT cannot be used in conjunction with
// MOVEMENTFLAG_FORWARD, MOVEMENTFLAG_BACKWARD, MOVEMENTFLAG_STRAFE_LEFT, MOVEMENTFLAG_STRAFE RIGHT (tested 3.3.5a)
// this will freeze clients. That's why we remove any current movement flags before
// setting MOVEMENTFLAG_ROOT
RemoveUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
if (GetTypeId() == TYPEID_PLAYER)
{
@@ -15709,7 +15719,7 @@ void Unit::SetRooted(bool apply)
SendMessageToSet(&data, true);
}
// RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
}
}
}
@@ -16804,7 +16814,7 @@ bool Unit::CheckPlayerCondition(Player* pPlayer)
bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
bool success = false;
uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->m_creatureEntry : GetEntry();
uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
{
@@ -17284,8 +17294,8 @@ void Unit::OutDebugInfo() const
if (IsVehicle())
{
sLog->outStringInLine("Passenger List: ");
for (SeatMap::iterator itr = GetVehicleKit()->m_Seats.begin(); itr != GetVehicleKit()->m_Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*GetVehicleBase(), itr->second.passenger))
for (SeatMap::iterator itr = GetVehicleKit()->Seats.begin(); itr != GetVehicleKit()->Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*GetVehicleBase(), itr->second.Passenger))
sLog->outStringInLine(UI64FMTD", ", passenger->GetGUID());
sLog->outString();
}
+1 -1
View File
@@ -643,7 +643,7 @@ enum MovementFlags
MOVEMENTFLAG_WALKING = 0x00000100, // Walking
MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures
MOVEMENTFLAG_LEVITATING = 0x00000400,
MOVEMENTFLAG_ROOT = 0x00000800,
MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT -> client freeze
MOVEMENTFLAG_JUMPING = 0x00001000,
MOVEMENTFLAG_FALLING = 0x00002000, // damage dealt on that type of falling
MOVEMENTFLAG_PENDING_STOP = 0x00004000,
+129 -154
View File
@@ -27,16 +27,16 @@
#include "CreatureAI.h"
#include "ZoneScript.h"
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0), m_bonusHP(0), m_creatureEntry(creatureEntry)
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry)
{
for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i)
{
if (uint32 seatId = m_vehicleInfo->m_seatID[i])
if (uint32 seatId = _vehicleInfo->m_seatID[i])
if (VehicleSeatEntry const* veSeat = sVehicleSeatStore.LookupEntry(seatId))
{
m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
if (veSeat->CanEnterOrExit())
++m_usableSeatNum;
++_usableSeatNum;
}
}
@@ -45,27 +45,27 @@ Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry)
Vehicle::~Vehicle()
{
for (SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
ASSERT(!itr->second.passenger);
for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
ASSERT(!itr->second.Passenger);
}
void Vehicle::Install()
{
if (Creature* creature = me->ToCreature())
if (Creature* creature = _me->ToCreature())
{
switch (m_vehicleInfo->m_powerType)
switch (_vehicleInfo->m_powerType)
{
case POWER_STEAM:
case POWER_HEAT:
case POWER_BLOOD:
case POWER_OOZE:
case POWER_WRATH:
me->setPowerType(POWER_ENERGY);
me->SetMaxPower(POWER_ENERGY, 100);
_me->setPowerType(POWER_ENERGY);
_me->SetMaxPower(POWER_ENERGY, 100);
break;
case POWER_PYRITE:
me->setPowerType(POWER_ENERGY);
me->SetMaxPower(POWER_ENERGY, 50);
_me->setPowerType(POWER_ENERGY);
_me->SetMaxPower(POWER_ENERGY, 50);
break;
default:
for (uint32 i = 0; i < MAX_SPELL_VEHICLE; ++i)
@@ -79,8 +79,8 @@ void Vehicle::Install()
if (spellInfo->powerType == POWER_ENERGY)
{
me->setPowerType(POWER_ENERGY);
me->SetMaxPower(POWER_ENERGY, 100);
_me->setPowerType(POWER_ENERGY);
_me->SetMaxPower(POWER_ENERGY, 100);
break;
}
}
@@ -108,7 +108,7 @@ void Vehicle::InstallAllAccessories(bool evading)
void Vehicle::Uninstall()
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Uninstall Entry: %u, GuidLow: %u", m_creatureEntry, me->GetGUIDLow());
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Uninstall Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow());
RemoveAllPassengers();
if (GetBase()->GetTypeId() == TYPEID_UNIT)
@@ -117,18 +117,18 @@ void Vehicle::Uninstall()
void Vehicle::Reset(bool evading /*= false*/)
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Reset Entry: %u, GuidLow: %u", m_creatureEntry, me->GetGUIDLow());
if (me->GetTypeId() == TYPEID_PLAYER)
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Reset Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow());
if (_me->GetTypeId() == TYPEID_PLAYER)
{
if (m_usableSeatNum)
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
if (_usableSeatNum)
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
}
else
{
ApplyAllImmunities();
InstallAllAccessories(evading);
if (m_usableSeatNum)
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
if (_usableSeatNum)
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
if (GetBase()->GetTypeId() == TYPEID_UNIT)
@@ -140,48 +140,47 @@ void Vehicle::ApplyAllImmunities()
// This couldn't be done in DB, because Vehicle's immunities are overriden by Player's ones
// Vehicles should be immune on Knockback, Deathgrip ...
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
_me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
_me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
// ... Fear, Snare, Root, Stun ...
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true);
// Mechanical units & vehicles ( which are not Bosses, they have own immunities in DB ) should be also immune on healing ( exceptions in switch below )
if (me->ToCreature() && me->ToCreature()->GetCreatureInfo()->type == CREATURE_TYPE_MECHANICAL && !me->ToCreature()->isWorldBoss())
if (_me->ToCreature() && _me->ToCreature()->GetCreatureInfo()->type == CREATURE_TYPE_MECHANICAL && !_me->ToCreature()->isWorldBoss())
{
// Heal & dispel ...
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);
_me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true);
// ... Shield & Immunity grant spells ...
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD , true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_IMMUNITY, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_UNATTACKABLE, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SCHOOL_ABSORB, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHIELD, true);
_me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_IMMUNE_SHIELD , true);
// ... Resistance, Split damage, Speed Increase, ...
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_INCREASE_SPEED, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_DAMAGE_SHIELD, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_SPLIT_DAMAGE_PCT, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_RESISTANCE, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true);
}
// Different immunities for vehicles goes below
switch (GetVehicleInfo()->m_ID)
{
case 160:
me->SetControlled(true, UNIT_STAT_ROOT);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
_me->SetControlled(true, UNIT_STAT_ROOT);
_me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true);
break;
default:
break;
@@ -190,12 +189,12 @@ void Vehicle::ApplyAllImmunities()
void Vehicle::RemoveAllPassengers()
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::RemoveAllPassengers. Entry: %u, GuidLow: %u", m_creatureEntry, me->GetGUIDLow());
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::RemoveAllPassengers. Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow());
// 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 m_Seats
me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE);
_me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE);
// Following the above logic, this assertion should NEVER fail.
// Even in 'hacky' cases, there should at least be VEHICLE_SPELL_RIDE_HARDCODED on us.
@@ -206,39 +205,39 @@ void Vehicle::RemoveAllPassengers()
bool Vehicle::HasEmptySeat(int8 seatId) const
{
SeatMap::const_iterator seat = m_Seats.find(seatId);
if (seat == m_Seats.end())
SeatMap::const_iterator seat = Seats.find(seatId);
if (seat == Seats.end())
return false;
return !seat->second.passenger;
return !seat->second.Passenger;
}
Unit* Vehicle::GetPassenger(int8 seatId) const
{
SeatMap::const_iterator seat = m_Seats.find(seatId);
if (seat == m_Seats.end())
SeatMap::const_iterator seat = Seats.find(seatId);
if (seat == Seats.end())
return NULL;
return ObjectAccessor::GetUnit(*GetBase(), seat->second.passenger);
return ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger);
}
int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
{
SeatMap::const_iterator seat = m_Seats.find(seatId);
if (seat == m_Seats.end())
SeatMap::const_iterator seat = Seats.find(seatId);
if (seat == Seats.end())
return -1;
while (seat->second.passenger || (!seat->second.seatInfo->CanEnterOrExit() && !seat->second.seatInfo->IsUsableByOverride()))
while (seat->second.Passenger || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
{
if (next)
{
++seat;
if (seat == m_Seats.end())
seat = m_Seats.begin();
if (seat == Seats.end())
seat = Seats.begin();
}
else
{
if (seat == m_Seats.begin())
seat = m_Seats.end();
if (seat == Seats.begin())
seat = Seats.end();
--seat;
}
@@ -258,9 +257,9 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ
if (passenger->GetEntry() == entry)
{
ASSERT(passenger->GetTypeId() == TYPEID_UNIT);
if (me->GetTypeId() == TYPEID_UNIT)
if (_me->GetTypeId() == TYPEID_UNIT)
{
if (me->ToCreature()->IsInEvadeMode() && passenger->ToCreature()->IsAIEnabled)
if (_me->ToCreature()->IsInEvadeMode() && passenger->ToCreature()->IsAIEnabled)
passenger->ToCreature()->AI()->EnterEvadeMode();
return;
}
@@ -269,12 +268,12 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ
passenger->ExitVehicle(); // this should not happen
}
if (TempSummon* accessory = me->SummonCreature(entry, *me, TempSummonType(type), summonTime))
if (TempSummon* accessory = _me->SummonCreature(entry, *_me, TempSummonType(type), summonTime))
{
if (minion)
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
if (!me->HandleSpellClick(accessory, seatId))
if (!_me->HandleSpellClick(accessory, seatId))
{
accessory->UnSummon();
return;
@@ -304,51 +303,51 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
SeatMap::iterator seat;
if (seatId < 0) // no specific seat requirement
{
for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
if (!seat->second.passenger && (seat->second.seatInfo->CanEnterOrExit() || seat->second.seatInfo->IsUsableByOverride()))
for (seat = Seats.begin(); seat != Seats.end(); ++seat)
if (!seat->second.Passenger && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride()))
break;
if (seat == m_Seats.end()) // no available seat
if (seat == Seats.end()) // no available seat
return false;
}
else
{
seat = m_Seats.find(seatId);
if (seat == m_Seats.end())
seat = Seats.find(seatId);
if (seat == Seats.end())
return false;
if (seat->second.passenger)
if (seat->second.Passenger)
{
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.passenger))
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger))
passenger->ExitVehicle();
else
seat->second.passenger = 0;
seat->second.Passenger = 0;
}
ASSERT(!seat->second.passenger);
ASSERT(!seat->second.Passenger);
}
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_vehicleInfo->m_ID, me->GetGUIDLow(), (int32)seat->first);
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first);
seat->second.passenger = unit->GetGUID();
if (seat->second.seatInfo->CanEnterOrExit())
seat->second.Passenger = unit->GetGUID();
if (seat->second.SeatInfo->CanEnterOrExit())
{
ASSERT(m_usableSeatNum);
--m_usableSeatNum;
if (!m_usableSeatNum)
ASSERT(_usableSeatNum);
--_usableSeatNum;
if (!_usableSeatNum)
{
if (me->GetTypeId() == TYPEID_PLAYER)
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
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);
_me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
}
if (seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11))
if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11))
unit->AddUnitState(UNIT_STAT_ONVEHICLE);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
VehicleSeatEntry const* veSeat = seat->second.seatInfo;
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;
@@ -356,43 +355,28 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
unit->m_movementInfo.t_time = 0; // 1 for player
unit->m_movementInfo.t_seat = seat->first;
if (me->GetTypeId() == TYPEID_UNIT
if (_me->GetTypeId() == TYPEID_UNIT
&& unit->GetTypeId() == TYPEID_PLAYER
&& seat->first == 0 && seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
&& seat->first == 0 && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
{
if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE))
if (!_me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE))
ASSERT(false);
// hack: should be done by aura system
if (VehicleScalingInfo const* scalingInfo = sObjectMgr->GetVehicleScalingInfo(m_vehicleInfo->m_ID))
{
Player* player = unit->ToPlayer();
float averageItemLevel = player->GetAverageItemLevel();
if (averageItemLevel < scalingInfo->baseItemLevel)
averageItemLevel = scalingInfo->baseItemLevel;
averageItemLevel -= scalingInfo->baseItemLevel;
float currentHealthPct = float(me->GetHealth() / me->GetMaxHealth());
m_bonusHP = uint32(me->GetMaxHealth() * (averageItemLevel * scalingInfo->scalingFactor));
me->SetMaxHealth(me->GetMaxHealth() + m_bonusHP);
me->SetHealth(uint32((me->GetHealth() + m_bonusHP) * currentHealthPct));
}
}
if (me->IsInWorld())
if (_me->IsInWorld())
{
unit->SendClearTarget(); // SMSG_BREAK_TARGET
unit->SetControlled(true, UNIT_STAT_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT
unit->SendMonsterMoveTransport(me); // SMSG_MONSTER_MOVE_TRANSPORT
unit->SendMonsterMoveTransport(_me); // SMSG_MONSTER_MOVE_TRANSPORT
if (me->GetTypeId() == TYPEID_UNIT)
if (_me->GetTypeId() == TYPEID_UNIT)
{
if (me->ToCreature()->IsAIEnabled)
me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
if (_me->ToCreature()->IsAIEnabled)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
// update all passenger's positions
RelocatePassengers(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
}
}
@@ -408,38 +392,29 @@ void Vehicle::RemovePassenger(Unit* unit)
return;
SeatMap::iterator seat = GetSeatIteratorForPassenger(unit);
ASSERT(seat != m_Seats.end());
ASSERT(seat != Seats.end());
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s exit vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_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(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first);
seat->second.passenger = 0;
if (seat->second.seatInfo->CanEnterOrExit())
seat->second.Passenger = 0;
if (seat->second.SeatInfo->CanEnterOrExit())
{
if (!m_usableSeatNum)
if (!_usableSeatNum)
{
if (me->GetTypeId() == TYPEID_PLAYER)
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
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);
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
++m_usableSeatNum;
++_usableSeatNum;
}
unit->ClearUnitState(UNIT_STAT_ONVEHICLE);
if (me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
{
me->RemoveCharmedBy(unit);
if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
_me->RemoveCharmedBy(unit);
if (m_bonusHP)
{
me->SetHealth(me->GetHealth() - m_bonusHP);
me->SetMaxHealth(me->GetMaxHealth() - m_bonusHP);
m_bonusHP = 0;
}
}
if (me->IsInWorld())
if (_me->IsInWorld())
{
unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
unit->m_movementInfo.t_pos.Relocate(0, 0, 0, 0);
@@ -447,12 +422,12 @@ void Vehicle::RemovePassenger(Unit* unit)
unit->m_movementInfo.t_seat = 0;
}
if (me->GetTypeId() == TYPEID_UNIT && me->ToCreature()->IsAIEnabled)
me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, false);
if (_me->GetTypeId() == TYPEID_UNIT && _me->ToCreature()->IsAIEnabled)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, false);
// only for flyable vehicles
if (unit->HasUnitMovementFlag(MOVEMENTFLAG_FLYING))
me->CastSpell(unit, VEHICLE_SPELL_PARACHUTE, true);
_me->CastSpell(unit, VEHICLE_SPELL_PARACHUTE, true);
if (GetBase()->GetTypeId() == TYPEID_UNIT)
sScriptMgr->OnRemovePassenger(this, unit);
@@ -460,12 +435,12 @@ void Vehicle::RemovePassenger(Unit* unit)
void Vehicle::RelocatePassengers(float x, float y, float z, float ang)
{
Map* map = me->GetMap();
Map* map = _me->GetMap();
ASSERT(map != NULL);
// not sure that absolute position calculation is correct, it must depend on vehicle orientation and pitch angle
for (SeatMap::const_iterator itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.passenger))
for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger))
{
ASSERT(passenger->IsInWorld());
ASSERT(passenger->IsOnVehicle(GetBase()));
@@ -482,11 +457,11 @@ void Vehicle::RelocatePassengers(float x, float y, float z, float ang)
void Vehicle::Dismiss()
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Dismiss Entry: %u, GuidLow %u", m_creatureEntry, me->GetGUIDLow());
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Dismiss Entry: %u, GuidLow %u", _creatureEntry, _me->GetGUIDLow());
Uninstall();
me->DestroyForNearbyPlayers();
me->CombatStop();
me->AddObjectToRemoveList();
_me->DestroyForNearbyPlayers();
_me->CombatStop();
_me->AddObjectToRemoveList();
}
void Vehicle::InitMovementInfoForBase()
@@ -494,23 +469,23 @@ void Vehicle::InitMovementInfoForBase()
uint32 vehicleFlags = GetVehicleInfo()->m_flags;
if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE)
me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_STRAFE);
_me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_STRAFE);
if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING)
me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_JUMPING);
_me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_NO_JUMPING);
if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING)
me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_TURNING);
_me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_TURNING);
if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING)
me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
_me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING)
me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING);
_me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING);
}
VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit* passenger)
{
SeatMap::iterator itr;
for (itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
if (itr->second.passenger == passenger->GetGUID())
return itr->second.seatInfo;
for (itr = Seats.begin(); itr != Seats.end(); ++itr)
if (itr->second.Passenger == passenger->GetGUID())
return itr->second.SeatInfo;
return NULL;
}
@@ -518,19 +493,19 @@ VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit* passenger)
SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger)
{
SeatMap::iterator itr;
for (itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
if (itr->second.passenger == passenger->GetGUID())
for (itr = Seats.begin(); itr != Seats.end(); ++itr)
if (itr->second.Passenger == passenger->GetGUID())
return itr;
return m_Seats.end();
return Seats.end();
}
uint8 Vehicle::GetAvailableSeatCount() const
{
uint8 ret = 0;
SeatMap::const_iterator itr;
for (itr = m_Seats.begin(); itr != m_Seats.end(); ++itr)
if (!itr->second.passenger && (itr->second.seatInfo->CanEnterOrExit() || itr->second.seatInfo->IsUsableByOverride()))
for (itr = Seats.begin(); itr != Seats.end(); ++itr)
if (!itr->second.Passenger && (itr->second.SeatInfo->CanEnterOrExit() || itr->second.SeatInfo->IsUsableByOverride()))
++ret;
return ret;
+13 -24
View File
@@ -79,9 +79,9 @@ enum VehicleSpells
struct VehicleSeat
{
explicit VehicleSeat(VehicleSeatEntry const *_seatInfo) : seatInfo(_seatInfo), passenger(0) {}
VehicleSeatEntry const *seatInfo;
uint64 passenger;
explicit VehicleSeat(VehicleSeatEntry const *seatInfo) : SeatInfo(seatInfo), Passenger(0) {}
VehicleSeatEntry const *SeatInfo;
uint64 Passenger;
};
struct VehicleAccessory
@@ -95,16 +95,8 @@ struct VehicleAccessory
uint32 SummonTime;
};
struct VehicleScalingInfo
{
uint32 ID;
float baseItemLevel;
float scalingFactor;
};
typedef std::vector<VehicleAccessory> VehicleAccessoryList;
typedef std::map<uint32, VehicleAccessoryList> VehicleAccessoryMap;
typedef std::map<uint32, VehicleScalingInfo> VehicleScalingMap;
typedef std::map<int8, VehicleSeat> SeatMap;
class Vehicle
@@ -122,9 +114,9 @@ class Vehicle
void InstallAllAccessories(bool evading);
void ApplyAllImmunities();
Unit* GetBase() const { return me; }
VehicleEntry const* GetVehicleInfo() const { return m_vehicleInfo; }
uint32 const& GetCreatureEntry() const { return m_creatureEntry; }
Unit* GetBase() const { return _me; }
VehicleEntry const* GetVehicleInfo() const { return _vehicleInfo; }
uint32 const& GetCreatureEntry() const { return _creatureEntry; }
bool HasEmptySeat(int8 seatId) const;
Unit* GetPassenger(int8 seatId) const;
@@ -137,9 +129,9 @@ class Vehicle
void RelocatePassengers(float x, float y, float z, float ang);
void RemoveAllPassengers();
void Dismiss();
bool IsVehicleInUse() { return m_Seats.begin() != m_Seats.end(); }
bool IsVehicleInUse() { return Seats.begin() != Seats.end(); }
SeatMap m_Seats;
SeatMap Seats;
protected:
uint16 GetExtraMovementFlagsForBase() const;
@@ -148,14 +140,11 @@ class Vehicle
private:
SeatMap::iterator GetSeatIteratorForPassenger(Unit* passenger);
void InitMovementInfoForBase();
protected:
Unit* me;
VehicleEntry const* m_vehicleInfo;
uint32 m_usableSeatNum; // Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags
uint32 m_bonusHP;
uint32 m_creatureEntry; // Can be different than me->GetBase()->GetEntry() in case of players
void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime);
Unit* _me;
VehicleEntry const* _vehicleInfo;
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
};
#endif
+10 -54
View File
@@ -1434,8 +1434,8 @@ void ObjectMgr::LoadCreatures()
// 0 1 2 3 4 5 6 7 8 9 10
QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, "
// 11 12 13 14 15 16 17 18 19 20 21 22
"currentwaypoint, curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags "
// 11 12 13 14 15 16 17 18 19 20 21
"currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags "
"FROM creature "
"LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
"LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
@@ -1494,15 +1494,14 @@ void ObjectMgr::LoadCreatures()
data.currentwaypoint= fields[11].GetUInt32();
data.curhealth = fields[12].GetUInt32();
data.curmana = fields[13].GetUInt32();
data.is_dead = fields[14].GetBool();
data.movementType = fields[15].GetUInt8();
data.spawnMask = fields[16].GetUInt8();
data.phaseMask = fields[17].GetUInt16();
int16 gameEvent = fields[18].GetInt16();
uint32 PoolId = fields[19].GetUInt32();
data.npcflag = fields[20].GetUInt32();
data.unit_flags = fields[21].GetUInt32();
data.dynamicflags = fields[22].GetUInt32();
data.movementType = fields[14].GetUInt8();
data.spawnMask = fields[15].GetUInt8();
data.phaseMask = fields[16].GetUInt16();
int16 gameEvent = fields[17].GetInt16();
uint32 PoolId = fields[18].GetUInt32();
data.npcflag = fields[19].GetUInt32();
data.unit_flags = fields[20].GetUInt32();
data.dynamicflags = fields[21].GetUInt32();
MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
if (!mapEntry)
@@ -1724,7 +1723,6 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 /*team*/, uint32 mapId, float
data.currentwaypoint = 0;
data.curhealth = stats->GenerateHealth(cInfo);
data.curmana = stats->GenerateMana(cInfo);
data.is_dead = false;
data.movementType = cInfo->MovementType;
data.spawnMask = 1;
data.phaseMask = PHASEMASK_NORMAL;
@@ -2935,48 +2933,6 @@ void ObjectMgr::LoadVehicleAccessories()
sLog->outString();
}
void ObjectMgr::LoadVehicleScaling()
{
uint32 oldMSTime = getMSTime();
m_VehicleScalingMap.clear(); // needed for reload case
uint32 count = 0;
QueryResult result = WorldDatabase.Query("SELECT `entry`, `baseItemLevel`, `scalingFactor` FROM `vehicle_scaling_info`");
if (!result)
{
sLog->outString(">> Loaded 0 vehicle scaling entries. DB table `vehicle_scaling_info` is empty.");
sLog->outString();
return;
}
do
{
Field *fields = result->Fetch();
uint32 vehicleEntry = fields[0].GetUInt32();
float baseItemLevel = fields[1].GetFloat();
float scalingFactor = fields[2].GetFloat();
if (!sVehicleStore.LookupEntry(vehicleEntry))
{
sLog->outErrorDb("Table `vehicle_scaling_info`: vehicle entry %u does not exist.", vehicleEntry);
continue;
}
m_VehicleScalingMap[vehicleEntry].ID = vehicleEntry;
m_VehicleScalingMap[vehicleEntry].baseItemLevel = baseItemLevel;
m_VehicleScalingMap[vehicleEntry].scalingFactor = scalingFactor;
++count;
} while (result->NextRow());
sLog->outString(">> Loaded %u vehicle scaling entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
void ObjectMgr::LoadPetLevelInfo()
{
uint32 oldMSTime = getMSTime();
-10
View File
@@ -791,14 +791,6 @@ class ObjectMgr
return NULL;
}
VehicleScalingInfo const* GetVehicleScalingInfo(uint32 vehicleEntry) const
{
VehicleScalingMap::const_iterator itr = m_VehicleScalingMap.find(vehicleEntry);
if (itr != m_VehicleScalingMap.end())
return &itr->second;
return NULL;
}
DungeonEncounterList const* GetDungeonEncounterList(uint32 mapId, Difficulty difficulty)
{
UNORDERED_MAP<uint32, DungeonEncounterList>::const_iterator itr = mDungeonEncounters.find(MAKE_PAIR32(mapId, difficulty));
@@ -896,7 +888,6 @@ class ObjectMgr
void LoadMailLevelRewards();
void LoadVehicleTemplateAccessories();
void LoadVehicleAccessories();
void LoadVehicleScaling();
void LoadGossipText();
@@ -1280,7 +1271,6 @@ class ObjectMgr
VehicleAccessoryMap m_VehicleTemplateAccessoryMap;
VehicleAccessoryMap m_VehicleAccessoryMap;
VehicleScalingMap m_VehicleScalingMap;
typedef std::vector<LocaleConstant> LocalForIndex;
LocalForIndex m_LocalForIndex;
@@ -498,7 +498,7 @@ namespace Trinity
bool operator()(Creature* u)
{
if (i_funit->GetTypeId() != TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) ||
u->getDeathState() != CORPSE || u->isDeadByDefault() || u->isInFlight() ||
u->getDeathState() != CORPSE || u->isInFlight() ||
(u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0 ||
(u->GetDisplayId() != u->GetNativeDisplayId()))
return false;
@@ -525,7 +525,7 @@ namespace Trinity
}
bool operator()(Creature* u)
{
if (u->getDeathState() != CORPSE || u->isInFlight() || u->isDeadByDefault() ||
if (u->getDeathState() != CORPSE || u->isInFlight() ||
(u->GetDisplayId() != u->GetNativeDisplayId()) ||
(u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL) != 0)
return false;
@@ -316,10 +316,14 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recv_data*/)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_PVP_LOG_DATA Message");
Battleground *bg = _player->GetBattleground();
Battleground* bg = _player->GetBattleground();
if (!bg)
return;
// Prevent players from sending BuildPvpLogDataPacket in an arena except for when sent in BattleGround::EndBattleGround.
if (bg->isArena())
return;
WorldPacket data;
sBattlegroundMgr->BuildPvpLogDataPacket(&data, bg);
SendPacket(&data);
+30
View File
@@ -754,6 +754,36 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
data >> mi->splineElevation;
// This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid,
// and when used in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD
// it will freeze clients that receive this player's movement info.
if (mi->HasMovementFlag(MOVEMENTFLAG_ROOT))
mi->flags &= ~MOVEMENTFLAG_ROOT;
// Cannot hover and jump at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
mi->flags &= ~MOVEMENTFLAG_JUMPING;
// Cannot ascend and descend at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING))
mi->flags &= ~(MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
// Cannot move left and right at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT))
mi->flags &= ~(MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
// Cannot strafe left and right at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT))
mi->flags &= ~(MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
// Cannot pitch up and down at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN))
mi->flags &= ~(MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
// Cannot move forwards and backwards at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD))
mi->flags &= ~(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
}
void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
-1
View File
@@ -2516,7 +2516,6 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
|| (m_targets.GetUnitTarget()->getDeathState() == CORPSE
&& m_targets.GetUnitTarget()->GetDisplayId() == m_targets.GetUnitTarget()->GetNativeDisplayId()
&& m_targets.GetUnitTarget()->GetTypeId() == TYPEID_UNIT
&& !m_targets.GetUnitTarget()->ToCreature()->isDeadByDefault()
&& !(m_targets.GetUnitTarget()->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)
&& m_targets.GetUnitTarget()->GetDisplayId() == m_targets.GetUnitTarget()->GetNativeDisplayId()))))
{
+26 -41
View File
@@ -35,9 +35,9 @@ SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS];
SpellMgr::SpellMgr()
{
for (int i = 0; i < TOTAL_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < TOTAL_SPELL_EFFECTS; ++i)
{
switch(i)
switch (i)
{
case SPELL_EFFECT_PERSISTENT_AREA_AURA: //27
case SPELL_EFFECT_SUMMON: //28
@@ -99,9 +99,9 @@ SpellMgr::SpellMgr()
}
}
for (int i = 0; i < TOTAL_SPELL_TARGETS; ++i)
for (uint8 i = 0; i < TOTAL_SPELL_TARGETS; ++i)
{
switch(i)
switch (i)
{
case TARGET_UNIT_CASTER:
case TARGET_UNIT_CASTER_FISHING:
@@ -226,7 +226,7 @@ SpellMgr::SpellMgr()
for (int32 i = 0; i < TOTAL_SPELL_TARGETS; ++i)
{
switch(i)
switch (i)
{
case TARGET_UNIT_AREA_ENEMY_DST:
case TARGET_UNIT_AREA_ENEMY_SRC:
@@ -322,8 +322,8 @@ uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell* spell)
int32 castTime = spellCastTimeEntry->CastTime;
if (spell && spell->GetCaster())
spell->GetCaster()->ModSpellCastTime(spellInfo, castTime, spell);
if (Unit *caster = (spell ? spell->GetCaster() : NULL))
caster->ModSpellCastTime(spellInfo, castTime, spell);
if (spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO && (!spell || !(spell->IsAutoRepeat())))
castTime += 500;
@@ -492,7 +492,7 @@ AuraState GetSpellAuraState(SpellEntry const* spellInfo)
return AURA_STATE_BLEEDING;
if (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST)
for (uint8 i = 0; i<MAX_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STUN
|| spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_ROOT)
return AURA_STATE_FROZEN;
@@ -1187,7 +1187,7 @@ void SpellMgr::LoadSpellTargetPositions()
}
bool found = false;
for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (spellInfo->EffectImplicitTargetA[i] == TARGET_DST_DB || spellInfo->EffectImplicitTargetB[i] == TARGET_DST_DB)
{
@@ -1227,7 +1227,7 @@ void SpellMgr::LoadSpellTargetPositions()
bool found = false;
for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
switch(spellInfo->EffectImplicitTargetA[j])
switch (spellInfo->EffectImplicitTargetA[j])
{
case TARGET_DST_DB:
found = true;
@@ -1235,7 +1235,7 @@ void SpellMgr::LoadSpellTargetPositions()
}
if (found)
break;
switch(spellInfo->EffectImplicitTargetB[j])
switch (spellInfo->EffectImplicitTargetB[j])
{
case TARGET_DST_DB:
found = true;
@@ -1420,7 +1420,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
// spellFamilyName is Ok need check for spellFamilyMask if present
if (spellProcEvent->spellFamilyMask)
{
if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)
if (!(spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags))
return false;
hasFamilyMask = true;
// Some spells are not considered as active even with have spellfamilyflags
@@ -1661,8 +1661,6 @@ void SpellMgr::LoadSpellGroups()
QueryResult result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
if (!result)
{
sLog->outString();
sLog->outString(">> Loaded %u spell group definitions", count);
return;
@@ -1746,7 +1744,6 @@ void SpellMgr::LoadSpellGroupStackRules()
QueryResult result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
if (!result)
{
sLog->outString(">> Loaded 0 spell group stack rules");
sLog->outString();
return;
@@ -1793,8 +1790,6 @@ void SpellMgr::LoadSpellThreats()
QueryResult result = WorldDatabase.Query("SELECT entry, Threat FROM spell_threat");
if (!result)
{
sLog->outString(">> Loaded %u aggro generating spells", count);
sLog->outString();
return;
@@ -1844,9 +1839,9 @@ bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
return false;
// All stance spells. if any better way, change it.
for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch(spellInfo->SpellFamilyName)
switch (spellInfo->SpellFamilyName)
{
case SPELLFAMILY_PALADIN:
// Paladin aura Spell
@@ -1982,7 +1977,7 @@ int32 SpellMgr::CalculateSpellEffectAmount(SpellEntry const* spellEntry, uint8 e
}
// roll in a range <1;EffectDieSides> as of patch 3.3.3
switch(randomPoints)
switch (randomPoints)
{
case 0: break;
case 1: basePoints += 1; break; // range 1..1
@@ -2036,9 +2031,7 @@ int32 SpellMgr::CalculateSpellEffectBaseAmount(int32 value, SpellEntry const* sp
float SpellMgr::CalculateSpellEffectValueMultiplier(SpellEntry const* spellEntry, uint8 effIndex, Unit* caster, Spell* spell)
{
float multiplier = spellEntry->EffectValueMultiplier[effIndex];
if (caster)
if (Player* modOwner = caster->GetSpellModOwner())
if (Player* modOwner = (caster ? caster->GetSpellModOwner() : NULL))
modOwner->ApplySpellMod(spellEntry->Id, SPELLMOD_VALUE_MULTIPLIER, multiplier, spell);
return multiplier;
}
@@ -2046,9 +2039,7 @@ float SpellMgr::CalculateSpellEffectValueMultiplier(SpellEntry const* spellEntry
float SpellMgr::CalculateSpellEffectDamageMultiplier(SpellEntry const* spellEntry, uint8 effIndex, Unit* caster, Spell* spell)
{
float multiplier = spellEntry->EffectDamageMultiplier[effIndex];
if (caster)
if (Player* modOwner = caster->GetSpellModOwner())
if (Player* modOwner = (caster ? caster->GetSpellModOwner() : NULL))
modOwner->ApplySpellMod(spellEntry->Id, SPELLMOD_DAMAGE_MULTIPLIER, multiplier, spell);
return multiplier;
}
@@ -2060,7 +2051,7 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell
return spellInfo;
bool needRankSelection = false;
for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (IsPositiveEffect(spellInfo->Id, i) && (
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
@@ -2142,7 +2133,6 @@ void SpellMgr::LoadSpellLearnSpells()
QueryResult result = WorldDatabase.Query("SELECT entry, SpellID, Active FROM spell_learn_spell");
if (!result)
{
sLog->outString(">> Loaded 0 spell learn spells");
sLog->outString();
sLog->outErrorDb("`spell_learn_spell` table is empty!");
@@ -2207,7 +2197,7 @@ void SpellMgr::LoadSpellLearnSpells()
continue;
// talent or passive spells or skill-step spells auto-casted and not need dependent learning,
// pet teaching spells don't must be dependent learning (casted)
// pet teaching spells must not be dependent learning (casted)
// other required explicit dependent learning
dbc_node.autoLearned = entry->EffectImplicitTargetA[i] == TARGET_UNIT_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry, SPELL_EFFECT_SKILL_STEP);
@@ -2312,7 +2302,6 @@ void SpellMgr::LoadPetLevelupSpellMap()
for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
{
CreatureFamilyEntry const *creatureFamily = sCreatureFamilyStore.LookupEntry(i);
if (!creatureFamily) // not exist
continue;
@@ -2835,7 +2824,7 @@ SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spell
}
// bg spell checks
switch(spellInfo->Id)
switch (spellInfo->Id)
{
case 23333: // Warsong Flag
case 23335: // Silverwing Flag
@@ -3275,7 +3264,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
return false;
// Extra conditions -- leaving the possibility add extra conditions...
switch(spellId)
switch (spellId)
{
case 58600: // No fly Zone - Dalaran
{
@@ -3289,13 +3278,13 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
return false;
break;
}
case SPELL_OIL_REFINERY: // Oil Refinery - Isle of Conquest.
case SPELL_QUARRY: // Quarry - Isle of Conquest.
case 68719: // Oil Refinery - Isle of Conquest.
case 68720: // Quarry - Isle of Conquest.
{
if (player->GetBattlegroundTypeId() != BATTLEGROUND_IC || !player->GetBattleground())
return false;
uint8 nodeType = spellId == SPELL_OIL_REFINERY ? NODE_TYPE_REFINERY : NODE_TYPE_QUARRY;
uint8 nodeType = spellId == 68719 ? NODE_TYPE_REFINERY : NODE_TYPE_QUARRY;
uint8 nodeState = player->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H;
BattlegroundIC* pIC = static_cast<BattlegroundIC*>(player->GetBattleground());
@@ -3341,7 +3330,7 @@ bool SpellMgr::CanAurasStack(Aura const *aura1, Aura const *aura2, bool sameCast
// check same periodic auras
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch(spellInfo_1->EffectApplyAuraName[i])
switch (spellInfo_1->EffectApplyAuraName[i])
{
// DOT or HOT from different casters will stack
case SPELL_AURA_PERIODIC_DAMAGE:
@@ -3460,7 +3449,6 @@ void SpellMgr::LoadSpellEnchantProcData()
QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data");
if (!result)
{
sLog->outString(">> Loaded %u spell enchant proc event conditions", count);
sLog->outString();
return;
@@ -3505,7 +3493,6 @@ void SpellMgr::LoadSpellRequired()
if (!result)
{
sLog->outString(">> Loaded 0 spell required records");
sLog->outString();
sLog->outErrorDb("`spell_required` table is empty!");
@@ -3562,7 +3549,6 @@ void SpellMgr::LoadSpellRanks()
if (!result)
{
sLog->outString(">> Loaded 0 spell rank records");
sLog->outString();
sLog->outErrorDb("`spell_ranks` table is empty!");
@@ -4414,7 +4400,6 @@ void SpellMgr::LoadEnchantCustomAttr()
for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
{
SpellEntry * spellInfo = (SpellEntry*)GetSpellStore()->LookupEntry(i);
if (!spellInfo)
continue;
@@ -4482,7 +4467,7 @@ void SpellMgr::LoadSpellLinked()
if (trigger > 0)
{
switch(type)
switch (type)
{
case 0: mSpellCustomAttr[trigger] |= SPELL_ATTR0_CU_LINK_CAST; break;
case 1: mSpellCustomAttr[trigger] |= SPELL_ATTR0_CU_LINK_HIT; break;
-3
View File
@@ -1349,9 +1349,6 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading Creature template addons...");
sObjectMgr->LoadCreatureTemplateAddons();
sLog->outString("Loading Vehicle scaling information...");
sObjectMgr->LoadVehicleScaling();
sLog->outString("Loading Reputation Reward Rates...");
sObjectMgr->LoadReputationRewardRate();
-32
View File
@@ -63,7 +63,6 @@ public:
static ChatCommand npcSetCommandTable[] =
{
{ "allowmove", SEC_ADMINISTRATOR, false, &HandleNpcSetAllowMovementCommand, "", NULL },
{ "deathstate", SEC_GAMEMASTER, false, &HandleNpcSetDeathStateCommand, "", NULL },
{ "entry", SEC_ADMINISTRATOR, false, &HandleNpcSetEntryCommand, "", NULL },
{ "factionid", SEC_GAMEMASTER, false, &HandleNpcSetFactionIdCommand, "", NULL },
{ "flag", SEC_GAMEMASTER, false, &HandleNpcSetFlagCommand, "", NULL },
@@ -1157,37 +1156,6 @@ public:
return true;
}
//npc deathstate handling
static bool HandleNpcSetDeathStateCommand(ChatHandler* handler, const char* args)
{
if (!*args)
return false;
Creature* pCreature = handler->getSelectedCreature();
if (!pCreature || pCreature->isPet())
{
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
if (strncmp(args, "on", 3) == 0)
pCreature->SetDeadByDefault(true);
else if (strncmp(args, "off", 4) == 0)
pCreature->SetDeadByDefault(false);
else
{
handler->SendSysMessage(LANG_USE_BOL);
handler->SetSentErrorMessage(true);
return false;
}
pCreature->SaveToDB();
pCreature->Respawn();
return true;
}
static bool HandleNpcAddFormationCommand(ChatHandler* handler, const char* args)
{
if (!*args)
@@ -221,6 +221,7 @@ enum FreyaEvents
#define WAVE_TIME 60000 // Normal wave is one minute
#define TIME_DIFFERENCE 10000 // If difference between waveTime and WAVE_TIME is bigger then TIME_DIFFERENCE, schedule EVENT_WAVE in 10 seconds
#define DATA_GETTING_BACK_TO_NATURE 1
#define DATA_KNOCK_ON_WOOD 2
class npc_iron_roots : public CreatureScript
{
@@ -341,8 +342,7 @@ class boss_freya : public CreatureScript
me->setFaction(35);
me->DeleteThreatList();
me->CombatStop(true);
me->ForcedDespawn(7500);
if (elderCount)
me->DespawnOrUnsummon(7500);
me->CastSpell(me, SPELL_KNOCK_ON_WOOD_CREDIT, true);
Creature* Elder[3];
@@ -381,8 +381,6 @@ class boss_freya : public CreatureScript
}
}
instance->SetData(DATA_KNOCK_ON_WOOD_ACHIEVEMENTS, elderCount);
if (Elder[0]->isAlive())
{
Elder[0]->CastSpell(me, SPELL_BRIGHTLEAF_ESSENCE, true);
@@ -418,6 +416,8 @@ class boss_freya : public CreatureScript
{
case DATA_GETTING_BACK_TO_NATURE:
return attunedToNature;
case DATA_KNOCK_ON_WOOD:
return elderCount;
}
return 0;
@@ -1630,6 +1630,66 @@ class achievement_getting_back_to_nature : public AchievementCriteriaScript
}
};
class achievement_knock_on_wood : public AchievementCriteriaScript
{
public:
achievement_knock_on_wood() : AchievementCriteriaScript("achievement_knock_on_wood")
{
}
bool OnCheck(Player* /*player*/, Unit* target)
{
if (!target)
return false;
if (Creature* Freya = target->ToCreature())
if (Freya->AI()->GetData(DATA_KNOCK_ON_WOOD) >= 1)
return true;
return false;
}
};
class achievement_knock_knock_on_wood : public AchievementCriteriaScript
{
public:
achievement_knock_knock_on_wood() : AchievementCriteriaScript("achievement_knock_knock_on_wood")
{
}
bool OnCheck(Player* /*player*/, Unit* target)
{
if (!target)
return false;
if (Creature* Freya = target->ToCreature())
if (Freya->AI()->GetData(DATA_KNOCK_ON_WOOD) >= 2)
return true;
return false;
}
};
class achievement_knock_knock_knock_on_wood : public AchievementCriteriaScript
{
public:
achievement_knock_knock_knock_on_wood() : AchievementCriteriaScript("achievement_knock_knock_knock_on_wood")
{
}
bool OnCheck(Player* /*player*/, Unit* target)
{
if (!target)
return false;
if (Creature* Freya = target->ToCreature())
if (Freya->AI()->GetData(DATA_KNOCK_ON_WOOD) == 3)
return true;
return false;
}
};
void AddSC_boss_freya()
{
new boss_freya();
@@ -1650,4 +1710,7 @@ void AddSC_boss_freya()
new spell_freya_attuned_to_nature_dose_reduction();
new spell_freya_iron_roots();
new achievement_getting_back_to_nature();
new achievement_knock_on_wood();
new achievement_knock_knock_on_wood();
new achievement_knock_knock_knock_on_wood();
}
@@ -85,7 +85,7 @@ enum Yells
SAY_BERSERK = -1603238,
};
enum
enum Achievemments
{
ACHIEV_DISARMED_START_EVENT = 21687,
};
@@ -95,14 +95,9 @@ class boss_kologarn : public CreatureScript
public:
boss_kologarn() : CreatureScript("boss_kologarn") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return GetUlduarAI<boss_kologarnAI>(pCreature);
}
struct boss_kologarnAI : public BossAI
{
boss_kologarnAI(Creature *pCreature) : BossAI(pCreature, BOSS_KOLOGARN), vehicle(pCreature->GetVehicleKit()),
boss_kologarnAI(Creature* creature) : BossAI(creature, BOSS_KOLOGARN), vehicle(creature->GetVehicleKit()),
left(false), right(false)
{
ASSERT(vehicle);
@@ -115,7 +110,7 @@ class boss_kologarn : public CreatureScript
Reset();
}
Vehicle *vehicle;
Vehicle* vehicle;
bool left, right;
uint64 eyebeamTarget;
@@ -140,7 +135,7 @@ class boss_kologarn : public CreatureScript
void Reset()
{
_Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
eyebeamTarget = 0;
}
@@ -149,7 +144,8 @@ class boss_kologarn : public CreatureScript
DoScriptText(SAY_DEATH, me);
DoCast(SPELL_KOLOGARN_PACIFY);
me->GetMotionMaster()->MoveTargetedHome();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetCorpseDelay(604800); // Prevent corpse from despawning.
_JustDied();
}
@@ -204,7 +200,6 @@ class boss_kologarn : public CreatureScript
if (!right && !left)
events.ScheduleEvent(EVENT_STONE_SHOUT, 5000);
if (instance)
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_DISARMED_START_EVENT);
}
else
@@ -234,7 +229,6 @@ class boss_kologarn : public CreatureScript
summon->CastSpell(summon, SPELL_FOCUSED_EYEBEAM_PERIODIC, true);
summon->CastSpell(summon, SPELL_FOCUSED_EYEBEAM_VISUAL, true);
summon->SetReactState(REACT_PASSIVE);
summon->SetFlag(UNIT_FIELD_ATTACK_POWER, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
// One of the above spells is a channeled spell, we need to clear this unit state for MoveChase to work
summon->ClearUnitState(UNIT_STAT_CASTING);
@@ -249,7 +243,7 @@ class boss_kologarn : public CreatureScript
}
}
void UpdateAI(const uint32 diff)
void UpdateAI(uint32 const diff)
{
if (!UpdateVictim())
return;
@@ -289,14 +283,14 @@ class boss_kologarn : public CreatureScript
break;
case EVENT_RESPAWN_LEFT_ARM:
{
if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_LEFT_ARM) : 0))
if (Creature* arm = Unit::GetCreature(*me, instance->GetData64(DATA_LEFT_ARM)))
RespawnArm(arm->ToCreature());
events.CancelEvent(EVENT_RESPAWN_LEFT_ARM);
break;
}
case EVENT_RESPAWN_RIGHT_ARM:
{
if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_RIGHT_ARM) : 0))
if (Creature* arm = Unit::GetCreature(*me, instance->GetData64(DATA_RIGHT_ARM)))
RespawnArm(arm->ToCreature());
events.CancelEvent(EVENT_RESPAWN_RIGHT_ARM);
break;
@@ -312,8 +306,7 @@ class boss_kologarn : public CreatureScript
}
break;
case EVENT_FOCUSED_EYEBEAM:
Unit* eyebeamTargetUnit = SelectTarget(SELECT_TARGET_FARTHEST, 0, 0, true);
if (eyebeamTargetUnit)
if (Unit* eyebeamTargetUnit = SelectTarget(SELECT_TARGET_FARTHEST, 0, 0, true))
{
eyebeamTarget = eyebeamTargetUnit->GetGUID();
DoCast(SPELL_SUMMON_FOCUSED_EYEBEAM);
@@ -335,6 +328,11 @@ class boss_kologarn : public CreatureScript
arm->CastSpell(arm, SPELL_ARM_ENTER_VISUAL, true);
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetUlduarAI<boss_kologarnAI>(creature);
}
};
class spell_ulduar_rubble_summon : public SpellScriptLoader
@@ -374,14 +372,14 @@ class spell_ulduar_rubble_summon : public SpellScriptLoader
class StoneGripTargetSelector : public std::unary_function<Unit *, bool>
{
public:
StoneGripTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) {}
StoneGripTargetSelector(Creature* me, Unit const* victim) : _me(me), _victim(victim) {}
bool operator() (Unit* pTarget)
bool operator() (Unit* target)
{
if (pTarget == _victim && _me->getThreatManager().getThreatList().size() > 1)
if (target == _victim && _me->getThreatManager().getThreatList().size() > 1)
return true;
if (pTarget->GetTypeId() != TYPEID_PLAYER)
if (target->GetTypeId() != TYPEID_PLAYER)
return true;
return false;
@@ -472,11 +470,8 @@ class spell_ulduar_cancel_stone_grip : public SpellScriptLoader
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* target = this->GetHitPlayer();
if (!target)
return;
if (!target->GetVehicle())
Unit* target = GetHitUnit();
if (!target || !target->GetVehicle())
return;
switch (target->GetMap()->GetDifficulty())
@@ -506,7 +501,7 @@ class spell_ulduar_cancel_stone_grip : public SpellScriptLoader
class spell_ulduar_squeezed_lifeless : public SpellScriptLoader
{
public:
public:
spell_ulduar_squeezed_lifeless() : SpellScriptLoader("spell_ulduar_squeezed_lifeless") { }
class spell_ulduar_squeezed_lifeless_SpellScript : public SpellScript
@@ -515,7 +510,7 @@ public:
void HandleInstaKill(SpellEffIndex /*effIndex*/)
{
if (!GetHitPlayer()->GetVehicle())
if (!GetHitPlayer() || !GetHitPlayer()->GetVehicle())
return;
Position pos;
@@ -588,8 +583,8 @@ class spell_ulduar_stone_grip : public SpellScriptLoader
void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Player* pOwner = GetOwner()->ToPlayer())
pOwner->RemoveAurasDueToSpell(aurEff->GetAmount());
if (Player* owner = GetOwner()->ToPlayer())
owner->RemoveAurasDueToSpell(aurEff->GetAmount());
}
void OnRemoveVehicle(AuraEffect const* /*aurEff*/, AuraEffectHandleModes mode)
@@ -600,13 +595,13 @@ class spell_ulduar_stone_grip : public SpellScriptLoader
if (GetOwner()->GetTypeId() != TYPEID_UNIT)
return;
Player* pCaster = GetCaster() ? GetCaster()->ToPlayer() : NULL;
if (!pCaster || !pCaster->IsOnVehicle(GetOwner()->ToUnit()))
Player* caster = GetCaster() ? GetCaster()->ToPlayer() : NULL;
if (!caster || !caster->IsOnVehicle(GetOwner()->ToUnit()))
return;
pCaster->RemoveAurasDueToSpell(GetId());
pCaster->ExitVehicle();
pCaster->GetMotionMaster()->MoveJump(1756.25f + irand(-3, 3), -8.3f + irand(-3, 3), 448.8f, 5.0f, 5.0f);
caster->RemoveAurasDueToSpell(GetId());
caster->ExitVehicle();
caster->GetMotionMaster()->MoveJump(1756.25f + irand(-3, 3), -8.3f + irand(-3, 3), 448.8f, 5.0f, 5.0f);
PreventDefaultAction();
}
@@ -652,7 +647,6 @@ class spell_kologarn_stone_shout : public SpellScriptLoader
void AddSC_boss_kologarn()
{
new boss_kologarn();
new spell_ulduar_rubble_summon();
new spell_ulduar_squeezed_lifeless();
new spell_ulduar_cancel_stone_grip();
@@ -79,6 +79,7 @@ class instance_ulduar : public InstanceMapScript
uint32 TeamInInstance;
uint32 HodirRareCacheData;
uint8 elderCount;
bool conSpeedAtory;
std::set<uint64> mRubbleSpawns;
@@ -117,6 +118,7 @@ class instance_ulduar : public InstanceMapScript
TeamInInstance = 0;
HodirRareCacheData = 0;
elderCount = 0;
conSpeedAtory = false;
memset(Encounter, 0, sizeof(Encounter));
memset(XTToyPileGUIDs, 0, sizeof(XTToyPileGUIDs));
@@ -210,23 +212,6 @@ class instance_ulduar : public InstanceMapScript
case NPC_KOLOGARN:
KologarnGUID = creature->GetGUID();
break;
case NPC_KOLOGARN_BRIDGE:
// The below hacks are courtesy of the grid/visibilitysystem
if (GetBossState(BOSS_KOLOGARN) == DONE)
{
creature->SetDeadByDefault(true);
creature->setDeathState(CORPSE);
creature->DestroyForNearbyPlayers();
creature->UpdateObjectVisibility(true);
}
else
{
creature->SetDeadByDefault(false);
creature->setDeathState(CORPSE);
creature->RemoveCorpse(true);
}
break;
case NPC_AURIAYA:
AuriayaGUID = creature->GetGUID();
break;
@@ -374,6 +359,29 @@ class instance_ulduar : public InstanceMapScript
}
}
void OnCreatureDeath(Creature* creature)
{
switch (creature->GetEntry())
{
case NPC_CORRUPTED_SERVITOR:
case NPC_MISGUIDED_NYMPH:
case NPC_GUARDIAN_LASHER:
case NPC_FOREST_SWARMER:
case NPC_MANGROVE_ENT:
case NPC_IRONROOT_LASHER:
case NPC_NATURES_BLADE:
case NPC_GUARDIAN_OF_LIFE:
if (!conSpeedAtory)
{
DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_CON_SPEED_ATORY);
conSpeedAtory = true;
}
break;
default:
break;
}
}
void ProcessEvent(GameObject* /*gameObject*/, uint32 eventId)
{
// Flame Leviathan's Tower Event triggers
@@ -440,7 +448,7 @@ class instance_ulduar : public InstanceMapScript
if (state == DONE)
{
if (GameObject* HodirRareCache = instance->GetGameObject(HodirRareCacheGUID))
if (GetData(DATA_HODIR_RARE_CACHE) == 1)
if (GetData(DATA_HODIR_RARE_CACHE))
HodirRareCache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
if (GameObject* HodirChest = instance->GetGameObject(HodirChestGUID))
HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay());
@@ -480,9 +488,12 @@ class instance_ulduar : public InstanceMapScript
break;
case DATA_HODIR_RARE_CACHE:
HodirRareCacheData = data;
break;
case DATA_KNOCK_ON_WOOD_ACHIEVEMENTS:
elderCount = data;
if (!HodirRareCacheData)
{
if (Creature* Hodir = instance->GetCreature(HodirGUID))
if (GameObject* gameObject = instance->GetGameObject(HodirRareCacheGUID))
Hodir->RemoveGameObject(gameObject, false);
}
break;
default:
break;
@@ -582,33 +593,13 @@ class instance_ulduar : public InstanceMapScript
{
case TYPE_COLOSSUS:
return Encounter[type];
break;
case DATA_HODIR_RARE_CACHE:
return HodirRareCacheData;
break;
}
return 0;
}
bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* /*player*/, Unit const* /*target*/, uint32 /*miscvalue1*/)
{
switch (criteriaId)
{
case CRITERIA_KNOCK_ON_WOOD_10:
case CRITERIA_KNOCK_ON_WOOD_25:
return elderCount >= 1;
case CRITERIA_KNOCK_KNOCK_ON_WOOD_10:
case CRITERIA_KNOCK_KNOCK_ON_WOOD_25:
return elderCount >= 2;
case CRITERIA_KNOCK_KNOCK_KNOCK_ON_WOOD_10:
case CRITERIA_KNOCK_KNOCK_KNOCK_ON_WOOD_25:
return elderCount == 3;
default:
break;
}
return false;
return 0;
}
std::string GetSaveData()
@@ -67,6 +67,7 @@ enum UlduarBosses
enum UlduarNPCs
{
// General
NPC_LEVIATHAN = 33113,
NPC_IGNIS = 33118,
NPC_RAZORSCALE = 33186,
@@ -79,7 +80,6 @@ enum UlduarNPCs
NPC_MOLGEIM = 32927,
NPC_BRUNDIR = 32857,
NPC_KOLOGARN = 32930,
NPC_KOLOGARN_BRIDGE = 34297,
NPC_FOCUSED_EYEBEAM = 33632,
NPC_FOCUSED_EYEBEAM_RIGHT = 33802,
NPC_LEFT_ARM = 32933,
@@ -93,6 +93,8 @@ enum UlduarNPCs
NPC_VEZAX = 33271,
NPC_YOGGSARON = 33288,
NPC_ALGALON = 32871,
// Mimiron
NPC_LEVIATHAN_MKII = 33432,
NPC_VX_001 = 33651,
NPC_AERIAL_COMMAND_UNIT = 33670,
@@ -119,6 +121,16 @@ enum UlduarNPCs
NPC_BATTLE_PRIEST_GINA = 33330,
NPC_FIELD_MEDIC_PENNY = 32897,
NPC_FIELD_MEDIC_JESSI = 33326,
// Freya's trash NPCs
NPC_CORRUPTED_SERVITOR = 33354,
NPC_MISGUIDED_NYMPH = 33355,
NPC_GUARDIAN_LASHER = 33430,
NPC_FOREST_SWARMER = 33431,
NPC_MANGROVE_ENT = 33525,
NPC_IRONROOT_LASHER = 33526,
NPC_NATURES_BLADE = 33527,
NPC_GUARDIAN_OF_LIFE = 33528,
};
enum UlduarGameObjects
@@ -157,41 +169,7 @@ enum UlduarTowerEvents
EVENT_TOWER_OF_LIFE_DESTROYED = 21030,
};
enum UlduarAchievementCriteriaIds
{
// Flame Leviathan
CRITERIA_UNBROKEN_10 = 10044,
CRITERIA_UNBROKEN_25 = 10045,
CRITERIA_SHUTOUT_10 = 10054,
CRITERIA_SHUTOUT_25 = 10055,
CRITERIA_3_CAR_GARAGE_CHOPPER_10 = 10046,
CRITERIA_3_CAR_GARAGE_SIEGE_10 = 10047,
CRITERIA_3_CAR_GARAGE_DEMOLISHER_10 = 10048,
CRITERIA_3_CAR_GARAGE_CHOPPER_25 = 10049,
CRITERIA_3_CAR_GARAGE_SIEGE_25 = 10050,
CRITERIA_3_CAR_GARAGE_DEMOLISHER_25 = 10051,
// Ignis
CRITERIA_HOT_POCKET_10 = 10430,
CRITERIA_HOT_POCKET_25 = 10431,
// Razorscale
CRITERIA_QUICK_SHAVE_10 = 10062,
CRITERIA_QUICK_SHAVE_25 = 10063,
// Freya
CRITERIA_KNOCK_ON_WOOD_10 = 10447,
CRITERIA_KNOCK_ON_WOOD_25 = 10459,
CRITERIA_KNOCK_KNOCK_ON_WOOD_10 = 10448,
CRITERIA_KNOCK_KNOCK_ON_WOOD_25 = 10460,
CRITERIA_KNOCK_KNOCK_KNOCK_ON_WOOD_10 = 10449,
CRITERIA_KNOCK_KNOCK_KNOCK_ON_WOOD_25 = 10461,
};
enum UlduarAchievementData
{
DATA_KNOCK_ON_WOOD_ACHIEVEMENTS = 1,
};
#define CRITERIA_CON_SPEED_ATORY 21597
template<class AI>
CreatureAI* GetUlduarAI(Creature* creature)
@@ -69,11 +69,6 @@ uint32 OPvPCapturePointNA::GetAliveGuardsCount()
if (cr->isAlive())
++cnt;
}
else if (CreatureData const* cd = sObjectMgr->GetCreatureData(GUID_LOPART(itr->second)))
{
if (!cd->is_dead)
++cnt;
}
}
break;
default:
+113
View File
@@ -1154,6 +1154,117 @@ public:
}
};
enum Launch
{
SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
};
class spell_gen_launch : public SpellScriptLoader
{
public:
spell_gen_launch() : SpellScriptLoader("spell_gen_launch") {}
class spell_gen_launch_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gen_launch_SpellScript);
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
SpellEntry const* const spell = GetSpellInfo();
if (Player* player = GetHitPlayer())
{
player->CastSpell(player,spell->EffectTriggerSpell[1],true); // changes the player's seat
player->AddAura(SPELL_LAUNCH_NO_FALLING_DAMAGE,player); // prevents falling damage
}
}
void Launch()
{
WorldLocation const* const position = GetTargetDest();
if (Player* player = GetHitPlayer())
{
player->ExitVehicle();
// A better research is needed
// There is no spell for this, the following calculation was based on void Spell::CalculateJumpSpeeds
float speedZ = 10.0f;
float dist = position->GetExactDist2d(player->GetPositionX(),player->GetPositionY());
float speedXY = dist;
player->GetMotionMaster()->MoveJump(position->GetPositionX(),position->GetPositionY(),position->GetPositionZ(),speedXY,speedZ);
}
}
void Register()
{
OnEffect += SpellEffectFn(spell_gen_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST);
AfterHit += SpellHitFn(spell_gen_launch_SpellScript::Launch);
}
};
SpellScript* GetSpellScript() const
{
return new spell_gen_launch_SpellScript();
}
};
class spell_gen_vehicle_scaling : public SpellScriptLoader
{
public:
spell_gen_vehicle_scaling() : SpellScriptLoader("spell_gen_vehicle_scaling") { }
class spell_gen_vehicle_scaling_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_vehicle_scaling_AuraScript);
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Unit* caster = GetCaster();
if (!caster || !caster->ToPlayer())
return;
float factor;
uint16 baseItemLevel;
// TODO: Reserach coeffs for different vehicles
switch (GetId())
{
case 66668:
factor = 1.0f;
baseItemLevel = 205;
break;
default:
factor = 1.0f;
baseItemLevel = 170;
break;
}
float avgILvl = caster->ToPlayer()->GetAverageItemLevel();
if (avgILvl < baseItemLevel)
return; // TODO: Research possibility of scaling down
amount = uint16((avgILvl - baseItemLevel) * factor);
}
void Register()
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT);
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_vehicle_scaling_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT);
}
};
AuraScript* GetAuraScript() const
{
return new spell_gen_vehicle_scaling_AuraScript();
}
};
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -1181,4 +1292,6 @@ void AddSC_generic_spell_scripts()
new spell_gen_lifeblood();
new spell_gen_magic_rooster();
new spell_gen_allow_cast_from_item_only();
new spell_gen_launch();
new spell_gen_vehicle_scaling();
}