Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define NPC_ID_MADNESS_VISUAL 56173 // at center of the black hole. At phase 2 he will lean forward
- #define NPC_ID_MADNESS_ATTACKTARGET 57962 // spawned between platform 1 and 2 and can be reached by attacks and spells
- #define NPC_ID_MADNESS_FIGHT_CONTROLLER 56174 // spawned at teleport location and will spawn dynamic spawns
- #define MADNESS_INDEX_GUID_VISUAL 0
- #define MADNESS_INDEX_GUID_ATTACK 1
- #define MADNESS_INDEX_ACTIVE_PLATFORM 2
- #define MADNESS_INDEX_ACTIVE_PLATFORMS 3
- #define MADNESS_LOOSE_HP_PCT_TENTACLE 15
- #define SPELL_ID_ASSAULT_ASPECT 1
- #define SPELL_COOL_ASSAULT_ASPECT 900000
- #define SPELL_ID_CATACLYSM 106523
- #define SPELL_COOL_CATACLYSM 900000
- //#define SPELL_ID_ELEMENTIUM_BOLT 1
- //#define SPELL_COOL_ELEMENTIUM_BOLT 1
- #define NPC_ID_ELEMENTIUM_BOLT 56262
- #define NPC_MINPROC_ELEMENTIUM_BOLT 1
- #define NPC_COOL_ELEMENTIUM_BOLT 600000
- #define SPELL_ID_ELEMNTIUM_BLAST 105723
- #define SPELL_ID_ELEMNTIUM_BLAST_PULSE 110632
- #define SPELL_COOL_ELEMNTIUM_BLAST 5000
- #define SPELL_ID_CORRUPTING_PARASITE 108649
- #define SPELL_COOL_CORRUPTING_PARASITE 18000
- #define SPELL_MINPROC_CORRUPTING_PARASITE 5
- #define NPC_ID_CORRUPTING_PARASITE 57479 //auto created by spell when it ends
- #define SPELL_ID_CORRUPTING_PARASITE_BACKLASH 108597
- #define SPELL_ID_UNSTABLE_CORRUPTION 108813
- #define SPELL_COOL_UNSTABLE_CORRUPTION 10000 //this does about 600k DMG / tick
- #define NPC_ID_HEMORRHAGE_VISUAL_LOC 56359
- //#define SPELL_ID_HEMORRHAGE 105875 //or 106767 actually spawns the mobs
- //#define SPELL_ID_HEMORRHAGE_VISUAL 105861
- //#define SPELL_COOL_HEMORRHAGE 40000
- #define NPC_ID_REGENERATIVE_BLOOD 56263 //or 56710
- #define NPC_COOL_REGENERATIVE_BLOOD 37000
- #define NPC_MINPROC_REGENERATIVE_BLOOD 4
- #define SPELL_ID_REGENERATIVE 105937
- #define SPELL_COOL_REGENERATIVE 1000 //1.4M health => needs 140k dps
- #define SPELL_ID_DEGENRATIVE_BITE 105841
- #define SPELL_COOL_DEGENRATIVE_BITE 1000
- #define NPC_ID_LIMB0 56168
- #define NPC_ID_LIMB1 56846
- #define NPC_ID_LIMB2 56167
- #define NPC_ID_LIMB3 56168
- #define TENTACLE_START_FIGHT_HP_PCT 95
- #define NPC_ID_BLISTERING_TENTACLE 56188
- #define NPC_COOL_LIMB_TENTACLE 600000 //at 25% health pct drop
- #define NPC_MINPROC_LIMB_TENTACLE 3
- #define SPELL_ID_BURNING_BLOOD 105408
- #define SPELL_COOL_BURNING_BLOOD 2000
- //#define SPELL_ID_BLISTERING_TENTACLE 1
- //#define SPELL_COOL_BLISTERING_TENTACLE 1
- #define SPELL_ID_BLISTERING_HEAT 105444 //aura that periodically does AOE DMG
- #define SPELL_COOL_BLISTERING_HEAT 2000
- #define SPELL_ID_AGONIZING_PAIN 106548
- //#define SPELL_COOL_AGONIZING_PAIN 1
- #define NPC_ID_MUTATED_CORRUPTION 56471
- #define NPC_COOL_MUTATED_CORRUPTION 600000
- #define NPC_MINPROC_MUTATED_CORRUPTION 1
- #define SPELL_ID_CRUSH 106385
- #define SPELL_COOL_CRUSH 8000
- #define SPELL_ID_IMPALE 106400 //for full cast. Players have a chance to pop defense
- #define SPELL_COOL_IMPALE 12000
- #define NPC_ID_CONGEALING_BLOOD 57798
- #define NPC_COOL_CONGEALING_BLOOD 37000
- #define NPC_MINPROC_CONGEALING_BLOOD 5
- #define SPELL_ID_CONGEALING_BLOOD_HEAL 109102
- #define NPC_ID_ELEMENTIUM_FRAGMENT 56724
- #define NPC_COOL_ELEMENTIUM_FRAGMENT 25000
- #define NPC_MINPROC_ELEMENTIUM_FRAGMENT 3
- #define SPELL_ID_SHRAPNEL_TARGETED 106794
- #define SPELL_ID_SHRAPNEL_DMG 106791
- #define SPELL_COOL_SHRAPNEL 15000
- #define NPC_ID_ELEMNTIUM_TERROR 56710
- #define NPC_COOL_ELEMNTIUM_TERROR 30000
- #define NPC_MINPROC_ELEMENTIUM_TERROR 5
- #define SPELL_ID_TETANUS 106730
- #define SPELL_COOL_TETANUS 2000
- #define SPELL_ID_CORRUPTED_BLOOD 106835
- #define SPELL_COOL_CORRUPTED_BLOOD 2000
- #define SPELL_ID_ALEXTRASZA_PRESENCE 106028
- #define SPELL_ID_CAUTERIZE 109045
- #define SPELL_COOL_CAUTERIZE 1000
- #define SPELL_ID_NOZDORMU_PRESENCE 106027
- #define SPELL_ID_TIME_ZONE 1
- #define SPELL_ID_YSERA_PRESENCE 106457
- #define SPELL_ID_ENTER_THE_DREAM 106464 //cancel dream to enter dreamer effect
- #define SPELL_ID_ENTER_THE_DREAM_EFFECT 106466
- #define SPELL_ID_KALECGOS_PRESENCE 106029
- #define SPELL_ID_SPELLWEAVING 106040
- #define SPELL_ID_CARRYING_WINDS 106664
- #define NPC_ID_ASPECT_ALEXSTRASZA 56099
- #define NPC_ID_ASPECT_NOZDORMU 56102
- #define NPC_ID_ASPECT_KALECGOS 56101
- #define NPC_ID_ASPECT_YSERA 56100
- #define NPC_ID_ASPECT_THRALL 56103
- #define LIMIT_SPAWN_COUNT_OF_SAME_TYPE 20
- #ifdef _DEBUG
- /*
- #define TEMP_DISABLE_TENTACLE_SAPWNS
- #define TEMP_DISABLE_BLOOD_SAPWNS
- #define TEMP_DISABLE_PHASE1
- #define TEMP_DISABLE_REQ_HEROIC
- */
- #endif
- #define MADNESSPLATFORM_COUNT 4
- #define MadnessZdifference -105.0f
- const float MadnessSpawnLocation[4] = { -11903.9f, 11989.0f, -113.1f, 2.1f };
- const float MadnessAttackSpawnLocation[4] = { -12063.5f, 12198.9f, -12.9f, 2.16f };
- const float MadnessPhaseLocation[4] = { -12137.9f, 12079.0f, -113.1f, 2.1f };
- const float CorruptionLocations[MADNESSPLATFORM_COUNT][3] = { { -11929.0f, 12297.0f, -2.0f },{ -12028.0f, 12265.5f, -6.1f },{ -12107.4f, 12201.9f, -5.2f },{ -12160.9f, 12057.0f, 2.5f} };
- const float PlatformCenterLocations[MADNESSPLATFORM_COUNT][3] = { { -11956.0f, 12270.0f, 1.5f },{ -12035.6f, 12221.6f, -6.1f },{ -12097.4f, 12161.0f, -2.7f },{ -12122.4f, 12074.2f, 2.3f } };
- const float LimbLocations[MADNESSPLATFORM_COUNT][5] = { { -11941.0f, 12248.9f, 12.2f, 1.98f, NPC_ID_LIMB0 },{ -12005.8f, 12190.2f, -6.4f, 2.12f, NPC_ID_LIMB1 },{ -12065.0f, 12127.2f, -3.1f, 2.33f, NPC_ID_LIMB2 },{ -12097.0f, 12067.0f, 13.5f, 2.21f, NPC_ID_LIMB3 } };
- const float LimbTentacleLocations[MADNESSPLATFORM_COUNT][3] = { { -11941.0f, 12248.9f, 12.2f },{ -12025.8f, 12208.2f, -6.4f },{ -12073.0f, 12145.2f, -3.1f },{ -12097.0f, 12067.0f, 13.5f } };
- const uint32 DespawnOldEncounterDynamicEntries[] = { NPC_ID_MADNESS_VISUAL, NPC_ID_MADNESS_ATTACKTARGET, NPC_ID_ELEMENTIUM_BOLT, NPC_ID_CORRUPTING_PARASITE, NPC_ID_HEMORRHAGE_VISUAL_LOC, NPC_ID_REGENERATIVE_BLOOD, NPC_ID_BLISTERING_TENTACLE, NPC_ID_LIMB0, NPC_ID_LIMB1, NPC_ID_LIMB2, NPC_ID_LIMB3, NPC_ID_MUTATED_CORRUPTION, NPC_ID_CONGEALING_BLOOD, NPC_ID_ELEMENTIUM_FRAGMENT, NPC_ID_ELEMNTIUM_TERROR, 0 }; //despawn these in case encounter resets
- const float ElementiumBoltStart[MADNESSPLATFORM_COUNT][3] ={ { -11961.0f, 12228.0f, 21.0f }, { -12015.0f, 12143.0f, 21.0f }, { -12015.0f, 12143.0f, 21.0f }, { -12071.0f, 12087.0f, 21.0f } };
- class DeathwingMadnessController : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(DeathwingMadnessController);
- /*
- http://www.youtube.com/watch?v=qxScIr3UlTg&feature=player_detailpage#t=278s
- Stage One: The Final Assault
- Deathwing assaults his enemies while attached to the platforms by his twisted limbs.
- Assault Aspect – Deathwing searches for his next enemy to assault. Deathwing assaults the platform with the largest number of players and an attached limb.
- Cataclysm – Deathwing attempts to finish the job he started by bringing forth a second Cataclysm, inflicting 1462500 to 1537500 Fire damage to all players.
- Elementium Bolt – Deathwing creates an Elementium Bolt, sending it to the target platform.
- Elementium Blast – If the Elementium Bolt reaches its destination, the bolt inflicts 380250 to 399750 Fire damage to all players and an additional 380250 to 399750 Fire damage every 5 sec until players destroy the Elementium Bolt. The initial damage decreases the further the player stands from the targeted location.
- Corrupting Parasite – A Corrupting Parasite inflicts increasing Shadow damage periodically. When Corrupting Parasite's duration ends, the parasite detaches from the player and causes a Parasitic Backlash. This inflicts 243750 to 256250 Fire damage to players within 10 yards of the host.
- Corrupting Parasite – After the Corrupting Parasite's duration ends, the parasite detaches from the host.
- Unstable Corruption – The Corrupting Parasite casts Unstable Corruption, inflicting 10% of the Corrupted Parasite's health as Fire damage to all players.
- Hemorrhage – Deathwing's tentacle begins to Hemorrhage, creating several Regenerative Blood at a nearby location.
- Regenerative Blood – The Regenerative Blood of Deathwing forms. Regenerative Bloods gain ten energy every 1 sec. The melee attacks of a Regenerative Blood also cause Degenerative Bite.
- Regenerative – A Regenerative Blood heals to full health when it reaches maximum energy.
- In Looking for Raid Difficulty, Regenerative Blood heals 50% of max health when it reaches maximum energy.
- Degenerative Bite – Melee attacks cause Degenerative Bite, inflicting 1462 to 1537 Shadow damage every 1 sec for 10 sec. This effect stacks.
- Limb Tentacle – Deathwing grasps onto each platform with one of his limbs.
- Burning Blood – The Burning Blood gushes from the Tentacle, inflicting Fire damage every 2 sec. The damage increases as the Limb Tentacle's health lowers.
- Blistering Tentacle – At 75%, 50%, and 25% remaining health the Limb Tentacle sprouts several Blistering Tentacles that are immune to Area of Effect abilities.
- Blistering Heat – The Blistering Heat inflicts 2500 Fire damage every 2 sec, and increases its damage by 5% for 3 sec. This effect stacks.
- Agonizing Pain – The pain from severing Deathwing's limb interrupts his concentration, stunning him and inflicting 20% of his health in damage.
- Mutated Corruption – A Mutated Corruption appears shortly after assaulting a platform.
- Crush – The crushing weight of the Mutated Corruption inflicts 100000 Physical damage to enemies in a cone in front of the Corruption.
- Impale – The Mutated Corruption impales its target, inflicting 400000 Physical damage to the target.
- Stage Two: The Last Stand
- At 20% remaining health, Deathwing falls forward onto the platform.
- Congealing Blood – Deathwing begins to Hemorrhage, creating several Congealing Blood at a nearby location. The Blood then moves towards Deathwing.
- Congealing Blood – If a Congealing Blood reaches Deathwing, it heals him for 1% of his maximum health.
- Elementium Fragment – Pieces of Deathwing's armor chip off, forming three Elementium Fragments nearby.
- In 25 player raids, eight Elementium Fragments form.
- Shrapnel – The Fragment fires a piece of Shrapnel at a random player, inflicting 195000 to 205000 unresistable Physical damage.
- Elementium Terror – Pieces of Deathwing's armor chip off, forming two Elementium Terrors nearby.
- Tetanus – The Elementium Terror's melee attacks cause Tetanus, inflicting 58500 to 61500 Physical damage and an additional 19500 to 20500 Physical damage every 1 sec. The effect stacks.
- Corrupted Blood – Corrupted Blood gushes from Deathwing, inflicting Fire damage every 2 sec. The damage increases as Deathwing's health lowers. At 15%, 10%, and 5% remaining health, Deathwing hemorrages. This increases the damage dealt by Corrupted Blood.
- The Aspects
- The Dragon Aspects assist in the fight against Deathwing. Each aspect channels Expose Weakness on their respective Limb Tentacle when Deathwing begins to cast Cataclysm. Expose Weakness increases the damage done to the Tentacle by 100%. Each Aspect also channels Concentration after the players destroy their respective tentacle, preventing the Aspect from assisting the players with their presence and their special powers. The Aspects resume assisting the players when Stage Two begins.
- Alexstrasza
- Alexstrasza's Presence – The Presence of Alexstrasza increases the player's maximum health by 20%.
- Cauterize – Alexstrasza Cauterizes the Blistering Tentacles, inflicting lethal damage over 5 sec. Cauterize also reduces the damage inflicted by Corrupted Blood.
- In Heroic Difficulty Alexstrasza Cauterizes the Corrupting Parasite, inflicting 3% Fire damage every 0.5 sec.
- Nozdormu
- Nozdormu's Presence – The Presence of Nozdormu increases the player's haste by 20%.
- Time Zone – Nozdormu forms a Time Zone at the target location, causing the Elementium Meteor to lapse in time and decrease its travel speed dramatically upon entering the zone. Any enemy creatures within the Time Zone have their attack speed decreased by 50%.
- In Heroic Difficulty the Time Zone slows the effects of Corrupting Parasite.
- Ysera
- Ysera's Presence – The Presence of Ysera increases player healing done by 20%.
- Enter the Dream – The Presence of Ysera allows players to enter the Dream, decreasing damage taken by 50% for 2 sec.
- Kalecgos
- Kalecgos' Presence – The Presence of Kalecgos increases player damage dealt by 20%.
- Spellweaving – The Presence of Kalecgos allows attacks and abilities to cause Spellweaving. Spellweaving inflicts 22425 to 23575 Arcane damage to enemies within 6 yards, excluding the current target.
- Thrall
- Carrying Winds – The Carrying Winds take players between adjacent platforms, and increase their movement speed by 60% for 10 sec. This effect stacks.
- */
- uint32 YellIndex;
- uint32 TalkCooldown;
- uint32 phase;
- float DifficultyScale;
- uint32 AssaultAspectTimer;
- uint32 CataclysmTimer;
- uint64 LimbGUIDs[MADNESSPLATFORM_COUNT];
- uint32 FaintTimer;
- DeathwingMadnessController(Creature* pCreature) : CreatureAIScript(pCreature)
- {
- phase = 0;
- }
- void OnLoad()
- {
- DifficultyScale = 1.0f;
- if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_10_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_10HEROIC;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN )
- DifficultyScale = SPEED_SCALE_DIFF_25NORMAL;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_25HEROIC;
- //make him attack faster as difficulty increases
- // uint32 attacktime_now = _unit->GetUInt32Value( UNIT_FIELD_BASEATTACKTIME );
- // _unit->SetUInt32Value( UNIT_FIELD_BASEATTACKTIME, MAX( 500, attacktime_now * DifficultyScale ) ); //attack a bit faster cause there are more healers
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->m_canMove = false;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- _unit->GetAIInterface()->setOutOfCombatRange( 700.0f * 700.0f );
- // _unit->bInvincible = true;
- // _unit->static_object = true; //do not deactivate. Need to monitor the fight all the time
- // int64 *MadnessGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_GUID_VISUAL );
- // *MadnessGUID = _unit->GetGUID();
- RegisterAIUpdateEvent( 1000 );
- ConvertToStaticSpawn( _unit, true );
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- }
- void AIUpdate()
- {
- if( _unit->isAlive() == false )
- return;
- int64 *EncounterStatus = _unit->GetMapMgr()->GetCreateIn64Extension( EXTENSION_MAP_BOS_KILLS );
- if( *EncounterStatus & EXTENSION_FLAG_MADNESS_DIED )
- return;
- // Unit *tank = _unit->GetAIInterface()->GetNextTarget();
- InrangeLoopExitAutoCallback AutoLock;
- if( _unit->GetInRangePlayerSetBegin( AutoLock ) == _unit->GetInRangePlayerSetEnd() )
- return;
- Unit *tank = *_unit->GetInRangePlayerSetBegin( AutoLock );
- if( tank == NULL )
- {
- phase = 0;
- return;
- }
- uint32 TickNow = GetTickCount();
- // Init phase
- Creature *Madness;
- if( phase == 0 )
- {
- TalkCooldown = TickNow + RandomUInt() % 25000;
- YellIndex = 0;
- phase = 1;
- AssaultAspectTimer = TickNow + RandomUInt() % 25000;
- CataclysmTimer = TickNow + RandomUInt() % 25000;
- // HemorrhageTimer = TickNow + RandomUInt() % 25000;
- //activate nearby mapmanager cells
- float distX = _unit->GetPositionX() - MadnessSpawnLocation[0];
- float distY = _unit->GetPositionY() - MadnessSpawnLocation[1];
- int32 dist = sqrt( distX * distX + distY * distY );
- dist += 50;
- dist = dist / _cellSize;
- uint32 x = _unit->GetMapMgr()->GetPosX(_unit->GetPositionX());
- uint32 y = _unit->GetMapMgr()->GetPosY(_unit->GetPositionY());
- _unit->GetMapMgr()->UpdateCellActivity( x, y, dist, 2 );
- //despawn all dynamic spawns
- DespawnEncounterSpawns( _unit, DespawnOldEncounterDynamicEntries );
- //spawn madness
- {
- Madness = _unit->GetMapMgr()->CreateCreature( NPC_ID_MADNESS_VISUAL, true, MadnessSpawnLocation[0], MadnessSpawnLocation[1], MadnessSpawnLocation[2], MadnessSpawnLocation[3] );
- ConvertToStaticSpawn( Madness, true );
- }
- Madness->CastSpell( Madness, SPELL_ID_CATACLYSM, false );
- {
- Creature *c;
- c = _unit->GetMapMgr()->GetCreatureByEntry( NPC_ID_ASPECT_ALEXSTRASZA );
- ConvertToStaticSpawn( c, true );
- c = _unit->GetMapMgr()->GetCreatureByEntry( NPC_ID_ASPECT_NOZDORMU );
- ConvertToStaticSpawn( c, true );
- c = _unit->GetMapMgr()->GetCreatureByEntry( NPC_ID_ASPECT_KALECGOS );
- ConvertToStaticSpawn( c, true );
- c = _unit->GetMapMgr()->GetCreatureByEntry( NPC_ID_ASPECT_YSERA );
- ConvertToStaticSpawn( c, true );
- }
- //spawn new limbs
- #ifndef TEMP_DISABLE_PHASE1
- for( int i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- uint32 LimbEntry = LimbLocations[i][4];
- Creature *c = _unit->GetMapMgr()->CreateCreature( LimbEntry, true, LimbLocations[i][0], LimbLocations[i][1], LimbLocations[i][2], LimbLocations[i][3] );
- if( c )
- {
- LimbGUIDs[i] = c->GetGUID();
- int64 *LimbIndex = c->GetCreateIn64Extension( NPC_ID_LIMB0 );
- *LimbIndex = i; //self awarness for inter object comunication if required
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + *LimbIndex );
- *CanActivePlatformIndex = 1;
- }
- // c = _unit->GetMapMgr()->CreateCreature( NPC_ID_HEMORRHAGE_VISUAL_LOC, true, LimbTentacleLocations[i][0], LimbTentacleLocations[i][1], LimbTentacleLocations[i][2] );
- // if( c )
- // {
- // int64 *HemoTargetNPCGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_HEMORRHAGE_VISUAL_LOC + i );
- // *HemoTargetNPCGUID = c->GetGUID();
- // }
- }
- #endif
- // Madness->SetPosition( MadnessSpawnLocation[0], MadnessSpawnLocation[1], MadnessSpawnLocation[2], _unit->GetOrientation() );
- // Madness->GetAIInterface()->StopMovement( 0 );
- }
- int64 *MadnessGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_GUID_VISUAL );
- Madness = _unit->GetMapMgr()->GetCreature( *MadnessGUID );
- if( Madness == NULL )
- return;
- if (phase == 1)
- {
- if( TalkCooldown < TickNow )
- {
- Madness->SendChatMessage( CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, DeathwingMadnessYells[ YellIndex ] );
- YellIndex = ( YellIndex + 1 ) % 15;
- TalkCooldown = TickNow + (20000 + RandomUInt() % 10000);
- }
- //count platform players
- /* uint32 PlatformPlayerCount[MADNESSPLATFORM_COUNT];
- memset( PlatformPlayerCount, 0, sizeof( PlatformPlayerCount ) );
- float PlatformRadius = 40.0f * 40.0f;
- InRangePlayerSet::iterator itr3;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- for( itr3 = _unit->GetInRangePlayerSetBegin( AutoLock ); itr3 != _unit->GetInRangePlayerSetEnd(); itr3++)
- {
- if( (*itr3)->isAlive() == false )
- continue;
- float BestPlatformDist = 99999999999999.0f;
- uint32 BestPlatformIndex = 0;
- for( uint32 i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- float dist = Distance2DSq( PlatformCenterLocations[ i ][0], PlatformCenterLocations[ i ][1], (*itr3)->GetPositionX(), (*itr3)->GetPositionY() );
- if( dist < BestPlatformDist )
- {
- BestPlatformDist = dist;
- BestPlatformIndex = i;
- }
- }
- PlatformPlayerCount[ BestPlatformIndex ]++;
- }
- _unit->ReleaseInrangeLock();
- //get which platform has most players on it
- uint32 BestPlayerCount = 0;
- uint32 BestPlayerCountIndex = 0;
- for( uint32 i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + i );
- if( *CanActivePlatformIndex == 1 && PlatformPlayerCount[i] > BestPlayerCount )
- {
- BestPlayerCount = PlatformPlayerCount[i];
- BestPlayerCountIndex = i;
- }
- }
- //set as active platform
- int64 *AcctivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORM );
- *AcctivePlatformIndex = BestPlayerCountIndex;
- //get the tank of this platform
- Unit *PlatformCorruption = _unit->GetMapMgr()->GetCreature( LimbGUIDs[ BestPlayerCountIndex ] );
- Unit *PlatformTank = NULL;
- if( PlatformCorruption )
- PlatformTank = PlatformCorruption->GetAIInterface()->GetMostHated();
- if( PlatformTank )
- {
- if( AssaultAspectTimer < TickNow )
- {
- Madness->CastSpell( PlatformTank, SPELL_ID_ASSAULT_ASPECT, false );
- AssaultAspectTimer = TickNow + (SPELL_COOL_ASSAULT_ASPECT + RandomUInt() % SPELL_COOL_ASSAULT_ASPECT)*DifficultyScale;
- }
- if( CataclysmTimer < TickNow )
- {
- Madness->CastSpell( PlatformTank, SPELL_ID_CATACLYSM, false );
- CataclysmTimer = TickNow + (SPELL_COOL_CATACLYSM + RandomUInt() % SPELL_COOL_CATACLYSM)*DifficultyScale;
- }
- } */
- //time to enter next phase ?
- bool LimbsLeft = false;
- char LimbKilled = false;
- for( uint32 i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + i );
- if( *CanActivePlatformIndex )
- LimbsLeft = true;
- else
- LimbKilled++;
- }
- if( Madness->GetHealthPct() <= 100 + 5 - MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT || LimbsLeft == false
- // || LimbKilled != 0
- )
- {
- phase = 2;
- //move head between platform 2-3
- Madness->SetUInt32Value( UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOMSPELL01 );
- FaintTimer = TickNow + 5000;
- // Madness->bInvincible = false;
- //EMOTE_ONESHOT_CUSTOMSPELL05 ->sparkling explode
- //spawn madness attack target
- {
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_MADNESS_ATTACKTARGET, true, MadnessAttackSpawnLocation[0], MadnessAttackSpawnLocation[1], MadnessAttackSpawnLocation[2], MadnessAttackSpawnLocation[3] );
- ConvertToStaticSpawn( c, true );
- // Madness->bInvincible = true;
- Madness->SetUInt32Value( UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NOT_ATTACKABLE_2 | UNIT_FLAG_NOT_ATTACKABLE_9 );
- }
- {
- char buff[500];
- sprintf( buff, "Debug MSG : You should go to the platform where taxi ported you" );
- Madness->SendChatMessage( CHAT_MSG_MONSTER_PARTY, LANG_UNIVERSAL, buff );
- }
- }
- }
- else if (phase == 2)
- {
- //keep head forward
- if( FaintTimer < TickNow )
- {
- Madness->SetUInt32Value( UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOMSPELL02 );
- for( uint32 i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + i );
- *CanActivePlatformIndex = 1;
- }
- }
- }
- }
- };
- class DeathwingMadnessVisual : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(DeathwingMadnessVisual);
- DeathwingMadnessVisual(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- _unit->GetAIInterface()->setOutOfCombatRange( 700.0f * 700.0f );
- _unit->m_canRegenerateHP = false;
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- _unit->bInvincible = true;
- }
- void OnDied(Unit *mKiller)
- {
- }
- };
- class DeathwingMadnessAttackTarget : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(DeathwingMadnessAttackTarget);
- DeathwingMadnessAttackTarget(Creature* pCreature) : CreatureAIScript(pCreature) { }
- uint32 CongealingBloodTimer,CongealingBloodCounter;
- uint32 ElementiumFragmentTimer,ElementiumFragmentCounter;
- uint32 ElementiumTerrorTimer,ElementiumTerrorCounter;
- uint32 CorruptedBloodTimer;
- uint32 phase;
- float DifficultyScale;
- void OnLoad()
- {
- _unit->GetAIInterface()->setOutOfCombatRange( 700.0f * 700.0f );
- ConvertToStaticSpawn( _unit, true );
- _unit->m_canRegenerateHP = false;
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- //copy health from visual target
- int64 *MadnessGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_GUID_VISUAL );
- Creature *Madness = _unit->GetMapMgr()->GetCreature( *MadnessGUID );
- if( Madness )
- {
- _unit->SetMaxHealth( Madness->GetMaxHealth() );
- _unit->SetHealth( Madness->GetHealth() );
- }
- RegisterAIUpdateEvent( 2000 );
- phase = 0;
- DifficultyScale = 1.0f;
- if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_10_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_10HEROIC;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN )
- DifficultyScale = SPEED_SCALE_DIFF_25NORMAL;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_25HEROIC;
- }
- void AIUpdate()
- {
- Unit *tank = _unit->GetAIInterface()->GetNextTarget();
- if( tank == NULL )
- {
- phase = 0;
- return;
- }
- uint32 TickNow = GetTickCount();
- if( phase == 0 )
- {
- phase = 1;
- CongealingBloodTimer = TickNow + 5000 + RandomUInt() % 25000;
- CongealingBloodCounter = 0;
- ElementiumFragmentTimer = TickNow + 10000 + RandomUInt() % 25000;
- ElementiumFragmentCounter = 0;
- ElementiumTerrorTimer = TickNow + 15000 + RandomUInt() % 25000;
- ElementiumTerrorCounter = 0;
- CorruptedBloodTimer = TickNow + 20000 + RandomUInt() % 25000;
- }
- if( phase == 1 )
- {
- //this happens when raid wipes :( Health resets to full. Maybe later reset the whole encounter ?
- if( _unit->GetHealthPct() > ( 100 + - MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT ) )
- {
- _unit->SetHealth( _unit->GetMaxHealth() / 100 * ( 100 + - MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT ) );
- }
- uint32 PlatformPlayerCount[MADNESSPLATFORM_COUNT];
- memset( PlatformPlayerCount, 0, sizeof( PlatformPlayerCount ) );
- float PlatformRadius = 40.0f * 40.0f;
- InRangePlayerSetRecProt::iterator itr3;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- for( itr3 = _unit->GetInRangePlayerSetBegin( AutoLock ); itr3 != _unit->GetInRangePlayerSetEnd(); itr3++)
- {
- if( (*itr3)->isAlive() == false )
- continue;
- float BestPlatformDist = 99999999999999.0f;
- uint32 BestPlatformIndex = 0;
- for( uint32 i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- float dist = Distance2DSq( PlatformCenterLocations[ i ][0], PlatformCenterLocations[ i ][1], (*itr3)->GetPositionX(), (*itr3)->GetPositionY() );
- if( dist < BestPlatformDist )
- {
- BestPlatformDist = dist;
- BestPlatformIndex = i;
- }
- }
- PlatformPlayerCount[ BestPlatformIndex ]++;
- }
- _unit->ReleaseInrangeLock();
- //get which platform has most players on it
- uint32 BestPlayerCount = 0;
- uint32 BestPlayerCountIndex = 0;
- for( uint32 i=0;i<MADNESSPLATFORM_COUNT;i++)
- {
- if( PlatformPlayerCount[i] > BestPlayerCount )
- {
- BestPlayerCount = PlatformPlayerCount[i];
- BestPlayerCountIndex = i;
- }
- }
- //set as active platform
- uint32 SelectedPlatform = BestPlayerCountIndex;
- if( CongealingBloodTimer < TickNow
- #ifndef TEMP_DISABLE_REQ_HEROIC
- && IS_HEROIC_INSTANCE_DIFFICULTIE( _unit->GetMapMgr()->instance_difficulty )
- #endif
- )
- {
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_CONGEALING_BLOOD );
- if( *ActiveSpawnCount < LIMIT_SPAWN_COUNT_OF_SAME_TYPE )
- {
- // uint32 BloodsToCreateCount = float2int32( 5 / DifficultyScale );
- uint32 BloodsToCreateCount = float2int32( 3 / DifficultyScale );
- for(uint32 i=0;i<BloodsToCreateCount;i++)
- {
- float RandX = PlatformCenterLocations[ SelectedPlatform ][0] + 5.0f - ( RandomUInt() % 100 ) / 10.0f;
- float RandY = PlatformCenterLocations[ SelectedPlatform ][1] + 5.0f - ( RandomUInt() % 100 ) / 10.0f;
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_CONGEALING_BLOOD, true, RandX, RandY, PlatformCenterLocations[ SelectedPlatform ][2] );
- *ActiveSpawnCount += 1;
- }
- CongealingBloodTimer = TickNow + (NPC_COOL_CONGEALING_BLOOD + RandomUInt() % NPC_COOL_CONGEALING_BLOOD)*DifficultyScale;
- CongealingBloodCounter++;
- }
- }
- else if( ShouldForceProc( _unit, CongealingBloodCounter, NPC_MINPROC_CONGEALING_BLOOD, MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT ) )
- CongealingBloodTimer = 1;
- if( ElementiumFragmentTimer < TickNow )
- {
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_ELEMENTIUM_FRAGMENT );
- if( *ActiveSpawnCount < LIMIT_SPAWN_COUNT_OF_SAME_TYPE )
- {
- float RandX = PlatformCenterLocations[ SelectedPlatform ][0] + 15.0f - ( RandomUInt() % 300 ) / 10.0f;
- float RandY = PlatformCenterLocations[ SelectedPlatform ][1] + 15.0f - ( RandomUInt() % 300 ) / 10.0f;
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_ELEMENTIUM_FRAGMENT, true, RandX, RandY, PlatformCenterLocations[ SelectedPlatform ][2] );
- *ActiveSpawnCount += 1;
- ElementiumFragmentTimer = TickNow + (NPC_COOL_ELEMENTIUM_FRAGMENT + RandomUInt() % NPC_COOL_ELEMENTIUM_FRAGMENT)*DifficultyScale;
- ElementiumFragmentCounter++;
- }
- }
- else if( ShouldForceProc( _unit, ElementiumFragmentCounter, NPC_MINPROC_ELEMENTIUM_FRAGMENT, MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT ) )
- ElementiumFragmentTimer = 1;
- if( ElementiumTerrorTimer < TickNow )
- {
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_ELEMNTIUM_TERROR );
- if( *ActiveSpawnCount < LIMIT_SPAWN_COUNT_OF_SAME_TYPE )
- {
- float RandX = PlatformCenterLocations[ SelectedPlatform ][0] + 15.0f - ( RandomUInt() % 300 ) / 10.0f;
- float RandY = PlatformCenterLocations[ SelectedPlatform ][1] + 15.0f - ( RandomUInt() % 300 ) / 10.0f;
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_ELEMNTIUM_TERROR, true, RandX, RandY, PlatformCenterLocations[ SelectedPlatform ][2] );
- *ActiveSpawnCount += 1;
- ElementiumTerrorTimer = TickNow + (NPC_COOL_ELEMNTIUM_TERROR + RandomUInt() % NPC_COOL_ELEMNTIUM_TERROR)*DifficultyScale;
- ElementiumTerrorCounter++;
- }
- }
- else if( ShouldForceProc( _unit, ElementiumTerrorCounter, NPC_MINPROC_ELEMENTIUM_TERROR, MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT ) )
- ElementiumTerrorTimer = 1;
- if( CorruptedBloodTimer < TickNow )
- {
- //each lost health pct adds 100% dmg. Should scale up to 35000 DPS ( base is 350 )
- int32 BurningBloodDMGPCT = 100 * ( ( 101 + - MADNESS_LOOSE_HP_PCT_TENTACLE * MADNESSPLATFORM_COUNT ) - _unit->GetHealthPct() * DifficultyScale );
- InRangePlayerSetRecProt::iterator itr3;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- for( itr3 = _unit->GetInRangePlayerSetBegin( AutoLock ); itr3 != _unit->GetInRangePlayerSetEnd(); itr3++)
- {
- if( (*itr3)->isAlive() == false )
- continue;
- SpellEntry *spellInfo = dbcSpell.LookupEntryForced( SPELL_ID_CORRUPTED_BLOOD );
- Spell *spell = SpellPool.PooledNew( __FILE__, __LINE__ );
- spell->Init( _unit, spellInfo ,true, NULL);
- SpellCastTargets targets( (*itr3)->GetGUID() );
- spell->forced_pct_mod[0] = BurningBloodDMGPCT;
- spell->prepare(&targets);
- }
- _unit->ReleaseInrangeLock();
- CorruptedBloodTimer = TickNow + SPELL_COOL_CORRUPTED_BLOOD; //needs to be fixed or it will not stack
- }
- }
- }
- void OnDied(Unit *mKiller)
- {
- int64 *EncounterStatus = _unit->GetMapMgr()->GetCreateIn64Extension( EXTENSION_MAP_BOS_KILLS );
- *EncounterStatus |= EXTENSION_FLAG_MADNESS_DIED;
- // _unit->GetMapMgr()->CreateCreature( MOB_ENTRY_DRAGONSOUL_TELEPORTER, true, _unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ() );
- RemoveAIUpdateEvent();
- //try to see players lie about BOSS difficulty
- LOG_CREATURE_DEATH( _unit->GetEntry(), mKiller );
- int64 *MadnessGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_GUID_VISUAL );
- Creature *Madness = _unit->GetMapMgr()->GetCreature( *MadnessGUID );
- if( Madness )
- {
- Madness->bInvincible = false;
- Madness->SetHealth( 1 );
- Madness->DealDamage( Madness, 100, NULL );
- }
- //spawn GO that players can loot
- /* GameObject *go = u_caster->GetMapMgr()->CreateGameObject(210220);
- if( go == NULL )
- {
- sLog.outDebug("Missing GO proto 210220");
- return;
- }
- go->CreateFromProto( 210220, _unit->GetMapId(), -12100.5f, 12173.6f, -2.73425f, 5.09636f );
- go->SetUInt64Value( OBJECT_FIELD_CREATED_BY, m_caster->GetGUID() );
- go->SetInstanceID( _unit->GetInstanceID() );
- go->PushToWorld( _unit->GetMapMgr() );
- sEventMgr.AddEvent(go, &GameObject::ExpireAndDelete, EVENT_GAMEOBJECT_EXPIRE, 5*60*1000, 1,0);
- */
- _unit->SetUInt32Value( UNIT_FIELD_DISPLAYID, 35268 );
- _unit->SetScale( 0.5f );
- if( mKiller && mKiller->IsPlayer() && SafePlayerCast( mKiller )->GetGuild() )
- SafePlayerCast( mKiller )->GetGuild()->GuildNewsAdd( GUILD_NEWS_LOG_DUNGEON_ENCOUNTER, mKiller->GetGUID(), 1299 );
- }
- };
- const uint32 DespawnOldLimbEncounterDynamicEntries[] = { NPC_ID_ELEMENTIUM_BOLT, NPC_ID_CORRUPTING_PARASITE, NPC_ID_HEMORRHAGE_VISUAL_LOC, NPC_ID_REGENERATIVE_BLOOD, NPC_ID_BLISTERING_TENTACLE, NPC_ID_MUTATED_CORRUPTION, 0 }; //despawn these in case encounter resets
- class LimbGeneric : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(LimbGeneric);
- uint32 phase;
- float DifficultyScale;
- uint32 RegenerativeBloodTimer,RegenerativeBloodCounter;
- uint32 CorruptionTimer,CorruptionCounter;
- uint32 LimbTentacleTimer,LimbTentacleCounter;
- uint32 BurningBloodTimer;
- uint32 AlexStraszaCauterizeTimer;
- uint32 ElementiumBoltTimer,ElementiumBoltCounter;
- uint32 CorruptingParasiteTimer,CorruptingParasiteCounter;
- LimbGeneric(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- DifficultyScale = 1.0f;
- if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_10_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_10HEROIC;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN )
- DifficultyScale = SPEED_SCALE_DIFF_25NORMAL;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_25HEROIC;
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->m_canMove = false;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- _unit->GetAIInterface()->setOutOfCombatRange( 700.0f * 700.0f ); //once we start combat we should try to not reset
- RegisterAIUpdateEvent( 1000 );
- phase = 0;
- //self root to not face the tank as we gain agro
- // _unit->CastSpell( _unit, 105451, true );
- }
- void AIUpdate()
- {
- //wait for some DPS
- if( _unit->GetHealthPct() > TENTACLE_START_FIGHT_HP_PCT )
- {
- return;
- }
- Unit *tank = _unit->GetAIInterface()->GetNextTarget();
- //try to get an alive player near us if we did not agro any
- if( tank == NULL )
- {
- InRangePlayerSetRecProt::iterator itr3;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- float Radius = 70.0f * 70.0f;
- for( itr3 = _unit->GetInRangePlayerSetBegin( AutoLock ); itr3 != _unit->GetInRangePlayerSetEnd(); itr3++)
- {
- if( (*itr3)->isAlive() == false )
- continue;
- if( Distance2DSq( (*itr3)->GetPositionX(), (*itr3)->GetPositionY(), _unit->GetPositionX(), _unit->GetPositionY() ) > Radius )
- continue;
- tank = (*itr3);
- break;
- }
- _unit->ReleaseInrangeLock();
- }
- if( tank == NULL )
- {
- //stop spamming the server and let people port to us again
- if( phase != 0 )
- {
- DespawnEncounterSpawns( _unit, DespawnOldLimbEncounterDynamicEntries );
- _unit->SetHealth( _unit->GetMaxHealth() );
- }
- phase = 0;
- return;
- }
- uint32 TickNow = GetTickCount();
- // Init phase
- if( phase == 0 )
- {
- phase = 1;
- CorruptionTimer = TickNow + 15000 + RandomUInt() % 25000;
- CorruptionCounter = 0;
- LimbTentacleTimer = TickNow + 25000 * DifficultyScale + RandomUInt() % 25000;
- LimbTentacleCounter = 0;
- RegenerativeBloodTimer = TickNow + 35000 * DifficultyScale + RandomUInt() % 25000;
- RegenerativeBloodCounter = 0;
- BurningBloodTimer = TickNow + 35000 * DifficultyScale + RandomUInt() % 25000;
- AlexStraszaCauterizeTimer = TickNow;
- ElementiumBoltTimer = TickNow + 5000 * DifficultyScale + RandomUInt() % 25000;
- ElementiumBoltCounter = 0;
- CorruptingParasiteTimer = TickNow + 10000 * DifficultyScale + RandomUInt() % 25000;
- CorruptingParasiteCounter = 0;
- _unit->SetHealth( _unit->GetMaxHealth() );
- }
- if( phase == 1 )
- {
- //only spawn on active platform
- int64 *LimbIndex = _unit->GetCreateIn64Extension( NPC_ID_LIMB0 );
- // int64 *AcctivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORM );
- // if( *LimbIndex != *AcctivePlatformIndex )
- //////////////////////////////////////////////////
- //AOE dps
- if( BurningBloodTimer < TickNow )
- {
- //each lost health pct adds 100% dmg. Should scale up to 35000 DPS ( base is 350 )
- int32 BurningBloodDMGPCT = 100 * ( 101 - _unit->GetHealthPct() * DifficultyScale );
- float Radius = 70.0f * 70.0f;
- InRangePlayerSetRecProt::iterator itr3;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- for( itr3 = _unit->GetInRangePlayerSetBegin( AutoLock ); itr3 != _unit->GetInRangePlayerSetEnd(); itr3++)
- {
- if( (*itr3)->isAlive() == false )
- continue;
- if( Distance2DSq( (*itr3)->GetPositionX(), (*itr3)->GetPositionY(), _unit->GetPositionX(), _unit->GetPositionY() ) > Radius )
- continue;
- SpellEntry *spellInfo = dbcSpell.LookupEntryForced( SPELL_ID_BURNING_BLOOD );
- Spell *spell = SpellPool.PooledNew( __FILE__, __LINE__ );
- spell->Init( _unit, spellInfo ,true, NULL);
- SpellCastTargets targets( (*itr3)->GetGUID() );
- spell->forced_pct_mod[0] = BurningBloodDMGPCT;
- spell->prepare(&targets);
- }
- _unit->ReleaseInrangeLock();
- BurningBloodTimer = TickNow + SPELL_COOL_BURNING_BLOOD; //needs to be fixed or it will not stack
- }
- //////////////////////////////////////////////////
- if( CorruptionTimer!= 0 && CorruptionTimer < TickNow )
- {
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_MUTATED_CORRUPTION, true, CorruptionLocations[*LimbIndex][0], CorruptionLocations[*LimbIndex][1], CorruptionLocations[*LimbIndex][2] );
- if( c )
- c->GetAIInterface()->AttackReaction( tank, 10, 0 );
- CorruptionTimer = 0;
- CorruptionCounter++;
- }
- //protection against imba DPS. Will flood events also
- else if( ShouldForceProc( _unit, CorruptionCounter, NPC_MINPROC_MUTATED_CORRUPTION, TENTACLE_START_FIGHT_HP_PCT ) )
- CorruptionTimer = 1;
- //////////////////////////////////////////////////
- if( RegenerativeBloodTimer < TickNow )
- {
- int64 *ActiveBloodCount = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_REGENERATIVE_BLOOD );
- if( *ActiveBloodCount < LIMIT_SPAWN_COUNT_OF_SAME_TYPE )
- {
- // int64 *HemoTargetNPCGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_HEMORRHAGE_VISUAL_LOC + *LimbIndex );
- // Creature *HemoTarget = _unit->GetMapMgr()->GetCreature( *HemoTargetNPCGUID );
- // if( HemoTarget )
- // HemoTarget->CastSpell( HemoTarget, SPELL_ID_HEMORRHAGE_VISUAL, true ); //we should have dedicated NPCs for these. They look like red circle on the ground
- //spawn a hemmorhage NPC that just marks the spawn location of the regenerative bloods
- // uint32 RegenerativeBloodSpawnCount = 6 / DifficultyScale; // [6,8]
- uint32 RegenerativeBloodSpawnCount = 4 / DifficultyScale; // [6,8]
- for( uint32 i=0;i<RegenerativeBloodSpawnCount;i++)
- {
- float RandX = 5.0f - ( RandomUInt() % 100 ) / 10.0f;
- float RandY = 5.0f - ( RandomUInt() % 100 ) / 10.0f;
- #ifndef TEMP_DISABLE_BLOOD_SAPWNS
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_REGENERATIVE_BLOOD, true, LimbTentacleLocations[*LimbIndex][0] + RandX, LimbTentacleLocations[*LimbIndex][1] + RandY, PlatformCenterLocations[*LimbIndex][2] );
- #endif
- *ActiveBloodCount += 1;
- }
- RegenerativeBloodCounter++;
- /*{
- char buff[500];
- sprintf( buff, "Debug MSG : Number of bloods %d, casts %d", (int32)(*ActiveBloodCount), RegenerativeBloodCounter );
- _unit->SendChatMessage( CHAT_MSG_MONSTER_PARTY, LANG_UNIVERSAL, buff );
- }*/
- }
- RegenerativeBloodTimer = TickNow + (NPC_COOL_REGENERATIVE_BLOOD + RandomUInt() % NPC_COOL_REGENERATIVE_BLOOD)*DifficultyScale;
- //do not spawn everything at the same time pls. Extend our spawn timer
- LimbTentacleTimer = MAX( TickNow + MIN( 10000, NPC_COOL_REGENERATIVE_BLOOD / 2 ), LimbTentacleTimer );
- }
- //protection against imba DPS. Will flood events also
- else if( ShouldForceProc( _unit, RegenerativeBloodCounter, NPC_MINPROC_REGENERATIVE_BLOOD, TENTACLE_START_FIGHT_HP_PCT ) )
- RegenerativeBloodTimer = 1;
- //////////////////////////////////////////////////
- if( LimbTentacleTimer < TickNow ) //blistering tentactle
- {
- int64 *ActiveTentacleCount = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_BLISTERING_TENTACLE );
- if( *ActiveTentacleCount < LIMIT_SPAWN_COUNT_OF_SAME_TYPE )
- {
- // uint32 LimbTentacleSpawnCount = 7 / DifficultyScale; // [7,10]
- uint32 LimbTentacleSpawnCount = 5 / DifficultyScale; // [7,10]
- for( uint32 i=0;i<LimbTentacleSpawnCount;i++)
- {
- float RandX = 5.0f - ( RandomUInt() % 100 ) / 10.0f;
- float RandY = 5.0f - ( RandomUInt() % 100 ) / 10.0f;
- #ifndef TEMP_DISABLE_TENTACLE_SAPWNS
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_BLISTERING_TENTACLE, true, LimbTentacleLocations[*LimbIndex][0] + RandX, LimbTentacleLocations[*LimbIndex][1] + RandY, PlatformCenterLocations[*LimbIndex][2] );
- #endif
- *ActiveTentacleCount += 1;
- }
- LimbTentacleCounter++;
- /*{
- char buff[500];
- sprintf( buff, "Debug MSG : Number of tentacles %d, casts %d", (int32)(*ActiveTentacleCount), LimbTentacleCounter );
- _unit->SendChatMessage( CHAT_MSG_MONSTER_PARTY, LANG_UNIVERSAL, buff );
- }*/
- }
- LimbTentacleTimer = TickNow + (NPC_COOL_LIMB_TENTACLE + RandomUInt() % NPC_COOL_LIMB_TENTACLE)*DifficultyScale;
- //do not spawn everything at the same time pls
- RegenerativeBloodTimer = MAX( TickNow + MIN( 10000, NPC_COOL_LIMB_TENTACLE / 2 ), RegenerativeBloodTimer );
- }
- //protection against imba DPS. Will flood events also
- else if( ShouldForceProc( _unit, LimbTentacleCounter, NPC_MINPROC_LIMB_TENTACLE, TENTACLE_START_FIGHT_HP_PCT ) )
- LimbTentacleTimer = 1;
- if( ElementiumBoltTimer < TickNow )
- {
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_ELEMENTIUM_BOLT );
- if( *ActiveSpawnCount < LIMIT_SPAWN_COUNT_OF_SAME_TYPE )
- {
- Creature *c = _unit->GetMapMgr()->CreateCreature( NPC_ID_ELEMENTIUM_BOLT, true, ElementiumBoltStart[ *LimbIndex ][0], ElementiumBoltStart[ *LimbIndex ][1], ElementiumBoltStart[ *LimbIndex ][2] );
- if( c )
- {
- int64 *MyLimIndex = c->GetCreateIn64Extension( NPC_ID_ELEMENTIUM_BOLT );
- *MyLimIndex = *LimbIndex;
- // c->GetAIInterface()->MoveTo( PlatformCenterLocations[ *LimbIndex ][0], PlatformCenterLocations[ *LimbIndex ][1], PlatformCenterLocations[ *LimbIndex ][2], 0.0f );
- }
- ElementiumBoltTimer = TickNow + (NPC_COOL_ELEMENTIUM_BOLT + RandomUInt() % NPC_COOL_ELEMENTIUM_BOLT)*DifficultyScale;
- ElementiumBoltCounter++;
- *ActiveSpawnCount += 1;
- }
- }
- else if( _unit->GetHealthPct() < 50 && ShouldForceProc( _unit, ElementiumBoltCounter, NPC_MINPROC_ELEMENTIUM_BOLT, TENTACLE_START_FIGHT_HP_PCT ) )
- ElementiumBoltTimer = 1;
- if(
- #ifndef TEMP_DISABLE_REQ_HEROIC
- IS_HEROIC_INSTANCE_DIFFICULTIE( _unit->GetMapMgr()->instance_difficulty ) &&
- #endif
- CorruptingParasiteTimer < TickNow )
- {
- AI_Spell sp;
- sp.spelltargetType = TTYPE_ENEMY_FOR_BUFF;
- sp.minrange = 0.0f;
- sp.maxrange = 20.0f;
- sp.procChance = 100;
- sp.spell = dbcSpell.LookupEntryForced( SPELL_ID_CORRUPTING_PARASITE );
- Unit *t = _unit->GetAIInterface()->FindTargetForSpellTargetType( &sp );
- if( t )
- {
- _unit->CastSpell( t, SPELL_ID_CORRUPTING_PARASITE, false );
- CorruptingParasiteTimer = TickNow + (SPELL_COOL_CORRUPTING_PARASITE + RandomUInt() % SPELL_COOL_CORRUPTING_PARASITE)*DifficultyScale;
- CorruptingParasiteCounter++;
- }
- }
- else if( ShouldForceProc( _unit, CorruptingParasiteCounter, SPELL_MINPROC_CORRUPTING_PARASITE, TENTACLE_START_FIGHT_HP_PCT ) )
- CorruptingParasiteTimer = 1;
- //get the tentacle of the active platform
- if( AlexStraszaCauterizeTimer < TickNow )
- {
- AlexStraszaCauterizeTimer = TickNow + SPELL_COOL_CAUTERIZE; //3% HP every X seconds
- uint32 RequiresPlatform = 0;
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + RequiresPlatform );
- if( *CanActivePlatformIndex == 1 )
- {
- int64 *AspectGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_ASPECT_ALEXSTRASZA );
- Creature *Aspect = _unit->GetMapMgr()->GetCreature( *AspectGUID );
- if( Aspect )
- {
- //cauterize the blistering tentacles and corrupted parasites
- InRangeSetRecProt::iterator itr,itr2;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- for( itr2 = _unit->GetInRangeSetBegin( AutoLock ); itr2 != _unit->GetInRangeSetEnd();)
- {
- itr = itr2;
- itr2++; //maybe scripts can change list. Should use lock instead of this to prevent multiple changes. This protects to 1 deletion only
- if( (*itr)->IsCreature() == false || SafeUnitCast( *itr )->isAlive() == false )
- continue;
- if( (*itr)->GetEntry() == NPC_ID_BLISTERING_TENTACLE // NPC_ID_BLISTERING_TENTACLE
- || ( (*itr)->GetEntry() == NPC_ID_CORRUPTING_PARASITE )
- )
- {
- Aspect->CastSpell( SafeCreatureCast(*itr), SPELL_ID_CAUTERIZE, false );
- }
- }
- _unit->ReleaseInrangeLock();
- }
- }
- }
- }
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- //cast Agonizing Pain on deathwing
- int64 *MadnessGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_GUID_VISUAL );
- // *MadnessGUID = _unit->GetGUID();
- Creature *DW = _unit->GetMapMgr()->GetCreature( *MadnessGUID );
- if( DW )
- {
- DW->InterruptSpell( ); //in case he is channeling "cataclysm"
- // DW->CastSpell( DW, SPELL_ID_AGONIZING_PAIN, false );
- //loose 20% of health
- int32 HealthLost = -(int32)DW->GetMaxHealth() / 100 * MADNESS_LOOSE_HP_PCT_TENTACLE;
- DW->ModHealth( HealthLost );
- /*{
- char buff[500];
- sprintf( buff, "Debug MSG : Limb died. Madness GUID %d, health mod %d", (int32)(*MadnessGUID), HealthLost );
- _unit->SendChatMessage( CHAT_MSG_MONSTER_PARTY, LANG_UNIVERSAL, buff );
- }/**/
- }
- //mark that the limb on this platform is dead and there is no point to activate it anymore
- int64 *LimbIndex = _unit->GetCreateIn64Extension( NPC_ID_LIMB0 );
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + *LimbIndex );
- *CanActivePlatformIndex = 0;
- //no need to block vision. Just begone
- _unit->Despawn( 1, 0 );
- }
- };
- //sub spawn of limbs
- class BlisteringTentacle : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(BlisteringTentacle);
- BlisteringTentacle(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- _unit->GetAIInterface()->m_canMove = false;
- for(uint32 i=0;i<SCHOOL_COUNT;i++)
- _unit->AoeDamageTakenPctMod[ i ] = 0.0f;
- _unit->CastSpell( _unit, SPELL_ID_BLISTERING_HEAT, false );
- }
- void OnDied(Unit *mKiller)
- {
- //no need to block vision. Just begone
- _unit->Despawn( 1, 0 );
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( _unit->GetEntry() );
- *ActiveSpawnCount -= 1;
- }
- };
- class MutatedCorruption : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(MutatedCorruption);
- MutatedCorruption(Creature* pCreature) : CreatureAIScript(pCreature) { }
- uint32 CrushTimer;
- uint32 ImpaleTimer;
- float DifficultyScale;
- void OnLoad()
- {
- DifficultyScale = 1.0f;
- if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_10_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_10HEROIC;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN )
- DifficultyScale = SPEED_SCALE_DIFF_25NORMAL;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_25HEROIC;
- _unit->GetAIInterface()->m_canMove = false;
- CrushTimer = SPELL_COOL_CRUSH;
- ImpaleTimer = SPELL_COOL_IMPALE;
- _unit->GetAIInterface()->setOutOfCombatRange( 120.0f * 120.0f ); //once we start combat we should try to not reset
- RegisterAIUpdateEvent( 5000 );
- }
- void AIUpdate()
- {
- Unit *tank = _unit->GetAIInterface()->GetNextTarget();
- if( tank == NULL )
- {
- return;
- }
- uint32 TickNow = GetTickCount();
- if( CrushTimer < TickNow && _unit->isCasting() == false )
- {
- _unit->CastSpell( tank, SPELL_ID_CRUSH, false );
- CrushTimer = TickNow + (SPELL_COOL_CRUSH + RandomUInt() % SPELL_COOL_CRUSH)*DifficultyScale;
- }
- if( ImpaleTimer < TickNow && _unit->isCasting() == false )
- {
- _unit->CastSpell( tank, SPELL_ID_IMPALE, false );
- ImpaleTimer = TickNow + (SPELL_COOL_IMPALE + RandomUInt() % SPELL_COOL_IMPALE)*DifficultyScale;
- }
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- }
- };
- class RegenerativeBlood : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(RegenerativeBlood);
- RegenerativeBlood(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- //proc on attack
- SpellEntry *sp = dbcSpell.LookupEntryForced( SPELL_ID_DEGENRATIVE_BITE ); //Degenerative Bite
- ProcTriggerSpell pts( sp, NULL );
- pts.caster = _unit->GetGUID();
- pts.spellId = sp->Id;
- pts.procFlags = PROC_ON_MELEE_ATTACK;
- pts.created_with_value = sp->eff[0].EffectBasePoints + 1;
- pts.procCharges = 0;
- pts.procChance = 100;
- pts.procInterval = SPELL_COOL_DEGENRATIVE_BITE;
- _unit->RegisterScriptProcStruct( pts );
- _unit->PctPowerRegenModifier[POWER_TYPE_MANA] = 0.0f;
- _unit->SetPower( POWER_TYPE_MANA, 0 );
- _unit->SetPowerType( POWER_TYPE_MANA );
- _unit->SetMaxPower( POWER_TYPE_MANA, 100 );
- RegisterAIUpdateEvent( SPELL_COOL_REGENERATIVE );
- }
- void AIUpdate()
- {
- _unit->ModPower( POWER_TYPE_MANA, 10 );
- // _unit->UpdatePowerAmm( true, POWER_TYPE_MANA );
- if( _unit->GetPower( POWER_TYPE_MANA ) == 100 )
- {
- _unit->SetPower( POWER_TYPE_MANA, 0 );
- _unit->CastSpell( _unit, SPELL_ID_REGENERATIVE, false ); //self heal to max
- }
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- //no need to block vision. Just begone
- _unit->Despawn( 1, 0 );
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( _unit->GetEntry() );
- *ActiveSpawnCount -= 1;
- }
- };
- class CorruptingParasite : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(CorruptingParasite);
- CorruptingParasite(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- //cast backlash
- _unit->CastSpell( _unit, SPELL_ID_CORRUPTING_PARASITE_BACKLASH, true );
- RegisterAIUpdateEvent( SPELL_COOL_UNSTABLE_CORRUPTION );
- }
- void AIUpdate()
- {
- SpellEntry *spellInfo = dbcSpell.LookupEntryForced( SPELL_ID_UNSTABLE_CORRUPTION );
- Spell *spell = SpellPool.PooledNew( __FILE__, __LINE__ );
- spell->Init( _unit, spellInfo ,true, NULL);
- SpellCastTargets targets( _unit->GetGUID() );
- spell->forced_basepoints[0] = spellInfo->eff[0].EffectBasePoints * _unit->GetHealth() / 100; //with 6M health this does 600k dmg / tick ? :O
- spell->prepare(&targets);
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- }
- };
- class ElementiumBolt : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(ElementiumBolt);
- ElementiumBolt(Creature* pCreature) : CreatureAIScript(pCreature) { }
- uint8 phase;
- uint32 StartMoveTimer;
- uint32 ElementiumPulseTick;
- void OnLoad()
- {
- _unit->m_walkSpeed = 2.5f ;
- _unit->m_runSpeed = _unit->m_walkSpeed;
- _unit->m_base_runSpeed = _unit->m_runSpeed;
- _unit->m_base_walkSpeed = _unit->m_walkSpeed;
- _unit->m_flySpeed = _unit->m_walkSpeed;
- _unit->m_backFlySpeed = 4.5f / 2;
- _unit->m_backWalkSpeed = 4.5f / 2; // this should really be named m_backRunSpeed
- _unit->m_swimSpeed = 4.722222f / 2;
- _unit->m_backSwimSpeed = 2.5f / 2;
- _unit->m_turnRate = 3.141593f / 2;
- _unit->m_pitchRate = 3.141593f / 2;
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- RegisterAIUpdateEvent( 1000 );
- StartMoveTimer = GetTickCount() + 5000;
- phase = 0;
- ElementiumPulseTick = 0;
- }
- void AIUpdate()
- {
- if( phase == 0 )
- {
- if( StartMoveTimer != 0 )
- {
- if( StartMoveTimer < GetTickCount() )
- {
- int64 *MyLimIndex = _unit->GetCreateIn64Extension( NPC_ID_ELEMENTIUM_BOLT );
- _unit->GetAIInterface()->MoveTo( PlatformCenterLocations[ *MyLimIndex ][0], PlatformCenterLocations[ *MyLimIndex ][1], PlatformCenterLocations[ *MyLimIndex ][2], 0.0f );
- StartMoveTimer = 0;
- }
- else
- {
- return;
- }
- }
- //we are getting updated but we did not even started moving
- if( _unit->GetAIInterface()->m_creatureState == STOPPED )
- phase = 1;
- }
- else if( phase == 1 )
- {
- _unit->CastSpell( _unit, SPELL_ID_ELEMNTIUM_BLAST, false ); //AOE
- phase = 2;
- ElementiumPulseTick = GetTickCount() + SPELL_COOL_ELEMNTIUM_BLAST;
- }
- else if( phase == 2 )
- {
- uint32 TickNow = GetTickCount();
- if( ElementiumPulseTick < TickNow )
- {
- _unit->CastSpell( _unit, SPELL_ID_ELEMNTIUM_BLAST_PULSE, false ); //AOE pulse until destroyed
- ElementiumPulseTick = TickNow + SPELL_COOL_ELEMNTIUM_BLAST;
- }
- }
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- //no need to block vision. Just begone
- _unit->Despawn( 1, 0 );
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( _unit->GetEntry() );
- *ActiveSpawnCount -= 1;
- }
- };
- class CongealingBlood : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(CongealingBlood);
- CongealingBlood(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- _unit->m_walkSpeed = 1.2f ;
- _unit->m_runSpeed = _unit->m_walkSpeed;
- _unit->m_base_runSpeed = _unit->m_runSpeed;
- _unit->m_base_walkSpeed = _unit->m_walkSpeed;
- _unit->m_flySpeed = _unit->m_walkSpeed;
- _unit->m_backFlySpeed = 4.5f / 2;
- _unit->m_backWalkSpeed = 4.5f / 2; // this should really be named m_backRunSpeed
- _unit->m_swimSpeed = 4.722222f / 2;
- _unit->m_backSwimSpeed = 2.5f / 2;
- _unit->m_turnRate = 3.141593f / 2;
- _unit->m_pitchRate = 3.141593f / 2;
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- RegisterAIUpdateEvent( 3000 );
- }
- void AIUpdate()
- {
- int64 *MadnessGUID = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_ATTACKTARGET );
- Creature *DW = _unit->GetMapMgr()->GetCreature( *MadnessGUID );
- if( DW == NULL )
- return;
- //always try to move closer
- if( _unit->GetAIInterface()->m_creatureState == STOPPED )
- _unit->GetAIInterface()->MoveTo( DW->GetPositionX(), DW->GetPositionY(), -6.1f, 0.0f );
- //if we reach owner we heal him 1% HP and suicide
- if( DW->GetDistance2dSq( _unit ) < 5.0f*5.0f )
- {
- uint32 PCT1HP = DW->GetMaxHealth() * 1 / 100;
- if( DW->isAlive() )
- _unit->Heal( DW, SPELL_ID_CONGEALING_BLOOD_HEAL, PCT1HP );
- RemoveAIUpdateEvent();
- _unit->Despawn( 1, 0 );
- }
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( _unit->GetEntry() );
- *ActiveSpawnCount -= 1;
- }
- };
- //periodically cast shrapnel at a nearby player
- class ElementiumFragment : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(ElementiumFragment);
- uint32 ShrapnelTimer;
- float DifficultyScale;
- ElementiumFragment(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- DifficultyScale = 1.0f;
- if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_10_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_10HEROIC;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN )
- DifficultyScale = SPEED_SCALE_DIFF_25NORMAL;
- else if( _unit->GetMapMgr()->instance_difficulty & INSTANCE_FLAG_RAID_25_MEN_HEROIC )
- DifficultyScale = SPEED_SCALE_DIFF_25HEROIC;
- _unit->GetAIInterface()->m_canMove = false;
- ShrapnelTimer = 0;
- RegisterAIUpdateEvent( 5000 );
- }
- void AIUpdate()
- {
- Unit *tank = _unit->GetAIInterface()->GetNextTarget();
- if( tank == NULL )
- {
- ShrapnelTimer = SPELL_COOL_SHRAPNEL;
- return;
- }
- uint32 TickNow = GetTickCount();
- if( ShrapnelTimer - 7000 < TickNow && ShrapnelTimer > TickNow && _unit->isCasting() == false )
- {
- _unit->CastSpell( tank, SPELL_ID_SHRAPNEL_TARGETED, false );
- }
- else if( ShrapnelTimer < TickNow && _unit->isCasting() == false )
- {
- _unit->CastSpell( tank, SPELL_ID_SHRAPNEL_DMG, false );
- ShrapnelTimer = TickNow + (SPELL_COOL_SHRAPNEL + RandomUInt() % SPELL_COOL_SHRAPNEL)*DifficultyScale;
- }
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( _unit->GetEntry() );
- *ActiveSpawnCount -= 1;
- }
- };
- //large melee dmg
- class ElementiumTerror : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(ElementiumTerror);
- ElementiumTerror(Creature* pCreature) : CreatureAIScript(pCreature) { }
- void OnLoad()
- {
- //proc on attack
- SpellEntry *sp = dbcSpell.LookupEntryForced( SPELL_ID_TETANUS ); //Degenerative Bite
- ProcTriggerSpell pts( sp, NULL );
- pts.caster = _unit->GetGUID();
- pts.spellId = sp->Id;
- pts.procFlags = PROC_ON_MELEE_ATTACK;
- pts.created_with_value = sp->eff[0].EffectBasePoints + 1;
- pts.procCharges = 0;
- pts.procChance = 100;
- pts.procInterval = SPELL_COOL_TETANUS;
- _unit->RegisterScriptProcStruct( pts );
- }
- void AIUpdate()
- {
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- int64 *ActiveSpawnCount = _unit->GetMapMgr()->GetCreateIn64Extension( _unit->GetEntry() );
- *ActiveSpawnCount -= 1;
- }
- };
- class AspectAIGeneric : public CreatureAIScript
- {
- public:
- ADD_CREATURE_FACTORY_FUNCTION(AspectAIGeneric);
- AspectAIGeneric(Creature* pCreature) : CreatureAIScript(pCreature) { }
- uint32 CastSpell1,CastSpell2;
- uint32 RequiresPlatform;
- void OnLoad()
- {
- _unit->GetAIInterface()->disable_melee = true;
- _unit->GetAIInterface()->disable_combat = true;
- _unit->GetAIInterface()->disable_targeting = true;
- _unit->bInvincible = true;
- _unit->GetAIInterface()->m_moveFly = true;
- //aura that will buff nearby players
- CastSpell1 = CastSpell2 = 0;
- RequiresPlatform = MADNESSPLATFORM_COUNT + 1;
- if( _unit->GetEntry() == NPC_ID_ASPECT_ALEXSTRASZA )
- {
- CastSpell1 = SPELL_ID_ALEXTRASZA_PRESENCE;
- RequiresPlatform = 0;
- }
- else if( _unit->GetEntry() == NPC_ID_ASPECT_NOZDORMU )
- {
- CastSpell1 = SPELL_ID_NOZDORMU_PRESENCE;
- RequiresPlatform = 1;
- }
- else if( _unit->GetEntry() == NPC_ID_ASPECT_YSERA )
- {
- CastSpell1 = SPELL_ID_YSERA_PRESENCE;
- CastSpell2 = SPELL_ID_ENTER_THE_DREAM;
- RequiresPlatform = 2;
- }
- else if( _unit->GetEntry() == NPC_ID_ASPECT_KALECGOS )
- {
- CastSpell1 = SPELL_ID_KALECGOS_PRESENCE;
- CastSpell2 = SPELL_ID_SPELLWEAVING;
- RequiresPlatform = 3;
- }
- else if( _unit->GetEntry() == NPC_ID_ASPECT_THRALL ) //thrall
- {
- // CastSpell1 = SPELL_ID_CARRYING_WINDS;
- RequiresPlatform = MADNESSPLATFORM_COUNT + 1;
- }
- //do not unload us until map gets destroyed to not go out of range :(
- // _unit->GetMapMgr()->PushStaticObject( _unit );
- // _unit->static_object = true; //do not go out of visual range
- _unit->GetAIInterface()->setOutOfCombatRange( 700.0f * 700.0f );
- RegisterAIUpdateEvent( 5000 ); //less then the duration of the presence spell
- }
- void AIUpdate()
- {
- if( RequiresPlatform < MADNESSPLATFORM_COUNT )
- {
- int64 *CanActivePlatformIndex = _unit->GetMapMgr()->GetCreateIn64Extension( NPC_ID_MADNESS_VISUAL + MADNESS_INDEX_ACTIVE_PLATFORMS + RequiresPlatform );
- if( *CanActivePlatformIndex == 0 )
- return;
- }
- InRangePlayerSetRecProt::iterator itr2;
- _unit->AquireInrangeLock(); //make sure to release lock before exit function !
- InrangeLoopExitAutoCallback AutoLock;
- for( itr2 = _unit->GetInRangePlayerSetBegin( AutoLock ); itr2 != _unit->GetInRangePlayerSetEnd(); itr2++)
- {
- if( (*itr2)->isAlive() == false )
- continue;
- float dist = (*itr2)->GetDistance2dSq( _unit );
- if( dist > (700.0f * 700.0f) )
- continue;
- if( CastSpell1 )
- _unit->CastSpell( (*itr2), CastSpell1, true );
- if( CastSpell2 )
- _unit->CastSpell( (*itr2), CastSpell2, true );
- }
- _unit->ReleaseInrangeLock();
- }
- void OnDied(Unit *mKiller)
- {
- RemoveAIUpdateEvent();
- }
- };
- void DeathwingMadnessPlatformAreatriggers(Player * pPlayer, uint32 AreaTrigger)
- {
- /* 7412 - left areatrigger fall in abyss
- 7110, 7315
- 7111 - back to 7110
- 7112, 7317
- 7113, 7318 - back to 7112
- 7114, 7319
- 7115, 7320 - back to 7114
- */
- bool DoJump = false;
- float m_destX;
- float m_destY;
- float m_destZ;
- switch(AreaTrigger)
- {
- case 7412:
- {
- pPlayer->SafeTeleport( pPlayer->GetMapId(), pPlayer->GetInstanceID(), -12128.0f, 12181.0f, 2.0f, 5.50f );
- }break;
- case 7110:
- // case 7315: //land trigger
- {
- m_destX = -12028.0f;
- m_destY = 12229.0f;
- m_destZ = -6.0f;
- DoJump = true;
- } break;
- case 7111:
- // case 7316: //land trigger
- {
- m_destX = -11967.0f;
- m_destY = 12262.0f;
- m_destZ = 2.0f;
- DoJump = true;
- } break;
- case 7112:
- // case 7317: //land trigger
- {
- m_destX = -12089.0f;
- m_destY = 12163.0f;
- m_destZ = -2.0f;
- DoJump = true;
- } break;
- case 7113:
- // case 7318: //land trigger
- {
- m_destX = -12047.0f;
- m_destY = 12210.0f;
- m_destZ = -5.0f;
- DoJump = true;
- } break;
- case 7114:
- // case 7319: //land trigger
- {
- m_destX = -12117.0f;
- m_destY = 12085.0f;
- m_destZ = 3.0f;
- DoJump = true;
- } break;
- case 7115:
- // case 7320: //land trigger
- {
- m_destX = -12101.0f;
- m_destY = 12149.0f;
- m_destZ = -2.0f;
- DoJump = true;
- } break;
- }
- if( DoJump == true )
- {
- float radius = sqrt( Distance2DSq( pPlayer->GetPositionX(), pPlayer->GetPositionY(), m_destX, m_destY ) );
- float speed = 137.0f / 15.0f; //well this is just 1 example from blizz :p
- uint32 timetofly = (uint32)(radius * speed);
- float raise_mob_to_height = radius * 2.5f; //no idea about this value, should be parabolic parameter some sort
- pPlayer->SpeedCheatDelay( radius * 1000 / speed + MIN( 5000, pPlayer->GetSession()->GetLatency() ) + 2000 ); //should start sampling again after we land
- pPlayer->GetAIInterface()->SendMoveToPacket( m_destX, m_destY, m_destZ, 0.0f, timetofly, MONSTER_MOVE_FLAG_HEROIC_LEAP, raise_mob_to_height );
- pPlayer->CastSpell( pPlayer, SPELL_ID_CARRYING_WINDS, true ); //comes from Thrall
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement