本文整理汇总了C++中Spell::prepare方法的典型用法代码示例。如果您正苦于以下问题:C++ Spell::prepare方法的具体用法?C++ Spell::prepare怎么用?C++ Spell::prepare使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Spell
的用法示例。
在下文中一共展示了Spell::prepare方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint8 castCount;
uint32 spellId;
uint8 castFlags;
recvPacket >> guid >> castCount >> spellId >> castFlags;
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL, guid: " UI64FMTD ", castCount: %u, spellId %u, castFlags %u", guid, castCount, spellId, castFlags);
// This opcode is also sent from charmed and possessed units (players and creatures)
if (!_player->GetGuardianPet() && !_player->GetCharm())
return;
Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
{
sLog->outError("HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName());
return;
}
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
sLog->outError("WORLD: unknown PET spell id %i", spellId);
return;
}
if (spellInfo->StartRecoveryCategory > 0) // Check if spell is affected by GCD
if (caster->GetTypeId() == TYPEID_UNIT && caster->GetCharmInfo() && caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
{
caster->SendPetCastFail(spellId, SPELL_FAILED_NOT_READY);
return;
}
// do not cast not learned spells
if (!caster->HasSpell(spellId) || spellInfo->IsPassive())
return;
SpellCastTargets targets;
targets.Read(recvPacket, caster);
HandleClientCastFlags(recvPacket, castFlags, targets);
caster->ClearUnitState(UNIT_STATE_FOLLOW);
Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE);
spell->m_cast_count = castCount; // probably pending spell cast
spell->m_targets = targets;
// TODO: need to check victim?
SpellCastResult result;
if (caster->m_movedPlayer)
result = spell->CheckPetCast(caster->m_movedPlayer->GetSelectedUnit());
else
result = spell->CheckPetCast(NULL);
if (result == SPELL_CAST_OK)
{
if (caster->GetTypeId() == TYPEID_UNIT)
{
Creature* pet = caster->ToCreature();
pet->AddCreatureSpellCooldown(spellId);
if (pet->isPet())
{
Pet* p = (Pet*)pet;
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}
}
spell->prepare(&(spell->m_targets));
}
else
{
caster->SendPetCastFail(spellId, result);
if (caster->GetTypeId() == TYPEID_PLAYER)
{
if (!caster->ToPlayer()->HasSpellCooldown(spellId))
GetPlayer()->SendClearCooldown(spellId, caster);
}
else
{
if (!caster->ToCreature()->HasSpellCooldown(spellId))
GetPlayer()->SendClearCooldown(spellId, caster);
}
spell->finish(false);
delete spell;
}
}
示例2: ApplyEnchantmentBonus
//.........这里部分代码省略.........
int32 val = Entry->min[c];
if( RandomSuffixAmount )
val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );
if( Apply )
m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, val );
else
m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, -val );
m_owner->CalcDamage();
}break;
case 3: // Cast spell (usually means apply aura)
{
if( Apply )
{
SpellCastTargets targets( m_owner->GetGUID() );
SpellEntry* sp;
if( Entry->spell[c] != 0 )
{
sp = dbcSpell.LookupEntryForced( Entry->spell[c] );
if( sp == NULL )
continue;
Spell* spell = NULLSPELL;
//Never found out why,
//but this Blade of Life's Inevitability spell must be casted by the item, not owner.
if( m_itemProto->ItemId != 34349 )
spell = (new Spell( m_owner, sp, true, NULLAURA ));
else
spell = (new Spell( TO_ITEM(this), sp, true, NULLAURA ));
spell->i_caster = TO_ITEM(this);
spell->prepare( &targets );
}
}
else
{
if( Entry->spell[c] != 0 )
m_owner->RemoveAura( Entry->spell[c] );
}
}break;
case 4: // Modify physical resistance
{
int32 val = Entry->min[c];
if( RandomSuffixAmount )
val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() );
if( Apply )
{
m_owner->FlatResistanceModifierPos[Entry->spell[c]] += val;
}
else
{
m_owner->FlatResistanceModifierPos[Entry->spell[c]] -= val;
}
m_owner->CalcResistance( Entry->spell[c] );
}break;
case 5: //Modify rating ...order is PLAYER_FIELD_COMBAT_RATING_1 and above
{
//spellid is enum ITEM_STAT_TYPE
//min=max is amount
int32 val = Entry->min[c];
示例3: Use
//.........这里部分代码省略.........
// BG flag click
// AB:
// 15001
// 15002
// 15003
// 15004
// 15005
bg->EventPlayerClickedOnFlag(player, this);
return; //we don;t need to delete flag ... it is despawned!
}
break;
}
case GAMEOBJECT_TYPE_FLAGDROP: // 26
{
if(user->GetTypeId()!=TYPEID_PLAYER)
return;
Player* player = (Player*)user;
if( player->isAllowUseBattleGroundObject() )
{
// in battleground check
BattleGround *bg = player->GetBattleGround();
if(!bg)
return;
// BG flag dropped
// WS:
// 179785 - Silverwing Flag
// 179786 - Warsong Flag
// EotS:
// 184142 - Netherstorm Flag
GameObjectInfo const* info = GetGOInfo();
if(info)
{
switch(info->id)
{
case 179785: // Silverwing Flag
// check if it's correct bg
if(bg->GetTypeID() == BATTLEGROUND_WS)
bg->EventPlayerClickedOnFlag(player, this);
break;
case 179786: // Warsong Flag
if(bg->GetTypeID() == BATTLEGROUND_WS)
bg->EventPlayerClickedOnFlag(player, this);
break;
case 184142: // Netherstorm Flag
if(bg->GetTypeID() == BATTLEGROUND_EY)
bg->EventPlayerClickedOnFlag(player, this);
break;
}
}
//this cause to call return, all flags must be deleted here!!
spellId = 0;
Delete();
}
break;
}
case GAMEOBJECT_TYPE_BARBER_CHAIR: //32
{
GameObjectInfo const* info = GetGOInfo();
if(!info)
return;
if(user->GetTypeId()!=TYPEID_PLAYER)
return;
Player* player = (Player*)user;
// fallback, will always work
player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET);
WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0);
player->GetSession()->SendPacket(&data);
player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight);
return;
}
default:
sLog.outDebug("Unknown Object Type %u", GetGoType());
break;
}
if(!spellId)
return;
SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId );
if(!spellInfo)
{
sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType());
return;
}
Spell *spell = new Spell(spellCaster, spellInfo, false);
// spell target is user of GO
SpellCastTargets targets;
targets.setUnitTarget( user );
spell->prepare(&targets);
}
示例4: Update
//.........这里部分代码省略.........
if( m_castingSpell )
{
//printf("we have a spell to cast\n");
SpellCastTime *sd = dbcSpellCastTime.LookupEntry( m_castingSpell->sp->CastingTimeIndex );
//do not stop for instant casts
if(GetCastTime(sd) != 0)
{
StopMovement(0);
//printf("spell is not instant so we are going to stop movement \n");
}
float distance = m_Unit->GetDistanceSq( SpellTarget );
if( distance <= m_castingSpell->sp->base_range_or_radius_sqr || m_castingSpell->sp->base_range_or_radius_sqr == 0 )
{
//printf("we are in range and going to cast spell \n");
m_AIState = STATE_CASTING;
Spell *nspell = SpellPool.PooledNew();
nspell->Init(m_Unit, m_castingSpell->sp, false, NULL);
#ifdef SPELL_EFF_PCT_SCALE_WITH_DIFFICULTY
if( m_castingSpell->max_scale )
{
nspell->forced_basepoints[ 0 ] = (uint32)( m_castingSpell->max_scale * ( DifficultyLevel + CombatDifficultyLevel) );
if( nspell->forced_basepoints[ 0 ] > m_castingSpell->max_scale * 2)
nspell->forced_basepoints[ 0 ] = m_castingSpell->max_scale * 2;
}
#endif
targets.m_unitTarget = SpellTarget->GetGUID();
nspell->prepare( &targets );
CastSpell( m_Unit, m_castingSpell->sp, targets );
SetSpellDuration( m_castingSpell );
//mana regen is to big, he can cast forever, double mana usage maybe regulates this
m_Unit->ModSignedInt32Value( UNIT_FIELD_POWER1, -m_castingSpell->sp->manaCost );
}
else // Target out of Range -> Run to it
{
//printf("we are going to move closer \n");
m_moveRun = true;
_CalcDestinationAndMove( SpellTarget, sqrt( m_castingSpell->sp->base_range_or_radius_sqr ) );
}
}
// check if pets regenrate mana, If not then we should implement that too
//if owner is mounted then we mount too. Speed is not set though
if( m_PetOwner->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) && m_Unit->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) == 0 )
{
if( Owner_side == OWNER_SIDE_ALIANCE )
m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, HELPER_MOUNT_A_DISPLAY );
else
m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, OWNER_SIDE_HORDE );
m_moveSprint = true;
}
else if( m_PetOwner->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) == 0 && m_Unit->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) != 0 )
{
m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, 0 );
m_moveSprint = false;
}
示例5: HandleTrainerBuySpellOpcode
//.........这里部分代码省略.........
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER);
if (!unit)
{
DEBUG_LOG("WORLD: HandleTrainerBuySpellOpcode - %s not found or you can't interact with him.", guid.GetString().c_str());
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
{
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
}
if (!unit->IsTrainerOf(_player, true))
{
return;
}
// check present spell in trainer spell list
TrainerSpellData const* cSpells = unit->GetTrainerSpells();
TrainerSpellData const* tSpells = unit->GetTrainerTemplateSpells();
if (!cSpells && !tSpells)
{
return;
}
// Try find spell in npc_trainer
TrainerSpell const* trainer_spell = cSpells ? cSpells->Find(spellId) : NULL;
// Not found, try find in npc_trainer_template
if (!trainer_spell && tSpells)
{
trainer_spell = tSpells->Find(spellId);
}
// Not found anywhere, cheating?
if (!trainer_spell)
{
return;
}
// can't be learn, cheat? Or double learn with lags...
uint32 reqLevel = 0;
if (!_player->IsSpellFitByClassAndRace(trainer_spell->spell, &reqLevel))
{
return;
}
reqLevel = trainer_spell->isProvidedReqLevel ? trainer_spell->reqLevel : std::max(reqLevel, trainer_spell->reqLevel);
if (_player->GetTrainerSpellState(trainer_spell, reqLevel) != TRAINER_SPELL_GREEN)
{
return;
}
SpellEntry const* proto = sSpellStore.LookupEntry(trainer_spell->spell);
SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->EffectTriggerSpell[0]);
// apply reputation discount
uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
if (_player->GetMoney() < nSpellCost)
{
return;
}
_player->ModifyMoney(-int32(nSpellCost));
SendPlaySpellVisual(guid, 0xB3); // visual effect on trainer
WorldPacket data(SMSG_PLAY_SPELL_IMPACT, 8 + 4); // visual effect on player
data << _player->GetObjectGuid();
data << uint32(0x016A); // index from SpellVisualKit.dbc
SendPacket(&data);
// learn explicitly to prevent lost money at lags, learning spell will be only show spell animation
//[-ZERO] _player->learnSpell(trainer_spell->spell, false);
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << ObjectGuid(guid);
data << uint32(spellId); // should be same as in packet from client
SendPacket(&data);
Spell* spell;
if (proto->SpellVisual == 222)
{
spell = new Spell(_player, proto, false);
}
else
{
spell = new Spell(unit, proto, false);
}
SpellCastTargets targets;
targets.setUnitTarget(_player);
spell->prepare(&targets);
}
示例6: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint8 castCount;
uint32 spellId;
uint8 castFlags;
recvPacket >> guid >> castCount >> spellId >> castFlags;
;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL, guid: " UI64FMTD ", castCount: %u, spellId %u, castFlags %u", guid, castCount, spellId, castFlags);
// This opcode is also sent from charmed and possessed units (players and creatures)
if (!_player->GetGuardianPet() && !_player->GetCharm())
return;
Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
{
sLog->outError("HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str());
return;
}
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
sLog->outError("WORLD: unknown PET spell id %i", spellId);
return;
}
// do not cast not learned spells
if (!caster->HasSpell(spellId) || spellInfo->IsPassive())
return;
SpellCastTargets targets;
targets.Read(recvPacket, caster);
HandleClientCastFlags(recvPacket, castFlags, targets);
bool SetFollow = caster->HasUnitState(UNIT_STATE_FOLLOW);
caster->ClearUnitState(UNIT_STATE_FOLLOW);
Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE);
spell->m_cast_count = castCount; // probably pending spell cast
spell->m_targets = targets;
spell->LoadScripts();
// Xinef: Send default target, fixes return on NeedExplicitUnitTarget
Unit* target = targets.GetUnitTarget();
if (!target && spell->m_spellInfo->NeedsExplicitUnitTarget())
target = _player->GetSelectedUnit();
SpellCastResult result = spell->CheckPetCast(target);
if (result == SPELL_CAST_OK)
{
if (Creature* creature = caster->ToCreature())
{
creature->AddSpellCooldown(spellId, 0, 0);
if (Pet* pet = creature->ToPet())
{
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk(PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}
}
spell->prepare(&(spell->m_targets));
}
else
{
if (!caster->GetCharmInfo() || !caster->GetCharmInfo()->GetForcedSpell())
spell->SendPetCastResult(result);
if (caster->GetTypeId() == TYPEID_PLAYER)
{
if (!caster->ToPlayer()->HasSpellCooldown(spellId))
GetPlayer()->SendClearCooldown(spellId, caster);
}
else
{
if (!caster->ToCreature()->HasSpellCooldown(spellId))
GetPlayer()->SendClearCooldown(spellId, caster);
// reset specific flags in case of spell fail. AI will reset other flags
if (caster->IsPet())
caster->PetSpellFail(spellInfo, targets.GetUnitTarget(), result);
}
spell->finish(false);
delete spell;
}
if (SetFollow && !caster->IsInCombat())
caster->AddUnitState(UNIT_STATE_FOLLOW);
}
示例7: HandleCastSpellOpcode
//.........这里部分代码省略.........
if (!GetPlayer()->HasSpell(spellId))
{
sCheatLog.writefromsession(this, "Cast spell %lu but doesn't have that spell.", spellId);
LOG_DETAIL("WORLD: Spell isn't cast because player \'%s\' is cheating", GetPlayer()->GetName());
return;
}
if (spellInfo->Attributes & ATTRIBUTES_PASSIVE)
{
sCheatLog.writefromsession(this, "Cast passive spell %lu.", spellId);
LOG_DETAIL("WORLD: Spell isn't cast because player \'%s\' is cheating", GetPlayer()->GetName());
return;
}
if (GetPlayer()->GetOnMeleeSpell() != spellId)
{
//autoshot 75
if ((spellInfo->AttributesExB & ATTRIBUTESEXB_ACTIVATE_AUTO_SHOT) /*spellInfo->Attributes == 327698*/) // auto shot..
{
//sLog.outString( "HandleSpellCast: Auto Shot-type spell cast (id %u, name %s)" , spellInfo->Id , spellInfo->Name );
Item* weapon = GetPlayer()->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_RANGED);
if (!weapon)
return;
uint32 spellid;
switch (weapon->GetProto()->SubClass)
{
case 2: // bows
case 3: // guns
case 18: // crossbow
spellid = SPELL_RANGED_GENERAL;
break;
case 16: // thrown
spellid = SPELL_RANGED_THROW;
break;
case 19: // wands
spellid = SPELL_RANGED_WAND;
break;
default:
spellid = 0;
break;
}
if (!spellid)
spellid = spellInfo->Id;
if (!_player->m_onAutoShot)
{
_player->m_AutoShotTarget = _player->GetSelection();
uint32 duration = _player->GetBaseAttackTime(RANGED);
SpellCastTargets targets(recvPacket, GetPlayer()->GetGUID());
if (!targets.m_unitTarget)
{
LOG_DEBUG("Cancelling auto-shot cast because targets.m_unitTarget is null!");
return;
}
SpellEntry* sp = dbcSpell.LookupEntry(spellid);
_player->m_AutoShotSpell = sp;
_player->m_AutoShotDuration = duration;
//This will fix fast clicks
if (_player->m_AutoShotAttackTimer < 500)
_player->m_AutoShotAttackTimer = 500;
_player->m_onAutoShot = true;
}
return;
}
if (_player->m_currentSpell)
{
if (_player->m_currentSpell->getState() == SPELL_STATE_CASTING)
{
// cancel the existing channel spell, cast this one
_player->m_currentSpell->cancel();
}
else
{
// send the error message
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
return;
}
}
SpellCastTargets targets(recvPacket, GetPlayer()->GetGUID());
// some anticheat stuff
if (spellInfo->self_cast_only)
{
if (targets.m_unitTarget && targets.m_unitTarget != _player->GetGUID())
{
// send the error message
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0);
return;
}
}
Spell* spell = sSpellFactoryMgr.NewSpell(GetPlayer(), spellInfo, false, NULL);
spell->extra_cast_number = cn;
spell->prepare(&targets);
}
}
示例8: HandleCastSpellOpcode
//.........这里部分代码省略.........
// WPE allows them to mod the outgoing packet and basicly choose what ever spell they want :(
if (!GetPlayer()->HasSpell(spellId) || spellInfo->Attributes & ATTRIBUTES_PASSIVE)
{
sLog.outDetail("WORLD: Spell isn't casted because player \"%s\" is cheating", GetPlayer()->GetName());
return;
}
if (GetPlayer()->GetOnMeleeSpell() != spellId)
{
//autoshot 75
if ((spellInfo->AttributesExB & FLAGS3_ACTIVATE_AUTO_SHOT) /*spellInfo->Attributes == 327698*/) // auto shot..
{
//sLog.outString( "HandleSpellCast: Auto Shot-type spell cast (id %u, name %s)" , spellInfo->Id , spellInfo->Name );
Item *weapon = GetPlayer()->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_RANGED);
if (!weapon)
return;
uint32 spellid;
switch (weapon->GetProto()->SubClass)
{
case 2: // bows
case 3: // guns
case 18: // crossbow
spellid = SPELL_RANGED_GENERAL;
break;
case 16: // thrown
spellid = SPELL_RANGED_THROW;
break;
case 19: // wands
spellid = SPELL_RANGED_WAND;
break;
default:
spellid = 0;
break;
}
if (!spellid)
spellid = spellInfo->Id;
if (!_player->m_onAutoShot)
{
_player->m_AutoShotTarget = _player->GetSelection();
uint32 duration = _player->GetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME);
SpellCastTargets targets(recvPacket, GetPlayer()->GetGUID());
if (!targets.m_unitTarget)
{
sLog.outString("Cancelling auto-shot cast because targets.m_unitTarget is null!");
return;
}
SpellEntry *sp = dbcSpell.LookupEntry(spellid);
_player->m_AutoShotSpell = sp;
_player->m_AutoShotDuration = duration;
//This will fix fast clicks
if (_player->m_AutoShotAttackTimer < 500)
_player->m_AutoShotAttackTimer = 500;
_player->m_onAutoShot = true;
}
return;
}
/*const char * name = sSpellStore.LookupString(spellInfo->Name);
if(name)
sChatHandler.SystemMessageToPlr(_player, "%sSpell Cast:%s %s %s[Group %u, family %u]", MSG_COLOR_LIGHTBLUE,
MSG_COLOR_SUBWHITE, name, MSG_COLOR_YELLOW, spellInfo->SpellGroupType, spellInfo->SpellFamilyName);*/
if (_player->m_currentSpell)
{
if (_player->m_currentSpell->getState() == SPELL_STATE_CASTING)
{
// cancel the existing channel spell, cast this one
_player->m_currentSpell->cancel();
}
else
{
// send the error message
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
return;
}
}
SpellCastTargets targets(recvPacket, GetPlayer()->GetGUID());
// some anticheat stuff
if (spellInfo->self_cast_only)
{
if (targets.m_unitTarget && targets.m_unitTarget != _player->GetGUID())
{
// send the error message
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0);
return;
}
}
Spell *spell = SpellPool.PooledNew();
spell->Init(GetPlayer(), spellInfo, false, NULL);
spell->extra_cast_number = cn;
spell->prepare(&targets);
}
}
示例9: HandleUseItemOpcode
//.........这里部分代码省略.........
if (p_User->GetStandState() != 1)
p_User->SetStandState(STANDSTATE_SIT);
// loop through the auras and removing existing eating spells
}
else // cebernic: why not stand up
{
if (!p_User->CombatStatus.IsInCombat() && !p_User->IsMounted())
{
if (p_User->GetStandState())
{
p_User->SetStandState(STANDSTATE_STAND);
}
}
}
// cebernic: remove stealth on using item
if (!(spellInfo->AuraInterruptFlags & ATTRIBUTESEX_NOT_BREAK_STEALTH))
{
if (p_User->IsStealth())
p_User->RemoveAllAuraType(SPELL_AURA_MOD_STEALTH);
}
if (itemProto->RequiredLevel)
{
if (_player->getLevel() < itemProto->RequiredLevel)
{
_player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_ITEM_RANK_NOT_ENOUGH);
return;
}
}
if (itemProto->RequiredSkill)
{
if (!_player->_HasSkillLine(itemProto->RequiredSkill))
{
_player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_ITEM_RANK_NOT_ENOUGH);
return;
}
if (itemProto->RequiredSkillRank)
{
if (_player->_GetSkillLineCurrent(itemProto->RequiredSkill, false) < itemProto->RequiredSkillRank)
{
_player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_ITEM_RANK_NOT_ENOUGH);
return;
}
}
}
if ((itemProto->AllowableClass && !(_player->getClassMask() & itemProto->AllowableClass)) || (itemProto->AllowableRace && !(_player->getRaceMask() & itemProto->AllowableRace)))
{
_player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_YOU_CAN_NEVER_USE_THAT_ITEM);
return;
}
if (!_player->Cooldown_CanCast(spellInfo))
{
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_NOT_READY, cn, 0);
return;
}
if (_player->m_currentSpell)
{
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
return;
}
if (itemProto->ForcedPetId >= 0)
{
if (itemProto->ForcedPetId == 0)
{
if (_player->GetGUID() != targets.m_unitTarget)
{
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0);
return;
}
}
else
{
if (!_player->GetSummon() || _player->GetSummon()->GetEntry() != (uint32)itemProto->ForcedPetId)
{
_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
return;
}
}
}
Spell* spell = sSpellFactoryMgr.NewSpell(_player, spellInfo, false, NULL);
spell->extra_cast_number = cn;
spell->i_caster = tmpItem;
spell->m_glyphslot = glyphIndex;
//GetPlayer()->setCurrentSpell(spell);
spell->prepare(&targets);
#ifdef ENABLE_ACHIEVEMENTS
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, itemProto->ItemId, 0, 0);
#endif
}
示例10: HandleSpellClick
void WorldSession::HandleSpellClick(WorldPacket & recvPacket)
{
CHECK_INWORLD_RETURN
LOG_DETAIL("WORLD: got CMSG_SPELLCLICK packet, data length = %i", recvPacket.size());
if (_player->getDeathState() == CORPSE)
return;
uint64 target_guid; // this will store the guid of the object we are going to use it's spell. There must be a dbc that indicates what spells a unit has
recvPacket >> target_guid;
//we have only 1 example atm for entry : 28605
Unit* target_unit = _player->GetMapMgr()->GetUnit(target_guid);
if (!target_unit)
return;
if (!_player->isInRange(target_unit, MAX_INTERACTION_RANGE))
return;
if (target_unit->IsVehicle()){
if (target_unit->GetVehicleComponent() != NULL)
target_unit->GetVehicleComponent()->AddPassenger(_player);
return;
}
uint32 creature_id = target_unit->GetEntry();
uint32 cast_spell_id = 0;
if (!_player->HasAurasWithNameHash(SPELL_HASH_LIGHTWELL_RENEW) && target_unit->RemoveAura(59907))
{
SpellClickSpell *sp = SpellClickSpellStorage.LookupEntry(creature_id);
if (sp == NULL){
if (target_unit->IsCreature()){
Creature *c = TO< Creature* >(target_unit);
sChatHandler.BlueSystemMessage(this, "NPC Id %u ( %s ) has no spellclick spell associated with it.", c->GetProto()->Id, c->GetCreatureInfo()->Name);
LOG_ERROR("Spellclick packet received for creature %u but there is no spell associated with it.", creature_id);
return;
}
}
cast_spell_id = sp->SpellID;
target_unit->CastSpell(_player, cast_spell_id, true);
if (!target_unit->HasAura(59907))
TO_CREATURE(target_unit)->Despawn(0, 0); //IsCreature() check is not needed, refer to r2387 and r3230
return;
}
SpellClickSpell *sp = SpellClickSpellStorage.LookupEntry(creature_id);
if (sp == NULL){
if (target_unit->IsCreature()){
Creature *c = TO< Creature* >(target_unit);
sChatHandler.BlueSystemMessage(this, "NPC Id %u ( %s ) has no spellclick spell associated with it.", c->GetProto()->Id, c->GetCreatureInfo()->Name);
LOG_ERROR("Spellclick packet received for creature %u but there is no spell associated with it.", creature_id);
return;
}
}
cast_spell_id = sp->SpellID;
if (cast_spell_id == 0)
return;
SpellEntry* spellInfo = dbcSpell.LookupEntryForced(cast_spell_id);
if (spellInfo == NULL)
return;
Spell* spell = sSpellFactoryMgr.NewSpell(_player, spellInfo, false, NULL);
SpellCastTargets targets(target_guid);
spell->prepare(&targets);
}
示例11: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
{
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint32 spellid;
uint8 cast_count;
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
recvPacket >> guid >> cast_count >> spellid >> unk_flags;
sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
if (!_player->GetPet() && !_player->GetCharm())
return;
if (GUID_HIPART(guid) == HIGHGUID_PLAYER)
return;
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if (!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
{
sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
if (pet->GetGlobalCooldown() > 0)
return;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
if (!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
// do not cast not learned spells
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
return;
SpellCastTargets targets;
if (!targets.read(&recvPacket,pet,spellInfo))
return;
pet->clearUnitState(UNIT_STAT_FOLLOW);
pet->InterruptNonMeleeSpells(false);
Spell *spell = new Spell(pet, spellInfo, false);
spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
SpellCastResult result = spell->CheckPetCast(NULL);
if (result == SPELL_CAST_OK)
{
pet->AddCreatureSpellCooldown(spellid);
if (pet->isPet())
{
//10% chance to play special pet attack talk, else growl
//actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if(((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}
spell->prepare(&(spell->m_targets));
}
else
{
pet->SendPetCastFail(spellid, result);
if (!pet->HasSpellCooldown(spellid))
GetPlayer()->SendClearCooldown(spellid, pet);
spell->finish(false);
delete spell;
}
}
示例12: HandleSpellClick
void WorldSession::HandleSpellClick(WorldPacket& recvPacket)
{
LOG_DETAIL("WORLD: got CMSG_SPELLCLICK packet, data length = %i", recvPacket.size());
if (_player->getDeathState() == CORPSE)
return;
uint64_t unitGuid; // this will store the guid of the object we are going to use it's spell. There must be a dbc that indicates what spells a unit has
recvPacket >> unitGuid;
//we have only 1 example atm for entry : 28605
Unit* unitTarget = _player->GetMapMgr()->GetUnit(unitGuid);
if (!unitTarget)
return;
if (!_player->isInRange(unitTarget, MAX_INTERACTION_RANGE))
return;
if (unitTarget->isVehicle())
{
if (unitTarget->GetVehicleComponent() != nullptr)
unitTarget->GetVehicleComponent()->AddPassenger(_player);
return;
}
uint32_t creature_id = unitTarget->getEntry();
uint32_t cast_spell_id = 0;
if (unitTarget->RemoveAura(59907))
{
uint32 lightwellRenew[] =
{
//SPELL_HASH_LIGHTWELL_RENEW
7001,
27873,
27874,
28276,
48084,
48085,
60123,
0
};
if (!_player->hasAurasWithId(lightwellRenew))
{
SpellClickSpell const* sp = sMySQLStore.getSpellClickSpell(creature_id);
if (sp == nullptr)
{
if (unitTarget->isCreature())
{
Creature* c = static_cast<Creature*>(unitTarget);
sChatHandler.BlueSystemMessage(this, "NPC Id %u (%s) has no spellclick spell associated with it.", c->GetCreatureProperties()->Id, c->GetCreatureProperties()->Name.c_str());
LOG_ERROR("Spellclick packet received for creature %u but there is no spell associated with it.", creature_id);
return;
}
}
else
{
cast_spell_id = sp->SpellID;
unitTarget->CastSpell(_player, cast_spell_id, true);
}
if (!unitTarget->HasAura(59907))
static_cast<Creature*>(unitTarget)->Despawn(0, 0); //IsCreature() check is not needed, refer to r2387 and r3230
return;
}
}
SpellClickSpell const* sp = sMySQLStore.getSpellClickSpell(creature_id);
if (sp == nullptr)
{
if (unitTarget->isCreature())
{
Creature* c = static_cast< Creature* >(unitTarget);
sChatHandler.BlueSystemMessage(this, "NPC Id %u (%s) has no spellclick spell associated with it.", c->GetCreatureProperties()->Id, c->GetCreatureProperties()->Name.c_str());
LOG_ERROR("Spellclick packet received for creature %u but there is no spell associated with it.", creature_id);
return;
}
}
else
{
cast_spell_id = sp->SpellID;
SpellInfo* spellInfo = sSpellCustomizations.GetSpellInfo(cast_spell_id);
if (spellInfo == nullptr)
return;
Spell* spell = sSpellFactoryMgr.NewSpell(_player, spellInfo, false, nullptr);
SpellCastTargets targets(unitGuid);
spell->prepare(&targets);
}
}
示例13: LogError
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32_t spellId;
uint8_t castCount;
uint32_t glyphSlot;
uint8_t missileflag;
recvPacket >> castCount;
recvPacket >> spellId;
recvPacket >> glyphSlot;
recvPacket >> missileflag;
// check for spell id
SpellInfo* spellInfo = sSpellCustomizations.GetSpellInfo(spellId);
if (!spellInfo)
{
LogError("WORLD: unknown spell id %i", spellId);
return;
}
if (!_player->isAlive() && _player->getShapeShiftForm() != FORM_SPIRITOFREDEMPTION && !(spellInfo->getAttributes() & ATTRIBUTES_DEAD_CASTABLE)) //They're dead, not in spirit of redemption and the spell can't be cast while dead.
return;
LogDetail("WORLD: got cast spell packet, spellId - %i (%s), data length = %i", spellId, spellInfo->getName().c_str(), recvPacket.size());
// Check does player have the spell
if (!GetPlayer()->HasSpell(spellId))
{
sCheatLog.writefromsession(this, "Cast spell %lu but doesn't have that spell.", spellId);
LogDetail("WORLD: Spell isn't cast because player \'%s\' is cheating", GetPlayer()->GetName());
return;
}
// Check is player trying to cast a passive spell
if (spellInfo->isPassive())
{
sCheatLog.writefromsession(this, "Cast passive spell %lu.", spellId);
LogDetail("WORLD: Spell isn't cast because player \'%s\' is cheating", GetPlayer()->GetName());
return;
}
// Check are we already casting this autorepeat spell
if ((spellInfo->getAttributesExB() & ATTRIBUTESEXB_AUTOREPEAT) && _player->getCurrentSpell(CURRENT_AUTOREPEAT_SPELL) != nullptr
&& spellInfo == _player->getCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->GetSpellInfo())
{
return;
}
// TODO: move this check to new Spell::prepare() and clean it
if (_player->isCastingNonMeleeSpell(false, true, true, spellInfo->getId() == 75))
{
_player->SendCastResult(spellId, SPELL_FAILED_SPELL_IN_PROGRESS, castCount, 0);
return;
}
SpellCastTargets targets(recvPacket, GetPlayer()->getGuid());
// some anticheat stuff
if (spellInfo->custom_self_cast_only)
{
if (targets.m_unitTarget && targets.m_unitTarget != _player->getGuid())
{
// send the error message
_player->SendCastResult(spellInfo->getId(), SPELL_FAILED_BAD_TARGETS, castCount, 0);
return;
}
}
Spell* spell = sSpellFactoryMgr.NewSpell(GetPlayer(), spellInfo, false, nullptr);
spell->extra_cast_number = castCount;
spell->m_glyphslot = glyphSlot;
spell->prepare(&targets);
}
示例14: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
ObjectGuid guid;
uint32 spellid;
recvPacket >> guid >> spellid;
DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, spellid %u", guid.GetString().c_str(), spellid);
Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
{
sLog.outError("HandlePetCastSpellOpcode: %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
return;
}
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
if (!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
return;
// do not cast not learned spells
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
return;
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(pet);
pet->clearUnitState(UNIT_STAT_MOVING);
Spell* spell = new Spell(pet, spellInfo, false);
spell->m_targets = targets;
SpellCastResult result = spell->CheckPetCast(nullptr);
if (result == SPELL_CAST_OK)
{
pet->AddCreatureSpellCooldown(spellid);
if (pet->IsPet())
{
((Pet*)pet)->CheckLearning(spellid);
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction();
}
spell->prepare(&(spell->m_targets));
}
else
{
pet->SendPetCastFail(spellid, result);
if (!pet->HasSpellCooldown(spellid))
GetPlayer()->SendClearCooldown(spellid, pet);
spell->finish(false);
delete spell;
}
}
示例15: UpdateAI
//.........这里部分代码省略.........
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// ignore some combinations of combat state and combat/noncombat spells
if (!inCombat)
{
// ignore attacking spells, and allow only self/around spells
if (!IsPositiveSpell(spellInfo->Id))
continue;
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this reqs:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
// allow only spell without spell cost or with spell cost but not duration limit
int32 duration = GetSpellDuration(spellInfo);
if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
continue;
// allow only spell without cooldown > duration
int32 cooldown = GetSpellRecoveryTime(spellInfo);
if (cooldown >= 0 && duration >= 0 && cooldown > duration)
continue;
}
}
else
{
// just ignore non-combat spells
if (IsNonCombatSpell(spellInfo))
continue;
}
Spell *spell = new Spell(m_creature, spellInfo, false);
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue;
}
else
{
bool spellUsed = false;
for(std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = ObjectAccessor::GetUnit(*m_creature,*tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if(!Target)
continue;
if(spell->CanAutoCast(Target))
{
targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell));
spellUsed = true;
break;
}
}
if (!spellUsed)
delete spell;
}
}
//found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = targetSpellStore[index].second;
Unit* target = targetSpellStore[index].first;
targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets;
targets.setUnitTarget( target );
if (!m_creature->HasInArc(M_PI_F, target))
{
m_creature->SetInFront(target);
if (target->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)target);
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer( (Player*)owner );
}
m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
spell->prepare(&targets);
}
// deleted cached Spell objects
for(TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
delete itr->second;
}
}