- Timestamp:
- 11/19/08 13:48:11 (17 years ago)
- Location:
- trunk/src/game
- Files:
-
- 6 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/ArenaTeam.cpp
r207 r226 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/game/ArenaTeamHandler.cpp
r102 r226 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 -
trunk/src/game/SharedDefines.h
r168 r226 221 221 #define SPELL_ATTR_STOP_ATTACK_TARGET 0x00100000 // 20 Stop attack after use this spell (and not begin attack if use) 222 222 #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 224 224 #define SPELL_ATTR_UNK23 0x00800000 // 23 castable while dead? 225 225 #define SPELL_ATTR_CASTABLE_WHILE_MOUNTED 0x01000000 // 24 castable while mounted 226 226 #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? 228 228 #define SPELL_ATTR_CASTABLE_WHILE_SITTING 0x08000000 // 27 castable while sitting 229 229 #define SPELL_ATTR_CANT_USED_IN_COMBAT 0x10000000 // 28 Cannot be used in combat … … 267 267 #define SPELL_ATTR_EX2_UNK0 0x00000001 // 0 268 268 #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? 270 270 #define SPELL_ATTR_EX2_UNK3 0x00000008 // 3 271 271 #define SPELL_ATTR_EX2_UNK4 0x00000010 // 4 … … 306 306 #define SPELL_ATTR_EX3_UNK6 0x00000040 // 6 307 307 #define SPELL_ATTR_EX3_UNK7 0x00000080 // 7 308 #define SPELL_ATTR_EX3_ UNK8 0x00000100 // 8308 #define SPELL_ATTR_EX3_PLAYERS_ONLY 0x00000100 // 8 Player only? 309 309 #define SPELL_ATTR_EX3_UNK9 0x00000200 // 9 310 310 #define SPELL_ATTR_EX3_MAIN_HAND 0x00000400 // 10 Main hand weapon required -
trunk/src/game/Spell.cpp
r220 r226 955 955 if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) ) 956 956 { 957 if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED))958 unit->SetStandState(PLAYER_STATE_NONE);959 960 957 m_caster->CombatStart(unit); 961 958 } … … 1283 1280 cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster)); 1284 1281 } 1285 if(!( spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_PLAYERS_ONLY))1282 if(!(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY)) 1286 1283 { 1287 1284 TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_object_notifier(notifier); … … 2298 2295 2299 2296 // 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)) 2301 2298 { 2302 2299 … … 2325 2322 { 2326 2323 m_spellState = SPELL_STATE_CASTING; 2324 m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags); 2327 2325 SendChannelStart(GetSpellDuration(m_spellInfo)); 2328 2326 } … … 2568 2566 { 2569 2567 // always cancel for channeled spells 2570 if( m_spellState == SPELL_STATE_CASTING )2571 cancel();2568 //if( m_spellState == SPELL_STATE_CASTING ) 2569 // cancel(); 2572 2570 // 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)) 2574 2573 cancel(); 2575 2574 } … … 2602 2601 // check for incapacitating player states 2603 2602 if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED)) 2604 cancel();2605 2606 // check if player has turned if flag is set2607 if( m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation() )2608 2603 cancel(); 2609 2604 } … … 2669 2664 if(!m_caster) 2670 2665 return; 2666 2667 if(IsChanneledSpell(m_spellInfo)) 2668 m_caster->UpdateInterruptMask(); 2671 2669 2672 2670 if(m_spellState == SPELL_STATE_FINISHED) … … 4762 4760 } 4763 4761 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-backed4762 void 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 4771 4769 4772 4770 // 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; 4775 4773 4776 4774 //check resist chance -
trunk/src/game/Unit.cpp
r217 r226 182 182 m_Visibility = VISIBILITY_ON; 183 183 184 m_interruptMask = 0; 184 185 m_detectInvisibilityMask = 0; 185 186 m_invisibilityMask = 0; … … 466 467 void Unit::RemoveAurasWithInterruptFlags(uint32 flag) 467 468 { 469 if(!(m_interruptMask & flag)) 470 return; 471 472 // interrupt auras 468 473 AuraList::iterator iter, next; 469 474 for (iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); iter = next) … … 479 484 next = m_interruptableAuras.begin(); 480 485 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 496 void 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; 484 507 } 485 508 … … 527 550 } 528 551 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 540 552 //Script Event damage taken 541 553 if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() ) 542 554 ((Creature *)pVictim)->AI()->DamageTaken(this, damage); 543 555 544 if(!damage) 556 if(!damage) //when will zero damage? need interrupt aura? 545 557 { 546 558 // Rage from physical damage received . … … 869 881 } 870 882 871 // polymorphed and other negative transformed cases872 if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED))873 pVictim->RemoveAurasDueToSpell(pVictim->getTransForm());874 875 883 if(damagetype == DIRECT_DAMAGE|| damagetype == SPELL_DIRECT_DAMAGE) 876 884 pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE); … … 910 918 } 911 919 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 { 948 932 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) 959 946 { 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 ) 961 949 spell->DelayedChannel(); 962 950 } 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 damage971 {972 sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id);973 pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);974 951 } 975 952 } … … 3796 3773 m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur); 3797 3774 if(Aur->GetSpellProto()->AuraInterruptFlags) 3775 { 3798 3776 m_interruptableAuras.push_back(Aur); 3777 AddInterruptMask(Aur->GetSpellProto()->AuraInterruptFlags); 3778 } 3799 3779 if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) 3800 3780 { … … 4164 4144 m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); 4165 4145 if((*i).second->GetSpellProto()->AuraInterruptFlags) 4146 { 4166 4147 m_interruptableAuras.remove((*i).second); 4148 UpdateInterruptMask(); 4149 } 4167 4150 if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) 4168 4151 m_ccAuras.remove((*i).second); … … 8485 8468 void Unit::CombatStart(Unit* target) 8486 8469 { 8470 if(!target->IsStandState() && !target->hasUnitState(UNIT_STAT_STUNNED)) 8471 target->SetStandState(PLAYER_STATE_NONE); 8472 8487 8473 if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER && ((Creature*)target)->AI()) 8488 8474 ((Creature*)target)->AI()->AttackStart(this); -
trunk/src/game/Unit.h
r215 r226 40 40 enum SpellInterruptFlags 41 41 { 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? 47 47 }; 48 48 … … 1189 1189 1190 1190 Aura* GetDummyAura(uint32 spell_id) const; 1191 uint32 GetInterruptMask() const { return m_interruptMask; } 1192 void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } 1193 void UpdateInterruptMask(); 1191 1194 1192 1195 uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } … … 1335 1338 1336 1339 AuraList m_modAuras[TOTAL_AURAS]; 1340 uint32 m_interruptMask; 1337 1341 AuraList m_interruptableAuras; 1338 1342 AuraList m_ccAuras;