Trying to improve the script and can use some help. I’m too unexperienced to do it alone.
[CODE]
– Bloodlord Mandokir SQL fix by nelegalno
– Bloodlord Mandokir 1-Man Solo (Death Knight) - YouTube
UPDATE script_texts
SET content_default
=“$N! I’m watching you!” WHERE entry
=-1309018;
– Bloodlord Mandokir 1-Man Solo (Death Knight) - YouTube
DELETE FROM script_texts
WHERE entry
=-1309024;
INSERT INTO script_texts
(npc_entry
,entry
,content_default
,content_loc1
,content_loc2
,content_loc3
,content_loc4
,content_loc5
,content_loc6
,content_loc7
,content_loc8
,sound
,type
,language
,emote
,comment
) VALUES
(11382,-1309024,“Bloodlord Mandokir goes into a rage after seeing his raptor fall in battle!”,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,8413,2,0,0,“mandokir SAY_EMOTE_ENRAGE”);
[/SQL][/CODE]
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Mandokir
SD%Complete: 90
SDComment: Ohgan function needs improvements.
SDCategory: Zul'Gurub
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulgurub.h"
enum Texts
{
SAY_AGGRO = -1309015,
SAY_DING_KILL = -1309016,
SAY_GRATS_JINDO = -1309017,
SAY_WATCH = -1309018,
SAY_WATCH_WHISPER = -1309019, // is this text for real? easter egg?
SAY_EMOTE_ENRAGE = -1309024, // -1309020 to -1309023 are in use
};
enum Spells
{
SPELL_CHARGE = 24408,
SPELL_CLEAVE = 7160, // [is this correct?] shouldnt 20691 replace 7160 == Execute ( http://old.wowhead.com/spell=7160 )
SPELL_FEAR = 29321,
SPELL_WHIRLWIND = 15589, // 15589 is triggered by 13736 ( http://old.wowhead.com/spell=15589#triggered-by )
SPELL_MORTAL_STRIKE = 16856,
SPELL_ENRAGE = 24318,
SPELL_WATCH = 24314,
SPELL_LEVEL_UP = 24312, // 96662 for v4 ( http://www.wowpedia.org/Bloodlord_Mandokir_(tactics)#Attacks_.26_Abilities )
SPELL_MOUNT_UP = 23243,
SPELL_GUILLOTINE = 24316, // Used when charge fails
SPELL_SUNDERARMOR = 24317, // Used by Ohgan
};
enum Creatures
{
NPC_OHGAN = 14988,
NPC_VILEBRANCH_SPEAKER = 11391, // When killed, Mandokir comes down
};
class boss_mandokir : public CreatureScript
{
public:
boss_mandokir()
: CreatureScript("boss_mandokir") {}
struct boss_mandokirAI : public ScriptedAI
{
boss_mandokirAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
uint32 KillCount;
uint32 Watch_Timer;
uint32 TargetInRange;
uint32 Cleave_Timer;
uint32 Whirlwind_Timer;
uint32 Fear_Timer;
uint32 MortalStrike_Timer;
uint32 Check_Timer;
float targetX;
float targetY;
float targetZ;
InstanceScript* instance;
bool endWatch;
bool someWatched;
bool RaptorDead;
bool CombatStart;
bool SpeakerDead;
uint64 WatchTarget;
void Reset()
{
KillCount = 0;
Watch_Timer = 33000;
Cleave_Timer = 7000;
Whirlwind_Timer = 20000;
Fear_Timer = 1000;
MortalStrike_Timer = 1000;
Check_Timer = 1000;
targetX = 0.0f;
targetY = 0.0f;
targetZ = 0.0f;
TargetInRange = 0;
// He no longer watches anyone when he resets
WatchTarget = 0;
// Set back all bools
someWatched = false;
endWatch = false;
RaptorDead = false;
CombatStart = false;
SpeakerDead = false;
}
void JustReachedHome()
{
// Cast mount once we reach home, not when we reset
DoCast(me, SPELL_MOUNT_UP);
}
void KilledUnit(Unit* victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
{
++KillCount;
if (KillCount == 3)
{
// Make Mandokir yell 'DING!' to everyone in Zul'gurub
DoScriptText(SAY_DING_KILL, me);
if (instance)
{
uint64 JindoGUID = instance->GetData64(DATA_JINDO);
if (JindoGUID)
{
if (Unit* jTemp = Unit::GetUnit(*me, JindoGUID))
{
if (jTemp->isAlive())
// Make Jin'do yell 'GRATS!' to everyone in Zul'gurub. (only if Jin'do is still alive)
DoScriptText(SAY_GRATS_JINDO, jTemp);
}
}
}
DoCast(me, SPELL_LEVEL_UP, true);
KillCount = 0;
}
}
}
void EnterCombat(Unit* /*who*/)
{
DoScriptText(SAY_AGGRO, me);
}
void UpdateAI(const uint32 diff)
{
if (!SpeakerDead)
{
if (!me->FindNearestCreature(NPC_VILEBRANCH_SPEAKER, 100.0f, true))
{
me->GetMotionMaster()->MovePoint(0, -12196.3f, -1948.37f, 130.36f);
SpeakerDead = true;
}
}
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && SpeakerDead)
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
if (!UpdateVictim())
return;
if (me->getVictim() && me->isAlive())
{
if (!CombatStart)
{
// At combat Start Mandokir is mounted so we must unmount it first
me->Dismount();
// And summon his raptor
me->SummonCreature(NPC_OHGAN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);
CombatStart = true;
}
if (Watch_Timer <= diff) // Every 20 Sec Mandokir will check this
{
// If someone is 'watched' and he moved (different point from the point when spell was casted) or casted a spell, we will charge that player
// Cast Guillotine if player is in melee range making Mandokir unable to charge that player
if (WatchTarget)
{
Unit* unit = Unit::GetUnit(*me, WatchTarget);
if (unit && (
targetX != unit->GetPositionX() ||
targetY != unit->GetPositionY() ||
targetZ != unit->GetPositionZ() ||
unit->isInCombat()))
{
if (me->IsWithinMeleeRange(unit))
{
// Cast Guillotine since we can not charge the watched player
DoCast(unit, SPELL_GUILLOTINE);
}
else
{
DoCast(unit, SPELL_CHARGE);
// Summon a player
//me->SendMonsterMove(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 0, true, 1);
AttackStart(unit);
}
}
}
someWatched = false;
Watch_Timer = 20000;
} else Watch_Timer -= diff;
if ((Watch_Timer < 8000) && !someWatched) // 8 sec (cast time + expire time) before the check for the watch effect mandokir will cast watch debuff on a random target
{
if (Unit* p = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
DoScriptText(SAY_WATCH, me, p);
DoCast(p, SPELL_WATCH);
WatchTarget = p->GetGUID();
someWatched = true;
endWatch = true;
}
}
// One second before the buff expires we will store the position. If moved, we will charge, or cast Guillotine if player is in melee range.
if ((Watch_Timer < 1000) && endWatch)
{
Unit* unit = Unit::GetUnit(*me, WatchTarget);
if (unit)
{
targetX = unit->GetPositionX();
targetY = unit->GetPositionY();
targetZ = unit->GetPositionZ();
}
endWatch = false;
}
if (!someWatched)
{
// Cleave
if (Cleave_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_CLEAVE);
Cleave_Timer = 7000;
} else Cleave_Timer -= diff;
// Whirlwind
if (Whirlwind_Timer <= diff)
{
DoCast(me, SPELL_WHIRLWIND);
Whirlwind_Timer = 18000;
} else Whirlwind_Timer -= diff;
// If more than 3 targets are within melee range, mandokir will cast Fear
if (Fear_Timer <= diff)
{
TargetInRange = 0;
std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
for (; i != me->getThreatManager().getThreatList().end(); ++i)
{
Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
if (unit && me->IsWithinMeleeRange(unit))
++TargetInRange;
}
if (TargetInRange > 3)
DoCast(me->getVictim(), SPELL_FEAR);
Fear_Timer = 4000;
} else Fear_Timer -=diff;
// Mortal Strike if target is at or below 50% HP
if (me->getVictim() && me->getVictim()->HealthBelowPct(50))
{
if (MortalStrike_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_MORTAL_STRIKE);
MortalStrike_Timer = 15000;
} else MortalStrike_Timer -= diff;
}
}
// If Ohgan is dead, Mandokir will cast Frenzy and say his enrage line
if (Check_Timer <= diff)
{
if (instance)
{
if (instance->GetData(DATA_OHGAN) == DONE)
{
if (!RaptorDead)
{
// Say his enrage line once Ohgan is dead
DoScriptText(SAY_EMOTE_ENRAGE, me);
DoCast(me, SPELL_ENRAGE);
RaptorDead = true;
}
}
}
Check_Timer = 1000;
} else Check_Timer -= diff;
DoMeleeAttackIfReady();
}
}
};
CreatureAI* GetAI(Creature* creature) const
{
return new boss_mandokirAI(creature);
}
};
// Ohgan
class mob_ohgan : public CreatureScript
{
public:
mob_ohgan()
: CreatureScript("mob_ohgan") {}
struct mob_ohganAI : public ScriptedAI
{
mob_ohganAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
uint32 SunderArmor_Timer;
InstanceScript* instance;
void Reset()
{
SunderArmor_Timer = 5000;
}
void EnterCombat(Unit* /*who*/) {}
void JustDied(Unit* /*killer*/)
{
if (instance)
instance->SetData(DATA_OHGAN, DONE);
}
void UpdateAI (const uint32 diff)
{
// Return since we have no target
if (!UpdateVictim())
return;
// SunderArmor_Timer
if (SunderArmor_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_SUNDERARMOR);
SunderArmor_Timer = urand(10000, 15000);
} else SunderArmor_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return new mob_ohganAI(creature);
}
};
void AddSC_boss_mandokir()
{
new boss_mandokir();
new mob_ohgan();
}
The initial discussion can be found here: Pull Request #7499: [Zul’Gurub] Bloodlord Mandokir fix by nelegalno · TrinityCore/TrinityCore · GitHub
Problems:
-
Ohgan doesn’t atack the player once spawned
-
Ghosts aren’t spawned