Changeset 135

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

[svn] Merge from mangos.
Wed Oct 29 15:06:00 http://github.com/mangos/mangos/commit/034b8a34a9b621443e97d0ac4b667b603ba31ef1
Mon Oct 27 14:36:42 http://github.com/mangos/mangos/commit/fa072d15107b44344af8c9ef686839984e241a1b

Original author: megamage
Date: 2008-10-29 18:06:01-05:00

Location:
trunk/src/game
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/Creature.h

    r123 r135  
    572572        void GetCombatStartPosition(float &x, float &y, float &z) { x = CombatStartX; y = CombatStartY; z = CombatStartZ; } 
    573573 
     574        uint32 GetGlobalCooldown() const { return m_GlobalCooldown; } 
     575 
    574576    protected: 
    575577        bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL); 
  • trunk/src/game/ObjectMgr.cpp

    r126 r135  
    67856785    wstrToLower( wname ); 
    67866786 
     6787    // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found 
     6788    const GameTele* alt = NULL; 
    67876789    for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr) 
     6790    { 
    67886791        if(itr->second.wnameLow == wname) 
    67896792            return &itr->second; 
    6790  
    6791     return NULL; 
     6793        else if (alt == NULL && itr->second.wnameLow.find(wname) != std::wstring::npos) 
     6794            alt = &itr->second; 
     6795    } 
     6796 
     6797    return alt; 
    67926798} 
    67936799 
  • trunk/src/game/PetAI.cpp

    r102 r135  
    3939} 
    4040 
    41 PetAI::PetAI(Creature &c) : i_pet(c), i_victimGuid(0), i_tracker(TIME_INTERVAL_LOOK) 
     41PetAI::PetAI(Creature &c) : i_pet(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false) 
    4242{ 
    4343    m_AllySet.clear(); 
     
    6666void PetAI::AttackStart(Unit *u) 
    6767{ 
    68     if( i_pet.getVictim() || !u || i_pet.isPet() && ((Pet&)i_pet).getPetType()==MINI_PET ) 
     68    if( inCombat || !u || (i_pet.isPet() && ((Pet&)i_pet).getPetType() == MINI_PET) ) 
    6969        return; 
    7070 
     
    7676        // hope it doesn't start to leak memory without this :-/ 
    7777        //i_pet->Clear(); 
    78         i_victimGuid = u->GetGUID(); 
    7978        i_pet.GetMotionMaster()->MoveChase(u); 
     79        inCombat = true; 
    8080    } 
    8181} 
     
    9292bool PetAI::_needToStop() const 
    9393{ 
    94     if(!i_pet.getVictim() || !i_pet.isAlive()) 
    95         return true; 
    96  
    9794    // This is needed for charmed creatures, as once their target was reset other effects can trigger threat 
    9895    if(i_pet.isCharmed() && i_pet.getVictim() == i_pet.GetCharmer()) 
     
    104101void PetAI::_stopAttack() 
    105102{ 
    106     if( !i_victimGuid ) 
    107         return; 
    108  
    109     Unit* victim = ObjectAccessor::GetUnit(i_pet, i_victimGuid ); 
    110  
    111     if ( !victim ) 
    112         return; 
    113  
    114     assert(!i_pet.getVictim() || i_pet.getVictim() == victim); 
    115  
     103    inCombat = false; 
    116104    if( !i_pet.isAlive() ) 
    117105    { 
     
    120108        i_pet.GetMotionMaster()->Clear(); 
    121109        i_pet.GetMotionMaster()->MoveIdle(); 
    122         i_victimGuid = 0; 
    123110        i_pet.CombatStop(); 
    124111        i_pet.getHostilRefManager().deleteReferences(); 
    125112 
    126113        return; 
    127     } 
    128     else if( !victim  ) 
    129     { 
    130         DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_pet.GetGUIDLow()); 
    131     } 
    132     else if( !victim->isAlive() ) 
    133     { 
    134         DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_pet.GetGUIDLow()); 
    135     } 
    136     else if( victim->HasStealthAura() ) 
    137     { 
    138         DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_pet.GetGUIDLow()); 
    139     } 
    140     else if( victim->isInFlight() ) 
    141     { 
    142         DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_pet.GetGUIDLow()); 
    143     } 
    144     else 
    145     { 
    146         DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_pet.GetGUIDLow()); 
    147114    } 
    148115 
     
    159126        i_pet.GetMotionMaster()->MoveIdle(); 
    160127    } 
    161     i_victimGuid = 0; 
    162128    i_pet.AttackStop(); 
    163129} 
     
    165131void PetAI::UpdateAI(const uint32 diff) 
    166132{ 
    167     // update i_victimGuid if i_pet.getVictim() !=0 and changed 
    168     if(i_pet.getVictim()) 
    169         i_victimGuid = i_pet.getVictim()->GetGUID(); 
     133    if (!i_pet.isAlive()) 
     134        return; 
    170135 
    171136    Unit* owner = i_pet.GetCharmerOrOwner(); 
     
    177142        m_updateAlliesTimer -= diff; 
    178143 
     144    if (inCombat && i_pet.getVictim() == NULL) 
     145        _stopAttack(); 
     146 
    179147    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc. 
    180     if( i_victimGuid ) 
     148    if( i_pet.getVictim() != NULL ) 
    181149    { 
    182150        if( _needToStop() ) 
    183151        { 
    184152            DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow()); 
    185             _stopAttack();                                  // i_victimGuid == 0 && i_pet.getVictim() == NULL now 
     153            _stopAttack(); 
    186154            return; 
    187155        } 
     
    229197    } 
    230198 
    231     //Autocast 
    232     HM_NAMESPACE::hash_map<uint32, Unit*> targetMap; 
    233     targetMap.clear(); 
    234     SpellCastTargets NULLtargets; 
    235  
    236     for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++) 
    237     { 
    238         uint32 spellID = i_pet.GetPetAutoSpellOnPos(i); 
    239         if (!spellID) 
    240             continue; 
    241  
    242         SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); 
    243         if (!spellInfo) 
    244             continue; 
    245  
    246         Spell *spell = new Spell(&i_pet, spellInfo, false, 0); 
    247  
    248         if(!IsPositiveSpell(spellInfo->Id) && i_pet.getVictim() && !_needToStop() && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim())) 
    249             targetMap[spellID] = i_pet.getVictim(); 
    250         else 
    251         { 
    252             spell->m_targets = NULLtargets; 
    253             for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) 
    254             { 
    255                 Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar); 
    256  
    257                 //only buff targets that are in combat, unless the spell can only be cast while out of combat 
    258                 if(!Target || (!Target->isInCombat() && !IsNonCombatSpell(spellInfo))) 
     199    if (i_pet.GetGlobalCooldown() == 0 && !i_pet.IsNonMeleeSpellCasted(false)) 
     200    { 
     201        //Autocast 
     202        for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++) 
     203        { 
     204            uint32 spellID = i_pet.GetPetAutoSpellOnPos(i); 
     205            if (!spellID) 
     206                continue; 
     207 
     208            SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); 
     209            if (!spellInfo) 
     210                continue; 
     211 
     212            // ignore some combinations of combat state and combat/noncombat spells 
     213            if (!inCombat) 
     214            { 
     215                if (!IsPositiveSpell(spellInfo->Id)) 
    259216                    continue; 
    260                 if(spell->CanAutoCast(Target)) 
    261                     targetMap[spellID] = Target; 
    262             } 
    263         } 
    264  
    265         delete spell; 
    266     } 
    267  
    268     //found units to cast on to 
    269     if(!targetMap.empty()) 
    270     { 
    271         uint32 index = urand(1, targetMap.size()); 
    272         HM_NAMESPACE::hash_map<uint32, Unit*>::iterator itr; 
    273         uint32 i; 
    274         for(itr = targetMap.begin(), i = 1; i < index; ++itr, ++i); 
    275  
    276         SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); 
    277  
    278         Spell *spell = new Spell(&i_pet, spellInfo, false); 
    279  
    280         SpellCastTargets targets; 
    281         targets.setUnitTarget( itr->second ); 
    282  
    283         if(!i_pet.HasInArc(M_PI, itr->second)) 
    284         { 
    285             i_pet.SetInFront(itr->second); 
    286             if( itr->second->GetTypeId() == TYPEID_PLAYER ) 
    287                 i_pet.SendUpdateToPlayer( (Player*)itr->second ); 
    288  
    289             if(owner && owner->GetTypeId() == TYPEID_PLAYER) 
    290                 i_pet.SendUpdateToPlayer( (Player*)owner ); 
    291         } 
    292  
    293         i_pet.AddCreatureSpellCooldown(itr->first); 
    294         if(i_pet.isPet()) 
    295             ((Pet*)&i_pet)->CheckLearning(itr->first); 
    296  
    297         spell->prepare(&targets); 
    298     } 
    299     targetMap.clear(); 
     217            } 
     218            else 
     219            { 
     220                if (IsNonCombatSpell(spellInfo)) 
     221                    continue; 
     222            } 
     223 
     224            Spell *spell = new Spell(&i_pet, spellInfo, false, 0); 
     225 
     226            if(inCombat && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim())) 
     227            { 
     228                m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(i_pet.getVictim(), spell)); 
     229                continue; 
     230            } 
     231            else 
     232            { 
     233                bool spellUsed = false; 
     234                for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) 
     235                { 
     236                    Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar); 
     237 
     238                    //only buff targets that are in combat, unless the spell can only be cast while out of combat 
     239                    if(!Target) 
     240                        continue; 
     241 
     242                    if(spell->CanAutoCast(Target)) 
     243                    { 
     244                        m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell)); 
     245                        spellUsed = true; 
     246                        break; 
     247                    } 
     248                } 
     249                if (!spellUsed) 
     250                    delete spell; 
     251            } 
     252        } 
     253 
     254        //found units to cast on to 
     255        if(!m_targetSpellStore.empty()) 
     256        { 
     257            uint32 index = urand(0, m_targetSpellStore.size() - 1); 
     258 
     259            Spell* spell  = m_targetSpellStore[index].second; 
     260            Unit*  target = m_targetSpellStore[index].first; 
     261 
     262            m_targetSpellStore.erase(m_targetSpellStore.begin() + index); 
     263 
     264            SpellCastTargets targets; 
     265            targets.setUnitTarget( target ); 
     266 
     267            if( !i_pet.HasInArc(M_PI, target) ) 
     268            { 
     269                i_pet.SetInFront(target); 
     270                if( target->GetTypeId() == TYPEID_PLAYER ) 
     271                    i_pet.SendUpdateToPlayer( (Player*)target ); 
     272 
     273                if(owner && owner->GetTypeId() == TYPEID_PLAYER) 
     274                    i_pet.SendUpdateToPlayer( (Player*)owner ); 
     275            } 
     276 
     277            i_pet.AddCreatureSpellCooldown(spell->m_spellInfo->Id); 
     278            if(i_pet.isPet()) 
     279                ((Pet*)&i_pet)->CheckLearning(spell->m_spellInfo->Id); 
     280 
     281            spell->prepare(&targets); 
     282        } 
     283        while (!m_targetSpellStore.empty()) 
     284        { 
     285            delete m_targetSpellStore.begin()->second; 
     286            m_targetSpellStore.erase(m_targetSpellStore.begin()); 
     287        } 
     288    } 
    300289} 
    301290 
  • trunk/src/game/PetAI.h

    r102 r135  
    2626 
    2727class Creature; 
     28class Spell; 
    2829 
    2930class TRINITY_DLL_DECL PetAI : public CreatureAI 
     
    3940        void AttackedBy(Unit*); 
    4041        bool IsVisible(Unit *) const; 
     42        void JustDied(Unit* who) { _stopAttack(); } 
    4143 
    4244        void UpdateAI(const uint32); 
    43         void UpdateAllies(); 
    4445        static int Permissible(const Creature *); 
    4546 
     
    4950        void _stopAttack(void); 
    5051 
     52        void UpdateAllies(); 
     53 
    5154        Creature &i_pet; 
    52         uint64 i_victimGuid; 
     55        bool inCombat; 
    5356        TimeTracker i_tracker; 
    54         //uint32 i_RepeatAction; 
    5557        std::set<uint64> m_AllySet; 
    5658        uint32 m_updateAlliesTimer; 
     59 
     60        typedef std::pair<Unit*, Spell*> TargetSpellPair; 
     61        std::vector<TargetSpellPair> m_targetSpellStore; 
    5762}; 
    5863#endif 
  • trunk/src/game/PetHandler.cpp

    r102 r135  
    167167                unit_target = NULL; 
    168168 
     169            if (((Creature*)pet)->GetGlobalCooldown() > 0) 
     170                return; 
     171 
    169172            // do not cast unknown spells 
    170173            SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); 
     
    602605    } 
    603606 
     607    if (pet->GetGlobalCooldown() > 0) 
     608        return; 
     609 
    604610    SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); 
    605611    if(!spellInfo)