Changeset 130

Show
Ignore:
Timestamp:
11/19/08 13:38:54 (17 years ago)
Author:
yumileroy
Message:

[svn] Add new function SelectUnit? and SelectUnitList? to select target or targets with check "isPlayer" and "isWithinDist". Also add target type SELECT_TARGET_NEAREST and SELECT_TARGET_FARTHEST.
SpellEffect? Fix for 40802,29364,43723,41931. Patch provided by WarHead?.
Update script of Fathom Lord. Patch provided by Blaymoira.

Original author: megamage
Date: 2008-10-28 16:28:42-05:00

Location:
trunk/src
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/bindings/scripts/include/sc_creature.cpp

    r118 r130  
    260260 
    261261    return NULL; 
     262} 
     263 
     264struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> 
     265{ 
     266    const Unit* me; 
     267    TargetDistanceOrder(const Unit* Target) : me(Target) {}; 
     268    // functor for operator ">" 
     269    bool operator()(const Unit* _Left, const Unit* _Right) const 
     270    { 
     271        return (me->GetDistance(_Left) < me->GetDistance(_Right)); 
     272    } 
     273}; 
     274 
     275Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly) 
     276{ 
     277    if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) 
     278    { 
     279        std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList(); 
     280        if(m_threatlist.empty()) return NULL; 
     281        std::list<Unit*> targetList; 
     282        std::list<HostilReference*>::iterator itr = m_threatlist.begin(); 
     283        for(; itr!= m_threatlist.end(); ++itr) 
     284        { 
     285            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
     286            if(!target 
     287                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     288                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     289            { 
     290                continue; 
     291            } 
     292            targetList.push_back(target); 
     293        } 
     294        if(position >= targetList.size()) 
     295            return NULL; 
     296        targetList.sort(TargetDistanceOrder(m_creature)); 
     297        if(targetType == SELECT_TARGET_NEAREST) 
     298        { 
     299            std::list<Unit*>::iterator i = targetList.begin(); 
     300            advance(i, position); 
     301            return *i; 
     302        } 
     303        else 
     304        { 
     305            std::list<Unit*>::reverse_iterator i = targetList.rbegin(); 
     306            advance(i, position); 
     307            return *i; 
     308        } 
     309    } 
     310    else 
     311    { 
     312        std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList(); 
     313        std::list<HostilReference*>::iterator i; 
     314        Unit *target; 
     315        while(position < m_threatlist.size()) 
     316        { 
     317            if(targetType == SELECT_TARGET_BOTTOMAGGRO) 
     318            { 
     319                i = m_threatlist.end(); 
     320                advance(i, - (int32)position - 1); 
     321            } 
     322            else 
     323            { 
     324                i = m_threatlist.begin(); 
     325                if(targetType == SELECT_TARGET_TOPAGGRO) 
     326                    advance(i, position); 
     327                else // random 
     328                    advance(i, position + rand()%(m_threatlist.size() - position)); 
     329            } 
     330 
     331            target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); 
     332            if(!target 
     333                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     334                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     335            { 
     336                m_threatlist.erase(i); 
     337            } 
     338            else 
     339            { 
     340                return target; 
     341            } 
     342        } 
     343    } 
     344 
     345    return NULL; 
     346} 
     347 
     348void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly) 
     349{ 
     350    if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) 
     351    { 
     352        std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList(); 
     353        if(m_threatlist.empty()) return; 
     354        std::list<HostilReference*>::iterator itr = m_threatlist.begin(); 
     355        for(; itr!= m_threatlist.end(); ++itr) 
     356        { 
     357            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
     358            if(!target 
     359                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     360                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     361            { 
     362                continue; 
     363            } 
     364            targetList.push_back(target); 
     365        } 
     366        targetList.sort(TargetDistanceOrder(m_creature)); 
     367        targetList.resize(num); 
     368        if(targetType == SELECT_TARGET_FARTHEST) 
     369            targetList.reverse(); 
     370    } 
     371    else 
     372    { 
     373        std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList(); 
     374        std::list<HostilReference*>::iterator i; 
     375        Unit *target; 
     376        while(m_threatlist.size()) 
     377        { 
     378            if(targetType == SELECT_TARGET_BOTTOMAGGRO) 
     379            { 
     380                i = m_threatlist.end(); 
     381                --i; 
     382            } 
     383            else 
     384            { 
     385                i = m_threatlist.begin(); 
     386                if(targetType == SELECT_TARGET_RANDOM) 
     387                    advance(i, rand()%m_threatlist.size()); 
     388            } 
     389 
     390            target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); 
     391            m_threatlist.erase(i); 
     392            if(!target 
     393                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     394                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     395            { 
     396                continue;                 
     397            } 
     398            targetList.push_back(target); 
     399        } 
     400    } 
    262401} 
    263402 
  • trunk/src/bindings/scripts/include/sc_creature.h

    r109 r130  
    147147    //Selects a unit from the creature's current aggro list 
    148148    Unit* SelectUnit(SelectAggroTarget target, uint32 position); 
     149    Unit* SelectUnit(SelectAggroTarget target, uint32 position, float dist, bool playerOnly); 
     150    void SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget target, float dist, bool playerOnly); 
    149151 
    150152    //Returns spells that meet the specified criteria from the creatures spell list 
  • trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp

    r109 r130  
    1717/* ScriptData 
    1818SDName: Boss_Fathomlord_Karathress 
    19 SD%Complete: 50 
    20 SDComment: Missing Multishot, pet, Totems, Windfury, Whirlwind 
     19SD%Complete: 70% 
     20SDComment: Cyclone workaround 
    2121SDCategory: Coilfang Resevoir, Serpent Shrine Cavern 
    2222EndScriptData */ 
     
    2424#include "precompiled.h" 
    2525#include "def_serpent_shrine.h" 
     26#include "../../../npc/npc_escortAI.h" 
    2627 
    2728//Karathress spells 
    28 #define SPELL_CATACLYSMIC_BOLT     38441 
    29 #define SPELL_POWER_OF_SHARKKIS    38455 
    30 #define SPELL_POWER_OF_TIDALVESS   38452 
    31 #define SPELL_POWER_OF_CARIBDIS    38451 
    32 #define SPELL_ENRAGE               24318 
     29#define SPELL_CATACLYSMIC_BOLT                  38441 
     30#define SPELL_POWER_OF_SHARKKIS                 38455 
     31#define SPELL_POWER_OF_TIDALVESS                38452 
     32#define SPELL_POWER_OF_CARIBDIS                 38451 
     33#define SPELL_ENRAGE                                    45078 
     34#define SPELL_SEAR_NOVA                                 38445 
     35#define SPELL_BLESSING_OF_THE_TIDES             38449 
     36 
    3337//Sharkkis spells 
    34 #define SPELL_LEECHING_THROW       29436 
    35 #define SPELL_THE_BEAST_WITHIN     38373 
     38#define SPELL_LEECHING_THROW                    29436 
     39#define SPELL_THE_BEAST_WITHIN                  38373 
     40#define SPELL_LEECHING_THROW                    29436 
     41#define SPELL_MULTISHOT                                 38366 
     42#define SPELL_THE_BEAST_WITHIN                  38373 
     43#define SPELL_SUMMON_FATHOM_LURKER              38433 
     44#define SPELL_SUMMON_FATHOM_SPOREBAT    38431 
     45#define SPELL_PET_ENRAGE                19574 
     46 
    3647//Tidalvess spells 
    37 #define SPELL_FROST_SHOCK          38234 
     48#define SPELL_FROST_SHOCK                               38234 
     49#define SPELL_SPITFIRE_TOTEM                    38236 
     50#define SPELL_POISON_CLEANSING_TOTEM    38306 
     51#define SPELL_POISON_CLEANSING_EFFECT   8167 
     52#define SPELL_EARTHBIND_TOTEM                   38304 
     53#define SPELL_EARTHBIND_TOTEM_EFFECT    6474 
     54#define SPELL_WINDFURY_WEAPON                   32911 
     55 
    3856//Caribdis Spells 
    39 #define SPELL_WATER_BOLT_VOLLEY    38335 
    40 #define SPELL_TIDAL_SURGE          38353 
    41 #define SPELL_HEAL                 41386 
    42  
    43 #define SAY_AGGRO                  "Guards, attention! We have visitors..." 
    44 #define SAY_SLAY1                  "I am rid of you." 
    45 #define SAY_GAIN_ABILITY1          "I am more powerful than ever!" 
    46 #define SAY_GAIN_ABILITY2          "Go on, kill them! I'll be the better for it!" 
    47 #define SAY_GAIN_ABILITY3          "More knowledge, more power!" 
    48 #define SAY_DEATH                  "Her ... excellency ... awaits!" 
    49  
    50 #define SOUND_AGGRO                11277 
    51 #define SOUND_PLYR_ATTACK          11278 
    52 #define SOUND_GAIN_ABILITY1        11279 
    53 #define SOUND_GAIN_ABILITY2        11280 
    54 #define SOUND_GAIN_ABILITY3        11281 
    55 #define SOUND_SLAY1                11282 
    56 #define SOUND_SLAY2                11283 
    57 #define SOUND_SLAY3                11284 
    58 #define SOUND_DEATH                11285 
     57#define SPELL_WATER_BOLT_VOLLEY                 38335 
     58#define SPELL_TIDAL_SURGE                               38358 
     59#define SPELL_TIDAL_SURGE_FREEZE                38357 
     60#define SPELL_HEAL                                              41386 
     61#define SPELL_SUMMON_CYCLONE                    38337 
     62#define SPELL_CYCLONE_CYCLONE                   29538 
     63 
     64//Yells and Quotes 
     65#define SAY_AGGRO                                               "Guards, attention! We have visitors..." 
     66#define SOUND_AGGRO                                             11277 
     67#define SAY_SLAY1                                               "I am rid of you." 
     68#define SOUND_SLAY1                                             11282 
     69#define SAY_SLAY2                                               "Land-dwelling scum!" 
     70#define SOUND_SLAY2                                             11284 
     71#define SAY_GAIN_ABILITY1                               "I am more powerful than ever!" 
     72#define SOUND_GAIN_ABILITY1                             11279 
     73#define SAY_GAIN_ABILITY2                               "Go on, kill them! I'll be the better for it!" 
     74#define SOUND_GAIN_ABILITY2                             11280 
     75#define SAY_GAIN_ABILITY3                               "More knowledge, more power!" 
     76#define SOUND_GAIN_ABILITY3                             11281 
     77#define SAY_DEATH                                               "Her ... excellency ... awaits!" 
     78#define SOUND_DEATH                                             11285 
     79#define SAY_GAIN_BLESSING_OF_TIDES              "Your overconfidence will be your undoing! Guards, lend me your strength!" 
     80#define SOUND_GAIN_BLESSING_OF_TIDES    11278 
     81#define SAY_MISC                                                "Alana be'lendor!" //don't know what use this 
     82#define SOUND_MISC                                              11283 
     83 
     84//Summoned Unit GUIDs 
     85#define CREATURE_CYCLONE                22104 
     86#define CREATURE_FATHOM_SPOREBAT        22120 
     87#define CREATURE_FATHOM_LURKER          22119 
     88#define CREATURE_SPITFIRE_TOTEM         22091 
     89#define CREATURE_EARTHBIND_TOTEM        22486 
     90#define CREATURE_POISON_CLEANSING_TOTEM 22487 
    5991 
    6092//entry and position for Seer Olum 
     
    81113    uint32 CataclysmicBolt_Timer; 
    82114    uint32 Enrage_Timer; 
     115        uint32 SearNova_Timer; 
     116 
     117        bool BlessingOfTides; 
    83118 
    84119    uint64 Advisors[3]; 
     
    88123        CataclysmicBolt_Timer = 10000; 
    89124        Enrage_Timer = 600000;                              //10 minutes 
    90  
    91         Creature* Advisor; 
    92         for(uint8 i = 0; i < 3; ++i) 
    93             if(Advisors[i]) 
    94         { 
    95             Advisor = ((Creature*)Unit::GetUnit(*m_creature, Advisors[i])); 
    96             if(Advisor) 
    97             { 
    98                 if(Advisor->isAlive()) 
    99                 { 
    100                     Advisor->DealDamage(Advisor, Advisor->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    101                     Advisor->RemoveCorpse(); 
    102                     Advisor->Respawn(); 
    103                 } 
    104                 Advisor->AI()->EnterEvadeMode(); 
    105             } 
    106         } 
    107  
    108         if( pInstance ) 
    109             pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED); 
    110     } 
     125                SearNova_Timer = 20000+rand()%40000; // 20 - 60 seconds 
     126 
     127                BlessingOfTides = false; 
     128 
     129 
     130 
     131                if(pInstance) 
     132                { 
     133                        uint64 RAdvisors[3]; 
     134                        RAdvisors[0] = pInstance->GetData64(DATA_SHARKKIS); 
     135                        RAdvisors[1] = pInstance->GetData64(DATA_TIDALVESS); 
     136                        RAdvisors[2] = pInstance->GetData64(DATA_CARIBDIS); 
     137                        //Respawn of the 3 Advisors 
     138                        Creature* pAdvisor = NULL; 
     139                        for( int i=0; i<3; i++ ) 
     140 
     141                 
     142                if(RAdvisors[i]) 
     143                { 
     144                        pAdvisor = ((Creature*)Unit::GetUnit((*m_creature), RAdvisors[i])); 
     145                        if(pAdvisor && !pAdvisor->isAlive()) 
     146                        { 
     147                        pAdvisor->Respawn(); 
     148                        pAdvisor->AI()->EnterEvadeMode(); 
     149                        pAdvisor->GetMotionMaster()->MoveTargetedHome(); 
     150                        } 
     151                } 
     152                pInstance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED); 
     153                } 
     154                         
     155                 
     156        } 
    111157 
    112158    void EventSharkkisDeath() 
     
    150196        DoPlaySoundToSet(m_creature, SOUND_AGGRO); 
    151197        DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL); 
     198                DoZoneInCombat(); 
    152199 
    153200        pInstance->SetData64(DATA_KARATHRESSEVENT_STARTER, who->GetGUID()); 
     
    165212            case 1: 
    166213                DoPlaySoundToSet(m_creature, SOUND_SLAY2); 
    167                 break; 
    168             case 2: 
    169                 DoPlaySoundToSet(m_creature, SOUND_SLAY3); 
     214                                DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL); 
    170215                break; 
    171216        } 
     
    178223 
    179224        if( pInstance ) 
    180             pInstance->SetData(DATA_FATHOMLORDKARATHRESSEVENT, NOT_STARTED); 
     225            pInstance->SetData(DATA_FATHOMLORDKARATHRESSEVENT, DONE); 
    181226 
    182227        //support for quest 10944 
     
    209254        //someone evaded! 
    210255        if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT)) 
     256                { 
    211257            EnterEvadeMode(); 
     258                        return; 
     259                } 
    212260 
    213261        //CataclysmicBolt_Timer 
     
    227275        }else CataclysmicBolt_Timer -= diff; 
    228276 
     277                //SearNova_Timer 
     278                if(SearNova_Timer < diff) 
     279                { 
     280                        DoCast(m_creature->getVictim(), SPELL_SEAR_NOVA); 
     281                        SearNova_Timer = 20000+rand()%40000; 
     282                }else SearNova_Timer -= diff; 
     283 
    229284        //Enrage_Timer 
    230285        if(Enrage_Timer < diff) 
     
    234289        }else Enrage_Timer -= diff; 
    235290 
     291                //Blessing of Tides Trigger 
     292                if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 75 && !BlessingOfTides) 
     293                { 
     294                        BlessingOfTides = true; 
     295                        bool continueTriggering; 
     296                        Creature* Advisor; 
     297                        for(uint8 i = 0; i < 4; ++i) 
     298                                if(Advisors[i]) 
     299                                { 
     300                                        Advisor = ((Creature*)Unit::GetUnit(*m_creature, Advisors[i])); 
     301                                        if(Advisor) 
     302                                        { 
     303                                                if(Advisor->isAlive()) 
     304                                                { 
     305                                                        continueTriggering = true; 
     306                                                        break; 
     307                                                } 
     308                                        } 
     309                                }                
     310                                if( continueTriggering ) 
     311                                { 
     312                                        DoCast(m_creature, SPELL_BLESSING_OF_THE_TIDES); 
     313                                        DoYell(SAY_GAIN_BLESSING_OF_TIDES, LANG_UNIVERSAL, NULL); 
     314                                        DoPlaySoundToSet(m_creature, SOUND_GAIN_BLESSING_OF_TIDES); 
     315                                } 
     316                } 
     317 
    236318        DoMeleeAttackIfReady(); 
    237319    } 
     
    251333    uint32 LeechingThrow_Timer; 
    252334    uint32 TheBeastWithin_Timer; 
     335        uint32 Multishot_Timer; 
     336        uint32 Pet_Timer; 
     337 
     338        bool pet; 
     339 
     340        uint64 SummonedPet; 
     341 
    253342 
    254343    void Reset() 
     
    256345        LeechingThrow_Timer = 20000; 
    257346        TheBeastWithin_Timer = 30000; 
     347                Multishot_Timer = 15000; 
     348                Pet_Timer = 10000; 
     349 
     350                pet = false; 
     351 
     352                Creature *Pet = (Creature*) Unit::GetUnit(*m_creature, SummonedPet); 
     353                if( Pet && Pet->isAlive() ) 
     354                { 
     355                        Pet->DealDamage( Pet, Pet->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false ); 
     356                } 
     357                 
     358                SummonedPet = 0; 
    258359 
    259360        if( pInstance ) 
     
    269370 
    270371            if(Karathress) 
    271                 ((boss_fathomlord_karathressAI*)Karathress->AI())->EventSharkkisDeath(); 
     372                                if(!m_creature->isAlive() && Karathress) 
     373                                        ((boss_fathomlord_karathressAI*)Karathress->AI())->EventSharkkisDeath(); 
    272374        } 
    273375    } 
     
    301403        //someone evaded! 
    302404        if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT)) 
    303             EnterEvadeMode(); 
     405                { 
     406                        EnterEvadeMode(); 
     407                        return; 
     408                } 
    304409 
    305410        //LeechingThrow_Timer 
     
    310415        }else LeechingThrow_Timer -= diff; 
    311416 
    312         //TheBeastWithin_Timer 
    313         if(TheBeastWithin_Timer < diff) 
    314         { 
    315             DoCast(m_creature, SPELL_THE_BEAST_WITHIN); 
    316             TheBeastWithin_Timer = 30000; 
    317         }else TheBeastWithin_Timer -= diff; 
     417                //Multishot_Timer 
     418                if(Multishot_Timer < diff) 
     419                { 
     420                        DoCast(m_creature->getVictim(), SPELL_MULTISHOT); 
     421                        Multishot_Timer = 20000; 
     422                }else Multishot_Timer -= diff; 
     423  
     424                //TheBeastWithin_Timer 
     425                if(TheBeastWithin_Timer < diff) 
     426                { 
     427                        DoCast(m_creature, SPELL_THE_BEAST_WITHIN); 
     428                        Creature *Pet = (Creature*) Unit::GetUnit(*m_creature, SummonedPet); 
     429                        if( Pet && Pet->isAlive() ) 
     430                        { 
     431                                Pet->CastSpell( Pet, SPELL_PET_ENRAGE, true ); 
     432                        } 
     433                        TheBeastWithin_Timer = 30000; 
     434                }else TheBeastWithin_Timer -= diff; 
     435  
     436                //Pet_Timer 
     437                if(Pet_Timer < diff && pet == false) 
     438                { 
     439                        pet = true; 
     440                        //uint32 spell_id; 
     441                        uint32 pet_id; 
     442                        switch( rand()%2 ) 
     443                        { 
     444                        case 0: 
     445                                //spell_id = SPELL_SUMMON_FATHOM_LURKER; 
     446                                pet_id = CREATURE_FATHOM_LURKER; 
     447                                break; 
     448                        case 1: 
     449                                //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT; 
     450                                pet_id = CREATURE_FATHOM_SPOREBAT; 
     451                                break; 
     452                        } 
     453                        //DoCast( m_creature, spell_id, true ); 
     454                        Creature *Pet = DoSpawnCreature(pet_id,0,0,0,0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000 ); 
     455                        Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0); 
     456                        if (Pet && target) 
     457                        { 
     458                                Pet->AI()->AttackStart(target); 
     459                                SummonedPet = Pet->GetGUID(); 
     460                        } 
     461                }else Pet_Timer -= diff; 
    318462 
    319463        DoMeleeAttackIfReady(); 
     
    333477 
    334478    uint32 FrostShock_Timer; 
     479        uint32 Spitfire_Timer; 
     480        uint32 PoisonCleansing_Timer; 
     481        uint32 Earthbind_Timer; 
    335482 
    336483    void Reset() 
    337484    { 
    338485        FrostShock_Timer = 25000; 
     486                Spitfire_Timer = 60000; 
     487                PoisonCleansing_Timer = 30000; 
     488                Earthbind_Timer = 45000; 
    339489 
    340490        if( pInstance ) 
     
    350500 
    351501            if(Karathress) 
    352                 ((boss_fathomlord_karathressAI*)Karathress->AI())->EventTidalvessDeath(); 
     502                                if(!m_creature->isAlive() && Karathress) 
     503                                        ((boss_fathomlord_karathressAI*)Karathress->AI())->EventTidalvessDeath(); 
    353504        } 
    354505    } 
     
    361512            pInstance->SetData(DATA_KARATHRESSEVENT, IN_PROGRESS); 
    362513        } 
     514                DoCast(m_creature, SPELL_WINDFURY_WEAPON); 
    363515    } 
    364516 
     
    382534        //someone evaded! 
    383535        if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT)) 
     536                { 
    384537            EnterEvadeMode(); 
     538                        return; 
     539                } 
     540 
     541                if( !m_creature->HasAura(SPELL_WINDFURY_WEAPON, 0) ) 
     542                { 
     543                        DoCast(m_creature, SPELL_WINDFURY_WEAPON); 
     544                } 
    385545 
    386546        //FrostShock_Timer 
     
    391551        }else FrostShock_Timer -= diff; 
    392552 
     553                //Spitfire_Timer 
     554                if(Spitfire_Timer < diff) 
     555                { 
     556                        DoCast(m_creature, SPELL_SPITFIRE_TOTEM); 
     557                        Unit *SpitfireTotem = Unit::GetUnit( *m_creature, CREATURE_SPITFIRE_TOTEM ); 
     558                        if( SpitfireTotem ) 
     559                        { 
     560                                ((Creature*)SpitfireTotem)->AI()->AttackStart( m_creature->getVictim() ); 
     561                        } 
     562                        Spitfire_Timer = 60000; 
     563                }else Spitfire_Timer -= diff; 
     564 
     565                //PoisonCleansing_Timer 
     566                if(PoisonCleansing_Timer < diff) 
     567                { 
     568                        DoCast(m_creature, SPELL_POISON_CLEANSING_TOTEM); 
     569                        PoisonCleansing_Timer = 30000; 
     570                }else PoisonCleansing_Timer -= diff; 
     571 
     572                //Earthbind_Timer 
     573                if(Earthbind_Timer < diff) 
     574                { 
     575                        DoCast(m_creature, SPELL_EARTHBIND_TOTEM); 
     576                        Earthbind_Timer = 45000; 
     577                }else Earthbind_Timer -= diff; 
     578 
    393579        DoMeleeAttackIfReady(); 
    394580    } 
     
    409595    uint32 TidalSurge_Timer; 
    410596    uint32 Heal_Timer; 
     597        uint32 Cyclone_Timer; 
    411598 
    412599    void Reset() 
     
    415602        TidalSurge_Timer = 15000+rand()%5000; 
    416603        Heal_Timer = 55000; 
     604                Cyclone_Timer = 30000+rand()%10000; 
    417605 
    418606        if(pInstance) 
     
    428616 
    429617            if(Karathress) 
    430                 ((boss_fathomlord_karathressAI*)Karathress->AI())->EventCaribdisDeath(); 
     618                                if(!m_creature->isAlive() && Karathress) 
     619                                        ((boss_fathomlord_karathressAI*)Karathress->AI())->EventCaribdisDeath(); 
    431620        } 
    432621    } 
     
    460649        //someone evaded! 
    461650        if(pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT)) 
     651                { 
    462652            EnterEvadeMode(); 
     653                        return; 
     654                } 
    463655 
    464656        //WaterBoltVolley_Timer 
     
    473665        { 
    474666            DoCast(m_creature->getVictim(), SPELL_TIDAL_SURGE); 
     667                        // Hacky way to do it - won't trigger elseways 
     668                        m_creature->getVictim()->CastSpell( m_creature->getVictim(), SPELL_TIDAL_SURGE_FREEZE, true ); 
    475669            TidalSurge_Timer = 15000+rand()%5000; 
    476670        }else TidalSurge_Timer -= diff; 
    477671 
    478         //Heal_Timer 
    479         if(Heal_Timer < diff) 
    480         { 
    481             // It can be cast on any of the mobs 
    482             Unit *pUnit = NULL; 
    483  
    484             if(pInstance) 
    485             { 
    486                 switch(rand()%4) 
    487                 { 
    488                     case 0: 
    489                         pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)); 
    490                         break; 
    491                     case 1: 
    492                         pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_SHARKKIS)); 
    493                         break; 
    494                     case 2: 
    495                         pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_TIDALVESS)); 
    496                         break; 
    497                     case 3: 
    498                         pUnit = m_creature; 
    499                         break; 
    500                 } 
    501             }else pUnit = m_creature; 
    502  
    503             if(pUnit && pUnit->isAlive()) 
    504                 DoCast(pUnit, SPELL_HEAL); 
    505  
    506             Heal_Timer = 60000; 
    507         }else Heal_Timer -= diff; 
    508  
    509         DoMeleeAttackIfReady(); 
    510     } 
     672                //Cyclone_Timer 
     673                if(Cyclone_Timer < diff) 
     674                { 
     675                        //DoCast(m_creature, SPELL_SUMMON_CYCLONE); // Doesn't work 
     676                        Cyclone_Timer = 30000+rand()%10000; 
     677                        Creature *Cyclone = m_creature->SummonCreature(CREATURE_CYCLONE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), (rand()%5), TEMPSUMMON_TIMED_DESPAWN, 15000); 
     678                        if( Cyclone ) 
     679                        { 
     680                                ((Creature*)Cyclone)->SetFloatValue(OBJECT_FIELD_SCALE_X, 3.0f); 
     681                                Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     682                                Cyclone->setFaction(m_creature->getFaction()); 
     683                                Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true); 
     684                                Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
     685                                if( target ) 
     686                                { 
     687                                        Cyclone->AI()->AttackStart(target); 
     688                                } 
     689                        } 
     690                }else Cyclone_Timer -= diff; 
     691 
     692                //Heal_Timer 
     693                if(Heal_Timer < diff) 
     694                { 
     695                        // It can be cast on any of the mobs 
     696                        Unit *pUnit = NULL; 
     697 
     698                        while( pUnit == NULL || !pUnit->isAlive() ) 
     699                        { 
     700                                pUnit = selectAdvisorUnit(); 
     701                        } 
     702 
     703                        if(pUnit && pUnit->isAlive()) 
     704                                DoCast(pUnit, SPELL_HEAL); 
     705                        Heal_Timer = 60000; 
     706                }else Heal_Timer -= diff; 
     707 
     708                DoMeleeAttackIfReady(); 
     709        } 
     710 
     711        Unit* selectAdvisorUnit() 
     712        { 
     713                Unit* pUnit; 
     714                if(pInstance) 
     715                { 
     716                        switch(rand()%4) 
     717                        { 
     718                        case 0: 
     719                                pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_KARATHRESS)); 
     720                                break; 
     721                        case 1: 
     722                                pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_SHARKKIS)); 
     723                                break;  
     724                        case 2: 
     725                                pUnit = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_TIDALVESS)); 
     726                                break; 
     727                        case 3: 
     728                                pUnit = m_creature; 
     729                                break; 
     730            } 
     731        }else pUnit = m_creature; 
     732  
     733                return pUnit; 
     734        } 
    511735}; 
    512736 
  • trunk/src/game/CreatureAI.h

    r102 r130  
    6666    SELECT_TARGET_TOPAGGRO,                                 //Selects targes from top aggro to bottom 
    6767    SELECT_TARGET_BOTTOMAGGRO,                              //Selects targets from bottom aggro to top 
     68    SELECT_TARGET_NEAREST, 
     69    SELECT_TARGET_FARTHEST, 
    6870}; 
    6971 
  • trunk/src/game/SpellEffects.cpp

    r128 r130  
    616616            switch(m_spellInfo->Id ) 
    617617            { 
     618                // Mingo's Fortune Giblets 
     619                case 40802: 
     620                { 
     621                    if (m_caster->GetTypeId() != TYPEID_PLAYER) return; 
     622 
     623                    Player *player = (Player*)m_caster; 
     624                    uint32 newitemid; 
     625 
     626                    switch(urand(1,20)) 
     627                    { 
     628                        case 1: newitemid = 32688; break; 
     629                        case 2: newitemid = 32689; break; 
     630                        case 3: newitemid = 32690; break; 
     631                        case 4: newitemid = 32691; break; 
     632                        case 5: newitemid = 32692; break; 
     633                        case 6: newitemid = 32693; break; 
     634                        case 7: newitemid = 32700; break; 
     635                        case 8: newitemid = 32701; break; 
     636                        case 9: newitemid = 32702; break; 
     637                        case 10: newitemid = 32703; break; 
     638                        case 11: newitemid = 32704; break; 
     639                        case 12: newitemid = 32705; break; 
     640                        case 13: newitemid = 32706; break; 
     641                        case 14: newitemid = 32707; break; 
     642                        case 15: newitemid = 32708; break; 
     643                        case 16: newitemid = 32709; break; 
     644                        case 17: newitemid = 32710; break; 
     645                        case 18: newitemid = 32711; break; 
     646                        case 19: newitemid = 32712; break; 
     647                        case 20: newitemid = 32713; break; 
     648                    } 
     649                    ItemPosCountVec dest; 
     650                    uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, newitemid, 1, false); 
     651                    if (msg != EQUIP_ERR_OK) 
     652                    { 
     653                        player->SendEquipError(msg, NULL, NULL); 
     654                        return; 
     655                    } 
     656                    Item *pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid)); 
     657 
     658                    if (!pItem) 
     659                    { 
     660                        player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); 
     661                        return; 
     662                    } 
     663                    player->SendNewItem(pItem, 1, true, true); 
     664                     
     665                    return; 
     666                } 
     667                // Encapsulate Voidwalker 
     668                case 29364: 
     669                { 
     670                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || ((Creature*)unitTarget)->isPet()) return; 
     671 
     672                    Creature* creatureTarget = (Creature*)unitTarget; 
     673                    GameObject* pGameObj = new GameObject; 
     674 
     675                    if (!creatureTarget || !pGameObj) return; 
     676 
     677                    if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(), 
     678                        creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(),  
     679                        creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1)) 
     680                    { 
     681                        delete pGameObj; 
     682                        return; 
     683                    } 
     684 
     685                    pGameObj->SetRespawnTime(0); 
     686                    pGameObj->SetOwnerGUID(m_caster->GetGUID()); 
     687                    pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); 
     688                    pGameObj->SetSpellId(m_spellInfo->Id); 
     689 
     690                    MapManager::Instance().GetMap(creatureTarget->GetMapId(), pGameObj)->Add(pGameObj); 
     691 
     692                    WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); 
     693                    data << uint64(pGameObj->GetGUID()); 
     694                    m_caster->SendMessageToSet(&data,true); 
     695 
     696                    return; 
     697                } 
     698                // Demon Broiled Surprise 
     699                case 43723: 
     700                { 
     701                    if (!unitTarget || unitTarget->isAlive() || unitTarget->GetTypeId() != TYPEID_UNIT || 
     702                        ((Creature*)unitTarget)->isPet()) return; 
     703 
     704                    Player *player = (Player*)m_caster; 
     705 
     706                    if (!player) return; 
     707 
     708                    player->CastSpell(unitTarget, 43753, true); 
     709 
     710                    if (player->GetQuestStatus(11379) == QUEST_STATUS_INCOMPLETE && unitTarget->GetEntry() == 19973) 
     711                        player->CastedCreatureOrGO(19973, unitTarget->GetGUID(), 43723); 
     712 
     713                    return; 
     714                } 
    618715                case 8063:                                  // Deviate Fish 
    619716                { 
     
    47894886        // Flame Crash 
    47904887        case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break; 
     4888        case 41931: 
     4889        { 
     4890            int bag=19; 
     4891            int slot=0; 
     4892            Item* item = NULL; 
     4893             
     4894            while (bag < 256) 
     4895            { 
     4896                item = ((Player*)m_caster)->GetItemByPos(bag,slot); 
     4897                if (item && item->GetEntry() == 38587) break; 
     4898                slot++; 
     4899                if (slot == 39) 
     4900                { 
     4901                    slot = 0; 
     4902                    bag++; 
     4903                } 
     4904            } 
     4905            if (bag < 256) 
     4906            { 
     4907                if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true); 
     4908                else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1); 
     4909                // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen) 
     4910                m_caster->CastSpell(m_caster,42518,true); 
     4911                return; 
     4912            } 
     4913        } 
    47914914        // Force Cast - Portal Effect: Sunwell Isle 
    47924915        case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break;