[svn] Improve TargetedMovement (TODO: let mob find "near angle" rather than "random angle").

Delete a repeated check in instance canenter().
Fix some spell targets.
Add some sunwell spell sql.
Fix Magtheridons earthquake. (TODO: need to find out why soul transfer has no effect when casted by mobs)
Let Brutallus dual wield. Enable burn (still no script effect).
Quick fix for shadowmoon valley illidan quest crash (wait for author's fix).

--HG--
branch : trunk
This commit is contained in:
megamage
2008-10-31 21:42:00 -05:00
parent 1c3d4c40c3
commit e2eb694c57
14 changed files with 313 additions and 303 deletions
+14
View File
@@ -0,0 +1,14 @@
DELETE FROM spell_linked_spell WHERE `spell_trigger` IN (46648, 46019, 46021, -46021, 46020);
INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46648, 44866, 1, 'Spectral Blast');
INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46019, 46021, 1, 'Teleport: Spectral Realm');
INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46021, 44852, 1, 'Spectral Realm Aura');
INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (-46021, 46020, 0, 'Teleport: Normal Realm');
INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (46020, 44867, 1, 'Spectral Exhaustion');
DELETE FROM spell_target_position WHERE `id` IN (46019, 46020);
INSERT INTO spell_target_position () VALUES (46019, 580, 1704.34, 928.17, -74.558, 0);
INSERT INTO spell_target_position () VALUES (46020, 580, 1704.34, 928.17, 53.079, 0);
--Magtheridon Earthquake
DELETE FROM spell_script_target WHERE `entry` IN (30657);
INSERT INTO spell_script_target VALUES ('30657', '1', '24136');
@@ -2079,7 +2079,7 @@ void boss_illidan_stormrageAI::Reset()
m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
DoCast(m_creature, SPELL_DUAL_WIELD, true);
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
}
void boss_illidan_stormrageAI::HandleTalkSequence()
@@ -31,7 +31,7 @@ EndScriptData */
#define SPELL_BLASTNOVA 30616
#define SPELL_CLEAVE 30619
#define SPELL_QUAKE_TRIGGER 30576 // must be cast with 30561 as the proc spell
#define SPELL_QUAKE_TRIGGER 30657 // must be cast with 30561 as the proc spell
#define SPELL_QUAKE_KNOCKBACK 30571
#define SPELL_BLAZE_TARGET 30541 // core bug, does not support target 7
#define SPELL_BLAZE_TRAP 30542
@@ -168,6 +168,21 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
pInstance =(ScriptedInstance*)m_creature->GetInstanceData();
m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
// target 7, random target with certain entry spell, need core fix
SpellEntry *TempSpell;
TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_BLAZE_TARGET);
if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 6)
{
TempSpell->EffectImplicitTargetA[0] = 6;
TempSpell->EffectImplicitTargetB[0] = 0;
}
TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_QUAKE_TRIGGER);
if(TempSpell && TempSpell->EffectTriggerSpell[0] != SPELL_QUAKE_KNOCKBACK)
{
TempSpell->EffectTriggerSpell[0] = SPELL_QUAKE_KNOCKBACK;
}
Reset();
}
@@ -328,8 +343,7 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
// to avoid blastnova interruption
if(!m_creature->IsNonMeleeSpellCasted(false))
{
int32 i = SPELL_QUAKE_KNOCKBACK;
m_creature->CastCustomSpell(m_creature, SPELL_QUAKE_TRIGGER, &i, 0, 0, false);
m_creature->CastSpell(m_creature, SPELL_QUAKE_TRIGGER, true);
Quake_Timer = 50000;
}
}else Quake_Timer -= diff;
@@ -26,8 +26,6 @@ EndScriptData */
#define SPELL_SOUL_TRANSFER 30531 // core bug, does not support target 7
#define SPELL_BLAZE_TARGET 30541 // core bug, does not support target 7
#define SPELL_DEBRIS_DAMAGE 30631 // core bug, does not support target 8
#define SPELL_DEBRIS_KNOCKDOWN 36449 // core bug, does not support target 8
#define CHAMBER_CENTER_X -15.14
#define CHAMBER_CENTER_Y 1.8
@@ -40,13 +38,6 @@ struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
instance_magtheridons_lair(Map *Map) : ScriptedInstance(Map)
{
Initialize();
// target 7, random target with certain entry spell, need core fix
SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_BLAZE_TARGET);
if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 6)
{
TempSpell->EffectImplicitTargetA[0] = 6;
TempSpell->EffectImplicitTargetB[0] = 0;
}
}
uint32 Encounters[ENCOUNTERS];
@@ -813,261 +813,266 @@ void DoSpeach(int phase)
struct TRINITY_DLL_DECL Overlord_MorghorAI : public ScriptedAI
{
Overlord_MorghorAI(Creature *c) : ScriptedAI(c) {Reset();}
Overlord_MorghorAI(Creature *c) : ScriptedAI(c)
{
Lord = NULL;
Yarzill = NULL;
Reset();
}
Unit* m_player;
Unit* PlayerCheck;
uint32 SpeachTimer;
uint32 SpeachNum;
uint64 PlayerGUID;
uint64 YazillGUID;
bool DoingSpeach;
bool Failed;
Unit* m_player;
Unit* PlayerCheck;
Creature* Lord;
Creature* Yarzill;
uint32 SpeachTimer;
uint32 SpeachNum;
void Reset()
{
if (Lord)
{
Lord->SetUInt64Value(UNIT_FIELD_TARGET, 0);
Lord->SetVisibility(VISIBILITY_OFF);
Lord->setDeathState(JUST_DIED);
}
uint64 PlayerGUID;
uint64 YazillGUID;
if (Yarzill)
{
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, 0);
}
m_creature->Relocate(-5085.77, 577.231, 86.6719, 2.32608);
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 2);
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
m_player = NULL;
PlayerCheck = NULL;
PlayerGUID = 0;
YazillGUID = 0;
Lord = NULL;
Yarzill = NULL;
DoingSpeach = false;
Failed = false;
SpeachNum = 0;
SpeachTimer = 0;
}
bool DoingSpeach;
bool Failed;
void BeginSpeach(Unit* target)
{
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
DoSay(OVERLORD_SAY_1,LANG_UNIVERSAL,target);
m_player = target;
PlayerCheck = NULL;
PlayerGUID = target->GetGUID();
SpeachTimer = 4200;
SpeachNum = 0;
DoingSpeach = true;
}
void Aggro(Unit *who){}
Creature* Lord;
Creature* Yarzill;
void MoveInLineOfSight(Unit *who)
{
if (!who)
return;
void Reset()
{
if (Lord)
{
Lord->SetUInt64Value(UNIT_FIELD_TARGET, 0);
Lord->SetVisibility(VISIBILITY_OFF);
Lord->setDeathState(JUST_DIED);
}
if (DoingSpeach)
{
if (who->GetEntry() == 23141 && m_creature->IsWithinDistInMap(who, 15))
{
if (!YazillGUID)
{
YazillGUID = who->GetGUID();
}
}
}
}
if (Yarzill)
{
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, 0);
}
void UpdateAI(const uint32 diff)
{
//Speach
if (DoingSpeach)
{
if (SpeachTimer < diff)
{
if (YazillGUID && !Yarzill)
Yarzill = ((Creature*)Unit::GetUnit((*m_creature), YazillGUID));
m_creature->Relocate(-5085.77, 577.231, 86.6719, 2.32608);
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 2);
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
m_player = NULL;
PlayerCheck = NULL;
PlayerGUID = 0;
YazillGUID = 0;
Lord = NULL;
Yarzill = NULL;
DoingSpeach = false;
Failed = false;
SpeachNum = 0;
SpeachTimer = 0;
}
if (!m_creature->IsWithinDistInMap(m_player, 50) && ((Player*)m_player)->GetQuestStatus(QUEST_LORD_ILLIDAN_STORMRAGE) == QUEST_STATUS_INCOMPLETE)
{
((Player*)m_player)->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE);
SpeachNum = 30;
}
void BeginSpeach(Unit* target)
{
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
DoSay(OVERLORD_SAY_1,LANG_UNIVERSAL,target);
m_player = target;
PlayerCheck = NULL;
PlayerGUID = target->GetGUID();
SpeachTimer = 4200;
SpeachNum = 0;
DoingSpeach = true;
}
switch (SpeachNum)
{
// Overlord Movement
case 0:
m_creature->GetMotionMaster()->MovePoint(0, -5104.41, 595.297, 85.6838);
SpeachTimer = 9000; SpeachNum++; break;
// Overlord Yell 1
case 1:
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SHOUT);
DoYell(OVERLORD_YELL_1,LANG_UNIVERSAL,m_player);
SpeachTimer = 4500; SpeachNum++; break;
// Overlord Angle
case 2:
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 3200; SpeachNum++; break;
// Overlord Say 2
case 3:
DoSay(OVERLORD_SAY_2,LANG_UNIVERSAL,NULL);
SpeachTimer = 2000; SpeachNum++; break;
// Summon Illidan
case 4:
Lord = m_creature->SummonCreature(LORD_ILLIDAN_STORMRAGE, -5107.83, 602.584, 85.2393, 4.92598, TEMPSUMMON_CORPSE_DESPAWN, 0);
Lord->LoadCreaturesAddon();
SpeachTimer = 350; SpeachNum++; break;
// Illidan Cast Red Bolt
case 5:
Lord->CastSpell(Lord, SPELL_ONE, true);
Lord->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Lord->GetGUID());
SpeachTimer = 2000; SpeachNum++; break;
// Overlord Yell 2
case 6:
DoYell(OVERLORD_YELL_2,LANG_UNIVERSAL,NULL);
SpeachTimer = 4500; SpeachNum++; break;
// Overlord Kneel
case 7:
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,8);
SpeachTimer = 2500; SpeachNum++; break;
// Overlord Say 3
case 8:
DoSay(OVERLORD_SAY_3,LANG_UNIVERSAL,NULL);
SpeachTimer = 6500; SpeachNum++; break;
// Illidan Say 1
case 9:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(1);
SpeachTimer = 5000; SpeachNum++; break;
// Overlord Say 4
case 10:
DoSay(OVERLORD_SAY_4,LANG_UNIVERSAL,m_player);
SpeachTimer = 6000; SpeachNum++; break;
// Illidan Say 2
case 11:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(2);
SpeachTimer = 5500; SpeachNum++; break;
// Illidan Say 3
case 12:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(3);
SpeachTimer = 4000; SpeachNum++; break;
// Illidan Angle
case 13:
Lord->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 1500; SpeachNum++; break;
// Illidan Say 4
case 14:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(4);
SpeachTimer = 1500; SpeachNum++; break;
// Illidan Cast
case 15:
PlayerCheck = Unit::GetUnit(*Lord, PlayerGUID);
if (PlayerCheck)
{
Lord->CastSpell(m_player, SPELL_TWO, true);
m_player->RemoveAurasDueToSpell(SPELL_THREE);
m_player->RemoveAurasDueToSpell(SPELL_FOUR);
SpeachTimer = 5000; SpeachNum++;
}
else
{
((Player*)m_player)->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE);
SpeachTimer = 100; SpeachNum = 30;
}
break;
// Illidan Say 5
case 16:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(5);
SpeachTimer = 5000; SpeachNum++; break;
// Illidan Say 6
case 17:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(6);
SpeachTimer = 5000; SpeachNum++; break;
// Illidan Say 7
case 18:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(7);
SpeachTimer = 5000; SpeachNum++; break;
// Illidan Fly
case 19:
Lord->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
Lord->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
SpeachTimer = 500; SpeachNum++; break;
// Overlord Say 5
case 20:
DoSay(OVERLORD_SAY_5,LANG_UNIVERSAL,NULL);
SpeachTimer = 500; SpeachNum++; break;
// Illidan Despawn
case 21:
Lord->SetVisibility(VISIBILITY_OFF);
Lord->setDeathState(JUST_DIED);
Lord = NULL;
SpeachTimer = 1000; SpeachNum++; break;
// Overlord Stand Up
case 22:
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
SpeachTimer = 2000; SpeachNum++; break;
// Overlord Angle
case 23:
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 5000; SpeachNum++; break;
// Overlord Say 6
case 24:
DoSay(OVERLORD_SAY_6,LANG_UNIVERSAL,NULL);
SpeachTimer = 2000; SpeachNum++; break;
// Complete Quest
case 25:
((Player*)m_player)->CompleteQuest(QUEST_LORD_ILLIDAN_STORMRAGE);
SpeachTimer = 6000; SpeachNum++; break;
// Goblin Angle
case 26:
if (Yarzill)
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 500; SpeachNum++; break;
// Cast Again Dragonaw Illusion
case 27:
m_player->RemoveAurasDueToSpell(SPELL_TWO);
m_player->RemoveAurasDueToSpell(41519);
m_player->CastSpell(m_player, SPELL_THREE, true);
m_player->CastSpell(m_player, SPELL_FOUR, true);
SpeachTimer = 1000; SpeachNum++; break;
// Goblin
case 28:
if (Yarzill)
((Yarzill_The_MercAI*)Yarzill->AI())->DoSpeach(m_player);
SpeachTimer = 5000; SpeachNum++; break;
// Goblin Off
case 29:
if (Yarzill)
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, 0);
SpeachTimer = 5000; SpeachNum++; break;
// Overlord Go Back
case 30:
m_creature->GetMotionMaster()->MovePoint(0, -5085.77, 577.231, 86.6719);
SpeachTimer = 5000; SpeachNum++; break;
// Reset
case 31:
Reset();
break;
default: break;
}
}else SpeachTimer -= diff;
}
}
void Aggro(Unit *who){}
void MoveInLineOfSight(Unit *who)
{
if (!who)
return;
if (DoingSpeach)
{
if (who->GetEntry() == 23141 && m_creature->IsWithinDistInMap(who, 15))
{
if (!YazillGUID)
{
YazillGUID = who->GetGUID();
}
}
}
}
void UpdateAI(const uint32 diff)
{
//Speach
if (DoingSpeach)
{
if (SpeachTimer < diff)
{
if (YazillGUID && !Yarzill)
Yarzill = ((Creature*)Unit::GetUnit((*m_creature), YazillGUID));
if (!m_creature->IsWithinDistInMap(m_player, 50) && ((Player*)m_player)->GetQuestStatus(QUEST_LORD_ILLIDAN_STORMRAGE) == QUEST_STATUS_INCOMPLETE)
{
((Player*)m_player)->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE);
SpeachNum = 30;
}
switch (SpeachNum)
{
// Overlord Movement
case 0:
m_creature->GetMotionMaster()->MovePoint(0, -5104.41, 595.297, 85.6838);
SpeachTimer = 9000; SpeachNum++; break;
// Overlord Yell 1
case 1:
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SHOUT);
DoYell(OVERLORD_YELL_1,LANG_UNIVERSAL,m_player);
SpeachTimer = 4500; SpeachNum++; break;
// Overlord Angle
case 2:
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 3200; SpeachNum++; break;
// Overlord Say 2
case 3:
DoSay(OVERLORD_SAY_2,LANG_UNIVERSAL,NULL);
SpeachTimer = 2000; SpeachNum++; break;
// Summon Illidan
case 4:
Lord = m_creature->SummonCreature(LORD_ILLIDAN_STORMRAGE, -5107.83, 602.584, 85.2393, 4.92598, TEMPSUMMON_CORPSE_DESPAWN, 0);
Lord->LoadCreaturesAddon();
SpeachTimer = 350; SpeachNum++; break;
// Illidan Cast Red Bolt
case 5:
Lord->CastSpell(Lord, SPELL_ONE, true);
Lord->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Lord->GetGUID());
SpeachTimer = 2000; SpeachNum++; break;
// Overlord Yell 2
case 6:
DoYell(OVERLORD_YELL_2,LANG_UNIVERSAL,NULL);
SpeachTimer = 4500; SpeachNum++; break;
// Overlord Kneel
case 7:
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,8);
SpeachTimer = 2500; SpeachNum++; break;
// Overlord Say 3
case 8:
DoSay(OVERLORD_SAY_3,LANG_UNIVERSAL,NULL);
SpeachTimer = 6500; SpeachNum++; break;
// Illidan Say 1
case 9:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(1);
SpeachTimer = 5000; SpeachNum++; break;
// Overlord Say 4
case 10:
DoSay(OVERLORD_SAY_4,LANG_UNIVERSAL,m_player);
SpeachTimer = 6000; SpeachNum++; break;
// Illidan Say 2
case 11:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(2);
SpeachTimer = 5500; SpeachNum++; break;
// Illidan Say 3
case 12:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(3);
SpeachTimer = 4000; SpeachNum++; break;
// Illidan Angle
case 13:
Lord->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 1500; SpeachNum++; break;
// Illidan Say 4
case 14:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(4);
SpeachTimer = 1500; SpeachNum++; break;
// Illidan Cast
case 15:
PlayerCheck = Unit::GetUnit(*Lord, PlayerGUID);
if (PlayerCheck)
{
Lord->CastSpell(m_player, SPELL_TWO, true);
m_player->RemoveAurasDueToSpell(SPELL_THREE);
m_player->RemoveAurasDueToSpell(SPELL_FOUR);
SpeachTimer = 5000; SpeachNum++;
}
else
{
((Player*)m_player)->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE);
SpeachTimer = 100; SpeachNum = 30;
}
break;
// Illidan Say 5
case 16:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(5);
SpeachTimer = 5000; SpeachNum++; break;
// Illidan Say 6
case 17:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(6);
SpeachTimer = 5000; SpeachNum++; break;
// Illidan Say 7
case 18:
((Lord_IllidanAI*)Lord->AI())->DoSpeach(7);
SpeachTimer = 5000; SpeachNum++; break;
// Illidan Fly
case 19:
Lord->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
Lord->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
SpeachTimer = 500; SpeachNum++; break;
// Overlord Say 5
case 20:
DoSay(OVERLORD_SAY_5,LANG_UNIVERSAL,NULL);
SpeachTimer = 500; SpeachNum++; break;
// Illidan Despawn
case 21:
Lord->SetVisibility(VISIBILITY_OFF);
Lord->setDeathState(JUST_DIED);
Lord = NULL;
SpeachTimer = 1000; SpeachNum++; break;
// Overlord Stand Up
case 22:
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
SpeachTimer = 2000; SpeachNum++; break;
// Overlord Angle
case 23:
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 5000; SpeachNum++; break;
// Overlord Say 6
case 24:
DoSay(OVERLORD_SAY_6,LANG_UNIVERSAL,NULL);
SpeachTimer = 2000; SpeachNum++; break;
// Complete Quest
case 25:
((Player*)m_player)->CompleteQuest(QUEST_LORD_ILLIDAN_STORMRAGE);
SpeachTimer = 6000; SpeachNum++; break;
// Goblin Angle
case 26:
if (Yarzill)
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, PlayerGUID);
SpeachTimer = 500; SpeachNum++; break;
// Cast Again Dragonaw Illusion
case 27:
m_player->RemoveAurasDueToSpell(SPELL_TWO);
m_player->RemoveAurasDueToSpell(41519);
m_player->CastSpell(m_player, SPELL_THREE, true);
m_player->CastSpell(m_player, SPELL_FOUR, true);
SpeachTimer = 1000; SpeachNum++; break;
// Goblin
case 28:
if (Yarzill)
((Yarzill_The_MercAI*)Yarzill->AI())->DoSpeach(m_player);
SpeachTimer = 5000; SpeachNum++; break;
// Goblin Off
case 29:
if (Yarzill)
Yarzill->SetUInt64Value(UNIT_FIELD_TARGET, 0);
SpeachTimer = 5000; SpeachNum++; break;
// Overlord Go Back
case 30:
m_creature->GetMotionMaster()->MovePoint(0, -5085.77, 577.231, 86.6719);
SpeachTimer = 5000; SpeachNum++; break;
// Reset
case 31:
Reset();
break;
default: break;
}
}else SpeachTimer -= diff;
}
}
};
CreatureAI* GetAI_Overlord_Morghor(Creature *_Creature)
@@ -59,6 +59,7 @@ EndScriptData */
#define SPELL_BURN 46394
#define SPELL_STOMP 45185
#define SPELL_BERSERK 26662
#define SPELL_DUAL_WIELD 42459
struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
{
@@ -75,6 +76,7 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
StompTimer = 30000;
BurnTimer = 60000;
BerserkTimer = 360000;
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
}
void Aggro(Unit *who)
@@ -145,8 +147,8 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
if(BurnTimer < diff)
{
Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
//DoCast(target,SPELL_BURN);
if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
target->CastSpell(target,SPELL_BURN,true);
BurnTimer = 60000;
}
else BurnTimer -= diff;
+8 -8
View File
@@ -1419,13 +1419,6 @@ InstanceMap::~InstanceMap()
*/
bool InstanceMap::CanEnter(Player *player)
{
if(!player->isGameMaster() && i_data && i_data->IsEncounterInProgress())
{
sLog.outDebug("InstanceMap::CanEnter - Player '%s' can't enter instance '%s' while an encounter is in progress.", player->GetName(), GetMapName());
player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
return false;
}
if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end())
{
sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode());
@@ -1444,12 +1437,19 @@ bool InstanceMap::CanEnter(Player *player)
// cannot enter while players in the instance are in combat
Group *pGroup = player->GetGroup();
if(pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId())
if(!player->isGameMaster() && pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId())
{
player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
return false;
}
/*if(!player->isGameMaster() && i_data && i_data->IsEncounterInProgress())
{
sLog.outDebug("InstanceMap::CanEnter - Player '%s' can't enter instance '%s' while an encounter is in progress.", player->GetName(), GetMapName());
player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
return false;
}*/
return Map::CanEnter(player);
}
+1 -11
View File
@@ -1531,14 +1531,4 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
z = GetPositionZ();
UpdateGroundPositionZ(x,y,z);
}
void WorldObject::GetRandomContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const
{
float object_size = obj->GetObjectSize();//here we use object_size to determine the angle offset, the bigger object the smaller angle offset, then this makes mob move naturally in visual.
//let assume 12.0f is the max size for object to have 0 angle offset.
float angle_offset_ratio = 1 - object_size/12.0f;
if (angle_offset_ratio < 0.05) angle_offset_ratio = 0.05;
// angle to face `obj` to `this`plus a random angle offset(from -90 degree to 90 degree)*angle_offset_ratio using distance from distance2dMin to distance2dMax includes size of `obj`
GetNearPoint(obj,x,y,z,object_size,distance2dMin+(distance2dMax-distance2dMin)*rand_norm(), GetAngle( obj ) + (M_PI/2 - M_PI * rand_norm()) * angle_offset_ratio);
}
}
-1
View File
@@ -377,7 +377,6 @@ class TRINITY_DLL_SPEC WorldObject : public Object
// angle to face `obj` to `this` using distance includes size of `obj`
GetNearPoint(obj,x,y,z,obj->GetObjectSize(),distance2d,GetAngle( obj ));
}
void GetRandomContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const;
float GetObjectSize() const
{
+4 -4
View File
@@ -1443,7 +1443,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
// area targets
case TARGET_AREAEFFECT_CUSTOM:
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
if(m_spellInfo->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
break;
@@ -1456,15 +1455,16 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_FRIENDLY);
break;
//case TARGET_AREAEFFECT_CUSTOM:
// m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
case TARGET_AREAEFFECT_CUSTOM:
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
case TARGET_UNIT_AREA_ENTRY:
{
SpellScriptTarget::const_iterator lower = spellmgr.GetBeginSpellScriptTarget(m_spellInfo->Id);
SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
if(lower==upper)
{
sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT, but does not have record in `spell_script_target`",m_spellInfo->Id);
SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
//sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT, but does not have record in `spell_script_target`",m_spellInfo->Id);
break;
}
// let it be done in one check?
+1 -15
View File
@@ -1982,24 +1982,10 @@ void Spell::EffectTeleportUnits(uint32 i)
((Player*)unitTarget)->TeleportTo(((Player*)unitTarget)->m_homebindMapId,((Player*)unitTarget)->m_homebindX,((Player*)unitTarget)->m_homebindY,((Player*)unitTarget)->m_homebindZ,unitTarget->GetOrientation(),unitTarget==m_caster ? TELE_TO_SPELL : 0);
return;
}
case TARGET_TABLE_X_Y_Z_COORDINATES:
{
// TODO: Only players can teleport?
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id);
if(!st)
{
sLog.outError( "Spell::EffectTeleportUnits - unknown Teleport coordinates for spell ID %u\n", m_spellInfo->Id );
return;
}
((Player*)unitTarget)->TeleportTo(st->target_mapId,st->target_X,st->target_Y,st->target_Z,st->target_Orientation,unitTarget==m_caster ? TELE_TO_SPELL : 0);
break;
}
default:
{
// If not exist data for dest location - return
if(!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION))
if(!m_targets.HasDest())
{
sLog.outError( "Spell::EffectTeleportUnits - unknown EffectImplicitTargetB[%u] = %u for spell ID %u\n", i, m_spellInfo->EffectImplicitTargetB[i], m_spellInfo->Id );
return;
+3 -3
View File
@@ -60,7 +60,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
if(!i_offset)
{
// to nearest random contact position
i_target->GetRandomContactPoint( &owner, x, y, z,0.5f,4.5f );
i_target->GetRandomContactPoint( &owner, x, y, z, 0.5f, ATTACK_DISTANCE - 0.5f );
}
else
{
@@ -164,7 +164,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
if (owner.GetObjectSize())
i_destinationHolder.ResetUpdate(50);
float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
float dist = owner.GetFloatValue(UNIT_FIELD_COMBATREACH) + i_target.getTarget()->GetFloatValue(UNIT_FIELD_COMBATREACH) + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
//More distance let have better performance, less distance let have more sensitive reaction at target move.
@@ -185,7 +185,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
owner.SetInFront(i_target.getTarget());
owner.StopMoving();
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
if(owner.IsWithinCombatDist(i_target.getTarget(), ATTACK_DISTANCE) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
owner.Attack(i_target.getTarget(),true);
}
}
+9 -1
View File
@@ -420,12 +420,20 @@ bool Unit::IsWithinCombatDist(Unit *obj, float dist2compare) const
float dz = GetPositionZ() - obj->GetPositionZ();
float distsq = dx*dx + dy*dy + dz*dz;
//not sure here, or combatreach + combatreach?
float sizefactor = GetObjectSize() + obj->GetFloatValue(UNIT_FIELD_COMBATREACH);
float sizefactor = GetFloatValue(UNIT_FIELD_COMBATREACH) + obj->GetFloatValue(UNIT_FIELD_COMBATREACH);
float maxdist = dist2compare + sizefactor;
return distsq < maxdist * maxdist;
}
void Unit::GetRandomContactPoint( const Unit* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const
{
uint32 attacker_number = getAttackers().size();
if(attacker_number > 0) --attacker_number;
GetNearPoint(obj,x,y,z,obj->GetFloatValue(UNIT_FIELD_COMBATREACH),distance2dMin+(distance2dMax-distance2dMin)*rand_norm()
, GetAngle(obj) + (attacker_number ? (M_PI/2 - M_PI * rand_norm()) * (float)attacker_number / GetFloatValue(UNIT_FIELD_COMBATREACH) / 3 : 0));
}
void Unit::RemoveSpellsCausingAura(AuraType auraType)
{
if (auraType >= TOTAL_AURAS) return;
+1
View File
@@ -721,6 +721,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetCanDualWield(bool value) { m_canDualWield = value; }
bool canReachWithAttack(Unit *pVictim) const;
bool IsWithinCombatDist(Unit *obj, float dist2compare) const;
void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const;
uint32 m_extraAttacks;
bool m_canDualWield;