Changeset 226

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

[svn] Some update on channeled spells.

Original author: megamage
Date: 2008-11-14 14:19:23-06:00

Location:
trunk/src/game
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/ArenaTeam.cpp

    r207 r226  
    1111 * This program is distributed in the hope that it will be useful, 
    1212 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1414 * GNU General Public License for more details. 
    1515 * 
    1616 * You should have received a copy of the GNU General Public License 
    1717 * along with this program; if not, write to the Free Software 
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
     18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
    1919 */ 
    2020 
  • trunk/src/game/ArenaTeamHandler.cpp

    r102 r226  
    1111 * This program is distributed in the hope that it will be useful, 
    1212 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1414 * GNU General Public License for more details. 
    1515 * 
    1616 * You should have received a copy of the GNU General Public License 
    1717 * along with this program; if not, write to the Free Software 
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
     18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
    1919 */ 
    2020 
  • trunk/src/game/SharedDefines.h

    r168 r226  
    221221#define SPELL_ATTR_STOP_ATTACK_TARGET             0x00100000            // 20 Stop attack after use this spell (and not begin attack if use) 
    222222#define SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK   0x00200000            // 21 Cannot be dodged/parried/blocked 
    223 #define SPELL_ATTR_UNK22                          0x00400000            // 22 
     223#define SPELL_ATTR_UNK22                          0x00400000            // 22 shoot spells 
    224224#define SPELL_ATTR_UNK23                          0x00800000            // 23 castable while dead? 
    225225#define SPELL_ATTR_CASTABLE_WHILE_MOUNTED         0x01000000            // 24 castable while mounted 
    226226#define SPELL_ATTR_DISABLED_WHILE_ACTIVE          0x02000000            // 25 Activate and start cooldown after aura fade or remove summoned creature or go 
    227 #define SPELL_ATTR_UNK26                          0x04000000            // 26 
     227#define SPELL_ATTR_UNK26                          0x04000000            // 26 Aura ignore immune? 
    228228#define SPELL_ATTR_CASTABLE_WHILE_SITTING         0x08000000            // 27 castable while sitting 
    229229#define SPELL_ATTR_CANT_USED_IN_COMBAT            0x10000000            // 28 Cannot be used in combat 
     
    267267#define SPELL_ATTR_EX2_UNK0                       0x00000001            // 0 
    268268#define SPELL_ATTR_EX2_UNK1                       0x00000002            // 1 
    269 #define SPELL_ATTR_EX2_UNK2                       0x00000004            // 2 
     269#define SPELL_ATTR_EX2_UNK2                       0x00000004            // 2 boss spells? 
    270270#define SPELL_ATTR_EX2_UNK3                       0x00000008            // 3 
    271271#define SPELL_ATTR_EX2_UNK4                       0x00000010            // 4 
     
    306306#define SPELL_ATTR_EX3_UNK6                       0x00000040            // 6 
    307307#define SPELL_ATTR_EX3_UNK7                       0x00000080            // 7 
    308 #define SPELL_ATTR_EX3_UNK8                       0x00000100            // 8 
     308#define SPELL_ATTR_EX3_PLAYERS_ONLY               0x00000100            // 8 Player only? 
    309309#define SPELL_ATTR_EX3_UNK9                       0x00000200            // 9 
    310310#define SPELL_ATTR_EX3_MAIN_HAND                  0x00000400            // 10 Main hand weapon required 
  • trunk/src/game/Spell.cpp

    r220 r226  
    955955        if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) ) 
    956956        { 
    957             if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED)) 
    958                 unit->SetStandState(PLAYER_STATE_NONE); 
    959  
    960957            m_caster->CombatStart(unit); 
    961958        } 
     
    12831280        cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 
    12841281    } 
    1285     if(!(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_PLAYERS_ONLY)) 
     1282    if(!(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY)) 
    12861283    { 
    12871284        TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier); 
     
    22982295 
    22992296    // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells 
    2300     if (m_spellInfo->speed > 0.0f) 
     2297    if (m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo)) 
    23012298    { 
    23022299 
     
    23252322    { 
    23262323        m_spellState = SPELL_STATE_CASTING; 
     2324        m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags); 
    23272325        SendChannelStart(GetSpellDuration(m_spellInfo)); 
    23282326    } 
     
    25682566    { 
    25692567        // always cancel for channeled spells 
    2570         if( m_spellState == SPELL_STATE_CASTING ) 
    2571             cancel(); 
     2568        //if( m_spellState == SPELL_STATE_CASTING ) 
     2569        //    cancel(); 
    25722570        // don't cancel for melee, autorepeat, triggered and instant spells 
    2573         else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) 
     2571        //else 
     2572        if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) 
    25742573            cancel(); 
    25752574    } 
     
    26022601                    // check for incapacitating player states 
    26032602                    if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED)) 
    2604                         cancel(); 
    2605  
    2606                     // check if player has turned if flag is set 
    2607                     if( m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation() ) 
    26082603                        cancel(); 
    26092604                } 
     
    26692664    if(!m_caster) 
    26702665        return; 
     2666 
     2667    if(IsChanneledSpell(m_spellInfo)) 
     2668        m_caster->UpdateInterruptMask(); 
    26712669 
    26722670    if(m_spellState == SPELL_STATE_FINISHED) 
     
    47624760} 
    47634761 
    4764 void Spell::Delayed() 
    4765 { 
    4766     if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER) 
    4767         return; 
    4768  
    4769     if (m_spellState == SPELL_STATE_DELAYED) 
    4770         return;                                             // spell is active and can't be time-backed 
     4762void Spell::Delayed() // only called in DealDamage() 
     4763{ 
     4764    if(!m_caster)// || m_caster->GetTypeId() != TYPEID_PLAYER) 
     4765        return; 
     4766 
     4767    //if (m_spellState == SPELL_STATE_DELAYED) 
     4768    //    return;                                             // spell is active and can't be time-backed 
    47714769 
    47724770    // spells not loosing casting time ( slam, dynamites, bombs.. ) 
    4773     if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)) 
    4774         return; 
     4771    //if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)) 
     4772    //    return; 
    47754773 
    47764774    //check resist chance 
  • trunk/src/game/Unit.cpp

    r217 r226  
    182182    m_Visibility = VISIBILITY_ON; 
    183183 
     184    m_interruptMask = 0; 
    184185    m_detectInvisibilityMask = 0; 
    185186    m_invisibilityMask = 0; 
     
    466467void Unit::RemoveAurasWithInterruptFlags(uint32 flag) 
    467468{ 
     469    if(!(m_interruptMask & flag)) 
     470        return; 
     471 
     472    // interrupt auras 
    468473    AuraList::iterator iter, next; 
    469474    for (iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); iter = next) 
     
    479484                next = m_interruptableAuras.begin(); 
    480485            else 
    481                 return; 
    482         } 
    483     } 
     486                break; 
     487        } 
     488    } 
     489 
     490    // interrupt channeled spell 
     491    if(Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL]) 
     492        if(spell->getState() == SPELL_STATE_CASTING && (spell->m_spellInfo->AuraInterruptFlags & flag)) 
     493            InterruptNonMeleeSpells(false); 
     494} 
     495 
     496void Unit::UpdateInterruptMask() 
     497{ 
     498    m_interruptMask = 0; 
     499    for(AuraList::iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i) 
     500    { 
     501        if(*i) 
     502            m_interruptMask |= (*i)->GetSpellProto()->AuraInterruptFlags; 
     503    } 
     504    if(Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL]) 
     505        if(spell->getState() == SPELL_STATE_CASTING) 
     506            m_interruptMask |= spell->m_spellInfo->AuraInterruptFlags; 
    484507} 
    485508 
     
    527550    } 
    528551 
    529     // remove affects from victim (including from 0 damage and DoTs) 
    530     //if(pVictim != this) 
    531     //    pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
    532  
    533     // remove affects from attacker at any non-DoT damage (including 0 damage) 
    534     if( damagetype != DOT) 
    535     { 
    536         if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED)) 
    537             pVictim->SetStandState(PLAYER_STATE_NONE); 
    538     } 
    539  
    540552    //Script Event damage taken 
    541553    if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() ) 
    542554        ((Creature *)pVictim)->AI()->DamageTaken(this, damage); 
    543555 
    544     if(!damage) 
     556    if(!damage) //when will zero damage? need interrupt aura? 
    545557    { 
    546558        // Rage from physical damage received . 
     
    869881        } 
    870882 
    871         // polymorphed and other negative transformed cases 
    872         if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED)) 
    873             pVictim->RemoveAurasDueToSpell(pVictim->getTransForm()); 
    874  
    875883        if(damagetype == DIRECT_DAMAGE|| damagetype == SPELL_DIRECT_DAMAGE) 
    876884            pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE); 
     
    910918        } 
    911919 
    912         // TODO: Store auras by interrupt flag to speed this up. 
    913         /*AuraMap& vAuras = pVictim->GetAuras(); 
    914         for (AuraMap::iterator i = vAuras.begin(), next; i != vAuras.end(); i = next) 
    915         { 
    916             const SpellEntry *se = i->second->GetSpellProto(); 
    917             next = i; ++next; 
    918             if( se->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DAMAGE ) 
    919             { 
    920                 bool remove = true; 
    921                 if (se->procFlags & (1<<3)) 
    922                 { 
    923                     if (!roll_chance_i(se->procChance)) 
    924                         remove = false; 
    925                 } 
    926                 if (remove) 
    927                 { 
    928                     pVictim->RemoveAurasDueToSpell(i->second->GetId()); 
    929                     // FIXME: this may cause the auras with proc chance to be rerolled several times 
    930                     next = vAuras.begin(); 
    931                 } 
    932             } 
    933             else */ 
    934         pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE); 
    935         pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0); 
    936  
    937         if (damagetype != NODAMAGE && damage && pVictim->GetTypeId() == TYPEID_PLAYER) 
    938         { 
    939             if( damagetype != DOT ) 
    940             { 
    941                 for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) 
    942                 { 
    943                     // skip channeled spell (processed differently below) 
    944                     if (i == CURRENT_CHANNELED_SPELL) 
    945                         continue; 
    946  
    947                     if(Spell* spell = pVictim->m_currentSpells[i]) 
     920        if (damagetype != NODAMAGE && damage)// && pVictim->GetTypeId() == TYPEID_PLAYER) 
     921        { 
     922            //if (se->procFlags & (1<<3)) 
     923            pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE); 
     924            pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0); 
     925 
     926            if(pVictim != this && pVictim->GetTypeId() == TYPEID_PLAYER) // does not support creature push_back 
     927            { 
     928                if(damagetype != DOT) 
     929                { 
     930                    if(Spell* spell = pVictim->m_currentSpells[CURRENT_GENERIC_SPELL]) 
     931                    { 
    948932                        if(spell->getState() == SPELL_STATE_PREPARING) 
    949                             spell->Delayed(); 
    950                 } 
    951             } 
    952  
    953             if(Spell* spell = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]) 
    954             { 
    955                 if (spell->getState() == SPELL_STATE_CASTING) 
    956                 { 
    957                     uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags; 
    958                     if( channelInterruptFlags & CHANNEL_FLAG_DELAY ) 
     933                        { 
     934                            uint32 interruptFlags = spell->m_spellInfo->InterruptFlags; 
     935                            if(interruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE) 
     936                                pVictim->InterruptNonMeleeSpells(false); 
     937                            else if(interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK) 
     938                                spell->Delayed(); 
     939                        } 
     940                    } 
     941                } 
     942 
     943                if(Spell* spell = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]) 
     944                { 
     945                    if(spell->getState() == SPELL_STATE_CASTING) 
    959946                    { 
    960                         if(pVictim!=this)                   //don't shorten the duration of channeling if you damage yourself 
     947                        uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags; 
     948                        if( channelInterruptFlags & CHANNEL_FLAG_DELAY ) 
    961949                            spell->DelayedChannel(); 
    962950                    } 
    963                     else if( (channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) ) 
    964                     { 
    965                         sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id); 
    966                         pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL); 
    967                     } 
    968                 } 
    969                 else if (spell->getState() == SPELL_STATE_DELAYED) 
    970                     // break channeled spell in delayed state on damage 
    971                 { 
    972                     sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id); 
    973                     pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL); 
    974951                } 
    975952            } 
     
    37963773        m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur); 
    37973774        if(Aur->GetSpellProto()->AuraInterruptFlags) 
     3775        { 
    37983776            m_interruptableAuras.push_back(Aur); 
     3777            AddInterruptMask(Aur->GetSpellProto()->AuraInterruptFlags); 
     3778        } 
    37993779        if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) 
    38003780        { 
     
    41644144        m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); 
    41654145        if((*i).second->GetSpellProto()->AuraInterruptFlags) 
     4146        { 
    41664147            m_interruptableAuras.remove((*i).second); 
     4148            UpdateInterruptMask(); 
     4149        } 
    41674150        if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) 
    41684151            m_ccAuras.remove((*i).second); 
     
    84858468void Unit::CombatStart(Unit* target) 
    84868469{ 
     8470    if(!target->IsStandState() && !target->hasUnitState(UNIT_STAT_STUNNED)) 
     8471        target->SetStandState(PLAYER_STATE_NONE); 
     8472 
    84878473    if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER && ((Creature*)target)->AI()) 
    84888474        ((Creature*)target)->AI()->AttackStart(this); 
  • trunk/src/game/Unit.h

    r215 r226  
    4040enum SpellInterruptFlags 
    4141{ 
    42     SPELL_INTERRUPT_FLAG_MOVEMENT     = 0x01, 
    43     SPELL_INTERRUPT_FLAG_DAMAGE       = 0x02, 
    44     SPELL_INTERRUPT_FLAG_INTERRUPT    = 0x04, 
    45     SPELL_INTERRUPT_FLAG_AUTOATTACK   = 0x08, 
    46     //SPELL_INTERRUPT_FLAG_TURNING      = 0x10              // not turning - maybe _complete_ interrupt on direct damage? 
     42    SPELL_INTERRUPT_FLAG_MOVEMENT     = 0x01, // why need this for instant? 
     43    SPELL_INTERRUPT_FLAG_PUSH_BACK    = 0x02, // push back 
     44    SPELL_INTERRUPT_FLAG_INTERRUPT    = 0x04, // interrupt 
     45    SPELL_INTERRUPT_FLAG_AUTOATTACK   = 0x08, // no 
     46    SPELL_INTERRUPT_FLAG_DAMAGE       = 0x10  // _complete_ interrupt on direct damage? 
    4747}; 
    4848 
     
    11891189 
    11901190        Aura* GetDummyAura(uint32 spell_id) const; 
     1191        uint32 GetInterruptMask() const { return m_interruptMask; } 
     1192        void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } 
     1193        void UpdateInterruptMask(); 
    11911194 
    11921195        uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } 
     
    13351338 
    13361339        AuraList m_modAuras[TOTAL_AURAS]; 
     1340        uint32 m_interruptMask; 
    13371341        AuraList m_interruptableAuras; 
    13381342        AuraList m_ccAuras;