aboutsummaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/AuctionHouseBot.cpp39
-rw-r--r--src/game/CombatHandler.cpp10
-rw-r--r--src/game/CreatureAI.cpp36
-rw-r--r--src/game/DynamicObject.cpp2
-rw-r--r--src/game/GridNotifiersImpl.h2
-rw-r--r--src/game/NPCHandler.cpp17
-rw-r--r--src/game/PetHandler.cpp12
-rw-r--r--src/game/Player.cpp528
-rw-r--r--src/game/Player.h3
-rw-r--r--src/game/SharedDefines.h5
-rw-r--r--src/game/Spell.cpp52
-rw-r--r--src/game/Spell.h2
-rw-r--r--src/game/SpellEffects.cpp8
-rw-r--r--src/game/SpellHandler.cpp6
-rw-r--r--src/game/SpellMgr.cpp9
-rw-r--r--src/game/Unit.cpp54
-rw-r--r--src/game/Unit.h4
17 files changed, 400 insertions, 389 deletions
diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp
index b2b06faae84..08b4695125f 100644
--- a/src/game/AuctionHouseBot.cpp
+++ b/src/game/AuctionHouseBot.cpp
@@ -503,14 +503,25 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World
}
}
+ uint32 bids = config->GetBidsPerInterval();
+ for (uint32 count = 1;count <= bids;count++)
+ {
+
// Do we have anything to bid? If not, stop here.
if(possibleBids.empty())
{
+ count = bids + 1;
return;
}
// Choose random auction from possible auctions
- uint32 auctionID = possibleBids[urand(0, possibleBids.size() - 1)];
+ uint32 vectorPos = urand(0, possibleBids.size() - 1);
+ uint32 auctionID = possibleBids[vectorPos];
+
+ // Erase the auction from the vector to prevent bidding on item in next itteration.
+ vector<uint32>::iterator iter = possibleBids.begin();
+ advance(iter, vectorPos);
+ possibleBids.erase(iter);
// from auctionhousehandler.cpp, creates auction pointer & player pointer
AuctionEntry* auction = auctionHouse->GetAuction(auctionID);
@@ -758,7 +769,7 @@ static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, World
auctionHouse->RemoveAuction(auction->Id);
// Remove from database
auction->DeleteFromDB();
-
+ }
delete auction;
}
}
@@ -781,33 +792,21 @@ void AuctionHouseBot()
addNewAuctions(&_AHBplayer, &AllianceConfig);
if (((_newrun - _lastrun_a) > (AllianceConfig.GetBiddingInterval() * 60)) && (AllianceConfig.GetBidsPerInterval() > 0))
{
- uint32 bids = AllianceConfig.GetBidsPerInterval();
- for (uint32 count = 1;count <= bids;count++)
- {
- addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session);
- _lastrun_a = _newrun;
- }
+ addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session);
+ _lastrun_a = _newrun;
}
addNewAuctions(&_AHBplayer, &HordeConfig);
if (((_newrun - _lastrun_h) > (HordeConfig.GetBiddingInterval() *60)) && (HordeConfig.GetBidsPerInterval() > 0))
{
- uint32 bids = HordeConfig.GetBidsPerInterval();
- for (uint32 count = 1;count <= bids;count++)
- {
- addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig, &_session);
- _lastrun_h = _newrun;
- }
+ addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig, &_session);
+ _lastrun_h = _newrun;
}
}
addNewAuctions(&_AHBplayer, &NeutralConfig);
if (((_newrun - _lastrun_n) > (NeutralConfig.GetBiddingInterval() * 60)) && (NeutralConfig.GetBidsPerInterval() > 0))
{
- uint32 bids = NeutralConfig.GetBidsPerInterval();
- for (uint32 count = 1;count <= bids;count++)
- {
- addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session);
- _lastrun_n = _newrun;
- }
+ addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session);
+ _lastrun_n = _newrun;
}
ObjectAccessor::Instance().RemoveObject(&_AHBplayer);
}
diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp
index 878d8e35648..f732f128fd0 100644
--- a/src/game/CombatHandler.cpp
+++ b/src/game/CombatHandler.cpp
@@ -49,7 +49,7 @@ void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data )
return;
}
- if(_player->IsFriendlyTo(pEnemy) || pEnemy->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
+ if(!_player->canAttack(pEnemy))
{
sLog.outError( "WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid));
@@ -58,14 +58,6 @@ void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data )
return;
}
- if(!pEnemy->isAlive())
- {
- // client can generate swing to known dead target if autoswitch between autoshot and autohit is enabled in client options
- // stop attack state at client
- SendAttackStop(pEnemy);
- return;
- }
-
_player->Attack(pEnemy,true);
}
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index 4668578c1be..6f0b5949236 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -71,26 +71,36 @@ void CreatureAI::OnCharmed(bool apply)
me->IsAIEnabled = false;
}
-void CreatureAI::DoZoneInCombat(Creature* pUnit)
+void CreatureAI::DoZoneInCombat(Creature* creature)
{
- if (!pUnit)
- pUnit = me;
-
- Map *map = pUnit->GetMap();
+ if (!creature)
+ creature = me;
+ Map *map = creature->GetMap();
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
{
- sLog.outError("DoZoneInCombat call for map that isn't an instance (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
+ sLog.outError("DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? ((Creature*)creature)->GetEntry() : 0);
return;
}
- if(!pUnit->getVictim())
- if(Unit *target = pUnit->SelectNearestTarget())
+ if(!creature->getVictim())
+ {
+ if(Unit *target = creature->SelectNearestTarget())
AttackStart(target);
+ else if(creature->isSummon())
+ {
+ if(Unit *summoner = ((TempSummon*)creature)->GetSummoner())
+ {
+ if(summoner->getVictim()
+ && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(summoner->getVictim())))
+ AttackStart(summoner->getVictim());
+ }
+ }
+ }
- if (!pUnit->CanHaveThreatList() || pUnit->getThreatManager().isThreatListEmpty())
+ if (!creature->CanHaveThreatList() || creature->getThreatManager().isThreatListEmpty())
{
- sLog.outError("DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
+ sLog.outError("DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? ((Creature*)creature)->GetEntry() : 0);
return;
}
@@ -100,9 +110,9 @@ void CreatureAI::DoZoneInCombat(Creature* pUnit)
if (Player* i_pl = i->getSource())
if (i_pl->isAlive())
{
- pUnit->SetInCombatWith(i_pl);
- i_pl->SetInCombatWith(pUnit);
- pUnit->AddThreat(i_pl, 0.0f);
+ creature->SetInCombatWith(i_pl);
+ i_pl->SetInCombatWith(creature);
+ creature->AddThreat(i_pl, 0.0f);
}
}
}
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index d294886619c..8969e4dfe04 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -88,7 +88,7 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 );
SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId );
- SetFloatValue( DYNAMICOBJECT_RADIUS, radius * 2); //diameter?
+ SetFloatValue( DYNAMICOBJECT_RADIUS, radius);
SetFloatValue( DYNAMICOBJECT_POS_X, x );
SetFloatValue( DYNAMICOBJECT_POS_Y, y );
SetFloatValue( DYNAMICOBJECT_POS_Z, z );
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index 7fc6c147f5b..54cbff2c7bb 100644
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -180,7 +180,7 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
uint32 eff_index = i_dynobject.GetEffIndex();
- if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_CHANNEL
+ if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_DEST_DYNOBJ_ALLY
|| spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_GROUND)
{
if(!i_check->IsFriendlyTo(target))
diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp
index 7d2985c0643..30d316afd83 100644
--- a/src/game/NPCHandler.cpp
+++ b/src/game/NPCHandler.cpp
@@ -157,6 +157,7 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
// reputation discount
float fDiscountMod = _player->GetReputationPriceDiscount(unit);
+ bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProffesionPoints() > 0;
uint32 count = 0;
for(TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
@@ -166,25 +167,27 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
continue;
- ++count;
-
bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell);
-
SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->learnedSpell);
uint32 req_spell = spellmgr.GetSpellRequired(tSpell->spell);
+ TrainerSpellState state = _player->GetTrainerSpellState(tSpell);
data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
- data << uint8(_player->GetTrainerSpellState(tSpell));
+ data << uint8(state==TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
data << uint32(floor(tSpell->spellCost * fDiscountMod));
- data << uint32(primary_prof_first_rank ? 1 : 0); // primary prof. learn confirmation dialog
+ data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
+ // primary prof. learn confirmation dialog
data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
data << uint8(tSpell->reqLevel);
data << uint32(tSpell->reqSkill);
data << uint32(tSpell->reqSkillValue);
- data << uint32(chain_node && chain_node->prev ? chain_node->prev : req_spell);
- data << uint32(chain_node && chain_node->prev ? req_spell : 0);
+ //prev + req or req + 0
+ data << uint32(!tSpell->IsCastable() && chain_node && chain_node->prev ? chain_node->prev : req_spell);
+ data << uint32(!tSpell->IsCastable() && chain_node && chain_node->prev ? req_spell : 0);
data << uint32(0);
+
+ ++count;
}
data << strTitle;
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 79cb16e0637..71ae527e7d7 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -116,20 +116,20 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
//TODO: Send proper error message to client
return;
}
+
// only place where pet can be player
- pet->clearUnitState(UNIT_STAT_FOLLOW);
- const uint64& selguid = _player->GetSelection();
- Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid);
+ Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
if(!TargetUnit)
return;
- // not let attack friendly units.
- if(GetPlayer()->IsFriendlyTo(TargetUnit))
+ if(!pet->canAttack(TargetUnit))
return;
+
// Not let attack through obstructions
//if(!pet->IsWithinLOSInMap(TargetUnit))
// return;
+ pet->clearUnitState(UNIT_STAT_FOLLOW);
// This is true if pet has no target or has target but targets differs.
if(pet->getVictim() != TargetUnit)
{
@@ -209,7 +209,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid
for(uint32 i = 0; i < 3;++i)
{
- if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
+ if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_DYNOBJ_ENEMY)
return;
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index c5325de71ab..a5a33c7d2fd 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -3785,7 +3785,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
// check primary prof. limit
if(spellmgr.IsPrimaryProfessionFirstRankSpell(spell->Id) && GetFreePrimaryProffesionPoints() == 0)
- return TRAINER_SPELL_RED;
+ return TRAINER_SPELL_GREEN_DISABLED;
return TRAINER_SPELL_GREEN;
}
@@ -11721,301 +11721,303 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a
return;
if (!item->IsBroken())
- for (int s=0; s<3; s++)
{
- uint32 enchant_display_type = pEnchant->type[s];
- uint32 enchant_amount = pEnchant->amount[s];
- uint32 enchant_spell_id = pEnchant->spellid[s];
-
- switch(enchant_display_type)
+ for (int s=0; s<3; s++)
{
- case ITEM_ENCHANTMENT_TYPE_NONE:
- break;
- case ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL:
- // processed in Player::CastItemCombatSpell
- break;
- case ITEM_ENCHANTMENT_TYPE_DAMAGE:
- if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
- HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(enchant_amount), apply);
- else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND)
- HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(enchant_amount), apply);
- else if (item->GetSlot() == EQUIPMENT_SLOT_RANGED)
- HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
- break;
- case ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL:
- if(enchant_spell_id)
- {
- if(apply)
+ uint32 enchant_display_type = pEnchant->type[s];
+ uint32 enchant_amount = pEnchant->amount[s];
+ uint32 enchant_spell_id = pEnchant->spellid[s];
+
+ switch(enchant_display_type)
+ {
+ case ITEM_ENCHANTMENT_TYPE_NONE:
+ break;
+ case ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL:
+ // processed in Player::CastItemCombatSpell
+ break;
+ case ITEM_ENCHANTMENT_TYPE_DAMAGE:
+ if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
+ HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(enchant_amount), apply);
+ else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND)
+ HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(enchant_amount), apply);
+ else if (item->GetSlot() == EQUIPMENT_SLOT_RANGED)
+ HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ break;
+ case ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL:
+ if(enchant_spell_id)
{
- int32 basepoints = 0;
- // Random Property Exist - try found basepoints for spell (basepoints depends from item suffix factor)
- if (item->GetItemRandomPropertyId())
+ if(apply)
{
- ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
- if (item_rand)
+ int32 basepoints = 0;
+ // Random Property Exist - try found basepoints for spell (basepoints depends from item suffix factor)
+ if (item->GetItemRandomPropertyId())
{
- // Search enchant_amount
- for (int k=0; k<3; k++)
+ ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
+ if (item_rand)
{
- if(item_rand->enchant_id[k] == enchant_id)
+ // Search enchant_amount
+ for (int k=0; k<3; k++)
{
- basepoints = int32((item_rand->prefix[k]*item->GetItemSuffixFactor()) / 10000 );
- break;
+ if(item_rand->enchant_id[k] == enchant_id)
+ {
+ basepoints = int32((item_rand->prefix[k]*item->GetItemSuffixFactor()) / 10000 );
+ break;
+ }
}
}
}
+ // Cast custom spell vs all equal basepoints getted from enchant_amount
+ if (basepoints)
+ CastCustomSpell(this,enchant_spell_id,&basepoints,&basepoints,&basepoints,true,item);
+ else
+ CastSpell(this,enchant_spell_id,true,item);
}
- // Cast custom spell vs all equal basepoints getted from enchant_amount
- if (basepoints)
- CastCustomSpell(this,enchant_spell_id,&basepoints,&basepoints,&basepoints,true,item);
else
- CastSpell(this,enchant_spell_id,true,item);
+ RemoveAurasDueToItemSpell(item,enchant_spell_id);
}
- else
- RemoveAurasDueToItemSpell(item,enchant_spell_id);
- }
- break;
- case ITEM_ENCHANTMENT_TYPE_RESISTANCE:
- if (!enchant_amount)
- {
- ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
- if(item_rand)
+ break;
+ case ITEM_ENCHANTMENT_TYPE_RESISTANCE:
+ if (!enchant_amount)
{
- for (int k=0; k<3; k++)
+ ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
+ if(item_rand)
{
- if(item_rand->enchant_id[k] == enchant_id)
+ for (int k=0; k<3; k++)
{
- enchant_amount = uint32((item_rand->prefix[k]*item->GetItemSuffixFactor()) / 10000 );
- break;
+ if(item_rand->enchant_id[k] == enchant_id)
+ {
+ enchant_amount = uint32((item_rand->prefix[k]*item->GetItemSuffixFactor()) / 10000 );
+ break;
+ }
}
}
}
- }
- HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply);
- break;
- case ITEM_ENCHANTMENT_TYPE_STAT:
- {
- if (!enchant_amount)
+ HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply);
+ break;
+ case ITEM_ENCHANTMENT_TYPE_STAT:
{
- ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
- if(item_rand_suffix)
+ if (!enchant_amount)
{
- for (int k=0; k<3; k++)
+ ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
+ if(item_rand_suffix)
{
- if(item_rand_suffix->enchant_id[k] == enchant_id)
+ for (int k=0; k<3; k++)
{
- enchant_amount = uint32((item_rand_suffix->prefix[k]*item->GetItemSuffixFactor()) / 10000 );
- break;
+ if(item_rand_suffix->enchant_id[k] == enchant_id)
+ {
+ enchant_amount = uint32((item_rand_suffix->prefix[k]*item->GetItemSuffixFactor()) / 10000 );
+ break;
+ }
}
}
}
- }
- sLog.outDebug("Adding %u to stat nb %u",enchant_amount,enchant_spell_id);
- switch (enchant_spell_id)
- {
- case ITEM_MOD_AGILITY:
- sLog.outDebug("+ %u AGILITY",enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_AGILITY, enchant_amount, apply);
- break;
- case ITEM_MOD_STRENGTH:
- sLog.outDebug("+ %u STRENGTH",enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_STRENGTH, enchant_amount, apply);
- break;
- case ITEM_MOD_INTELLECT:
- sLog.outDebug("+ %u INTELLECT",enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_INTELLECT, enchant_amount, apply);
- break;
- case ITEM_MOD_SPIRIT:
- sLog.outDebug("+ %u SPIRIT",enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_SPIRIT, enchant_amount, apply);
- break;
- case ITEM_MOD_STAMINA:
- sLog.outDebug("+ %u STAMINA",enchant_amount);
- HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply);
- ApplyStatBuffMod(STAT_STAMINA, enchant_amount, apply);
- break;
- case ITEM_MOD_DEFENSE_SKILL_RATING:
- ((Player*)this)->ApplyRatingMod(CR_DEFENSE_SKILL, enchant_amount, apply);
- sLog.outDebug("+ %u DEFENCE", enchant_amount);
- break;
- case ITEM_MOD_DODGE_RATING:
- ((Player*)this)->ApplyRatingMod(CR_DODGE, enchant_amount, apply);
- sLog.outDebug("+ %u DODGE", enchant_amount);
- break;
- case ITEM_MOD_PARRY_RATING:
- ((Player*)this)->ApplyRatingMod(CR_PARRY, enchant_amount, apply);
- sLog.outDebug("+ %u PARRY", enchant_amount);
- break;
- case ITEM_MOD_BLOCK_RATING:
- ((Player*)this)->ApplyRatingMod(CR_BLOCK, enchant_amount, apply);
- sLog.outDebug("+ %u SHIELD_BLOCK", enchant_amount);
- break;
- case ITEM_MOD_HIT_MELEE_RATING:
- ((Player*)this)->ApplyRatingMod(CR_HIT_MELEE, enchant_amount, apply);
- sLog.outDebug("+ %u MELEE_HIT", enchant_amount);
- break;
- case ITEM_MOD_HIT_RANGED_RATING:
- ((Player*)this)->ApplyRatingMod(CR_HIT_RANGED, enchant_amount, apply);
- sLog.outDebug("+ %u RANGED_HIT", enchant_amount);
- break;
- case ITEM_MOD_HIT_SPELL_RATING:
- ((Player*)this)->ApplyRatingMod(CR_HIT_SPELL, enchant_amount, apply);
- sLog.outDebug("+ %u SPELL_HIT", enchant_amount);
- break;
- case ITEM_MOD_CRIT_MELEE_RATING:
- ((Player*)this)->ApplyRatingMod(CR_CRIT_MELEE, enchant_amount, apply);
- sLog.outDebug("+ %u MELEE_CRIT", enchant_amount);
- break;
- case ITEM_MOD_CRIT_RANGED_RATING:
- ((Player*)this)->ApplyRatingMod(CR_CRIT_RANGED, enchant_amount, apply);
- sLog.outDebug("+ %u RANGED_CRIT", enchant_amount);
- break;
- case ITEM_MOD_CRIT_SPELL_RATING:
- ((Player*)this)->ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply);
- sLog.outDebug("+ %u SPELL_CRIT", enchant_amount);
- break;
-// Values from ITEM_STAT_MELEE_HA_RATING to ITEM_MOD_HASTE_RANGED_RATING are never used
-// in Enchantments
-// case ITEM_MOD_HIT_TAKEN_MELEE_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HIT_TAKEN_RANGED_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HIT_TAKEN_SPELL_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HASTE_MELEE_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HASTE_RANGED_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply);
-// break;
- case ITEM_MOD_HASTE_SPELL_RATING:
- ((Player*)this)->ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply);
- break;
- case ITEM_MOD_HIT_RATING:
- ((Player*)this)->ApplyRatingMod(CR_HIT_MELEE, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_HIT_RANGED, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_HIT_SPELL, enchant_amount, apply);
- sLog.outDebug("+ %u HIT", enchant_amount);
- break;
- case ITEM_MOD_CRIT_RATING:
- ((Player*)this)->ApplyRatingMod(CR_CRIT_MELEE, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_CRIT_RANGED, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply);
- sLog.outDebug("+ %u CRITICAL", enchant_amount);
- break;
-// Values ITEM_MOD_HIT_TAKEN_RATING and ITEM_MOD_CRIT_TAKEN_RATING are never used in Enchantment
-// case ITEM_MOD_HIT_TAKEN_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
-// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
-// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_RATING:
-// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
-// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
-// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
- case ITEM_MOD_RESILIENCE_RATING:
- ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
- sLog.outDebug("+ %u RESILIENCE", enchant_amount);
- break;
- case ITEM_MOD_HASTE_RATING:
- ((Player*)this)->ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply);
- ((Player*)this)->ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply);
- sLog.outDebug("+ %u HASTE", enchant_amount);
- break;
- case ITEM_MOD_EXPERTISE_RATING:
- ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply);
- sLog.outDebug("+ %u EXPERTISE", enchant_amount);
- break;
- case ITEM_MOD_ATTACK_POWER:
- HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
- HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
- sLog.outDebug("+ %u ATTACK_POWER", enchant_amount);
- break;
- case ITEM_MOD_RANGED_ATTACK_POWER:
- HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
- sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount);
- break;
- case ITEM_MOD_FERAL_ATTACK_POWER:
- ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
- sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount);
- break;
- case ITEM_MOD_SPELL_HEALING_DONE:
- ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
- sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount);
- break;
- case ITEM_MOD_SPELL_DAMAGE_DONE:
- ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
- sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount);
- break;
- case ITEM_MOD_MANA_REGENERATION:
- ((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply);
- sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount);
- break;
- case ITEM_MOD_ARMOR_PENETRATION_RATING:
- ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply);
- sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount);
- break;
- case ITEM_MOD_SPELL_POWER:
- ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
- ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
- sLog.outDebug("+ %u SPELL_POWER", enchant_amount);
- break;
- default:
- break;
- }
- break;
- }
- case ITEM_ENCHANTMENT_TYPE_TOTEM: // Shaman Rockbiter Weapon
- {
- if(getClass() == CLASS_SHAMAN)
- {
- float addValue = 0.0f;
- if(item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
+ sLog.outDebug("Adding %u to stat nb %u",enchant_amount,enchant_spell_id);
+ switch (enchant_spell_id)
{
- addValue = float(enchant_amount * item->GetProto()->Delay/1000.0f);
- HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, addValue, apply);
+ case ITEM_MOD_AGILITY:
+ sLog.outDebug("+ %u AGILITY",enchant_amount);
+ HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
+ ApplyStatBuffMod(STAT_AGILITY, enchant_amount, apply);
+ break;
+ case ITEM_MOD_STRENGTH:
+ sLog.outDebug("+ %u STRENGTH",enchant_amount);
+ HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply);
+ ApplyStatBuffMod(STAT_STRENGTH, enchant_amount, apply);
+ break;
+ case ITEM_MOD_INTELLECT:
+ sLog.outDebug("+ %u INTELLECT",enchant_amount);
+ HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply);
+ ApplyStatBuffMod(STAT_INTELLECT, enchant_amount, apply);
+ break;
+ case ITEM_MOD_SPIRIT:
+ sLog.outDebug("+ %u SPIRIT",enchant_amount);
+ HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, float(enchant_amount), apply);
+ ApplyStatBuffMod(STAT_SPIRIT, enchant_amount, apply);
+ break;
+ case ITEM_MOD_STAMINA:
+ sLog.outDebug("+ %u STAMINA",enchant_amount);
+ HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply);
+ ApplyStatBuffMod(STAT_STAMINA, enchant_amount, apply);
+ break;
+ case ITEM_MOD_DEFENSE_SKILL_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_DEFENSE_SKILL, enchant_amount, apply);
+ sLog.outDebug("+ %u DEFENCE", enchant_amount);
+ break;
+ case ITEM_MOD_DODGE_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_DODGE, enchant_amount, apply);
+ sLog.outDebug("+ %u DODGE", enchant_amount);
+ break;
+ case ITEM_MOD_PARRY_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_PARRY, enchant_amount, apply);
+ sLog.outDebug("+ %u PARRY", enchant_amount);
+ break;
+ case ITEM_MOD_BLOCK_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_BLOCK, enchant_amount, apply);
+ sLog.outDebug("+ %u SHIELD_BLOCK", enchant_amount);
+ break;
+ case ITEM_MOD_HIT_MELEE_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_HIT_MELEE, enchant_amount, apply);
+ sLog.outDebug("+ %u MELEE_HIT", enchant_amount);
+ break;
+ case ITEM_MOD_HIT_RANGED_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_HIT_RANGED, enchant_amount, apply);
+ sLog.outDebug("+ %u RANGED_HIT", enchant_amount);
+ break;
+ case ITEM_MOD_HIT_SPELL_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_HIT_SPELL, enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_HIT", enchant_amount);
+ break;
+ case ITEM_MOD_CRIT_MELEE_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_MELEE, enchant_amount, apply);
+ sLog.outDebug("+ %u MELEE_CRIT", enchant_amount);
+ break;
+ case ITEM_MOD_CRIT_RANGED_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_RANGED, enchant_amount, apply);
+ sLog.outDebug("+ %u RANGED_CRIT", enchant_amount);
+ break;
+ case ITEM_MOD_CRIT_SPELL_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_CRIT", enchant_amount);
+ break;
+// Values from ITEM_STAT_MELEE_HA_RATING to ITEM_MOD_HASTE_RANGED_RATING are never used
+// in Enchantments
+// case ITEM_MOD_HIT_TAKEN_MELEE_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
+// break;
+// case ITEM_MOD_HIT_TAKEN_RANGED_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
+// break;
+// case ITEM_MOD_HIT_TAKEN_SPELL_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
+// break;
+// case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
+// break;
+// case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
+// break;
+// case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
+// break;
+// case ITEM_MOD_HASTE_MELEE_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply);
+// break;
+// case ITEM_MOD_HASTE_RANGED_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply);
+// break;
+ case ITEM_MOD_HASTE_SPELL_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply);
+ break;
+ case ITEM_MOD_HIT_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_HIT_MELEE, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_HIT_RANGED, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_HIT_SPELL, enchant_amount, apply);
+ sLog.outDebug("+ %u HIT", enchant_amount);
+ break;
+ case ITEM_MOD_CRIT_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_MELEE, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_RANGED, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply);
+ sLog.outDebug("+ %u CRITICAL", enchant_amount);
+ break;
+// Values ITEM_MOD_HIT_TAKEN_RATING and ITEM_MOD_CRIT_TAKEN_RATING are never used in Enchantment
+// case ITEM_MOD_HIT_TAKEN_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
+// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
+// ((Player*)this)->ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
+// break;
+// case ITEM_MOD_CRIT_TAKEN_RATING:
+// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
+// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
+// ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
+// break;
+ case ITEM_MOD_RESILIENCE_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
+ sLog.outDebug("+ %u RESILIENCE", enchant_amount);
+ break;
+ case ITEM_MOD_HASTE_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply);
+ ((Player*)this)->ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply);
+ sLog.outDebug("+ %u HASTE", enchant_amount);
+ break;
+ case ITEM_MOD_EXPERTISE_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply);
+ sLog.outDebug("+ %u EXPERTISE", enchant_amount);
+ break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ sLog.outDebug("+ %u ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_RANGED_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_FERAL_ATTACK_POWER:
+ ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_HEALING_DONE:
+ ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_DAMAGE_DONE:
+ ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply);
+ sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
+ ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_POWER", enchant_amount);
+ break;
+ default:
+ break;
}
- else if(item->GetSlot() == EQUIPMENT_SLOT_OFFHAND )
+ break;
+ }
+ case ITEM_ENCHANTMENT_TYPE_TOTEM: // Shaman Rockbiter Weapon
+ {
+ if(getClass() == CLASS_SHAMAN)
{
- addValue = float(enchant_amount * item->GetProto()->Delay/1000.0f);
- HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, addValue, apply);
+ float addValue = 0.0f;
+ if(item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
+ {
+ addValue = float(enchant_amount * item->GetProto()->Delay/1000.0f);
+ HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, addValue, apply);
+ }
+ else if(item->GetSlot() == EQUIPMENT_SLOT_OFFHAND )
+ {
+ addValue = float(enchant_amount * item->GetProto()->Delay/1000.0f);
+ HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, addValue, apply);
+ }
}
+ break;
}
- break;
- }
- case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
- // processed in Player::CastItemUseSpell
- break;
- case ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET:
- // nothing do..
- break;
- default:
- sLog.outError("Unknown item enchantment (id = %d) display type: %d", enchant_id, enchant_display_type);
- break;
- } /*switch(enchant_display_type)*/
- } /*for*/
+ case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
+ // processed in Player::CastItemUseSpell
+ break;
+ case ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET:
+ // nothing do..
+ break;
+ default:
+ sLog.outError("Unknown item enchantment (id = %d) display type: %d", enchant_id, enchant_display_type);
+ break;
+ } /*switch(enchant_display_type)*/
+ } /*for*/
+ }
// visualize enchantment at player and equipped items
if(slot < MAX_INSPECTED_ENCHANTMENT_SLOT)
diff --git a/src/game/Player.h b/src/game/Player.h
index a40a7f1c40c..6a0db61896d 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -122,7 +122,8 @@ enum TrainerSpellState
{
TRAINER_SPELL_GREEN = 0,
TRAINER_SPELL_RED = 1,
- TRAINER_SPELL_GRAY = 2
+ TRAINER_SPELL_GRAY = 2,
+ TRAINER_SPELL_GREEN_DISABLED = 10 // custom value, not send to client: formally green but learn not allowed
};
enum ActionButtonUpdateState
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index e6aaf8619bc..1cdf2359201 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -1032,9 +1032,8 @@ enum Targets
TARGET_GAMEOBJECT_ITEM = 26,
//TARGET_OBJECT_ITEM_PICKLOCK
TARGET_UNIT_MASTER = 27,
- TARGET_ALL_ENEMY_IN_AREA_CHANNELED = 28,
- TARGET_UNIT_AREA_ENEMY_CHANNEL = 28,
- TARGET_UNIT_AREA_ALLY_CHANNEL = 29, // 28,29 only used for effect 27, if interrupt channel, pstAA cancel
+ TARGET_DEST_DYNOBJ_ENEMY = 28,
+ TARGET_DEST_DYNOBJ_ALLY = 29, // only for effect 27
TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER = 30, // in TargetB used only with TARGET_ALL_AROUND_CASTER and in self casting range in TargetA
TARGET_UNIT_AREA_ALLY = 30,
TARGET_ALL_FRIENDLY_UNITS_IN_AREA = 31,
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 5990c70a2e9..9590322617f 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -925,7 +925,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
spellHitTarget = m_caster;
}
- DoSpellHitOnUnit(spellHitTarget, mask);
+ if(spellHitTarget)
+ {
+ SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask);
+ if(missInfo != SPELL_MISS_NONE)
+ {
+ m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo);
+ m_damage = 0;
+ spellHitTarget = NULL;
+ }
+ }
// Do not take combo points on dodge
if (m_needComboPoints && m_targets.getUnitTargetGUID() == target->targetGUID)
@@ -1034,19 +1043,17 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
}
}
-void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
+SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
{
if(!unit || !effectMask)
- return;
+ return SPELL_MISS_EVADE;
// Recheck immune (only for delayed spells)
if( m_spellInfo->speed &&
(unit->IsImmunedToDamage(m_spellInfo) ||
unit->IsImmunedToSpell(m_spellInfo)))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
- m_damage = 0;
- return;
+ return SPELL_MISS_IMMUNE;
}
if (unit->GetTypeId() == TYPEID_PLAYER)
@@ -1067,9 +1074,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) &&
unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
if( !m_caster->IsFriendlyTo(unit) )
@@ -1077,9 +1082,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// for delayed spells ignore not visible explicit target
if(m_spellInfo->speed > 0.0f && unit==m_targets.getUnitTarget() && !unit->isVisibleForOrDetect(m_caster,false))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
@@ -1092,9 +1095,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// TODO: this cause soul transfer bugged
if(m_spellInfo->speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !IsPositiveSpell(m_spellInfo->Id))
{
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
- m_damage = 0;
- return;
+ return SPELL_MISS_EVADE;
}
// assisting case, healing and resurrection
@@ -1165,6 +1166,8 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if (unit->AddAura(Aur))
m_spellAura = Aur;
}
+
+ return SPELL_MISS_NONE;
}
void Spell::DoTriggersOnSpellHit(Unit *unit)
@@ -1988,17 +1991,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
- if(cur == TARGET_DEST_DEST)
- break;
-
- float x, y, z, angle, dist;
-
- dist = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- if (cur == TARGET_DEST_DEST_RANDOM)
- dist *= rand_norm();
-
+ float angle;
switch(cur)
{
+ case TARGET_DEST_DYNOBJ_ENEMY:
+ case TARGET_DEST_DYNOBJ_ALLY:
+ case TARGET_DEST_DEST:
+ return;
case TARGET_DEST_DEST_FRONT: angle = 0.0f; break;
case TARGET_DEST_DEST_BACK: angle = M_PI; break;
case TARGET_DEST_DEST_RIGHT: angle = M_PI/2; break;
@@ -2010,6 +2009,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
default: angle = rand_norm()*2*M_PI; break;
}
+ float dist, x, y, z;
+ dist = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ if (cur == TARGET_DEST_DEST_RANDOM)
+ dist *= rand_norm();
+
x = m_targets.m_destX;
y = m_targets.m_destY;
z = m_targets.m_destZ;
diff --git a/src/game/Spell.h b/src/game/Spell.h
index d7bbc119572..64aa7f24eb0 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -588,7 +588,7 @@ class Spell
void AddGOTarget(uint64 goGUID, uint32 effIndex);
void AddItemTarget(Item* target, uint32 effIndex);
void DoAllEffectOnTarget(TargetInfo *target);
- void DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
+ SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask);
void DoTriggersOnSpellHit(Unit *unit);
void DoAllEffectOnTarget(GOTargetInfo *target);
void DoAllEffectOnTarget(ItemTargetInfo *target);
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 1cbd5f94772..a1ae00b17c8 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -372,7 +372,12 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if(!radius) return;
float distance = m_caster->GetDistance2d(unitTarget);
damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius));
- }break;
+ break;
+ }
+ // Cataclysmic Bolt
+ case 38441:
+ damage = unitTarget->GetMaxHealth() / 2;
+ break;
}
break;
}
@@ -2753,7 +2758,6 @@ void Spell::EffectPersistentAA(uint32 i)
return;
}
dynObj->SetUInt32Value(OBJECT_FIELD_TYPE, 65);
- dynObj->SetUInt32Value(GAMEOBJECT_DISPLAYID, 368003);
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x01eeeeee);
caster->AddDynObject(dynObj);
dynObj->GetMap()->Add(dynObj);
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index b98d693c416..5cd5da67118 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -347,12 +347,8 @@ void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
recvPacket >> counter;
recvPacket >> spellId;
- //FIXME: hack, ignore unexpected client cancel Deadly Throw cast
- if(spellId==26679)
- return;
-
if(_player->IsNonMeleeSpellCasted(false))
- _player->InterruptNonMeleeSpells(false,spellId);
+ _player->InterruptNonMeleeSpells(false,spellId,false);
}
void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 6d93f292f8c..e4bee68d3a3 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -119,8 +119,6 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_AREA_ENTRY:
case TARGET_UNIT_AREA_PARTY_GROUND:
case TARGET_UNIT_AREA_PARTY:
- //case TARGET_UNIT_AREA_ENEMY_CHANNEL:
- //case TARGET_UNIT_AREA_ALLY_CHANNEL:
SpellTargetType[i] = TARGET_TYPE_AREA_DEST;
break;
case TARGET_DEST_TARGET_ENEMY:
@@ -153,6 +151,8 @@ SpellMgr::SpellMgr()
case TARGET_DEST_CASTER_RADIUS:
SpellTargetType[i] = TARGET_TYPE_DEST_CASTER;
break;
+ case TARGET_DEST_DYNOBJ_ENEMY:
+ case TARGET_DEST_DYNOBJ_ALLY:
case TARGET_DEST_DEST:
case TARGET_DEST_DEST_FRONT_LEFT:
case TARGET_DEST_DEST_BACK_LEFT:
@@ -182,9 +182,6 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_AREA_ENTRY:
case TARGET_UNIT_AREA_PARTY_GROUND:
case TARGET_UNIT_AREA_PARTY:
- //Check persistant aura seperately
- //case TARGET_UNIT_AREA_ENEMY_CHANNEL:
- //case TARGET_UNIT_AREA_ALLY_CHANNEL:
case TARGET_UNIT_PARTY_TARGET:
case TARGET_UNIT_PARTY_CASTER:
case TARGET_UNIT_CONE_ENEMY:
@@ -501,7 +498,7 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
case TARGET_ALL_ENEMY_IN_AREA:
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
case TARGET_IN_FRONT_OF_CASTER:
- case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
+ case TARGET_DEST_DYNOBJ_ENEMY:
case TARGET_CURRENT_ENEMY_COORDINATES:
case TARGET_UNIT_CHANNEL:
return false;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index f2f824481ad..b1a39c30cce 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -3394,12 +3394,14 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
pSpell->SetReferencedFromCurrent(true);
}
-void Unit::InterruptSpell(uint32 spellType, bool withDelayed)
+void Unit::InterruptSpell(uint32 spellType, bool withDelayed, bool withInstant)
{
assert(spellType < CURRENT_MAX_SPELL);
Spell *spell = m_currentSpells[spellType];
- if(spell && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) )
+ if(spell
+ && (withDelayed || spell->getState() != SPELL_STATE_DELAYED)
+ && (withInstant || spell->GetCastTime() > 0))
{
// for example, do not let self-stun aura interrupt itself
if(!spell->IsInterruptable())
@@ -3443,19 +3445,19 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip
return(false);
}
-void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id)
+void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id, bool withInstant)
{
// generic spells are interrupted if they are not finished or delayed
if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id))
- InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed);
+ InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed,withInstant);
// autorepeat spells are interrupted if they are not finished or delayed
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id))
- InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed);
+ InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed,withInstant);
// channeled spells are interrupted if they are not finished, even if they are delayed
if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id))
- InterruptSpell(CURRENT_CHANNELED_SPELL,true);
+ InterruptSpell(CURRENT_CHANNELED_SPELL,true,true);
}
Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
@@ -3484,10 +3486,9 @@ bool Unit::isInBack(Unit const* target, float distance, float arc) const
bool Unit::isInLine(Unit const* target, float distance) const
{
if(!HasInArc(M_PI, target) || !IsWithinDistInMap(target, distance)) return false;
- float width = (GetObjectSize() / 2 + target->GetObjectSize()) / 2;
- float angle = GetAngle(target);
- angle -= GetOrientation();
- return abs(sin(angle)) * distance < width;
+ float width = GetObjectSize() + target->GetObjectSize() * 0.5f;
+ float angle = GetAngle(target) - GetOrientation();
+ return abs(sin(angle)) * GetExactDistance2d(target->GetPositionX(), target->GetPositionY()) < width;
}
bool Unit::isInAccessiblePlaceFor(Creature const* c) const
@@ -9336,10 +9337,13 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask)
bool Unit::IsImmunedToDamage(SpellEntry const* spellInfo)
{
+ if(spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ return false;
+
uint32 shoolMask = GetSpellSchoolMask(spellInfo);
- if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
- !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) // can remove immune (by dispell or immune it)
- && (spellInfo->Id != 42292))
+ if(!(spellInfo->AttributesEx &
+ (SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE | SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
+ && spellInfo->Id != 42292)
{
//If m_immuneToSchool type contain this school type, IMMUNE damage.
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
@@ -9362,14 +9366,23 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
if (!spellInfo)
return false;
+ // Single spell immunity.
+ SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
+ for(SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
+ if(itr->type == spellInfo->Id)
+ return true;
+
+ if(spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ return false;
+
SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
if(itr->type == spellInfo->Dispel)
return true;
- if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
- !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) // can remove immune (by dispell or immune it)
- && (spellInfo->Id != 42292))
+ if(!(spellInfo->AttributesEx &
+ (SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE | SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
+ && spellInfo->Id != 42292)
{
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
@@ -9390,15 +9403,6 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
}
}
- SpellImmuneList const& idList = m_spellImmune[IMMUNITY_ID];
- for(SpellImmuneList::const_iterator itr = idList.begin(); itr != idList.end(); ++itr)
- {
- if(itr->type == spellInfo->Id)
- {
- return true;
- }
- }
-
return false;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 539d8859684..8e008e1357e 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1337,7 +1337,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetCurrentCastedSpell(Spell * pSpell);
virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { }
- void InterruptSpell(uint32 spellType, bool withDelayed = true);
+ void InterruptSpell(uint32 spellType, bool withDelayed = true, bool withInstant = true);
// set withDelayed to true to account delayed spells as casted
// delayed+channeled spells are always accounted as casted
@@ -1346,7 +1346,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// set withDelayed to true to interrupt delayed spells too
// delayed+channeled spells are always interrupted
- void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0);
+ void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true);
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;