void DoWaveSpawnForCreature(Creature* creature) { switch (creature->GetEntry()) { case ENTRY_BNAAR_C_CONSOLE: if (rand()%2) { add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2933.68f, 4162.55f, 164.00f, 1.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2927.36f, 4212.97f, 164.00f); } else { add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2927.36f, 4212.97f, 164.00f, 4.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2933.68f, 4162.55f, 164.00f); } Wave_Timer = 30000; break; case ENTRY_CORUU_C_CONSOLE: add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2445.21f, 2765.26f, 134.49f, 3.93f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2424.21f, 2740.15f, 133.81f); add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2429.86f, 2731.85f, 134.53f, 1.31f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2435.37f, 2766.04f, 133.81f); Wave_Timer = 20000; break; case ENTRY_DURO_C_CONSOLE: add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2986.80f, 2205.36f, 165.37f, 3.74f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2985.15f, 2197.32f, 164.79f); add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2952.91f, 2191.20f, 165.32f, 0.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 2060.01f, 2185.27f, 164.67f); Wave_Timer = 15000; break; case ENTRY_ARA_C_CONSOLE: if (rand()%2) { add = me->SummonCreature(ENTRY_ARA_TECH, 4035.11f, 4038.97f, 194.27f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); add = me->SummonCreature(ENTRY_ARA_TECH, 4033.66f, 4036.79f, 194.28f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); add = me->SummonCreature(ENTRY_ARA_TECH, 4037.13f, 4037.30f, 194.23f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); } else { add = me->SummonCreature(ENTRY_ARA_TECH, 3099.59f, 4049.30f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); add = me->SummonCreature(ENTRY_ARA_TECH, 3999.72f, 4046.75f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); add = me->SummonCreature(ENTRY_ARA_TECH, 3996.81f, 4048.26f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); } Wave_Timer = 15000; break; } }
void UpdateAI(const uint32 diff) { if (!me->isInCombat()) { if (instance) { // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. if ((instance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35))) { me->SetVisible(false); me->setFaction(35); } else if ((instance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35))) { me->setFaction(1720); me->SetVisible(true); } } if (DrainNordrassilTimer <= diff) { if (!IsChanneling) { Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000); if (temp) WorldTreeGUID = temp->GetGUID(); if (Unit* Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) { Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Nordrassil->SetDisplayId(11686); DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); IsChanneling = true; } } if (Unit* Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) { Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); DrainNordrassilTimer = 1000; } } else DrainNordrassilTimer -= diff; } if (!UpdateVictim()) return; if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged) BelowTenPercent = true; if (!Enraged) { if (EnrageTimer <= diff) { if (HealthAbovePct(10)) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); Enraged = true; Talk(SAY_ENRAGE); } } else EnrageTimer -= diff; if (CheckDistanceTimer <= diff) { // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000); if (Check) { Check->SetVisible(false); if (me->IsWithinDistInMap(Check, 75)) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); Enraged = true; Talk(SAY_ENRAGE); } } CheckDistanceTimer = 5000; } else CheckDistanceTimer -= diff; } if (BelowTenPercent) { if (!HasProtected) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); //all members of raid must get this buff DoCastVictim(SPELL_PROTECTION_OF_ELUNE, true); HasProtected = true; Enraged = true; } if (SummonWispTimer <= diff) { DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand()%40), float(rand()%40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); SummonWispTimer = 1500; ++WispCount; } else SummonWispTimer -= diff; if (WispCount >= 30) me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } if (Enraged) { // If protection active, do nothing if (HasProtected) return; if (HandOfDeathTimer <= diff) { DoCast(me->getVictim(), SPELL_HAND_OF_DEATH); HandOfDeathTimer = 2000; } else HandOfDeathTimer -= diff; return; // Don't do anything after this point. } if (SoulChargeCount) { if (SoulChargeTimer <= diff) UnleashSoulCharge(); else SoulChargeTimer -= diff; } if (GripOfTheLegionTimer <= diff) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); GripOfTheLegionTimer = urand(5000, 25000); } else GripOfTheLegionTimer -= diff; if (AirBurstTimer <= diff) { Talk(SAY_AIR_BURST); DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank AirBurstTimer = urand(25000, 40000); } else AirBurstTimer -= diff; if (FearTimer <= diff) { DoCast(me->getVictim(), SPELL_FEAR); FearTimer = 42000; } else FearTimer -= diff; if (DoomfireTimer <= diff) { Talk(SAY_DOOMFIRE); Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!temp) temp = me->getVictim(); //replace with spell cast 31903 once implicitTarget 73 implemented SummonDoomfire(temp); //supposedly three doomfire can be up at the same time DoomfireTimer = 20000; } else DoomfireTimer -= diff; if (MeleeRangeCheckTimer <= diff) { if (CanUseFingerOfDeath()) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); MeleeRangeCheckTimer = 1000; } MeleeRangeCheckTimer = 5000; } else MeleeRangeCheckTimer -= diff; DoMeleeAttackIfReady(); }
//this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_SELL_ITEM"); uint64 auctioneer, item; uint64 bid, buyout; uint32 etime, count; uint32 unk = 1; recv_data >> auctioneer; // uint64 recv_data >> unk; // 1 recv_data >> item; // uint64 recv_data >> count; // 3.2.2, number of items being auctioned recv_data >> bid; // uint64, 4.0.6 recv_data >> buyout; // uint64, 4.0.6 recv_data >> etime; // uint32 Player* player = GetPlayer(); if (!item || !bid || !etime) return; //check for cheaters Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer))); return; } AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction()); if (!auctionHouseEntry) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer))); return; } // client send time in minutes, convert to common used sec time etime *= MINUTE; // client understand only 3 auction time switch (etime) { case 1 * MIN_AUCTION_TIME: case 2 * MIN_AUCTION_TIME: case 4 * MIN_AUCTION_TIME: break; default: return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); Item* it = player->GetItemByGuid(item); //do not allow to sell already auctioned items if (sAuctionMgr->GetAItem(GUID_LOPART(item))) { sLog->outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", player->GetName(), GUID_LOPART(item)); SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction) if (!it) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_ITEM_NOT_FOUND); return; } if (!it->CanBeTraded()) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } if (it->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } if (it->IsNotEmptyBag()) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); //we have to take deposit : uint64 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, it, count); if (!player->HasEnoughMoney(deposit)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_NOT_ENOUGH_MONEY); return; } if (AccountMgr::IsGMAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), count); } player->ModifyMoney(-int32(deposit)); uint32 auction_time = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME)); AuctionEntry* AH = new AuctionEntry; AH->Id = sObjectMgr->GenerateAuctionID(); if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) AH->auctioneer = 23442; else AH->auctioneer = GUID_LOPART(auctioneer); AH->item_guidlow = GUID_LOPART(item); AH->item_template = it->GetEntry(); AH->owner = player->GetGUIDLow(); AH->startbid = (bid >> 32); AH->bidder = 0; AH->bid = 0; AH->buyout = (buyout >> 32); AH->expire_time = time(NULL) + auction_time; AH->deposit = (deposit >> 32); AH->auctionHouseEntry = auctionHouseEntry; sLog->outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), AH->auctioneer, bid, buyout, auction_time, AH->GetHouseId()); sAuctionMgr->AddAItem(it); auctionHouse->AddAuction(AH); player->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); it->DeleteFromInventoryDB(trans); it->SaveToDB(trans); // recursive and not have transaction guard into self, not in inventiory and can be save standalone AH->SaveToDB(trans); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); }
void UpdateAI(uint32 diff) override { //Check if we have a target if (!UpdateVictim()) return; uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE); if (currentPhase == PHASE_EYE_GREEN_BEAM || currentPhase == PHASE_EYE_RED_BEAM) { // EyeTentacleTimer if (EyeTentacleTimer <= diff) { //Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 20); //south SpawnEyeTentacle(10, 10); //south west SpawnEyeTentacle(20, 0); //west SpawnEyeTentacle(10, -10); //north west SpawnEyeTentacle(0, -20); //north SpawnEyeTentacle(-10, -10); //north east SpawnEyeTentacle(-20, 0); // east SpawnEyeTentacle(-10, 10); // south east EyeTentacleTimer = 45000; } else EyeTentacleTimer -= diff; } switch (currentPhase) { case PHASE_EYE_GREEN_BEAM: //BeamTimer if (BeamTimer <= diff) { //SPELL_GREEN_BEAM if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->InterruptNonMeleeSpells(false); DoCast(target, SPELL_GREEN_BEAM); //Correctly update our target me->SetTarget(target->GetGUID()); } //Beam every 3 seconds BeamTimer = 3000; } else BeamTimer -= diff; //ClawTentacleTimer if (ClawTentacleTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = me->SummonCreature(NPC_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500); if (Spawned && Spawned->AI()) Spawned->AI()->AttackStart(target); } //One claw tentacle every 12.5 seconds ClawTentacleTimer = 12500; } else ClawTentacleTimer -= diff; //PhaseTimer if (PhaseTimer <= diff) { //Switch to Dark Beam instance->SetData(DATA_CTHUN_PHASE, PHASE_EYE_RED_BEAM); me->InterruptNonMeleeSpells(false); me->SetReactState(REACT_PASSIVE); //Remove any target me->SetTarget(ObjectGuid::Empty); //Select random target for dark beam to start on if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { //Face our target DarkGlareAngle = me->GetAngle(target); DarkGlareTickTimer = 1000; DarkGlareTick = 0; ClockWise = RAND(true, false); } //Add red coloration to C'thun DoCast(me, SPELL_RED_COLORATION, true); //Freeze animation DoCast(me, SPELL_FREEZE_ANIM); me->SetOrientation(DarkGlareAngle); me->StopMoving(); //Darkbeam for 35 seconds PhaseTimer = 35000; } else PhaseTimer -= diff; break; case PHASE_EYE_RED_BEAM: if (DarkGlareTick < 35) { if (DarkGlareTickTimer <= diff) { //Set angle and cast if (ClockWise) me->SetOrientation(DarkGlareAngle + DarkGlareTick * float(M_PI) / 35); else me->SetOrientation(DarkGlareAngle - DarkGlareTick * float(M_PI) / 35); me->StopMoving(); //Actual dark glare cast, maybe something missing here? DoCast(me, SPELL_DARK_GLARE, false); //Increase tick ++DarkGlareTick; //1 second per tick DarkGlareTickTimer = 1000; } else DarkGlareTickTimer -= diff; } //PhaseTimer if (PhaseTimer <= diff) { //Switch to Eye Beam instance->SetData(DATA_CTHUN_PHASE, PHASE_EYE_GREEN_BEAM); BeamTimer = 3000; ClawTentacleTimer = 12500; //4 per Eye beam phase (unsure if they spawn during Dark beam) me->InterruptNonMeleeSpells(false); //Remove Red coloration from c'thun me->RemoveAurasDueToSpell(SPELL_RED_COLORATION); me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM); //set it back to aggressive me->SetReactState(REACT_AGGRESSIVE); //Eye Beam for 50 seconds PhaseTimer = 50000; } else PhaseTimer -= diff; break; //Transition phase case PHASE_CTHUN_TRANSITION: //Remove any target me->SetTarget(ObjectGuid::Empty); me->SetHealth(0); me->SetVisible(false); break; //Dead phase case PHASE_CTHUN_DONE: Creature* pPortal= me->FindNearestCreature(NPC_CTHUN_PORTAL, 10); if (pPortal) pPortal->DespawnOrUnsummon(); me->DespawnOrUnsummon(); break; } }
void UpdateFollowerAI(uint32 Diff) { if (!UpdateVictim()) { //we are doing the post-event, or... if (HasFollowState(STATE_FOLLOW_POSTEVENT)) { if (PostEventTimer <= Diff) { PostEventTimer = 5000; Creature* torta = Creature::GetCreature(*me, TortaGUID); if (!torta || !torta->isAlive()) { //something happened, so just complete SetFollowComplete(); return; } switch (PhasePostEvent) { case 1: Talk(SAY_TOOG_POST_1); break; case 2: torta->AI()->Talk(SAY_TORT_POST_2); break; case 3: Talk(SAY_TOOG_POST_3); break; case 4: torta->AI()->Talk(SAY_TORT_POST_4); break; case 5: Talk(SAY_TOOG_POST_5); break; case 6: torta->AI()->Talk(SAY_TORT_POST_6); me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, ToWaterLoc); break; } ++PhasePostEvent; } else PostEventTimer -= Diff; } //...we are doing regular speech check else if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { if (CheckSpeechTimer <= Diff) { CheckSpeechTimer = 5000; if (urand(0, 9) > 8) Talk(SAY_TOOG_WORRIED); } else CheckSpeechTimer -= Diff; } return; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (uiPhase) { if (uiTimer <= uiDiff) { switch (uiPhase) { case 1: DoScriptText(SAY_QUEST_ACCEPT_ATTACK, m_creature); uiTimer = 3000; uiPhase = 2; break; case 2: if (pTyrion) DoScriptText(SAY_TYRION_1, pTyrion); uiTimer = 3000; uiPhase = 3; break; case 3: m_creature->UpdateEntry(NPC_PRIESTESS_TYRIONA, ALLIANCE); uiTimer = 2000; uiPhase = 4; break; case 4: SetEscortPaused(false); uiPhase = 0; uiTimer = 0; break; case 5: if (Creature* pGuard = m_creature->FindNearestCreature(NPC_STORMWIND_ROYAL, 10.0f, true)) DoScriptText(SAY_GUARD_1, pGuard); uiTimer = 3000; uiPhase = 6; break; case 6: DoScriptText(SAY_SPYBOT_2, m_creature); uiTimer = 3000; uiPhase = 7; break; case 7: SetEscortPaused(false); uiTimer = 0; uiPhase = 0; break; case 8: if (pLescovar) DoScriptText(SAY_LESCOVAR_1, pLescovar); uiTimer = 3000; uiPhase = 9; break; case 9: DoScriptText(SAY_SPYBOT_4, m_creature); uiTimer = 3000; uiPhase = 10; break; case 10: if (pLescovar && pLescovar->isAlive()) { if (Player* pPlayer = GetPlayerForEscort()) CAST_AI(npc_lord_gregor_lescovarAI,pLescovar->AI())->Start(false, false, pPlayer->GetGUID()); CAST_AI(npc_lord_gregor_lescovarAI, pLescovar->AI())->SetMaxPlayerDistance(200.0f); } m_creature->DisappearAndDie(); uiTimer = 0; uiPhase = 0; break; } } else uiTimer -= uiDiff; } npc_escortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; DoMeleeAttackIfReady(); }
void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) { uint32 random = rand()%4; float SpawnLoc[3]; for (uint8 i = 0; i < 3; ++i) { SpawnLoc[i] = Base[random][i]; } Creature* creature = NULL; switch (entry) { case 17906: //GARGOYLE if (!FirstBossDead && (WaveCount == 1 || WaveCount == 3)) {//summon at tower creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0]+irand(-20, 20), SpawnPointSpecial[SPAWN_NEAR_TOWER][1]+irand(-20, 20), SpawnPointSpecial[SPAWN_NEAR_TOWER][2]+irand(-10, 10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); if (creature) CAST_AI(hyjal_trashAI, creature->AI())->useFlyPath = true; } else {//summon at gate creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_GARG_GATE][0]+irand(-10, 10), SpawnPointSpecial[SPAWN_GARG_GATE][1]+irand(-10, 10), SpawnPointSpecial[SPAWN_GARG_GATE][2]+irand(-10, 10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); } break; case 17907: //FROST_WYRM, if (FirstBossDead && WaveCount == 1) //summon at gate creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_WYRM_GATE][0], SpawnPointSpecial[SPAWN_WYRM_GATE][1], SpawnPointSpecial[SPAWN_WYRM_GATE][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); else { creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0], SpawnPointSpecial[SPAWN_NEAR_TOWER][1], SpawnPointSpecial[SPAWN_NEAR_TOWER][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); if (creature) CAST_AI(hyjal_trashAI, creature->AI())->useFlyPath = true; } break; case 17908: //GIANT_INFERNAL ++InfernalCount; if (InfernalCount > 7) InfernalCount = 0; creature = me->SummonCreature(entry, InfernalPos[InfernalCount][0], InfernalPos[InfernalCount][1], InfernalPos[InfernalCount][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); break; default: creature = me->SummonCreature(entry, SpawnLoc[0], SpawnLoc[1], SpawnLoc[2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); break; } if (creature) { // Increment Enemy Count to be used in World States and instance script ++EnemyCount; creature->SetWalk(false); creature->setActive(true); switch (entry) { case NECROMANCER: case ABOMINATION: case GHOUL: case BANSHEE: case CRYPT_FIEND: case GARGOYLE: case FROST_WYRM: case GIANT_INFERNAL: case FEL_STALKER: case RAGE_WINTERCHILL: case ANETHERON: case KAZROGAL: case AZGALOR: CAST_AI(hyjal_trashAI, creature->AI())->IsEvent = true; break; } if (instance) { if (instance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE) creature->SetDisableReputationGain(true);//no repu for solo farming } // Check if Creature is a boss. if (creature->isWorldBoss()) { if (!FirstBossDead) BossGUID[0] = creature->GetGUID(); else BossGUID[1] = creature->GetGUID(); CheckTimer = 5000; } } }
//this void is called when player clicks on search button void WorldSession::HandleAuctionListItems(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_ITEMS"); std::string searchedname; uint8 levelmin, levelmax, usable; uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; ObjectGuid guid; recvData >> guid; recvData >> listfrom; // start, used for page control listing by 50 elements recvData >> searchedname; recvData >> levelmin >> levelmax; recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; recvData >> quality >> usable; recvData.read_skip<uint8>(); // unk // this block looks like it uses some lame byte packing or similar... uint8 unkCnt; recvData >> unkCnt; for (uint8 i = 0; i < unkCnt; i++) { recvData.read_skip<uint8>(); recvData.read_skip<uint8>(); } Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionListItems - %s not found or you can't interact with him.", guid.ToString().c_str()); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); TC_LOG_DEBUG("auctionHouse", "Auctionhouse search (%s) list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid.ToString().c_str(), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4)); uint32 count = 0; uint32 totalcount = 0; data << (uint32) 0; // converting string that we try to find to lower case std::wstring wsearchedname; if (!Utf8toWStr(searchedname, wsearchedname)) return; wstrToLower(wsearchedname); auctionHouse->BuildListAuctionItems(data, _player, wsearchedname, listfrom, levelmin, levelmax, usable, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, count, totalcount); data.put<uint32>(0, count); data << (uint32) totalcount; data << (uint32) 300; // unk 2.3.0 const? SendPacket(&data); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; switch(Phase) { case 0: { // *Heroic mode only: if (IsHeroic()) { if (PyroblastTimer <= diff) { me->InterruptSpell(CURRENT_CHANNELED_SPELL); me->InterruptSpell(CURRENT_GENERIC_SPELL); DoCast(me, SPELL_SHOCK_BARRIER, true); DoCast(me->getVictim(), SPELL_PYROBLAST); PyroblastTimer = 60000; } else PyroblastTimer -= diff; } if (FireballTimer <= diff) { DoCast(me->getVictim(), SPELL_FIREBALL_NORMAL); FireballTimer = urand(2000,6000); } else FireballTimer -= diff; if (PhoenixTimer <= diff) { Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1); uint8 random = urand(1,2); float x = KaelLocations[random][0]; float y = KaelLocations[random][1]; Creature* Phoenix = me->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); if (Phoenix) { Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); SetThreatList(Phoenix); Phoenix->AI()->AttackStart(pTarget); } DoScriptText(SAY_PHOENIX, me); PhoenixTimer = 60000; } else PhoenixTimer -= diff; if (FlameStrikeTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { me->InterruptSpell(CURRENT_CHANNELED_SPELL); me->InterruptSpell(CURRENT_GENERIC_SPELL); DoCast(pTarget, SPELL_FLAMESTRIKE3, true); DoScriptText(SAY_FLAMESTRIKE, me); } FlameStrikeTimer = urand(15000,25000); } else FlameStrikeTimer -= diff; // Below 50% if (me->GetMaxHealth() * 0.5 > me->GetHealth()) { me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true); me->StopMoving(); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); GravityLapseTimer = 0; GravityLapsePhase = 0; Phase = 1; } DoMeleeAttackIfReady(); } break; case 1: { if (GravityLapseTimer <= diff) { switch(GravityLapsePhase) { case 0: if (FirstGravityLapse) // Different yells at 50%, and at every following Gravity Lapse { DoScriptText(SAY_GRAVITY_LAPSE, me); FirstGravityLapse = false; if (pInstance) { pInstance->HandleGameObject(pInstance->GetData64(DATA_KAEL_STATUE_LEFT), true); pInstance->HandleGameObject(pInstance->GetData64(DATA_KAEL_STATUE_RIGHT), true); } }else { DoScriptText(SAY_RECAST_GRAVITY, me); } DoCast(me, SPELL_GRAVITY_LAPSE_INITIAL); GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell GravityLapsePhase = 1; break; case 1: TeleportPlayersToSelf(); GravityLapseTimer = 1000; GravityLapsePhase = 2; break; case 2: CastGravityLapseKnockUp(); GravityLapseTimer = 1000; GravityLapsePhase = 3; break; case 3: CastGravityLapseFly(); GravityLapseTimer = 30000; GravityLapsePhase = 4; for (uint8 i = 0; i < 3; ++i) { Unit *pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); if (Orb && pTarget) { Orb->SetSpeed(MOVE_RUN, 0.5f); Orb->AddThreat(pTarget, 1000000.0f); Orb->AI()->AttackStart(pTarget); } } DoCast(me, SPELL_GRAVITY_LAPSE_CHANNEL); break; case 4: me->InterruptNonMeleeSpells(false); DoScriptText(SAY_TIRED, me); DoCast(me, SPELL_POWER_FEEDBACK); RemoveGravityLapse(); GravityLapseTimer = 10000; GravityLapsePhase = 0; break; } } else GravityLapseTimer -= diff; } break; } }
//this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_PLACE_BID"); ObjectGuid auctioneer; uint32 auctionId; uint32 price; recvData >> auctioneer; recvData >> auctionId >> price; if (!auctionId || !price) return; //check for cheaters Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - %s not found or you can't interact with him.", auctioneer.ToString().c_str()); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); AuctionEntry* auction = auctionHouse->GetAuction(auctionId); Player* player = GetPlayer(); if (!auction || auction->owner == player->GetGUIDLow()) { //you cannot bid your own auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN); return; } // impossible have online own another character (use this for speedup check in case online owner) ObjectGuid ownerGuid(HIGHGUID_PLAYER, auction->owner); Player* auction_owner = ObjectAccessor::FindPlayer(ownerGuid); if (!auction_owner && sObjectMgr->GetPlayerAccountIdByGUID(ownerGuid) == player->GetSession()->GetAccountId()) { //you cannot bid your another character auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN); return; } // cheating if (price <= auction->bid || price < auction->startbid) return; // price too low for next bid if not buyout if ((price < auction->buyout || auction->buyout == 0) && price < auction->bid + auction->GetAuctionOutBid()) { //auction has already higher bid, client tests it! return; } if (!player->HasEnoughMoney(price)) { //you don't have enought money!, client tests! //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); return; } SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (price < auction->buyout || auction->buyout == 0) { if (auction->bidder > 0) { if (auction->bidder == player->GetGUIDLow()) player->ModifyMoney(-int32(price - auction->bid)); else { // mail to last bidder and return money sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans); player->ModifyMoney(-int32(price)); } } else player->ModifyMoney(-int32(price)); auction->bidder = player->GetGUIDLow(); auction->bid = price; GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_AUCTION_BID); stmt->setUInt32(0, auction->bidder); stmt->setUInt32(1, auction->bid); stmt->setUInt32(2, auction->Id); trans->Append(stmt); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, ERR_AUCTION_OK, 0); } else { //buyout: if (player->GetGUIDLow() == auction->bidder) player->ModifyMoney(-int32(auction->buyout - auction->bid)); else { player->ModifyMoney(-int32(auction->buyout)); if (auction->bidder) //buyout for bidded auction .. sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans); } auction->bidder = player->GetGUIDLow(); auction->bid = auction->buyout; GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); //- Mails must be under transaction control too to prevent data loss sAuctionMgr->SendAuctionSalePendingMail(auction, trans); sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); sAuctionMgr->SendAuctionWonMail(auction, trans); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, ERR_AUCTION_OK); auction->DeleteFromDB(trans); sAuctionMgr->RemoveAItem(auction->itemGUIDLow); auctionHouse->RemoveAuction(auction); } player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
//this void is called when auction_owner cancels his auction void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_REMOVE_ITEM"); ObjectGuid auctioneer; uint32 auctionId; recvData >> auctioneer; recvData >> auctionId; //TC_LOG_DEBUG("Cancel AUCTION AuctionID: %u", auctionId); Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - %s not found or you can't interact with him.", auctioneer.ToString().c_str()); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); AuctionEntry* auction = auctionHouse->GetAuction(auctionId); Player* player = GetPlayer(); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (auction && auction->owner == player->GetGUIDLow()) { Item* pItem = sAuctionMgr->GetAItem(auction->itemGUIDLow); if (pItem) { if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid { uint32 auctionCut = auction->GetAuctionCut(); if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed return; //some auctionBidderNotification would be needed, but don't know that parts.. sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans); player->ModifyMoney(-int32(auctionCut)); } // item will deleted or added to received mail list MailDraft(auction->BuildAuctionMailSubject(AUCTION_CANCELED), AuctionEntry::BuildAuctionMailBody(0, 0, auction->buyout, auction->deposit, 0)) .AddItem(pItem) .SendMailTo(trans, player, auction, MAIL_CHECK_MASK_COPIED); } else { TC_LOG_ERROR("network", "Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->itemGUIDLow); SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR); return; } } else { SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR); //this code isn't possible ... maybe there should be assert TC_LOG_ERROR("network", "CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", player->GetGUIDLow(), auctionId); return; } //inform player, that auction is removed SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, ERR_AUCTION_OK); // Now remove the auction player->SaveInventoryAndGoldToDB(trans); auction->DeleteFromDB(trans); CharacterDatabase.CommitTransaction(trans); sAuctionMgr->RemoveAItem(auction->itemGUIDLow); auctionHouse->RemoveAuction(auction); }
//this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) { ObjectGuid auctioneer; uint32 itemsCount, etime, bid, buyout; recvData >> auctioneer; recvData >> itemsCount; ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot uint32 count[MAX_AUCTION_ITEMS]; memset(count, 0, sizeof(count)); if (itemsCount > MAX_AUCTION_ITEMS) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); recvData.rfinish(); return; } for (uint32 i = 0; i < itemsCount; ++i) { recvData >> itemGUIDs[i]; recvData >> count[i]; if (!itemGUIDs[i] || !count[i] || count[i] > 1000) { recvData.rfinish(); return; } } recvData >> bid; recvData >> buyout; recvData >> etime; if (!bid || !etime) return; if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUIDLow()); SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) not found or you can't interact with him.", auctioneer.ToString().c_str()); return; } AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction()); if (!auctionHouseEntry) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) has wrong faction.", auctioneer.ToString().c_str()); return; } etime *= MINUTE; switch (etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: break; default: return; } if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); Item* items[MAX_AUCTION_ITEMS]; uint32 finalCount = 0; uint32 itemEntry = 0; for (uint32 i = 0; i < itemsCount; ++i) { Item* item = _player->GetItemByGuid(itemGUIDs[i]); if (!item) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_ITEM_NOT_FOUND); return; } if (itemEntry == 0) itemEntry = item->GetTemplate()->ItemId; if (sAuctionMgr->GetAItem(item->GetGUIDLow()) || !item->CanBeTraded() || item->IsNotEmptyBag() || item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION) || item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } items[i] = item; finalCount += count[i]; } if (!finalCount) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } // check if there are 2 identical guids, in this case user is most likely cheating for (uint32 i = 0; i < itemsCount - 1; ++i) { for (uint32 j = i + 1; j < itemsCount; ++j) { if (itemGUIDs[i] == itemGUIDs[j]) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } } } for (uint32 i = 0; i < itemsCount; ++i) { Item* item = items[i]; if (item->GetMaxStackCount() < finalCount) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } } Item* item = items[0]; uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME)); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount); if (!_player->HasEnoughMoney(deposit)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY); return; } AuctionEntry* AH = new AuctionEntry(); if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) AH->auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD else AH->auctioneer = auctioneer.GetCounter(); // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (itemsCount == 1 && item->GetCount() == count[0]) { if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount()); } AH->Id = sObjectMgr->GenerateAuctionID(); AH->itemGUIDLow = item->GetGUIDLow(); AH->itemEntry = item->GetEntry(); AH->itemCount = item->GetCount(); AH->owner = _player->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(), AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(AH); _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(trans); item->SaveToDB(trans); AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, ERR_AUCTION_OK); GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size { Item* newItem = item->CloneItem(finalCount, _player); if (!newItem) { TC_LOG_ERROR("network", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item %u", item->GetEntry()); SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); delete AH; return; } if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount()); } AH->Id = sObjectMgr->GenerateAuctionID(); AH->itemGUIDLow = newItem->GetGUIDLow(); AH->itemEntry = newItem->GetEntry(); AH->itemCount = newItem->GetCount(); AH->owner = _player->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(newItem); auctionHouse->AddAuction(AH); for (uint32 j = 0; j < itemsCount; ++j) { Item* item2 = items[j]; // Item stack count equals required count, ready to delete item - cloned item will be used for auction if (item2->GetCount() == count[j]) { _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item2->DeleteFromInventoryDB(trans); item2->DeleteFromDB(trans); CharacterDatabase.CommitTransaction(trans); delete item2; } else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction { item2->SetCount(item2->GetCount() - count[j]); item2->SetState(ITEM_CHANGED, _player); _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]); item2->SendUpdateToPlayer(_player); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item2->SaveToDB(trans); CharacterDatabase.CommitTransaction(trans); } } SQLTransaction trans = CharacterDatabase.BeginTransaction(); newItem->SaveToDB(trans); AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, ERR_AUCTION_OK); GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } _player->ModifyMoney(-int32(deposit)); }
void UpdateAI(uint32 uiDiff) { if (!UpdateVictim()) return; if (me->GetPower(POWER_ENERGY) < 0) me->SetPower(POWER_ENERGY, 0); if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (me->GetPower(POWER_ENERGY) == 100) { me->RemoveFlag(UNIT_FIELD_FLAGS, 512); me->RemoveAura(SPELL_SELF_ROOT); me->RemoveAura(SPELL_BLESSING_RECHARGE); blessing = false; } if (m_uiSunStrikeTimer <= uiDiff && blessing == false) { Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0); if(victim) { DoCast(victim, SPELL_SUN_STRIKE); me->AddAura(SPELL_SUN_STRIKE_PERIODIC, victim); } m_uiSunStrikeTimer = urand(11000, 14000); } else m_uiSunStrikeTimer -= uiDiff; if (m_uiWindsTimer <= uiDiff && blessing == false) { if(Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) DoCast(victim, SPELL_SOLAR_WINDS); m_uiWindsTimer = urand(9000, 15000); } else m_uiWindsTimer -= uiDiff; if (m_uiLeapTimer <= uiDiff && blessing == false) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) { me->MonsterTextEmote(SAY_JUMP, NULL, true); me->AddThreat(pTarget, 9000.0f); DoCast(pTarget, SPELL_INFERNO_LEAP_MOB_SUMMON); DoCast(pTarget, SPELL_INFERNO_LEAP_CAST_TIME); leap_timer = 1500; leap = true; Creature* Summoned = me->FindNearestCreature(NPC_INFERNO_LEAP, 100, true); if (Summoned) { Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Summoned->SetFloatValue(OBJECT_FIELD_SCALE_X, Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.5f); Summoned->setFaction(me->getFaction()); Summoned->SetLevel(me->getLevel()); } m_uiLeapTimer = urand(18000, 22000); } } else m_uiLeapTimer -= uiDiff; if (leap_timer <= uiDiff && leap == true) { DoCastVictim(SPELL_INFERNO_LEAP); leap = false; } else leap_timer -= uiDiff; if (m_uiSunOrbTimer <= uiDiff && blessing == false) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) DoCast(pTarget, SPELL_SUMMON_ORB); m_uiSunOrbTimer = urand(24000, 31000); } else m_uiSunOrbTimer -= uiDiff; if (me->GetPower(POWER_ENERGY) == 0) { me->MonsterTextEmote(SAY_ANNOUNCE, NULL, true); DoCast(me, SPELL_BLESSING_RECHARGE); blessing = true; me->SetFlag(UNIT_FIELD_FLAGS, 512); me->AddAura(SPELL_SELF_ROOT, me); Talk(SAY_BLESSING); } if(!me->HasAura(SPELL_BLESSING_RECHARGE)) DoMeleeAttackIfReady(); }
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); }
void EnterCombat(Unit* pWho) { if (pMarzon && pMarzon->isAlive() && !pMarzon->isInCombat()) pMarzon->AI()->AttackStart(pWho); }
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) return false; 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 UpdateAI(const uint32 uiDiff) { if (uiPhase) { if (uiTimer <= uiDiff) { switch (uiPhase) { case 1: if (Creature* pGuard = m_creature->FindNearestCreature(NPC_STORMWIND_ROYAL, 8.0f, true)) DoScriptText(SAY_GUARD_2, pGuard); uiTimer = 3000; uiPhase = 2; break; case 2: DoGuardsDisappearAndDie(); uiTimer = 2000; uiPhase = 3; break; case 3: SetEscortPaused(false); uiTimer = 0; uiPhase = 0; break; case 4: DoScriptText(SAY_LESCOVAR_3, m_creature); uiTimer = 0; uiPhase = 0; break; case 5: if (pMarzon) DoScriptText(SAY_MARZON_1, pMarzon); uiTimer = 3000; uiPhase = 6; break; case 6: DoScriptText(SAY_LESCOVAR_4, m_creature); if (Player* pPlayer = GetPlayerForEscort()) pPlayer->AreaExploredOrEventHappens(QUEST_THE_ATTACK); uiTimer = 2000; uiPhase = 7; break; case 7: if (Creature* pTyrion = m_creature->FindNearestCreature(NPC_TYRION, 20.0f, true)) DoScriptText(SAY_TYRION_2, pTyrion); if (pMarzon) pMarzon->setFaction(14); m_creature->setFaction(14); uiTimer = 0; uiPhase = 0; break; } } else uiTimer -= uiDiff; } npc_escortAI::UpdateAI(uiDiff); if (!UpdateVictim()) return; DoMeleeAttackIfReady(); }
void DoIntro() { Creature* Madrigosa = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_MADRIGOSA) : 0); if (!Madrigosa) return; switch (IntroPhase) { case 0: DoScriptText(YELL_MADR_ICE_BARRIER, Madrigosa); IntroPhaseTimer = 7000; ++IntroPhase; break; case 1: me->SetInFront(Madrigosa); Madrigosa->SetInFront(me); DoScriptText(YELL_MADR_INTRO, Madrigosa, me); IntroPhaseTimer = 9000; ++IntroPhase; break; case 2: DoScriptText(YELL_INTRO, me, Madrigosa); IntroPhaseTimer = 13000; ++IntroPhase; break; case 3: DoCast(me, SPELL_INTRO_FROST_BLAST); Madrigosa->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->AttackStop(); Madrigosa->AttackStop(); IntroFrostBoltTimer = 3000; IntroPhaseTimer = 28000; ++IntroPhase; break; case 4: DoScriptText(YELL_INTRO_BREAK_ICE, me); IntroPhaseTimer = 6000; ++IntroPhase; break; case 5: Madrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE_CHANELLING, false); DoScriptText(YELL_MADR_TRAP, Madrigosa); DoCast(me, SPELL_INTRO_ENCAPSULATE); IntroPhaseTimer = 11000; ++IntroPhase; break; case 6: DoScriptText(YELL_INTRO_CHARGE, me); IntroPhaseTimer = 5000; ++IntroPhase; break; case 7: me->Kill(Madrigosa); DoScriptText(YELL_MADR_DEATH, Madrigosa); me->SetFullHealth(); me->AttackStop(); IntroPhaseTimer = 4000; ++IntroPhase; break; case 8: DoScriptText(YELL_INTRO_KILL_MADRIGOSA, me); me->SetOrientation(0.14f); me->StopMoving(); Madrigosa->setDeathState(CORPSE); IntroPhaseTimer = 8000; ++IntroPhase; break; case 9: DoScriptText(YELL_INTRO_TAUNT, me); IntroPhaseTimer = 5000; ++IntroPhase; break; case 10: EndIntro(); break; } }
void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) { npc_escortAI::UpdateAI(diff); if (WaitForTeleport) { if (TeleportTimer <= diff) { CellCoord pair(Trinity::ComputeCellCoord(me->GetPositionX(), me->GetPositionY())); Cell cell(pair); cell.SetNoCreate(); std::list<Creature*> creatures; Trinity::AllFriendlyCreaturesInGrid creature_check(me); Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(me, creatures, creature_check); TypeContainerVisitor <Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> creature_visitor(creature_searcher); cell.Visit(pair, creature_visitor, *(me->GetMap()), *me, me->GetGridActivationRange()); if (!creatures.empty()) { for (std::list<Creature*>::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) { if ((*itr) && (*itr)->isAlive()) { (*itr)->CastSpell(*itr, SPELL_TELEPORT_VISUAL, true); (*itr)->setFaction(35);//make them friendly so mobs won't attack them (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } } DoCast(me, SPELL_TELEPORT_VISUAL); bRetreat = true; RetreatTimer = 1000; } WaitForTeleport = false; Teleported = true; }TeleportTimer -= diff; } if (!Teleported) return; Overrun = false;//execute once switch (faction) { case 0://alliance for (uint8 i = 0; i < 92; ++i)//summon fires me->SummonGameObject(FLAMEOBJECT, AllianceFirePos[i][0], AllianceFirePos[i][1], AllianceFirePos[i][2], AllianceFirePos[i][3], AllianceFirePos[i][4], AllianceFirePos[i][5], AllianceFirePos[i][6], AllianceFirePos[i][7], 0); for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls { uint8 r = rand()%4; Creature* unit = me->SummonCreature(GHOUL, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } for (uint8 i = 0; i < 3; ++i)//summon 3 abominations { uint8 r = rand()%4; Creature* unit = me->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } for (uint8 i = 0; i < 5; ++i)//summon 5 gargoyles { Creature* unit = me->SummonCreature(GARGOYLE, AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { unit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]); CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } break; case 1://horde for (uint8 i = 0; i < 65; ++i)//summon fires me->SummonGameObject(FLAMEOBJECT, HordeFirePos[i][0], HordeFirePos[i][1], HordeFirePos[i][2], HordeFirePos[i][3], HordeFirePos[i][4], HordeFirePos[i][5], HordeFirePos[i][6], HordeFirePos[i][7], 0); for (uint8 i = 0; i < 26; ++i)//summon infernals { Creature* unit = me->SummonCreature(GIANT_INFERNAL, InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { unit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]); CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls { uint8 r = rand()%4; Creature* unit = me->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } for (uint8 i = 0; i < 5; ++i)//summon 5 abominations { uint8 r = rand()%4; Creature* unit = me->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } break; } }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (Summon_Timer < diff) { for(int i = 0; i < 3; ++i) { Unit* target = NULL; target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); Creature* Wraith = m_creature->SummonCreature(21062,m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); if (target && Wraith) Wraith->AI()->AttackStart(target); } DoScriptText(SAY_SUMMON, m_creature); Summon_Timer = urand(30000, 45000); }else Summon_Timer -= diff; if (ManaTap_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_MANA_TAP); ManaTap_Timer = urand(14000, 22000); }else ManaTap_Timer -= diff; if (ArcaneTorrent_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_ARCANE_TORRENT); ArcaneTorrent_Timer = urand(12000, 18000); }else ArcaneTorrent_Timer -= diff; if (Domination_Timer < diff) { if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) { DoScriptText(urand(0, 1) ? SAY_DOMINATION_1 : SAY_DOMINATION_2, m_creature); DoCastSpellIfCan(target,SPELL_DOMINATION); } Domination_Timer = urand(25000, 30000); }else Domination_Timer -= diff; //Only casting if Heroic Mode is used if (!m_bIsRegularMode) { if (ArcaneExplosion_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),H_SPELL_ARCANE_EXPLOSION); ArcaneExplosion_Timer = urand(10000, 14000); }else ArcaneExplosion_Timer -= diff; } if (!Enraged && m_creature->GetHealthPercent() < 21.0f) { DoCastSpellIfCan(m_creature, SPELL_FRENZY); DoScriptText(SAY_ENRAGE, m_creature); Enraged = true; } DoMeleeAttackIfReady(); }
// Function to process actions for linked NPCs void CreatureLinkingHolder::DoCreatureLinkingEvent(CreatureLinkingEvent eventType, Creature* pSource, Unit* pEnemy /* = NULL*/) { // This check will be needed in reload case if (!sCreatureLinkingMgr.IsLinkedEventTrigger(pSource)) return; // Ignore atypic behaviour if (pSource->IsControlledByPlayer()) return; if (eventType == LINKING_EVENT_AGGRO && !pEnemy) return; uint32 eventFlagFilter = 0; uint32 reverseEventFlagFilter = 0; switch (eventType) { case LINKING_EVENT_AGGRO: eventFlagFilter = EVENT_MASK_ON_AGGRO; reverseEventFlagFilter = FLAG_TO_AGGRO_ON_AGGRO; break; case LINKING_EVENT_EVADE: eventFlagFilter = EVENT_MASK_ON_EVADE; reverseEventFlagFilter = FLAG_TO_RESPAWN_ON_EVADE; break; case LINKING_EVENT_DIE: eventFlagFilter = EVENT_MASK_ON_DIE; reverseEventFlagFilter = 0; break; case LINKING_EVENT_RESPAWN: eventFlagFilter = EVENT_MASK_ON_RESPAWN; reverseEventFlagFilter = FLAG_FOLLOW; break; } // Process Slaves (by entry) HolderMapBounds bounds = m_holderMap.equal_range(pSource->GetEntry()); for (HolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr) ProcessSlaveGuidList(eventType, pSource, itr->second.linkingFlag & eventFlagFilter, itr->second.searchRange, itr->second.linkedGuids, pEnemy); // Process Slaves (by guid) bounds = m_holderGuidMap.equal_range(pSource->GetGUIDLow()); for (HolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr) ProcessSlaveGuidList(eventType, pSource, itr->second.linkingFlag & eventFlagFilter, itr->second.searchRange, itr->second.linkedGuids, pEnemy); // Process Master if (CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pSource)) { if (pInfo->linkingFlag & reverseEventFlagFilter) { Creature* pMaster = NULL; if (pInfo->mapId != INVALID_MAP_ID) // entry case { BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId); for (BossGuidMap::iterator itr = finds.first; itr != finds.second; ++itr) { pMaster = pSource->GetMap()->GetCreature(itr->second); if (pMaster && IsSlaveInRangeOfBoss(pSource, pMaster, pInfo->searchRange)) break; } } else // guid case { CreatureData const* masterData = sObjectMgr.GetCreatureData(pInfo->masterDBGuid); CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(masterData->id); pMaster = pSource->GetMap()->GetCreature(ObjectGuid(cInfo->GetHighGuid(), cInfo->Entry, pInfo->masterDBGuid)); } if (pMaster) { switch (eventType) { case LINKING_EVENT_AGGRO: if (pMaster->IsControlledByPlayer()) return; if (pMaster->isInCombat()) pMaster->SetInCombatWith(pEnemy); else pMaster->AI()->AttackStart(pEnemy); break; case LINKING_EVENT_EVADE: if (!pMaster->isAlive()) pMaster->Respawn(); break; case LINKING_EVENT_RESPAWN: if (pMaster->isAlive()) SetFollowing(pSource, pMaster); break; case LINKING_EVENT_DIE: // Nothing linked for this case break; } } } } }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; if (StormCount) { Unit* target = Unit::GetUnit(*me, CloudGUID); if (!target || !target->isAlive()) { EnterEvadeMode(); return; } else if (Unit* Cyclone = Unit::GetUnit(*me, CycloneGUID)) Cyclone->CastSpell(target, 25160, true); // keep casting or... if (StormSequenceTimer <= diff) HandleStormSequence(target); else StormSequenceTimer -= diff; return; } if (Enrage_Timer <= diff) { Talk(SAY_ENRAGE); DoCast(me, SPELL_BERSERK, true); Enrage_Timer = 600000; } else Enrage_Timer -= diff; if (StaticDisruption_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); TargetGUID = target->GetGUID(); DoCast(target, SPELL_STATIC_DISRUPTION, false); me->SetInFront(me->getVictim()); StaticDisruption_Timer = (10+rand()%8)*1000; // < 20s /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f; SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/ } else StaticDisruption_Timer -= diff; if (GustOfWind_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); DoCast(target, SPELL_GUST_OF_WIND); GustOfWind_Timer = urand(20, 30) * 1000; //20 to 30 seconds(bosskillers) } else GustOfWind_Timer -= diff; if (CallLighting_Timer <= diff) { DoCast(me->getVictim(), SPELL_CALL_LIGHTNING); CallLighting_Timer = urand(12, 17) * 1000; //totaly random timer. can't find any info on this } else CallLighting_Timer -= diff; if (!isRaining && ElectricalStorm_Timer < uint32(8000 + rand() % 5000)) { SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f); isRaining = true; } if (ElectricalStorm_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); if (!target) { EnterEvadeMode(); return; } target->CastSpell(target, 44007, true);//cloud visual DoCast(target, SPELL_ELECTRICAL_STORM, false);//storm cyclon + visual float x, y, z; target->GetPosition(x, y, z); if (target) { target->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0); } Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000); if (Cloud) { CloudGUID = Cloud->GetGUID(); Cloud->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); Cloud->StopMoving(); Cloud->SetObjectScale(1.0f); Cloud->setFaction(35); Cloud->SetMaxHealth(9999999); Cloud->SetHealth(9999999); Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } ElectricalStorm_Timer = 60000; //60 seconds(bosskillers) StormCount = 1; StormSequenceTimer = 0; } else ElectricalStorm_Timer -= diff; if (SummonEagles_Timer <= diff) { Talk(SAY_SUMMON); float x, y, z; me->GetPosition(x, y, z); for (uint8 i = 0; i < 8; ++i) { Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]); if (!bird) //they despawned on die { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { x = target->GetPositionX() + irand(-10, 10); y = target->GetPositionY() + irand(-10, 10); z = target->GetPositionZ() + urand(16, 20); if (z > 95) z = 95.0f - urand(0, 5); } Creature* creature = me->SummonCreature(MOB_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (creature) { creature->AddThreat(me->getVictim(), 1.0f); creature->AI()->AttackStart(me->getVictim()); BirdGUIDs[i] = creature->GetGUID(); } } } SummonEagles_Timer = 999999; } else SummonEagles_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } else m_uiBerserkTimer -= uiDiff; } if (m_uiDeathAndDecayTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { if (DoCastSpellIfCan(pTarget, SPELL_DEATH_AND_DECAY) == CAST_OK) m_uiDeathAndDecayTimer = 20000; } } else m_uiDeathAndDecayTimer -= uiDiff; if (m_uiMindControlCount) { if (m_uiDominateMindTimer < uiDiff) { for (uint8 i = 0; i < m_uiMindControlCount; ++i) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_DOMINATE_MIND, SELECT_FLAG_PLAYER)) DoCastSpellIfCan(pTarget, SPELL_DOMINATE_MIND, CAST_TRIGGERED); } DoScriptText(SAY_DOMINATE_MIND, m_creature); m_uiDominateMindTimer = 40000; } else m_uiDominateMindTimer -= uiDiff; } // Summon waves - in phase 1 or on heroic if (m_pInstance && (m_pInstance->IsHeroicDifficulty() || m_bIsPhaseOne)) { if (m_uiSummonWaveTimer < uiDiff) { DoSummonCultistWave(); m_uiCultistBuffTimer = 10000; m_uiDarkMartyrdomTimer = 40000; m_uiSummonWaveTimer = m_pInstance->IsHeroicDifficulty() ? 45000 : 60000; } else m_uiSummonWaveTimer -= uiDiff; if (m_uiCultistBuffTimer) { if (m_uiCultistBuffTimer <= uiDiff) { // Choose a random of Fanatic or Adherent bool bIsFanatic = roll_chance_i(50) ? true : false; uint32 uiNpcEntry = bIsFanatic ? NPC_CULT_FANATIC : NPC_CULT_ADHERENT; uint32 uiSpellEntry = bIsFanatic ? SPELL_DARK_TRANSFORMATION : SPELL_DARK_EMPOWERMENT; int32 iTextEntry = bIsFanatic ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT; Creature* pTarget = DoSelectRandomCultist(uiNpcEntry); if (pTarget && DoCastSpellIfCan(pTarget, uiSpellEntry) == CAST_OK) { // Remove the selected cultist from the list because we don't want it selected twice m_lCultistSpawnedGuidList.remove(pTarget->GetObjectGuid()); DoScriptText(iTextEntry, m_creature); m_uiCultistBuffTimer = 0; } } else m_uiCultistBuffTimer -= uiDiff; } if (m_uiDarkMartyrdomTimer) { if (m_uiDarkMartyrdomTimer <= uiDiff) { // Try to get a target on which to cast Martyrdom if (Creature* pTarget = DoSelectRandomCultist()) { if (DoCastSpellIfCan(pTarget, SPELL_DARK_MARTYRDOM) == CAST_OK) { DoScriptText(SAY_ANIMATE_DEAD, m_creature); m_uiDarkMartyrdomTimer = 0; } } else m_uiDarkMartyrdomTimer = 0; } else m_uiDarkMartyrdomTimer -= uiDiff; } } // Phase 1 specific spells if (m_bIsPhaseOne) { if (m_uiShadowBoltTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_BOLT) == CAST_OK) m_uiShadowBoltTimer = 2000; } } else m_uiShadowBoltTimer -= uiDiff; } // Phase 2 specific spells else { if (m_uiTouchOfInsignificanceTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_INSIGNIFICANCE) == CAST_OK) m_uiTouchOfInsignificanceTimer = 7000; } else m_uiTouchOfInsignificanceTimer -= uiDiff; if (m_uiFrostboltTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_FROSTBOLT) == CAST_OK) m_uiFrostboltTimer = urand(2000, 4000); } } else m_uiFrostboltTimer -= uiDiff; if (m_uiFrostboltVolleyTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FROSTBOLT_VOLLEY) == CAST_OK) m_uiFrostboltVolleyTimer = urand(15000, 20000); } else m_uiFrostboltVolleyTimer -= uiDiff; if (m_uiVengefulShadeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_SPIRIT) == CAST_OK) m_uiVengefulShadeTimer = 10000; } else m_uiVengefulShadeTimer -= uiDiff; DoMeleeAttackIfReady(); } }
void UpdateAI(const uint32 uiDiff) { if (!UpdateVictim()) return; if (m_uiBerserkTimer <= uiDiff) { DoScriptText(SAY_ENRAGE, me); DoCast(me, SPELL_BERSERK); m_uiBerserkTimer = 600000; } else m_uiBerserkTimer -= uiDiff; if (!me->HasAura(SPELL_BONE_STORM_CHANNEL)) { if(m_uiSaberSlashTimer <= uiDiff) { DoCast(me->getVictim(), RAID_MODE(SPELL_SABER_SLASH_10_NORMAL,SPELL_SABER_SLASH_25_NORMAL,SPELL_SABER_SLASH_10_HEROIC,SPELL_SABER_SLASH_10_HEROIC)); m_uiSaberSlashTimer = urand(7000,14000); } else m_uiSaberSlashTimer -= uiDiff; if (m_uiColdFlameTimer <= uiDiff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1)) { DoCast(pTarget, SPELL_COLD_FLAME_SPAWN); m_uiColdFlameTimer = 7000; } } else m_uiColdFlameTimer -= uiDiff; if(m_uiBoneStormChannelTimer <= uiDiff) { DoCastAOE(SPELL_BONE_STORM_CHANNEL); DoScriptText(SAY_BONE_STORM, me); DoScriptText(SAY_EMOTE_BONE_STORM, me); m_uiBoneStormChannelTimer = 50000; } else m_uiBoneStormChannelTimer -= uiDiff; if (m_uiBoneSpikeGraveyardTimer < uiDiff) { switch(urand(0, 2)) { case 0: DoScriptText(SAY_BONESPIKE_1, me); break; case 1: DoScriptText(SAY_BONESPIKE_2, me); break; case 2: DoScriptText(SAY_BONESPIKE_3, me); break; } uint32 count = RAID_MODE(1,3,1,3); for (uint8 i = 1; i <= count; i++) { Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1); // Nicht am Tank if (pTarget && !pTarget->HasAura(SPELL_BONE_SPIKE_IMPALING)) { Creature* Bone = me->SummonCreature(CREATURE_BONE_SPIKE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 999999); CAST_AI(BoneSpikeAI, Bone->AI())->SetPrisoner(pTarget); Bone->CastSpell(pTarget, SPELL_BONE_SPIKE_IMPALING, true); } } m_uiBoneSpikeGraveyardTimer = 15000; } else m_uiBoneSpikeGraveyardTimer -= uiDiff; } if (me->HasAura(SPELL_BONE_STORM_CHANNEL)) { if(m_uiColdFlameTimer2 <= uiDiff) { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) { me->SummonCreature(CREATURE_COLD_FLAME, me->GetPositionX()+20, me->GetPositionY()+20, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000); me->SummonCreature(CREATURE_COLD_FLAME, me->GetPositionX()-20, me->GetPositionY()-20, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000); me->SummonCreature(CREATURE_COLD_FLAME, me->GetPositionX()+20, me->GetPositionY()-20, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000); me->SummonCreature(CREATURE_COLD_FLAME, me->GetPositionX()-20, me->GetPositionY()+20, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000); DoResetThreat(); me->AddThreat(pTarget, 5000000.0f); m_uiColdFlameTimer2 = 4000; } } else m_uiColdFlameTimer2 -= uiDiff; if (getDifficulty() == RAID_DIFFICULTY_10MAN_HEROIC || getDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC) if (m_uiBoneSpikeGraveyardTimer < uiDiff) { switch(urand(0, 2)) { case 0: DoScriptText(SAY_BONESPIKE_1, me); break; case 1: DoScriptText(SAY_BONESPIKE_2, me); break; case 2: DoScriptText(SAY_BONESPIKE_3, me); break; } uint32 count = RAID_MODE(1,3,1,3); // 10 Normal x1 / 25 Normal 3x / 10 Heroic 1x / 25 Heroic 3x for (uint8 i = 1; i <= count; i++) { Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true); if (pTarget && !pTarget->HasAura(SPELL_BONE_SPIKE_IMPALING)) { Creature* Bone = me->SummonCreature(CREATURE_BONE_SPIKE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 999999); CAST_AI(BoneSpikeAI, Bone->AI())->SetPrisoner(pTarget); Bone->CastSpell(pTarget, SPELL_BONE_SPIKE_IMPALING, true); } } m_uiBoneSpikeGraveyardTimer = 15000; } else m_uiBoneSpikeGraveyardTimer -= uiDiff; if(m_uiBoneStormDamageTimer <= uiDiff) { DoCast(me, RAID_MODE(SPELL_BONE_STORM_10_NORMAL,SPELL_BONE_STORM_25_NORMAL,SPELL_BONE_STORM_10_HEROIC,SPELL_BONE_STORM_25_HEROIC)); m_uiBoneStormDamageTimer = 1000; } else m_uiBoneStormDamageTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void instance_pit_of_saron::JustDidDialogueStep(int32 iEntry) { switch (iEntry) { case SPELL_NECROMATIC_POWER: // Transfor all soldiers into undead if (Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS_INTRO)) pTyrannus->CastSpell(pTyrannus, SPELL_NECROMATIC_POWER, true); break; case SAY_OUTRO_3: // Move Tyrannus into position if (Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS_INTRO)) { pTyrannus->SetWalk(false); pTyrannus->GetMotionMaster()->MovePoint(0, afTyrannusMovePos[1][0], afTyrannusMovePos[1][1], afTyrannusMovePos[1][2]); } break; case SPELL_STRANGULATING: // Strangulate Krick if (Creature* pKrick = GetSingleCreatureFromStorage(NPC_KRICK)) { pKrick->CastSpell(pKrick, SPELL_STRANGULATING, true); pKrick->SetLevitate(true); pKrick->GetMotionMaster()->MovePoint(0, pKrick->GetPositionX(), pKrick->GetPositionY(), pKrick->GetPositionZ() + 5.0f); } break; case SAY_TYRANNUS_KRICK_2: // Kill Krick if (Creature* pKrick = GetSingleCreatureFromStorage(NPC_KRICK)) { pKrick->CastSpell(pKrick, SPELL_KRICK_KILL_CREDIT, true); pKrick->CastSpell(pKrick, SPELL_SUICIDE, true); } break; case SAY_JAINA_INTRO_3: case SAY_JAINA_KRICK_3: // Move Tyrannus to a safe position if (Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS_INTRO)) pTyrannus->GetMotionMaster()->MovePoint(0, afTyrannusMovePos[0][0], afTyrannusMovePos[0][1], afTyrannusMovePos[0][2]); break; case NPC_TYRANNUS: { Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS); if (!pTyrannus) return; // Spawn tunnel end event mobs for (uint8 i = 0; i < countof(aEventTunnelEndLocations); ++i) { if (Creature* pSummon = pTyrannus->SummonCreature(m_uiTeam == HORDE ? aEventTunnelEndLocations[i].uiEntryHorde : aEventTunnelEndLocations[i].uiEntryAlliance, aEventTunnelEndLocations[i].fX, aEventTunnelEndLocations[i].fY, aEventTunnelEndLocations[i].fZ, aEventTunnelEndLocations[i].fO, TEMPSUMMON_DEAD_DESPAWN, 0)) { pSummon->SetWalk(false); pSummon->GetMotionMaster()->MovePoint(0, aEventTunnelEndLocations[i].fMoveX, aEventTunnelEndLocations[i].fMoveY, aEventTunnelEndLocations[i].fMoveZ); } } break; } case NPC_RIMEFANG: // Eject Tyrannus and prepare for combat if (Creature* pRimefang = GetSingleCreatureFromStorage(NPC_RIMEFANG)) { pRimefang->CastSpell(pRimefang, SPELL_EJECT_ALL_PASSENGERS, true); pRimefang->SetWalk(false); pRimefang->GetMotionMaster()->MovePoint(0, afTyrannusMovePos[3][0], afTyrannusMovePos[3][1], afTyrannusMovePos[3][2]); } if (Creature* pTyrannus = GetSingleCreatureFromStorage(NPC_TYRANNUS)) pTyrannus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); break; case SAY_VICTUS_OUTRO_1: { Player* pPlayer = GetPlayerInMap(); if (!pPlayer) return; // Spawn Sindragosa if (Creature* pSummon = pPlayer->SummonCreature(aEventOutroLocations[0].uiEntryHorde, aEventOutroLocations[0].fX, aEventOutroLocations[0].fY, aEventOutroLocations[0].fZ, aEventOutroLocations[0].fO, TEMPSUMMON_TIMED_DESPAWN, 2 * MINUTE * IN_MILLISECONDS)) { pSummon->SetWalk(false); pSummon->GetMotionMaster()->MovePoint(0, aEventOutroLocations[0].fMoveX, aEventOutroLocations[0].fMoveY, aEventOutroLocations[0].fMoveZ); } // Spawn Jaina or Sylvanas if (Creature* pSummon = pPlayer->SummonCreature(m_uiTeam == HORDE ? aEventOutroLocations[1].uiEntryHorde : aEventOutroLocations[1].uiEntryAlliance, aEventOutroLocations[1].fX, aEventOutroLocations[1].fY, aEventOutroLocations[1].fZ, aEventOutroLocations[1].fO, TEMPSUMMON_TIMED_DESPAWN, 24 * HOUR * IN_MILLISECONDS)) { pSummon->SetWalk(false); pSummon->GetMotionMaster()->MovePoint(0, aEventOutroLocations[1].fMoveX, aEventOutroLocations[1].fMoveY, aEventOutroLocations[1].fMoveZ); } break; } case SAY_JAINA_OUTRO_1: // Visual effect for (GuidList::const_iterator itr = m_lArcaneShieldBunniesGuidList.begin(); itr != m_lArcaneShieldBunniesGuidList.end(); ++itr) { if (Creature* pBunny = instance->GetCreature(*itr)) pBunny->CastSpell(pBunny, SPELL_ARCANE_FORM, true); } // Teleport players if (Creature* pTemp = GetSingleCreatureFromStorage(m_uiTeam == HORDE ? NPC_SYLVANAS_PART2 : NPC_JAINA_PART2)) { pTemp->CastSpell(pTemp, m_uiTeam == HORDE ? SPELL_CALL_OF_SYLVANAS_2 : SPELL_JAINAS_CALL_2, true); pTemp->CastSpell(pTemp, m_uiTeam == HORDE ? SPELL_CALL_OF_SYLVANAS_2 : SPELL_JAINAS_CALL_2, true); } break; case SPELL_FROST_BOMB: // Frost bomb on the platform if (Creature* pSindragosa = GetSingleCreatureFromStorage(NPC_SINDRAGOSA)) pSindragosa->CastSpell(pSindragosa, SPELL_FROST_BOMB, true); // Visual effect for (GuidList::const_iterator itr = m_lFrozenAftermathBunniesGuidList.begin(); itr != m_lFrozenAftermathBunniesGuidList.end(); ++itr) { if (Creature* pBunny = instance->GetCreature(*itr)) pBunny->CastSpell(pBunny, SPELL_FROZEN_AFTERMATH, true); } break; case NPC_JAINA_PART2: // Visual effect remove for (GuidList::const_iterator itr = m_lArcaneShieldBunniesGuidList.begin(); itr != m_lArcaneShieldBunniesGuidList.end(); ++itr) { if (Creature* pBunny = instance->GetCreature(*itr)) pBunny->RemoveAurasDueToSpell(SPELL_ARCANE_FORM); } // Sindragosa exit if (Creature* pSindragosa = GetSingleCreatureFromStorage(NPC_SINDRAGOSA)) pSindragosa->GetMotionMaster()->MovePoint(0, 759.148f, 199.955f, 720.857f); // Jaina / Sylvanas starts moving (should use wp) if (Creature* pTemp = GetSingleCreatureFromStorage(m_uiTeam == HORDE ? NPC_SYLVANAS_PART2 : NPC_JAINA_PART2)) { pTemp->SetWalk(true); pTemp->GetMotionMaster()->MovePoint(0, 1057.76f, 111.927f, 628.4123f); } break; case SAY_JAINA_OUTRO_2: if (Creature* pTemp = GetSingleCreatureFromStorage(m_uiTeam == HORDE ? NPC_SYLVANAS_PART2 : NPC_JAINA_PART2)) pTemp->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); // ToDo: Jaina / Sylvanas should have some waypoint movement here and the door should be opened only when they get in front of it. DoUseDoorOrButton(GO_HALLS_OF_REFLECT_PORT); break; } }
void DoIntro() { Creature* Madrigosa = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MADRIGOSA)); if (!Madrigosa) return; switch (IntroPhase) { case 0: Madrigosa->AI()->Talk(YELL_MADR_ICE_BARRIER); IntroPhaseTimer = 7000; ++IntroPhase; break; case 1: me->SetInFront(Madrigosa); Madrigosa->SetInFront(me); Madrigosa->AI()->Talk(YELL_MADR_INTRO, me); IntroPhaseTimer = 9000; ++IntroPhase; break; case 2: Talk(YELL_INTRO, Madrigosa); IntroPhaseTimer = 13000; ++IntroPhase; break; case 3: DoCast(me, SPELL_INTRO_FROST_BLAST); Madrigosa->SetDisableGravity(true); me->AttackStop(); Madrigosa->AttackStop(); IntroFrostBoltTimer = 3000; IntroPhaseTimer = 28000; ++IntroPhase; break; case 4: Talk(YELL_INTRO_BREAK_ICE); IntroPhaseTimer = 6000; ++IntroPhase; break; case 5: Madrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE_CHANELLING, false); Madrigosa->AI()->Talk(YELL_MADR_TRAP); DoCast(me, SPELL_INTRO_ENCAPSULATE); IntroPhaseTimer = 11000; ++IntroPhase; break; case 6: Talk(YELL_INTRO_CHARGE); IntroPhaseTimer = 5000; ++IntroPhase; break; case 7: me->Kill(Madrigosa); Madrigosa->AI()->Talk(YELL_MADR_DEATH); me->SetFullHealth(); me->AttackStop(); IntroPhaseTimer = 4000; ++IntroPhase; break; case 8: Talk(YELL_INTRO_KILL_MADRIGOSA); me->SetOrientation(0.14f); me->StopMoving(); Madrigosa->setDeathState(CORPSE); IntroPhaseTimer = 8000; ++IntroPhase; break; case 9: Talk(YELL_INTRO_TAUNT); IntroPhaseTimer = 5000; ++IntroPhase; break; case 10: EndIntro(); break; } }
void InnkeeperGossip::GossipSelectOption(Object * pObject, Player * Plr, uint32 Id, uint32 IntId, const char * Code) { Creature * pCreature = (pObject->GetTypeId()==TYPEID_UNIT)?(TO_CREATURE(pObject)):NULLCREATURE; if(pCreature==NULLCREATURE) return; switch(IntId) { case 1: // VENDOR Plr->GetSession()->SendInventoryList(pCreature); break; case 2: // BINDER Plr->GetSession()->SendInnkeeperBind(pCreature); break; case 3: // WHAT CAN I DO ? // Prepare second menu GossipMenu *Menu; objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), 1853, Plr); Menu->AddItem(5, "Make this inn your home.", 2); Menu->SendTo(Plr); break; case 4: // EVENT OF HALLOWEEN if(!Plr->HasAura(SPELL_TRICK_OR_TREATED)) { pCreature->CastSpell(Plr, SPELL_TRICK_OR_TREATED, true); // either trick or treat, 50% chance if(rand()%2) { Plr->CastSpell(Plr, SPELL_TREAT, true); } else { int32 trickspell=0; switch (rand()%9) { case 0: trickspell=24753; // cannot cast, random 30sec break; case 1: trickspell=24713; // lepper gnome costume break; case 2: if(Plr->getGender() == 0){ trickspell=24735; // male ghost costume }else{ trickspell=24736; // female ghostcostume } break; case 3: if(Plr->getGender() == 0){ trickspell=24711; // male ninja costume }else{ trickspell=24710; // female ninja costume } break; case 4: if(Plr->getGender() == 0){ trickspell=24708; // male pirate costume }else{ trickspell=24709; // female pirate costume } break; case 5: trickspell=24723; // skeleton costume break; } pCreature->CastSpell(Plr, trickspell, true); } } Plr->Gossip_Complete(); break; } }
void WorldSession::SendListInventory( uint64 vendorguid ) { sLog.outDebug( "WORLD: Sent SMSG_LIST_INVENTORY" ); Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR); if (!pCreature) { sLog.outDebug( "WORLD: SendListInventory - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); _player->SendSellError( SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); if(!vItems) { _player->SendSellError( SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0); return; } uint8 numitems = vItems->GetItemCount(); uint8 count = 0; WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*8*4) ); data << uint64(vendorguid); data << uint8(numitems); float discountMod = _player->GetReputationPriceDiscount(pCreature); for(int i = 0; i < numitems; ++i ) { if(VendorItem const* crItem = vItems->GetItem(i)) { if(ItemPrototype const *pProto = objmgr.GetItemPrototype(crItem->item)) { if((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster()) continue; ++count; // reputation discount uint32 price = uint32(floor(pProto->BuyPrice * discountMod)); data << uint32(count); data << uint32(crItem->item); data << uint32(pProto->DisplayInfoID); data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); data << uint32(price); data << uint32(pProto->MaxDurability); data << uint32(pProto->BuyCount); data << uint32(crItem->ExtendedCost); } } } if ( count == 0 || data.size() != 8 + 1 + size_t(count) * 8 * 4 ) return; data.put<uint8>(8, count); SendPacket( &data ); }
//this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_PLACE_BID"); uint64 auctioneer; uint32 auctionId; uint32 priceTmp; uint64 price; recv_data >> auctioneer; recv_data >> auctionId >> priceTmp; price = priceTmp; if (!auctionId || !price) return; //check for cheaters Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer))); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); AuctionEntry* auction = auctionHouse->GetAuction(auctionId); Player* player = GetPlayer(); if (!auction || auction->owner == player->GetGUIDLow()) { //you cannot bid your own auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_DATABASE_ERROR); return; } // impossible have online own another character (use this for speedup check in case online owner) Player* auction_owner = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)); if (!auction_owner && sObjectMgr->GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == player->GetSession()->GetAccountId()) { //you cannot bid your another character auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN); return; } // cheating if (price <= auction->bid || price < auction->startbid) return; // price too low for next bid if not buyout if ((price < auction->buyout || auction->buyout == 0) && price < auction->bid + auction->GetAuctionOutBid()) { //auction has already higher bid, client tests it! return; } if (!player->HasEnoughMoney(price)) { //you don't have enought money!, client tests! //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); return; } SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (price < auction->buyout || auction->buyout == 0) { if (auction->bidder > 0) { if (auction->bidder == player->GetGUIDLow()) player->ModifyMoney(-int32(price - auction->bid)); else { // mail to last bidder and return money sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans); player->ModifyMoney(-int32(price)); } } else player->ModifyMoney(-int32(price)); auction->bidder = player->GetGUIDLow(); auction->bid = (price >> 32); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); trans->PAppend("UPDATE auctionhouse SET buyguid = '%u', lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0); } else { //buyout: if (player->GetGUIDLow() == auction->bidder)
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_creature->HasAura(SPELL_RIFT_SHIELD)) { if (ChaoticRiftGUID) { Unit* Rift = Unit::GetUnit((*m_creature), ChaoticRiftGUID); if (Rift && Rift->isDead()) { m_creature->RemoveAurasDueToSpell(SPELL_RIFT_SHIELD); ChaoticRiftGUID = 0; } return; } } else ChaoticRiftGUID = 0; if ((Phase == 0) && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.75)) { Phase = 1; DoScriptText(SAY_SHIELD, m_creature); DoCast(m_creature, SPELL_RIFT_SHIELD); int tmp = rand()%(2); Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if (Rift) { //DoCast(Rift, SPELL_CHARGE_RIFT); if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) Rift->AI()->AttackStart(pTarget); ChaoticRiftGUID = Rift->GetGUID(); DoScriptText(SAY_RIFT , m_creature); } } if ((Phase == 1) && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.50)) { Phase = 2; DoScriptText(SAY_SHIELD , m_creature); DoCast(m_creature, SPELL_RIFT_SHIELD); int tmp = rand()%(2); Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if (Rift) { //DoCast(Rift, SPELL_CHARGE_RIFT); if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) Rift->AI()->AttackStart(pTarget); ChaoticRiftGUID = Rift->GetGUID(); DoScriptText(SAY_RIFT , m_creature); } } if ((Phase == 2) && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25)) { Phase = 3; DoScriptText(SAY_SHIELD , m_creature); DoCast(m_creature, SPELL_RIFT_SHIELD); int tmp = rand()%(2); Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if (Rift) { //DoCast(Rift, SPELL_CHARGE_RIFT); if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) Rift->AI()->AttackStart(pTarget); ChaoticRiftGUID = Rift->GetGUID(); DoScriptText(SAY_RIFT , m_creature); } } if (SPELL_SPARK_Timer <= diff) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCast(pTarget, m_bIsRegularMode ? SPELL_SPARK_N : SPELL_SPARK_H); SPELL_SPARK_Timer = 5000; } else SPELL_SPARK_Timer -=diff; if (SPELL_CREATE_RIFT_Timer <= diff) { DoScriptText(SAY_RIFT , m_creature); int tmp = rand()%(2); Creature* Rift = m_creature->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[tmp][0], RiftLocation[tmp][1], RiftLocation[tmp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if (Rift) if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) Rift->AI()->AttackStart(pTarget); SPELL_CREATE_RIFT_Timer = 25000; } else SPELL_CREATE_RIFT_Timer -=diff; DoMeleeAttackIfReady(); }