void WorldSession::HandleInrangeQuestgiverQuery(WorldPacket & recv_data) { CHECK_INWORLD_RETURN; WorldPacket data(SMSG_INRANGE_QUESTGIVER_STATUS_QUERY_RESPONSE, 1000); Object::InRangeSet::iterator itr; Creature * pCreature; uint32 count = 0; data << count; // 32 count // <foreach count> // 64 guid // 8 status for( itr = _player->m_objectsInRange.begin(); itr != _player->m_objectsInRange.end(); ++itr ) { pCreature = static_cast<Creature*>(*itr); if( pCreature->GetTypeId() != TYPEID_UNIT ) continue; if( pCreature->isQuestGiver() ) { data << pCreature->GetGUID(); data << uint8(sQuestMgr.CalcStatus( pCreature, _player )); ++count; } } *(uint32*)(data.contents()) = count; SendPacket(&data); }
void WorldSession::HandleInrangeQuestgiverQuery(WorldPacket & recv_data) { CHECK_INWORLD_RETURN; //WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 1000); uint8 databuffer[10000]; StackPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, databuffer, 10000); Object::InRangeSet::iterator itr; Creature* pCreature; uint32 count = 0; data << count; // 32 count // <foreach count> // 64 guid // 8 status for( itr = _player->m_objectsInRange.begin(); itr != _player->m_objectsInRange.end(); ++itr ) { pCreature = TO_CREATURE(*itr); if( pCreature->GetTypeId() != TYPEID_UNIT ) continue; if( pCreature->isQuestGiver() ) { data << pCreature->GetGUID(); data << sQuestMgr.CalcStatus( pCreature, _player ); ++count; } } *(uint32*)(data.GetBufferPointer()) = count; SendPacket(&data); }
void WorldSession::HandleInrangeQuestgiverQuery(WorldPacket & recv_data) { CHECK_INWORLD_RETURN; WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 1000); Object::InRangeSet::iterator itr; Creature* pCreature; uint32 count = 0; data << count; for( itr = _player->m_objectsInRange.begin(); itr != _player->m_objectsInRange.end(); itr++ ) { pCreature = TO_CREATURE(*itr); if( pCreature->GetTypeId() != TYPEID_UNIT ) continue; if( pCreature->isQuestGiver() ) { data << pCreature->GetGUID(); data << sQuestMgr.CalcStatus( pCreature, _player ); ++count; } } data.put<uint32>(0, count); SendPacket(&data); }
void FleeingMovementGenerator<Creature>::Finalize(Creature& owner) { owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); owner.ClearUnitState(UNIT_STATE_FLEEING | UNIT_STATE_ROAMING); if (owner.GetTypeId() == TYPEID_UNIT && owner.getVictim()) owner.SetTarget(owner.getVictim()->GetGUID()); }
void JustDied(Unit *killer) { Creature* deathcharger = me->FindNearestCreature(28782, 30); if (!deathcharger) return; if (killer->GetTypeId() == TYPEID_PLAYER && deathcharger->GetTypeId() == TYPEID_UNIT && deathcharger->IsVehicle()) { deathcharger->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); deathcharger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); deathcharger->setFaction(2096); } }
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner) { owner.addUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE); owner.RemoveSplineFlag(SPLINEFLAG_WALKMODE); _setTargetLocation(owner); float x,y,z; i_destinationHolder.GetDestination(x,y,z); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly() && !(((Creature*)&owner)->canWalk() && ((Creature*)&owner)->IsAtGroundLevel(x,y,z))) owner.AddSplineFlag(SPLINEFLAG_UNKNOWN7); }
void FollowMovementGenerator<Creature>::Initialize(Creature &owner) { owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE); _updateWalkMode(owner); _updateSpeed(owner); _setTargetLocation(owner); float x,y,z; i_destinationHolder.GetDestination(x,y,z); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly() && !(((Creature*)&owner)->canWalk() && ((Creature*)&owner)->IsAtGroundLevel(x,y,z))) owner.AddSplineFlag(SPLINEFLAG_UNKNOWN7); }
void JustDied(Unit* killer) { Creature* deathcharger = me->FindNearestCreature(28782, 30); if (!deathcharger) return; if (killer->GetTypeId() == TYPEID_PLAYER && deathcharger->GetTypeId() == TYPEID_UNIT && deathcharger->IsVehicle()) { deathcharger->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); deathcharger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); deathcharger->setFaction(2096); me->ExitVehicle(); CAST_PLR(killer)->GroupEventHappens(12687, me); if (CAST_PLR(killer)->HasAura(REALM_OF_SHADOWS)) killer->RemoveAurasDueToSpell(REALM_OF_SHADOWS); me->DespawnOrUnsummon(); } }
static void RewardGroupAtKill_helper(Player* pGroupGuy, Unit* pVictim, uint32 count, bool PvP, float group_rate, uint32 sum_level, bool is_dungeon, Player* not_gray_member_with_max_level, Player* member_with_max_level, uint32 xp) { // honor can be in PvP and !PvP (racial leader) cases (for alive) if (pGroupGuy->isAlive()) pGroupGuy->RewardHonor(pVictim, count); // xp and reputation only in !PvP case // xp and reputation only in !PvP case if (!PvP) { if (pVictim->GetTypeId() == TYPEID_UNIT) { Creature* creatureVictim = static_cast<Creature*>(pVictim); float rate = group_rate * float(pGroupGuy->getLevel()) / sum_level; // if is in dungeon then all receive full reputation at kill // rewarded any alive/dead/near_corpse group member pGroupGuy->RewardReputation(creatureVictim, is_dungeon ? 1.0f : rate); // XP updated only for alive group member if (pGroupGuy->isAlive() && not_gray_member_with_max_level && pGroupGuy->getLevel() <= not_gray_member_with_max_level->getLevel()) { uint32 itr_xp = (member_with_max_level == not_gray_member_with_max_level) ? uint32(xp * rate) : uint32((xp * rate / 2) + 1); pGroupGuy->GiveXP(itr_xp, creatureVictim, group_rate); if (Pet* pet = pGroupGuy->GetPet()) // TODO: Pets need to get exp based on their level diff to the target, not the owners. // the whole RewardGroupAtKill needs a rewrite to match up with this anyways: // http://wowwiki.wikia.com/wiki/Formulas:Mob_XP?oldid=228414 pet->GivePetXP(itr_xp); } // quest objectives updated only for alive group member or dead but with not released body if (pGroupGuy->isAlive() || !pGroupGuy->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) { // normal creature (not pet/etc) can be only in !PvP case if (creatureVictim->GetTypeId() == TYPEID_UNIT) if (CreatureInfo const* normalInfo = creatureVictim->GetCreatureInfo()) pGroupGuy->KilledMonster(normalInfo, creatureVictim->GetObjectGuid()); } } } }
void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) { sLog->outDetail("CMSG_PET_SPELL_AUTOCAST"); uint64 guid; uint32 spellid; uint8 state; //1 for on, 0 for off recvPacket >> guid >> spellid >> state; if (!_player->GetGuardianPet() && !_player->GetCharm()) return; if (ObjectAccessor::FindPlayer(guid)) return; Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if (!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm())) { sLog->outError( "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName()); return; } // do not add not learned spells/ passive spells if (!pet->HasSpell(spellid) || IsAutocastableSpell(spellid)) return; CharmInfo *charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog->outError( "WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } if (pet->isPet()) ((Pet*) pet)->ToggleAutocast(spellid, state); else pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state); charmInfo->SetSpellAutocast(spellid, state); }
void HomeMovementGenerator<Creature>::_setTargetLocation(Creature& owner) { if (owner.hasUnitState(UNIT_STAT_NOT_MOVE)) return; Movement::MoveSplineInit<Unit*> init(owner); float x, y, z, o; // at apply we can select more nice return points base at current movegen if (owner.GetMotionMaster()->empty() || !owner.GetMotionMaster()->CurrentMovementGenerator()->GetResetPosition(owner, x, y, z, o)) owner.GetRespawnCoord(x, y, z, &o); init.SetFacing(o); init.MoveTo(x, y, z, true); init.SetSmooth(); // fix broken fly movement for old creatures //init.SetWalk(false); // hack for old creatures with bugged fly animation bool bSetWalk = (owner.GetTypeId() == TYPEID_UNIT && owner.IsLevitating() && owner.GetFloatValue(UNIT_FIELD_HOVERHEIGHT) == 0.0f); init.SetWalk(bSetWalk); init.Launch(); m_arrived = false; owner.clearUnitState(UNIT_STAT_ALL_DYN_STATES); }
bool ChatHandler::HandleCreatePetCommand(const char* /*args*/) { Player* player = m_session->GetPlayer(); Creature* creatureTarget = getSelectedCreature(); if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) { PSendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); // Creatures with family 0 crashes the server if (cInfo->family == 0) { PSendSysMessage("This creature cannot be tamed. (family id: 0)."); SetSentErrorMessage(true); return false; } if (player->GetPetGUID()) { PSendSysMessage("You already have a pet"); SetSentErrorMessage(true); return false; } // Everything looks OK, create new pet Pet* pet = new Pet(player, HUNTER_PET); if (!pet->CreateBaseAtCreature(creatureTarget)) { delete pet; PSendSysMessage("Error 1"); return false; } creatureTarget->setDeathState(JUST_DIED); creatureTarget->RemoveCorpse(); creatureTarget->SetHealth(0); // just for nice GM-mode view pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); if (!pet->InitStatsForLevel(creatureTarget->getLevel())) { sLog->outError("InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); PSendSysMessage("Error 2"); delete pet; return false; } // prepare visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); // this enables pet details window (Shift+P) pet->InitPetCreateSpells(); pet->SetFullHealth(); pet->GetMap()->AddToMap(pet->ToCreature()); // visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); player->SetMinion(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); return true; }
void boss_attumen::boss_attumenAI::UpdateAI(const uint32 diff) { if (ResetTimer) { if (ResetTimer <= diff) { ResetTimer = 0; Unit *pMidnight = Unit::GetUnit(*me, Midnight); if (pMidnight) { pMidnight->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pMidnight->SetVisible(true); } Midnight = 0; me->SetVisible(false); me->Kill(me); } } else ResetTimer -= diff; //Return since we have no target if (!UpdateVictim()) return; if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return; if (CleaveTimer <= diff) { DoCast(me->getVictim(), SPELL_SHADOWCLEAVE); CleaveTimer = urand(10000, 15000); } else CleaveTimer -= diff; if (CurseTimer <= diff) { DoCast(me->getVictim(), SPELL_INTANGIBLE_PRESENCE); CurseTimer = 30000; } else CurseTimer -= diff; if (RandomYellTimer <= diff) { DoScriptText(RAND(SAY_RANDOM1, SAY_RANDOM2), me); RandomYellTimer = urand(30000, 60000); } else RandomYellTimer -= diff; if (me->GetUInt32Value(UNIT_FIELD_DISPLAYID) == MOUNTED_DISPLAYID) { if (ChargeTimer <= diff) { Unit *pTarget = NULL; std::list<HostileReference *> t_list = me->getThreatManager().getThreatList(); std::vector<Unit *> target_list; for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (pTarget && !pTarget->IsWithinDist(me, ATTACK_DISTANCE, false)) target_list.push_back(pTarget); pTarget = NULL; } if (target_list.size()) pTarget = *(target_list.begin()+rand()%target_list.size()); DoCast(pTarget, SPELL_BERSERKER_CHARGE); ChargeTimer = 20000; } else ChargeTimer -= diff; } else { if (HealthBelowPct(25)) { Creature *pMidnight = Unit::GetCreature(*me, Midnight); if (pMidnight && pMidnight->GetTypeId() == TYPEID_UNIT) { CAST_AI(boss_midnight::boss_midnightAI, (pMidnight->AI()))->Mount(me); me->SetHealth(pMidnight->GetHealth()); DoResetThreat(); } } } DoMeleeAttackIfReady(); }
void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) { DETAIL_LOG( "HandlePetSetAction. CMSG_PET_SET_ACTION" ); uint64 petguid; uint8 count; recv_data >> petguid; // FIXME: charmed case //Pet* pet = ObjectAccessor::Instance().GetPet(petguid); if(ObjectAccessor::FindPlayer(petguid)) return; Creature* pet = _player->GetMap()->GetAnyTypeCreature(petguid); if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { sLog.outError( "HandlePetSetAction: Unknown pet or pet owner." ); return; } // pet can have action bar disabled if(pet->IsPet() && ((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { sLog.outError("WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } count = (recv_data.size() == 24) ? 2 : 1; uint32 position[2]; uint32 data[2]; bool move_command = false; for(uint8 i = 0; i < count; ++i) { recv_data >> position[i]; recv_data >> data[i]; uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); //ignore invalid position if(position[i] >= MAX_UNIT_ACTION_BAR_INDEX) return; // in the normal case, command and reaction buttons can only be moved, not removed // at moving count ==2, at removing count == 1 // ignore attempt to remove command|reaction buttons (not possible at normal case) if (act_state == ACT_COMMAND || act_state == ACT_REACTION) { if (count == 1) return; move_command = true; } } // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness) if (move_command) { uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]); if(act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION) { uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]); UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]); if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() || act_state_0 != actionEntry_1->GetType()) return; } uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]); if(act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION) { uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]); UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]); if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() || act_state_1 != actionEntry_0->GetType()) return; } } for(uint8 i = 0; i < count; ++i) { uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]); uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); DETAIL_LOG( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position[i], spell_id, uint32(act_state)); //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) { //sign for autocast if(act_state == ACT_ENABLED && spell_id) { if(pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, true); else ((Pet*)pet)->ToggleAutocast(spell_id, true); } //sign for no/turn off autocast else if(act_state == ACT_DISABLED && spell_id) { if(pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, false); else ((Pet*)pet)->ToggleAutocast(spell_id, false); } charmInfo->SetActionBar(position[i],spell_id,ActiveStates(act_state)); } } }
void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) { DETAIL_LOG("CMSG_PET_SPELL_AUTOCAST"); uint64 guid; uint32 spellid; uint8 state; //1 for on, 0 for off recvPacket >> guid >> spellid >> state; if(!_player->GetPet() && !_player->GetCharm()) return; Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid); if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { sLog.outError( "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); return; } // do not add not learned spells/ passive spells if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) return; CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } if(pet->isCharmed()) //state can be used as boolean pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state); else ((Pet*)pet)->ToggleAutocast(spellid, state); charmInfo->SetSpellAutocast(spellid,state); }
void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) { sLog.outDetail("CMSG_PET_SPELL_AUTOCAST"); uint64 guid; uint16 spellid; uint16 spellid2; //maybe second spell, automatically toggled off when first toggled on? uint8 state; //1 for on, 0 for off recvPacket >> guid >> spellid >> spellid2 >> state; if (!_player->GetGuardianPet() && !_player->GetCharm()) return; if (ObjectAccessor::FindPlayer(guid)) return; Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, guid); if (!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm())) { sLog.outError("HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName()); return; } // do not add not learned spells/ passive spells if (!pet->HasSpell(spellid) || !IsAutocastableSpell(spellid)) return; CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } if (pet->IsPet()) ((Pet*)pet)->ToggleAutocast(spellid, state); else pet->GetCharmInfo()->ToggleCreatureAutocast(spellid, state); for (uint8 i = 0; i < 10; ++i) { if ((charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) && spellid == charmInfo->GetActionBarEntry(i)->SpellOrAction) charmInfo->GetActionBarEntry(i)->Type = state ? ACT_ENABLED : ACT_DISABLED; } }
void UpdateAI(const uint32 uiDiff) override { if (!pEntered) // should also be in phase zero { float x,y,z; m_creature->GetClosePoint(x, y, z, m_creature->GetObjectBoundingRadius(), 15.0f, 0.0f); if (Creature* pTemp = m_creature->SummonCreature(NPC_HEAD, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0)) HeadGUID = pTemp->GetObjectGuid(); pEntered = true; m_uiPhase = PHASE_ONE; } Creature* pHead = m_pInstance->GetSingleCreatureFromStorage(NPC_HEAD); if (!m_pInstance) return; if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_uiPhase) { case PHASE_ONE: { // he gets his head if (!m_creature->HasAura(SPELL_HEAD)) DoCast(m_creature,SPELL_HEAD,false); if (((m_creature->GetHealth()*100) / (m_creature->GetMaxHealth())) <= 1) m_uiPhase = PHASE_TWO; if (m_uiCleave_Timer <= uiDiff) { m_creature->CastSpell(m_creature->getVictim(),SPELL_CLEAVE_PROC,false); m_uiCleave_Timer = 5000; }else m_uiCleave_Timer -= uiDiff; DoMeleeAttackIfReady(); break; } case PHASE_TWO: { if (m_creature->HasAura(SPELL_HEAD)) { m_creature->RemoveAurasDueToSpell(SPELL_HEAD); // visual of head flying off body ( really head flying at target which in this case needs to be the head npc ) DoCast(pHead,SPELL_SEND_HEAD,true); } ApplyRegenAuras(); if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) if (pHead && pHead->GetTypeId() == TYPEID_UNIT && pHead->AI()) pHead->AI()->AttackStart(pTarget); if ((pHead->GetHealth()*100) / (pHead->GetMaxHealth()) <= 66) /*|| (m_creature->GetHealth()*100) / (m_creature->GetMaxHealth()) <= 100)*/ { RemoveRegenAuras(); m_uiPhase = PHASE_THREE; } break; } case PHASE_THREE: { // give him his head back ( the head will target and cast spell send head at the body will look like head flying back on to body if (!m_creature->HasAura(SPELL_HEAD)) DoCast(m_creature,SPELL_HEAD,false); if (((m_creature->GetHealth()*100) / (m_creature->GetMaxHealth())) <= 1) m_uiPhase = PHASE_FOUR; if (m_uiConflageration_Timer <= uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { DoScriptText(SAY_CONFLAGRATION,m_creature); pTarget->CastSpell(pTarget,SPELL_CONFLAGRATION,false); } m_uiConflageration_Timer = 15000; }else m_uiConflageration_Timer -= uiDiff; DoMeleeAttackIfReady(); break; } case PHASE_FOUR: { if (m_creature->HasAura(SPELL_HEAD)) { m_creature->RemoveAurasDueToSpell(SPELL_HEAD); // visual of head flying off body ( really head flying at target which in this case needs to be the head npc ) DoCast(pHead,SPELL_SEND_HEAD,true); } ApplyRegenAuras(); if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) if (pHead->AI()) pHead->AI()->AttackStart(pTarget); if ((pHead->GetHealth()*100) / (pHead->GetMaxHealth()) <= 33) /*|| (m_creature->GetHealth()*100) / (m_creature->GetMaxHealth()) <= 100)*/ { RemoveRegenAuras(); m_uiPhase = PHASE_FIVE; } break; } case PHASE_FIVE: { if (!m_creature->HasAura(SPELL_HEAD)) DoCast(m_creature,SPELL_HEAD,false); if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) if (pHead->AI()) pHead->AI()->AttackStart(pTarget); if (m_uiPumpkinSprout_Timer <= uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { DoScriptText(SAY_SPROUTING_PUMPKINS,m_creature); m_creature->CastSpell(pTarget,SPELL_SUMMON_PUMPKIN,false); } m_uiPumpkinSprout_Timer = 30000; }else m_uiPumpkinSprout_Timer -= uiDiff; if (m_uiConflageration_Timer <= uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { DoScriptText(SAY_CONFLAGRATION,m_creature); pTarget->CastSpell(pTarget,SPELL_CONFLAGRATION,false); } m_uiConflageration_Timer = 15000; }else m_uiConflageration_Timer -= uiDiff; if (((m_creature->GetHealth()*100) / (m_creature->GetMaxHealth())) <= 1) { m_uiPhase = PHASE_FOUR; DoCast(pHead,SPELL_SEND_HEAD,true); } DoMeleeAttackIfReady(); break; //default: break; } } }
void WorldSession::HandlePetSetAction(WorldPacket& recv_data) { DETAIL_LOG("HandlePetSetAction. CMSG_PET_SET_ACTION"); ObjectGuid petGuid; uint8 count; recv_data >> petGuid; Creature* pet = _player->GetMap()->GetAnyTypeCreature(petGuid); if (!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { sLog.outError("HandlePetSetAction: Unknown pet or pet owner."); return; } CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } // pet can have action bar disabled if (pet->IsPet() && charmInfo->HasState(CHARM_STATE_ACTION,ACTIONS_DISABLE)) return; // if pet is chained - used first pet action bar if (((Pet*)pet)->GetPetCounter()) return; count = (recv_data.size() == 24) ? 2 : 1; uint32 position[2]; uint32 data[2]; bool move_command = false; for (uint8 i = 0; i < count; ++i) { recv_data >> position[i]; recv_data >> data[i]; uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); // ignore invalid position if (position[i] >= MAX_UNIT_ACTION_BAR_INDEX) return; // in the normal case, command and reaction buttons can only be moved, not removed // at moving count ==2, at removing count == 1 // ignore attempt to remove command|reaction buttons (not possible at normal case) if (act_state == ACT_COMMAND || act_state == ACT_REACTION) { if (count == 1) return; move_command = true; } } // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness) if (move_command) { uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]); if (act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION) { uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]); UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]); if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() || act_state_0 != actionEntry_1->GetType()) return; } uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]); if (act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION) { uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]); UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]); if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() || act_state_1 != actionEntry_0->GetType()) return; } } for (uint8 i = 0; i < count; ++i) { uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]); uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); DETAIL_LOG("Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position[i], spell_id, uint32(act_state)); // if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if ((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && ((Pet*)pet)->HasSpell(spell_id)) { // sign for autocast on/off if (act_state == ACT_ENABLED || act_state == ACT_DISABLED) { bool enabled = act_state == ACT_ENABLED; if (pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, enabled); else { GuidSet const& groupPets = _player->GetPets(); if (!groupPets.empty()) { for (GuidSet::const_iterator itr = groupPets.begin(); itr != groupPets.end(); ++itr) { if (Pet* pPet = GetPlayer()->GetMap()->GetPet(*itr)) { if (pPet->IsInWorld()) pPet->ToggleAutocast(spell_id, enabled); } } } } } charmInfo->SetActionBar(position[i], spell_id, ActiveStates(act_state)); } } }
void UpdateAI(const uint32 diff) { if (ResetTimer) { if (ResetTimer <= diff) { ResetTimer = 0; Unit *pMidnight = Unit::GetUnit(*m_creature, Midnight); if (pMidnight) { pMidnight->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pMidnight->SetVisibility(VISIBILITY_ON); } Midnight = 0; m_creature->SetVisibility(VISIBILITY_OFF); m_creature->DealDamage(m_creature, m_creature->GetHealth(), DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } } else ResetTimer -= diff; //Return since we have no target if (!UpdateVictim()) return; if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE )) return; if (CleaveTimer < diff) { AddSpellToCast(m_creature->getVictim(), SPELL_SHADOWCLEAVE); CleaveTimer = urand(10000, 16000); } else CleaveTimer -= diff; if (CurseTimer < diff) { AddSpellToCast(m_creature->getVictim(), SPELL_INTANGIBLE_PRESENCE); CurseTimer = 30000; } else CurseTimer -= diff; if (RandomYellTimer < diff) { DoScriptText(RAND(SAY_RANDOM1, SAY_RANDOM2), m_creature); RandomYellTimer = urand(30000, 61000); } else RandomYellTimer -= diff; if (m_creature->GetUInt32Value(UNIT_FIELD_DISPLAYID) == MOUNTED_DISPLAYID) { if (ChargeTimer < diff) { if (Unit * target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100.0f, true, 0, 5.0f)) AddSpellToCast(target, SPELL_BERSERKER_CHARGE); ChargeTimer = 20000; } else ChargeTimer -= diff; } else { if ((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 25) { Creature *pMidnight = Unit::GetCreature(*m_creature, Midnight); if (pMidnight && pMidnight->GetTypeId() == TYPEID_UNIT) { ((boss_midnightAI*)(pMidnight->AI()))->Mount(m_creature); m_creature->SetHealth(pMidnight->GetHealth()); DoResetThreat(); } } } CastNextSpellIfAnyAndReady(); DoMeleeAttackIfReady(); }
void WorldSession::HandlePetSetAction(WorldPacket & recv_data) { sLog.outDetail("HandlePetSetAction. CMSG_PET_SET_ACTION"); uint64 petguid; uint32 position; uint16 spell_id; uint16 act_state; uint8 count; recv_data >> petguid; // FIXME: charmed case //Pet* pet = ObjectAccessor::Instance().GetPet(petguid); if (ObjectAccessor::FindPlayer(petguid)) return; Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid); if (!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { sLog.outError("HandlePetSetAction: Unknown pet or pet owner."); return; } CharmInfo *charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } count = (recv_data.size() == 24) ? 2 : 1; for (uint8 i = 0; i < count; i++) { recv_data >> position; recv_data >> spell_id; recv_data >> act_state; sLog.outDetail("Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, act_state); //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id))) { //sign for autocast if (act_state == ACT_ENABLED && spell_id) { if (pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, true); else ((Pet*)pet)->ToggleAutocast(spell_id, true); } //sign for no/turn off autocast else if (act_state == ACT_DISABLED && spell_id) { if (pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, false); else ((Pet*)pet)->ToggleAutocast(spell_id, false); } charmInfo->GetActionBarEntry(position)->Type = act_state; charmInfo->GetActionBarEntry(position)->SpellOrAction = spell_id; } } }
void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) { sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION" ); uint64 petguid; uint8 count; recv_data >> petguid; Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid); if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) { sLog.outError( "HandlePetSetAction: Unknown pet or pet owner." ); return; } CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { sLog.outError("WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } count = (recv_data.size() == 24) ? 2 : 1; for(uint8 i = 0; i < count; ++i) { uint32 position; uint32 data; recv_data >> position; recv_data >> data; uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data); uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data); sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, uint32(act_state)); //ignore invalid position if(position >= MAX_UNIT_ACTION_BAR_INDEX) return; //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) { //sign for autocast if(act_state == ACT_ENABLED && spell_id) { if(pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, true); else ((Pet*)pet)->ToggleAutocast(spell_id, true); } //sign for no/turn off autocast else if(act_state == ACT_DISABLED && spell_id) { if(pet->isCharmed()) charmInfo->ToggleCreatureAutocast(spell_id, false); else ((Pet*)pet)->ToggleAutocast(spell_id, false); } charmInfo->SetActionBar(position,spell_id,ActiveStates(act_state)); } } }
void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) { TC_LOG_DEBUG("network.opcode", "WORLD: Received CMSG_PET_SPELL_AUTOCAST"); ObjectGuid guid; uint32 spellid; uint8 state; //1 for on, 0 for off recvPacket >> guid >> spellid >> state; if (!_player->GetGuardianPet() && !_player->GetCharm()) return; if (guid.IsPlayer()) return; Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if (!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm())) { TC_LOG_ERROR("entities.pet", "HandlePetSpellAutocastOpcode. %s isn't pet of player %s (%s).", guid.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); return; } SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); if (!spellInfo) { TC_LOG_ERROR("spells.pet", "WORLD: unknown PET spell id %u", spellid); return; } // do not add not learned spells/ passive spells if (!pet->HasSpell(spellid) || !spellInfo->IsAutocastable()) return; CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { TC_LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().GetCounter(), pet->GetTypeId()); return; } if (pet->IsPet()) ((Pet*)pet)->ToggleAutocast(spellInfo, state != 0); else pet->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, state != 0); charmInfo->SetSpellAutocast(spellInfo, state != 0); }