void Reset() { float x, y, z; me->GetPosition(x, y, z); //this visual aura some under ground me->SetPosition(x, y, z + 0.35f, 0.0f); Despawn(); Creature* debuff = DoSpawnCreature(HELPER, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 14500); if (debuff) { debuff->SetDisplayId(me->GetDisplayId()); debuff->CastSpell(debuff, SPELL_PUMPKIN_AURA_GREEN, false); CAST_AI(mob_wisp_invis::mob_wisp_invisAI, debuff->AI())->SetType(1); debuffGUID = debuff->GetGUID(); } sprouted = false; DoCast(me, SPELL_PUMPKIN_AURA, true); DoCast(me, SPELL_SPROUTING); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); }
void WaypointMovementGenerator<Creature>::StartMove(Creature& creature) { if (!i_path || i_path->empty()) return; if (Stopped(creature)) return; if (!creature.isAlive() || creature.hasUnitState(UNIT_STAT_NOT_MOVE)) return; WaypointPath::const_iterator currPoint = i_path->find(i_currentNode); MANGOS_ASSERT(currPoint != i_path->end()); if (WaypointBehavior* behavior = currPoint->second.behavior) { if (behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } if (m_isArrivalDone) { ++currPoint; if (currPoint == i_path->end()) currPoint = i_path->begin(); i_currentNode = currPoint->first; } m_isArrivalDone = false; creature.addUnitState(UNIT_STAT_ROAMING_MOVE); WaypointNode const& nextNode = currPoint->second;; Movement::MoveSplineInit init(creature); init.MoveTo(nextNode.x, nextNode.y, nextNode.z, true); if (nextNode.orientation != 100 && nextNode.delay != 0) init.SetFacing(nextNode.orientation); creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE) && !creature.IsLevitating(), false); init.Launch(); }
void SummonInfernal() { InfernalPoint *point = NULL; float posX,posY,posZ; if ((m_creature->GetMapId() != 532) || m_positions.empty()) { m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 60, posX, posY, posZ); } else { std::vector<InfernalPoint*>::iterator itr = m_positions.begin()+rand()%m_positions.size(); point = *itr; m_positions.erase(itr); posX = point->x; posY = point->y; posZ = INFERNAL_Z; } Creature *Infernal = m_creature->SummonCreature(NETHERSPITE_INFERNAL, posX, posY, posZ, 0, TEMPSUMMON_TIMED_DESPAWN, 180000); if (Infernal) { Infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE); Infernal->setFaction(m_creature->getFaction()); netherspite_infernalAI* pInfernalAI = dynamic_cast<netherspite_infernalAI*>(Infernal->AI()); if (pInfernalAI) { if (point) pInfernalAI->pPoint = point; pInfernalAI->m_malchezaarGuid = m_creature->GetObjectGuid(); } m_vInfernalGuids.push_back(Infernal->GetObjectGuid()); DoCastSpellIfCan(Infernal, SPELL_INFERNAL_RELAY); } DoScriptText(urand(0, 1) ? SAY_SUMMON1 : SAY_SUMMON2, m_creature); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_SUMMON_SMOULDERING_HATCHLING: { std::list<Creature*> eggs; MoltenEggCheck check(me); Trinity::CreatureListSearcher<MoltenEggCheck> searcher(me, eggs, check); me->VisitNearbyGridObject(20.0f, searcher); if (!eggs.empty()) { Creature* egg = Trinity::Containers::SelectRandomContainerElement(eggs); egg->CastSpell(egg, SPELL_SUMMON_SMOULDERING_HATCHLING, TRIGGERED_FULL_MASK); egg->SetDisplayId(MODEL_INVISIBLE_STALKER); egg->m_Events.AddEvent(new RespawnEggEvent(egg), egg->m_Events.CalculateTime(5000)); } if (_callHatchlingSpell) DoCastAOE(_callHatchlingSpell, true); _events.ScheduleEvent(EVENT_SUMMON_SMOULDERING_HATCHLING, urand(6000, 10000)); break; } default: break; } } DoMeleeAttackIfReady(); }
//set model of creature static bool HandleNpcSetModelCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 displayId = (uint32) atoi((char*) args); Creature *pCreature = handler->getSelectedCreature(); if (!pCreature || pCreature->isPet()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->SetDisplayId(displayId); pCreature->SetNativeDisplayId(displayId); pCreature->SaveToDB(); return true; }
void SummonNextWave() { //uint8 count = WavesInfo[WaveCount].SpawnCount; uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; //uint8 KaldoreiSoldierCount = 0; //uint8 AnubisathConquerorCount = 0; //uint8 QirajiWaspCount = 0; for (uint8 i = 0; i < 67; ++i) { Creature* Spawn = NULL; float X = SpawnLocation[locIndex + i].x; float Y = SpawnLocation[locIndex + i].y; float Z = SpawnLocation[locIndex + i].z; float O = SpawnLocation[locIndex + i].o; uint32 desptimer = WavesInfo[WaveCount].DespTimer; Spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, X, Y, Z, O, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, desptimer); if (Spawn) { Spawn->LoadCreaturesAddon(); if (Spawn->GetGUID() == 15423) Spawn->SetDisplayId(15427+rand()%4); if (i >= 30) WaveCount = 1; if (i >= 33) WaveCount = 2; if (i >= 45) WaveCount = 3; if (i >= 51) WaveCount = 4; if (WaveCount < 5) //1-4 Wave { CAST_AI(mob_qiraj_war_spawnAI, Spawn->AI())->MobGUID = me->GetGUID(); CAST_AI(mob_qiraj_war_spawnAI, Spawn->AI())->PlayerGUID = PlayerGUID; } } } WaveTimer = WavesInfo[WaveCount].SpawnTimer; AnnounceTimer = WavesInfo[WaveCount].YellTimer; }
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { if (!&creature) return true; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } if (i_currentNode >= i_path->size()) { sLog.outError("WaypointMovement currentNode (%u) is equal or bigger than path size (creature entry %u)", i_currentNode, creature.GetEntry()); i_currentNode = 0; } CreatureTraveller traveller(creature); i_nextMoveTime.Update(diff); if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) { if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost } // creature has been stopped in middle of the waypoint segment if (!i_destinationHolder.HasArrived() && creature.IsStopped()) { // Timer has elapsed, meaning this part controlled it if (i_nextMoveTime.Passed()) { SetStoppedByPlayer(false); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); // Now we re-set destination to same node and start travel const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else // if( !i_nextMoveTime.Passed()) { // unexpected end of timer && creature stopped && not at end of segment if (!IsStoppedByPlayer()) { // Put 30 seconds delay i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); SetStoppedByPlayer(true); // Mark we did it } } return true; // Abort here this update } if (creature.IsStopped()) { if (!m_isArrivalDone) { if (i_path->at(i_currentNode).orientation != 100) creature.SetOrientation(i_path->at(i_currentNode).orientation); if (i_path->at(i_currentNode).script_id) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for creature %u (entry %u).", i_path->at(i_currentNode).script_id, i_currentNode, creature.GetDBTableGUIDLow(), creature.GetEntry()); creature.GetMap()->ScriptsStart(sCreatureMovementScripts, i_path->at(i_currentNode).script_id, &creature, &creature); } // We have reached the destination and can process behavior if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior) { if (behavior->emote != 0) creature.HandleEmote(behavior->emote); if (behavior->spell != 0) { creature.CastSpell(&creature, behavior->spell, false); if (!IsActive(creature)) // force stop processing (cast can change movegens list) return true; // not expire now, but already lost } if (behavior->model1 != 0) creature.SetDisplayId(behavior->model1); if (behavior->textid[0]) { // Not only one text is set if (behavior->textid[1]) { // Select one from max 5 texts (0 and 1 already checked) int i = 2; for(; i < MAX_WAYPOINT_TEXT; ++i) { if (!behavior->textid[i]) break; } creature.Say(behavior->textid[rand() % i], 0, 0); } else creature.Say(behavior->textid[0], 0, 0); } } // wpBehaviour found // Can only do this once for the node m_isArrivalDone = true; // Inform script MovementInform(creature); if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost // prevent a crash at empty waypoint path. if (!i_path || i_path->empty() || i_currentNode >= i_path->size()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } } } // i_creature.IsStopped() // This is at the end of waypoint segment (incl. was previously stopped by player, extending the time) if (i_nextMoveTime.Passed()) { // If stopped then begin a new move segment if (creature.IsStopped()) { creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior) { if (behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } // behavior for "departure" of the current node is done m_isArrivalDone = false; // Proceed with increment current node and then send to the next destination ++i_currentNode; // Oops, end of the line so need to start from the beginning if (i_currentNode >= i_path->size()) i_currentNode = 0; if (i_path->at(i_currentNode).orientation != 100) creature.SetOrientation(i_path->at(i_currentNode).orientation); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else { // If not stopped then stop it creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); SetStoppedByPlayer(false); // Set TimeTracker to waittime for the current node i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); } } return true; }
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { if(!&creature) return true; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) return true; // prevent a crash at empty waypoint path. if(!i_path || i_path->empty()) return true; // i_path was modified by chat commands for example if(i_path->size() != i_hasDone.size()) i_hasDone.resize(i_path->size()); if(i_currentNode >= i_path->size()) i_currentNode = 0; CreatureTraveller traveller(creature); i_nextMoveTime.Update(diff); i_destinationHolder.UpdateTraveller(traveller, diff, false, true); // creature has been stopped in middle of the waypoint segment if (!i_destinationHolder.HasArrived() && creature.IsStopped()) { if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it { SetStopedByPlayer(false); // Now we re-set destination to same node and start travel creature.addUnitState(UNIT_STAT_ROAMING); if (creature.canFly()) creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else // if( !i_nextMoveTime.Passed()) { // unexpected end of timer && creature stopped && not at end of segment if (!IsStopedByPlayer()) { // Put 30 seconds delay i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); SetStopedByPlayer(true); // Mark we did it } } return true; // Abort here this update } if( creature.IsStopped()) { uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; if (!i_hasDone[idx]) { if (i_path->at(idx).orientation !=100) creature.SetOrientation(i_path->at(idx).orientation); if(WaypointBehavior *behavior = i_path->at(idx).behavior) { if(behavior->emote != 0) creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote); if(behavior->spell != 0) creature.CastSpell(&creature,behavior->spell, false); if(behavior->model1 != 0) creature.SetDisplayId(behavior->model1); if(behavior->textid[0]) { // Not only one text is set if( behavior->textid[1] ) { // Select one from max 5 texts (0 and 1 laready checked) int i = 2; for( ; i < MAX_WAYPOINT_TEXT; ++i ) if( !behavior->textid[i] ) break; creature.Say(behavior->textid[rand() % i], 0, 0); } else creature.Say(behavior->textid[0], 0, 0); } i_hasDone[idx] = true; MovementInform(creature); } // wpBehaviour found } // HasDone == false } // i_creature.IsStopped() if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player { if( creature.IsStopped() ) // If stopped then begin a new move segment { creature.addUnitState(UNIT_STAT_ROAMING); if (creature.canFly()) creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; if (i_path->at(idx).orientation !=100) creature.SetOrientation(i_path->at(idx).orientation); if(WaypointBehavior *behavior = i_path->at(idx).behavior ) { i_hasDone[idx] = false; if(behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } } else // If not stopped then stop it and set the reset of TimeTracker to waittime { creature.StopMoving(); SetStopedByPlayer(false); i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); ++i_currentNode; if( i_currentNode >= i_path->size() ) i_currentNode = 0; } } return true; }
void UpdateAI(const uint32 diff) { if (!Phase) return; // Reset if event is begun and we don't have a threatlist if (Phase && m_creature->getThreatManager().getThreatList().empty()) EnterEvadeMode(); if (Phase == 1) { if (AnimationTimer < diff) { // Release the cube m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); AnimationTimer = 8300; }else AnimationTimer -= diff; if (SummonEssenceTimer < diff) { // Ribs: open m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); Creature* EssenceSuffering = NULL; EssenceSuffering = m_creature->SummonCreature(23418, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); if (EssenceSuffering) { DoScriptText(SUFF_SAY_FREED, EssenceSuffering); if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0)) { EssenceSuffering->AddThreat(target); EssenceSuffering->AI()->AttackStart(target); } SufferingGUID = EssenceSuffering->GetGUID(); } EndingPhase = false; Phase = 2; }else SummonEssenceTimer -= diff; } if (Phase == 2) { if (SufferingGUID) { Creature* EssenceSuffering = NULL; EssenceSuffering = ((Creature*)Unit::GetUnit((*m_creature), SufferingGUID)); if (!EssenceSuffering || (!EssenceSuffering->isAlive())) EnterEvadeMode(); if (!EndingPhase) { if (EssenceSuffering) { if (EssenceSuffering->GetHealthPercent() < 10.0f) { DoScriptText(SUFF_SAY_RECAP, EssenceSuffering); MergeThreatList(EssenceSuffering); EssenceSuffering->RemoveAllAuras(); EssenceSuffering->DeleteThreatList(); EssenceSuffering->GetMotionMaster()->MoveFollow(m_creature,0.0f,0.0f); EssenceSuffering->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DespawnEssenceTimer = 4000; AnimationTimer = 2200; EndingPhase = true; } } } if ((EndingPhase) && (EssenceSuffering) && (EssenceSuffering->isAlive())) { if (AnimationTimer < diff) { // Return EssenceSuffering->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); AnimationTimer = 10000; }else AnimationTimer -= diff; if (DespawnEssenceTimer < diff) { DoScriptText(SUFF_SAY_AFTER, EssenceSuffering); EssenceSuffering->DeleteThreatList(); EssenceSuffering->SetDisplayId(11686); EssenceSuffering->setFaction(35); m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); SummonEssenceTimer = 20000; //60000; AnimationTimer = 18200; //58100; SoulDeathCount = 0; SoulCount = 0; SummonSoulTimer = 1000; EndingPhase = false; Phase = 3; SufferingGUID = 0; }else DespawnEssenceTimer -= diff; } } } if (Phase == 3) { if (SoulCount < 36) { if (SummonSoulTimer < diff) { SummonSoul(); SummonSoulTimer = 500; }else SummonSoulTimer -= diff; } if (SoulDeathCount >= SoulCount) { if (AnimationTimer < diff) { // Release the cube m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); AnimationTimer = 10000; }else AnimationTimer -= diff; if (SummonEssenceTimer < diff) { // Ribs: open m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); Creature* EssenceDesire = NULL; EssenceDesire = m_creature->SummonCreature(23419, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); if (EssenceDesire) { DoScriptText(DESI_SAY_FREED, EssenceDesire); if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) { EssenceDesire->AddThreat(target); EssenceDesire->AI()->AttackStart(target); } DesireGUID = EssenceDesire->GetGUID(); SoulDeathCount = 0; } Phase = 4; }else SummonEssenceTimer -= diff; } } if (Phase == 4) { if (DesireGUID) { Creature* EssenceDesire = NULL; EssenceDesire = ((Creature*)Unit::GetUnit((*m_creature), DesireGUID)); if (!EssenceDesire || !EssenceDesire->isAlive()) EnterEvadeMode(); if (!EndingPhase && EssenceDesire) { if (EssenceDesire->GetHealthPercent() < 10.0f) { MergeThreatList(EssenceDesire); EssenceDesire->GetMotionMaster()->MoveFollow(m_creature,0.0f,0.0f); EssenceDesire->RemoveAllAuras(); EssenceDesire->DeleteThreatList(); DoScriptText(DESI_SAY_RECAP, EssenceDesire); EssenceDesire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DespawnEssenceTimer = 4000; AnimationTimer = 2200; EndingPhase = true; } } if (EndingPhase && EssenceDesire) { if (EssenceDesire->isAlive()) { if (AnimationTimer < diff) { // Return EssenceDesire->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); AnimationTimer = 10000; }else AnimationTimer -= diff; if (DespawnEssenceTimer < diff) { EssenceDesire->DeleteThreatList(); EssenceDesire->setFaction(35); DoScriptText(DESI_SAY_AFTER, EssenceDesire); EssenceDesire->SetDisplayId(11686); m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); SummonEssenceTimer = 20000; AnimationTimer = 18200; SoulDeathCount = 0; SoulCount = 0; SummonSoulTimer = 1000; EndingPhase = false; Phase = 5; DesireGUID = 0; }else DespawnEssenceTimer -= diff; } } } } if (Phase == 5) { if (SoulCount < 36) { if (SummonSoulTimer < diff) { SummonSoul(); SummonSoulTimer = 500; }else SummonSoulTimer -= diff; } if (SoulDeathCount >= SoulCount) { if (AnimationTimer < diff) { // Release the cube m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); AnimationTimer = 10000; }else AnimationTimer -= diff; if (SummonEssenceTimer < diff) { // Ribs: open m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); Creature* EssenceAnger = NULL; EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); if (EssenceAnger) { if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0)) { EssenceAnger->AddThreat(target); EssenceAnger->AI()->AttackStart(target); } AngerGUID = EssenceAnger->GetGUID(); DoScriptText(ANGER_SAY_FREED, EssenceAnger); SoulDeathCount = 0; } Phase = 6; }else SummonEssenceTimer -= diff; } } if (Phase == 6) { if (AngerGUID) { Creature* EssenceAnger = NULL; EssenceAnger = ((Creature*)Unit::GetUnit((*m_creature), AngerGUID)); if (!EssenceAnger) EnterEvadeMode(); if (m_creature->isAlive() && EssenceAnger) { if (!EssenceAnger->isAlive()) { AngerGUID = 0; m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } } } } }
void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature) { if (!i_path || i_path->empty()) { return; } m_lastReachedWaypoint = i_currentNode; if (m_isArrivalDone) { return; } creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); m_isArrivalDone = true; WaypointPath::const_iterator currPoint = i_path->find(i_currentNode); MANGOS_ASSERT(currPoint != i_path->end()); WaypointNode const& node = currPoint->second; if (node.script_id) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for %s.", node.script_id, i_currentNode, creature.GetGuidStr().c_str()); creature.GetMap()->ScriptsStart(DBS_ON_CREATURE_MOVEMENT, node.script_id, &creature, &creature); } // We have reached the destination and can process behavior if (WaypointBehavior* behavior = node.behavior) { if (behavior->emote != 0) { creature.HandleEmote(behavior->emote); } if (behavior->spell != 0) { creature.CastSpell(&creature, behavior->spell, false); } if (behavior->model1 != 0) { creature.SetDisplayId(behavior->model1); } if (behavior->textid[0]) { int32 textId = behavior->textid[0]; // Not only one text is set if (behavior->textid[1]) { // Select one from max 5 texts (0 and 1 already checked) int i = 2; for (; i < MAX_WAYPOINT_TEXT; ++i) { if (!behavior->textid[i]) { break; } } textId = behavior->textid[urand(0, i - 1)]; } if (MangosStringLocale const* textData = sObjectMgr.GetMangosStringLocale(textId)) { creature.MonsterText(textData, NULL); } else { sLog.outErrorDb("%s reached waypoint %u, attempted to do text %i, but required text-data could not be found", creature.GetGuidStr().c_str(), i_currentNode, textId); } } } // Inform script if (creature.AI()) { uint32 type = WAYPOINT_MOTION_TYPE; if (m_PathOrigin == PATH_FROM_EXTERNAL && m_pathId > 0) type = EXTERNAL_WAYPOINT_MOVE + m_pathId; creature.AI()->MovementInform(type, i_currentNode); } // Wait delay ms Stop(node.delay); }
void UpdateAI(const uint32 diff) { if (!me->IsInCombat()) { if (pInstance) { // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((me->IsVisible()) || (me->getFaction() != 35))) { me->SetVisible(false); me->setFaction(35); } else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((!me->IsVisible()) || (me->getFaction() == 35))) { me->setFaction(1720); me->SetVisible(true); } } if (DrainNordrassilTimer <= diff) { if (!IsChanneling) { Creature* Nordrassil = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000); if (Nordrassil) { Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Nordrassil->SetDisplayId(11686); DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); IsChanneling = true; } } Creature* Nordrassil = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 5000); if (Nordrassil) { Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Nordrassil->SetDisplayId(11686); Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); DrainNordrassilTimer = 1000; } } else DrainNordrassilTimer -= diff; } if (!UpdateVictim()) return; if (((me->GetHealth() * 100 / me->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged) BelowTenPercent = true; if (!Enraged) { if (EnrageTimer <= diff) { if ((me->GetHealth() * 100 / me->GetMaxHealth()) > 10) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); Enraged = true; DoScriptText(SAY_ENRAGE, me); } } 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, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000); if (Check) { Check->SetVisible(false); if (me->IsWithinDistInMap(Check, 75)) { me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); Enraged = true; DoScriptText(SAY_ENRAGE, me); } } 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); HasProtected = true; Enraged = true; } if (SummonWispTimer <= diff) { Creature* Wisp = DoSpawnCreature(CREATURE_ANCIENT_WISP, rand() % 40, rand() % 40, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (Wisp) { Wisp->AI()->AttackStart(me); ((mob_ancient_wispAI*)Wisp->AI())->ArchimondeGUID = me->GetGUID(); } 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 (HandOfDeathTimer <= diff) { DoCastVictim( 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(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); GripOfTheLegionTimer = urand(5000, 25000); } else GripOfTheLegionTimer -= diff; if (AirBurstTimer <= diff) { if (urand(0, 1)) DoScriptText(SAY_AIR_BURST1, me); else DoScriptText(SAY_AIR_BURST2, me); DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank AirBurstTimer = urand(25000, 40000); } else AirBurstTimer -= diff; if (FearTimer <= diff) { DoCastVictim( SPELL_FEAR); FearTimer = 42000; } else FearTimer -= diff; if (DoomfireTimer <= diff) { SummonDoomfire(SelectUnit(SELECT_TARGET_RANDOM, 1)); DoomfireTimer = 40000; } else DoomfireTimer -= diff; if (MeleeRangeCheckTimer <= diff) { if (CanUseFingerOfDeath()) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); MeleeRangeCheckTimer = 1000; } MeleeRangeCheckTimer = 5000; } else MeleeRangeCheckTimer -= diff; DoMeleeAttackIfReady(); }
void GameEventMgr::ScriptedBackToOrig(uint32 event_id) { GameEventScriptMap::iterator event_backup = m_GameEventScriptBackup.find(event_id); if( event_backup == m_GameEventScriptBackup.end() ) return; set<EventScript*>::iterator itr = event_backup->second.begin(); for( itr; itr != event_backup->second.end(); itr++ ) { uint32 mapid = (*itr)->mapid; uint32 sql_id = (*itr)->sql_id; uint8 type = (*itr)->type; uint32 data1 = (*itr)->data_1; uint32 data2 = (*itr)->data_2; uint32 data3 = (*itr)->data_3; MapMgr * mapmgr = sInstanceMgr.GetMapMgr( mapid ); if( mapmgr == NULL ) return; Creature *c; GameObject *go; if(type < GAMEOBJECT_CHANGE_STATE) { c = mapmgr->GetSqlIdCreature( sql_id ); if( c == NULL ) return; } else { go = mapmgr->GetSqlIdGameObject( sql_id ); if( go == NULL ) return; } switch( type ) { case CREATURE_CHANGE_SCRIPTED_CHANGE: { CALL_SCRIPT_EVENT(c, GameEventFinish)(event_id); } break; case CREATURE_CHANGE_EMOTE: { c->Emote(EmoteType(data1)); c->SetEmoteState(data2); c->SetStandState(static_cast<uint8>(data3)); } break; case CREATURE_CHANGE_DISPLAYID: { c->SetDisplayId(data1); c->SetNativeDisplayId(data2); c->SetMount(data3); c->EventModelChange(); } break; case CREATURE_CHANGE_WEAPON: { c->SetEquippedItem(MELEE, data1); c->SetEquippedItem(OFFHAND, data2); c->SetEquippedItem(RANGED, data3); } break; case CREATURE_CHANGE_REACT: { c->SetFaction(data1); c->SetUInt32Value(UNIT_NPC_FLAGS, data2); c->SetUInt32Value(UNIT_FIELD_FLAGS, data3); } break; case CREATURE_CAST_SPELL_ON_EVENT_STOP: { SpellEntry * sp = dbcSpell.LookupEntryForced( data1 ); if( sp == NULL ) return; SpellCastTime * casttime = dbcSpellCastTime.LookupEntry(sp->CastingTimeIndex); Spell * spell = sSpellFactoryMgr.NewSpell(c, sp, false, NULL); SpellCastTargets t(0); // force self casting if( data2 ) { t.m_unitTarget = c->GetGUID(); } else { spell->GenerateTargets(&t); spell->m_targets = t; } if (objmgr.IsSpellDisabled(spell->GetProto()->Id) || spell->CanCast(false) != SPELL_CANCAST_OK || !spell->HasPower() || c->m_silenced || c->IsStunned() || c->IsFeared() ) { delete spell; return; } if( casttime->CastTime > 0 ) c->GetAIInterface()->StopMovement(casttime->CastTime); spell->prepare(&t); } break; case CREATURE_CHANGE_UPDATE_FIELD: { c->SetUInt32Value(data1, data2); } break; case GAMEOBJECT_CHANGE_STATE: { go->SetState((uint8)data1); } break; } } m_GameEventScriptBackup.erase(event_id); }
void GameEventMgr::DoScript(uint32 event_id, uint32 sql_id, uint8 type, uint32 data1, uint32 data2, uint32 data3, char * say, uint32 mapid) { MapMgr * mapmgr = sInstanceMgr.GetMapMgr( mapid ); if( mapmgr == NULL ) return; Creature *c; GameObject *go; if(type < GAMEOBJECT_CHANGE_STATE) { c = mapmgr->GetSqlIdCreature( sql_id ); if( c == NULL ) return; } else { go = mapmgr->GetSqlIdGameObject( sql_id ); if( go == NULL ) return; } // create backup for original values EventScript * es = new EventScript(); es->sql_id = sql_id; es->mapid = mapid; es->type = type; es->data_1 = 0; // null them out first! es->data_2 = 0; es->data_3 = 0; if( c && strlen(say) ) { c->SendChatMessage(CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, say); } switch( type ) { case CREATURE_CHANGE_SCRIPTED_CHANGE: { CALL_SCRIPT_EVENT(c, GameEventStart)(event_id); } break; case CREATURE_CHANGE_EMOTE: { // do not backup one-shoot emote c->Emote(EmoteType(data1)); // backup emote state first es->data_2 = c->GetEmoteState(); c->SetEmoteState(data2); // backup stand state es->data_3 = static_cast<uint32>(c->GetStandState()); c->SetStandState(static_cast<uint8>(data3)); } break; case CREATURE_CHANGE_DISPLAYID: { es->data_1 = c->GetDisplayId(); c->SetDisplayId(data1); es->data_2 = c->GetNativeDisplayId(); c->SetNativeDisplayId(data2); es->data_3 = c->GetMount(); c->SetMount(data3); c->EventModelChange(); } break; case CREATURE_CHANGE_WEAPON: { es->data_1 = c->GetEquippedItem(MELEE); es->data_2 = c->GetEquippedItem(OFFHAND); es->data_3 = c->GetEquippedItem(RANGED); c->SetEquippedItem(MELEE, data1); c->SetEquippedItem(OFFHAND, data2); c->SetEquippedItem(RANGED, data3); } break; case CREATURE_CHANGE_REACT: { es->data_1 = c->GetFaction(); c->SetFaction(data1); es->data_2 = c->GetUInt32Value(UNIT_NPC_FLAGS); c->SetUInt32Value(UNIT_NPC_FLAGS, data2); es->data_3 = c->GetUInt32Value(UNIT_FIELD_FLAGS); c->SetUInt32Value(UNIT_FIELD_FLAGS, data3); } break; case CREATURE_CAST_SPELL_ON_EVENT_START: { SpellEntry * sp = dbcSpell.LookupEntryForced( data1 ); if( sp == NULL ) return; SpellCastTime * casttime = dbcSpellCastTime.LookupEntry(sp->CastingTimeIndex); Spell * spell = sSpellFactoryMgr.NewSpell(c, sp, false, NULL); SpellCastTargets t(0); // force self casting if( data2 ) { t.m_unitTarget = c->GetGUID(); } else { spell->GenerateTargets(&t); spell->m_targets = t; } if (objmgr.IsSpellDisabled(spell->GetProto()->Id) || spell->CanCast(false) != SPELL_CANCAST_OK || !spell->HasPower() || c->m_silenced || c->IsStunned() || c->IsFeared() ) { delete spell; return; } if( casttime->CastTime > 0 ) c->GetAIInterface()->StopMovement(casttime->CastTime); spell->prepare(&t); } break; case CREATURE_CAST_SPELL_ON_EVENT_STOP: { // this time just backup it, we will procez it on event end es->data_1 = data1; es->data_2 = data2; } break; case CREATURE_CHANGE_UPDATE_FIELD: { es->data_1 = data1; es->data_2 = c->GetUInt32Value(data1); c->SetUInt32Value(data1, data2); } break; case CREATURE_CHANGE_DESPAWN: { GameEventMap::iterator itr = CheckAndReturnEvent( event_id ); if( itr == m_GameEventMap.end() ) return; uint32 current_time = mktime(&g_localTime); // this is calculated in seconds and added 1 extra second as timer for spawn and despawn uint32 respawntime = itr->second->end_time - current_time + 1; // values here are in miliseconds c->Despawn(0, respawntime*1000); delete es; return; } break; case GAMEOBJECT_CHANGE_STATE: { es->data_1 = (uint32)go->GetState(); go->SetState((uint8)data1); } break; } // insert event into storage GameEventScriptMap::iterator itr = m_GameEventScriptBackup.find(event_id); if( itr == m_GameEventScriptBackup.end() ) { set< EventScript* > s; s.insert( es ); m_GameEventScriptBackup.insert(make_pair(event_id, s)); } else { itr->second.insert( es ); } }
Creature* CBattleground::SpawnSpiritGuide(float x, float y, float z, float o, uint32 horde) { if(horde > 1) horde = 1; CreatureInfo* pInfo = CreatureNameStorage.LookupEntry(13116 + horde); if(pInfo == NULL) { return NULL; } Creature* pCreature = m_mapMgr->CreateCreature(pInfo->Id); pCreature->Create(pInfo->Name, m_mapMgr->GetMapId(), x, y, z, o); pCreature->SetEntry(13116 + horde); pCreature->SetScale(1.0f); pCreature->SetMaxHealth(10000); pCreature->SetMaxPower(POWER_TYPE_MANA, 4868); pCreature->SetMaxPower(POWER_TYPE_FOCUS, 200); pCreature->SetMaxPower(POWER_TYPE_HAPPINESS, 2000000); pCreature->SetHealth(100000); pCreature->SetPower(POWER_TYPE_MANA, 4868); pCreature->SetPower(POWER_TYPE_FOCUS, 200); pCreature->SetPower(POWER_TYPE_HAPPINESS, 2000000); pCreature->setLevel(60); pCreature->SetFaction(84 - horde); pCreature->setRace(0); pCreature->setClass(2); pCreature->setGender(1); pCreature->SetPowerType(0); pCreature->SetEquippedItem(MELEE, 22802); pCreature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PLUS_MOB | UNIT_FLAG_NOT_ATTACKABLE_9 | UNIT_FLAG_UNKNOWN_10 | UNIT_FLAG_PVP); // 4928 pCreature->SetBaseAttackTime(MELEE, 2000); pCreature->SetBaseAttackTime(OFFHAND, 2000); pCreature->SetBoundingRadius(0.208f); pCreature->SetCombatReach(1.5f); pCreature->SetDisplayId(13337 + horde); pCreature->SetNativeDisplayId(13337 + horde); pCreature->SetChannelSpellId(22011); pCreature->SetCastSpeedMod(1.0f); pCreature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE); pCreature->SetUInt32Value(UNIT_FIELD_BYTES_2, 1 | (0x10 << 8)); pCreature->DisableAI(); pCreature->SetCreatureInfo(pInfo); pCreature->SetCreatureProto(CreatureProtoStorage.LookupEntry(pInfo->Id)); pCreature->PushToWorld(m_mapMgr); return pCreature; }
void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate) { for(ModelEquipList::iterator itr = mGameEventModelEquip[event_id].begin();itr != mGameEventModelEquip[event_id].end();++itr) { // Remove the creature from grid CreatureData const* data = objmgr.GetCreatureData(itr->first); if(!data) continue; // Update if spawned Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT), (Creature*)NULL); if (pCreature) { if (activate) { itr->second.equipement_id_prev = pCreature->GetCurrentEquipmentId(); itr->second.modelid_prev = pCreature->GetDisplayId(); pCreature->LoadEquipment(itr->second.equipment_id, true); if (itr->second.modelid >0 && itr->second.modelid_prev != itr->second.modelid) { CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(itr->second.modelid); if (minfo) { pCreature->SetDisplayId(itr->second.modelid); pCreature->SetNativeDisplayId(itr->second.modelid); pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); } } } else { pCreature->LoadEquipment(itr->second.equipement_id_prev, true); if (itr->second.modelid_prev >0 && itr->second.modelid_prev != itr->second.modelid) { CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(itr->second.modelid_prev); if (minfo) { pCreature->SetDisplayId(itr->second.modelid_prev); pCreature->SetNativeDisplayId(itr->second.modelid_prev); pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); } } } } else // If not spawned { CreatureData const* data = objmgr.GetCreatureData(itr->first); if (data && activate) { CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(data->id); uint32 display_id = objmgr.ChooseDisplayId(0,cinfo,data); CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id); if (minfo) display_id = minfo->modelid; if (data->equipmentId == 0) itr->second.equipement_id_prev = cinfo->equipmentId; else if (data->equipmentId != -1) itr->second.equipement_id_prev = data->equipmentId; itr->second.modelid_prev = display_id; } } // now last step: put in data // just to have write access to it CreatureData& data2 = objmgr.NewOrExistCreatureData(itr->first); if (activate) { data2.displayid = itr->second.modelid; data2.equipmentId = itr->second.equipment_id; } else { data2.displayid = itr->second.modelid_prev; data2.equipmentId = itr->second.equipement_id_prev; } } }
void DoWork() { switch (m_phase) { case 0: // Time: 07/03/2015 11:08:09.619 if (Creature* npc_trigger = me->FindNearestCreature(50373, 20.0f)) if (m_npc = me->SummonCreature(50414, npc_trigger->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 40000)) { Position pos = me->GetNearPosition(1.5f, 1.72f); m_npc->GetMotionMaster()->MovePoint(0, pos, true); } m_phase = 1; break; case 1: // Time: 07/03/2015 11:08:10.539 Talk(0); m_timer = 3000; m_phase = 2; break; case 2: // Time: 07/03/2015 11:08:13.253 Number: 5796 if (m_npc && m_npc->IsAlive()) { m_npc->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL); m_npc->SetFacingToObject(me); } m_timer = 750; m_phase = 3; break; case 3: // Time: 07/03/2015 11:08:14.080 Number: 5805 me->HandleEmoteState(EMOTE_STATE_USE_STANDING); m_timer = 6000; m_phase = 4; break; case 4: // Time: 07/03/2015 11:08:20.133 Number: 5875 me->HandleEmoteState(EMOTE_ONESHOT_NONE); m_timer = 750; m_phase = 5; break; case 5: // Time: 07/03/2015 11:08:21.350 Number: 5891 me->HandleEmote(EMOTE_ONESHOT_POINT); m_timer = 2500; m_phase = 6; break; case 6: // Time: 07/03/2015 11:08:23.908 Number: 5934 Talk(1); m_timer = 250; m_phase = 7; break; case 7: // 07/03/2015 11:08:24.189 Number: 5935 if (m_npc && m_npc->IsAlive()) { m_npc->AddAura(93460, m_npc); m_npc->CastSpell(m_npc, 93460); m_npc->SetDisplayId(36775); m_npc->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); } m_timer = 2500; m_phase = 8; break; case 8: // Time: 07/03/2015 11:08:26.607 Number: 5967 if (m_npc && m_npc->IsAlive()) { m_npc->HandleEmote(EMOTE_ONESHOT_TALK); m_npc->AI()->Talk(0); } m_timer = 3750; m_phase = 9; break; case 9: // Time: 07/03/2015 11:08:30.257 Number: 6015 if (m_npc && m_npc->IsAlive()) m_npc->HandleEmote(EMOTE_ONESHOT_SALUTE); m_timer = 2500; m_phase = 10; break; case 10: // Time: 07/03/2015 11:08:32.691 Number: 6043 if (m_npc && m_npc->IsAlive()) m_npc->GetMotionMaster()->MovePath(5041401, false); m_timer = 45000; m_phase = 11; break; case 11: // Time: 07/03/2015 11:09:15.139 Number: 6405 if (m_npc && m_npc->IsAlive()) m_npc->DespawnOrUnsummon(); m_timer = urand(15000, 45000);; m_phase = 0; break; } }
void UpdateAI(const uint32 diff) { if(!m_creature->SelectHostileTarget() || !m_creature->getVictim() ) return; if (MovementInform_id >= 0) { Moving = false; m_creature->RemoveMonsterMoveFlag(MONSTER_MOVE_FLY); switch (MovementInform_id) { case 0: case 1: case 2: case 3: Platforms_Move_Timer = 30000+rand()%5000; break; case 4: DoCast(m_creature, SPELL_FLAME_QUILLS); FlameQuillsDuration_Timer = 10000; FlameQuills = true; break; case 5: m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->SetVisibility(VISIBILITY_ON); DoCast(m_creature, SPELL_REBIRTH); Phase2_begin = true; FakeDeath = false; break; case 6: m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, false); m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, DefaultSize/4.0f); DoCast(m_creature->getVictim(), SPELL_DIVE_BOMB_VISUAL); DiveBombCastDelay_Timer = 4000; break; case 7: m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, DefaultModel); m_creature->SetVisibility(VISIBILITY_OFF); // I know, that this sequence of commands looks stupid, but without it visual effect of Rebirth m_creature->SetVisibility(VISIBILITY_ON); // after Dive Bomb looks not perfect (Al'ar appears, and than again disappears and cast Rebirth). DoCast(m_creature, SPELL_REBIRTH_2); DiveBombCastDelay_Timer = 9999999; FlameBuffetAfterDiveBomb = true; DiveBomb_Timer = 40000+rand()%5000; FlameBuffet_Timer = 5000; break; } m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveIdle(); MovementInform_id = -1; } if (!Phase1) if (Enrage_Timer < diff) { DoCast(m_creature, SPELL_ENRAGE); Enrage_Timer = 600000; }else Enrage_Timer -= diff; if (Moving) { return; } if (Charge) { if (ChargeDelay_Timer < diff) { if (Charge_target && Charge_target_threat && Charge_target_threat > 0 && Charge_target->isAlive() && Charge_target->GetTypeId() == TYPEID_PLAYER && Charge_target->GetMaxHealth() > 2000 && Charge_target->IsInWorld()) { m_creature->getThreatManager().modifyThreatPercent(Charge_target, -100); m_creature->getThreatManager().addThreat(Charge_target, Charge_target_threat); } Charge = false; m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); }else ChargeDelay_Timer -= diff; return; } if (CorpseDisappear_Timer < diff) { m_creature->SetVisibility(VISIBILITY_OFF); m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); m_creature->SetHealth(m_creature->GetMaxHealth()); CreaturePointMove(5, waypoint[5][0], waypoint[5][1], waypoint[5][2]); CorpseDisappear_Timer = 9999999; }else CorpseDisappear_Timer -= diff; if (FakeDeath) return; if (Phase2_begin) { m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); MeltArmor_Timer = 60000; Charge_Timer = 7000; DiveBomb_Timer = 40000+rand()%5000; DiveBombCastDelay_Timer = 9999999; FlameBuffet_Timer = 9999999; FlamePatch_Timer = 30000; Phase2_begin = false; Phase1 = false; if(pInstance) pInstance->SetData(DATA_ALAREVENT, 2); } if (Phase1) { if (FlameQuills) { if (FlameQuillsDuration_Timer < diff) { switch(rand()%2) { case 0: cur_wp = 0; break; case 1: cur_wp = 3; break; } CreaturePointMove(cur_wp, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); FlameQuills = false; }else FlameQuillsDuration_Timer -= diff; return; } if (Platforms_Move_Timer < diff) { Creature* Summoned = NULL; Summoned = m_creature->SummonCreature(CREATURE_EMBER_OF_ALAR, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (Summoned) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if (target) Summoned->AI()->AttackStart(target); } if (rand()%100 <= 20) { cur_wp = 4; FlameQuills = true; } else { cur_wp++; if (cur_wp == 4) cur_wp = 0; } CreaturePointMove(cur_wp, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); }else Platforms_Move_Timer -= diff; if (FlameBuffet_Timer < diff) { std::list<HostileReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); if(!m_threatlist.empty()) { std::list<HostileReference*>::iterator i = m_threatlist.begin(); bool InMeleeRange = false; for(i = m_threatlist.begin(); i != m_threatlist.end(); ++i) { Unit* pUnit = NULL; pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); if (pUnit) if (m_creature->IsWithinDistInMap(pUnit, 5)) { InMeleeRange = true; m_creature->getThreatManager().addThreat(pUnit, 2.0f); break; }else m_creature->getThreatManager().modifyThreatPercent(pUnit, -100); } if (!InMeleeRange) DoCast(m_creature, SPELL_FLAME_BUFFET); } FlameBuffet_Timer = 1500; }else FlameBuffet_Timer -= diff; } else { if (FlameBuffetAfterDiveBomb) { if (FlameBuffet_Timer < diff) { if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 5)) { m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); FlameBuffetAfterDiveBomb = false; FlameBuffet_Timer = 9999999; } else { DoCast(m_creature, SPELL_FLAME_BUFFET); FlameBuffet_Timer = 1500; } } else FlameBuffet_Timer -= diff; } else { if (MeltArmor_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_MELT_ARMOR); MeltArmor_Timer = 60000; }else MeltArmor_Timer -= diff; if (Charge_Timer < diff) { Charge_target = SelectUnit(SELECT_TARGET_RANDOM, 1); if (Charge_target) { m_creature->SetInFront(Charge_target); Charge_target_threat = m_creature->getThreatManager().getThreat(Charge_target); m_creature->getThreatManager().addThreat(Charge_target, 100000000.0f); m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate*5.0f); DoCast(Charge_target, SPELL_CHARGE); ChargeDelay_Timer = 2000; Charge = true; } Charge_Timer = 30000; }else Charge_Timer -= diff; } if (!PrepareDiveBomb) { if (DiveBomb_Timer < diff) { PrepareDiveBomb = true; m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); DiveBomb_Timer2 = 1500; DiveBomb_Timer = 40000+rand()%5000; }else DiveBomb_Timer -= diff; } if (PrepareDiveBomb) { if (DiveBomb_Timer2 < diff) { CreaturePointMove(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]); PrepareDiveBomb = false; }else DiveBomb_Timer2 -= diff; } if (DiveBombCastDelay_Timer < diff) { m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false); m_creature->SetDisplayId(11686); Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if (target) DoCast(target, SPELL_DIVE_BOMB); m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, DefaultSize); m_creature->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL); m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate*2.0f); if (target) { CreaturePointMove(7, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); Creature* Summoned = NULL; for (int8 i=1; i<=2; i++) { Summoned = m_creature->SummonCreature(CREATURE_EMBER_OF_ALAR, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (Summoned) { Unit* target1 = NULL; target1 = SelectUnit(SELECT_TARGET_RANDOM, 0); if (target1) Summoned->AI()->AttackStart(target1); } } } DiveBombCastDelay_Timer = 9999999; }else DiveBombCastDelay_Timer -= diff; if (FlamePatch_Timer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if (target) { Creature* Summoned = NULL; Summoned = m_creature->SummonCreature(CREATURE_FLAME_PATCH_ALAR, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 120000); if (Summoned) { Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Summoned->SetFloatValue(OBJECT_FIELD_SCALE_X, Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.9f); Summoned->SetDisplayId(11686); Summoned->setFaction(m_creature->getFaction()); Summoned->SetLevel(m_creature->getLevel()); Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false); } } FlamePatch_Timer = 30000; }else FlamePatch_Timer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!me->isInCombat()) // sometimes isincombat but !incombat, faction bug? return; if (Berserk_Timer <= diff) { DoCast(me, SPELL_BERSERK, true); Berserk_Timer = 60000; } else Berserk_Timer -= diff; if (ForceMove) { if (ForceTimer <= diff) { me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); ForceTimer = 5000; } else ForceTimer -= diff; } if (WaitEvent) { if (WaitTimer) { if (WaitTimer <= diff) { if (AfterMoving) { me->GetMotionMaster()->MoveIdle(); AfterMoving = false; } switch (WaitEvent) { case WE_PLATFORM: Platforms_Move_Timer = 30000+rand()%5000; break; case WE_QUILL: DoCast(me, SPELL_FLAME_QUILLS, true); Platforms_Move_Timer = 1; WaitTimer = 10000; WaitEvent = WE_DUMMY; return; case WE_DIE: ForceMove = false; me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); WaitTimer = 5000; WaitEvent = WE_REVIVE; return; case WE_REVIVE: me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); me->SetFullHealth(); me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoZoneInCombat(); DoCast(me, SPELL_REBIRTH, true); MeltArmor_Timer = 60000; Charge_Timer = 7000; DiveBomb_Timer = 40000+rand()%5000; FlamePatch_Timer = 30000; Phase1 = false; break; case WE_METEOR: me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, false); DoCast(me, SPELL_DIVE_BOMB_VISUAL, false); WaitEvent = WE_DIVE; WaitTimer = 4000; return; case WE_DIVE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL); DoCast(target, SPELL_DIVE_BOMB, true); float dist = 3.0f; if (me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f)) dist = 5.0f; WaitTimer = 1000 + uint32(floor(dist / 80 * 1000.0f)); me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f); me->StopMoving(); WaitEvent = WE_LAND; } else { EnterEvadeMode(); return; } case WE_LAND: WaitEvent = WE_SUMMON; WaitTimer = 2000; return; case WE_SUMMON: for (uint8 i = 0; i < 2; ++i) DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetDisplayId(me->GetNativeDisplayId()); DoCast(me, SPELL_REBIRTH_2, true); break; case WE_DUMMY: default: break; } WaitEvent = WE_NONE; WaitTimer = 0; } else WaitTimer -= diff; } return; } if (Phase1) { if (me->getThreatManager().getThreatList().empty()) { EnterEvadeMode(); return; } if (Platforms_Move_Timer <= diff) { if (cur_wp == 4) { cur_wp = 0; WaitEvent = WE_PLATFORM; } else { if (urand(0, 4)) // next platform { DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (cur_wp == 3) cur_wp = 0; else ++cur_wp; WaitEvent = WE_PLATFORM; } else // flame quill { cur_wp = 4; WaitEvent = WE_QUILL; } } ForceMove = true; ForceTimer = 5000; me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); WaitTimer = 0; return; } else Platforms_Move_Timer -= diff; } else { if (Charge_Timer <= diff) { Unit* target= SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); if (target) DoCast(target, SPELL_CHARGE); Charge_Timer = 30000; } else Charge_Timer -= diff; if (MeltArmor_Timer <= diff) { DoCast(me->getVictim(), SPELL_MELT_ARMOR); MeltArmor_Timer = 60000; } else MeltArmor_Timer -= diff; if (DiveBomb_Timer <= diff) { me->AttackStop(); me->GetMotionMaster()->MovePoint(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 50); WaitEvent = WE_METEOR; WaitTimer = 0; DiveBomb_Timer = 40000+rand()%5000; return; } else DiveBomb_Timer -= diff; if (FlamePatch_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { Creature* Summoned = me->SummonCreature(CREATURE_FLAME_PATCH_ALAR, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 120000); 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->SetDisplayId(11686); Summoned->setFaction(me->getFaction()); Summoned->SetLevel(me->getLevel()); Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false); } } FlamePatch_Timer = 30000; } else FlamePatch_Timer -= diff; } DoMeleeAttackIfReady(); }
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { if (!&creature) return true; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } if (i_currentNode >= i_path->size()) i_currentNode = 0; CreatureTraveller traveller(creature); i_nextMoveTime.Update(diff); if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) { if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost } // creature has been stopped in middle of the waypoint segment if (!i_destinationHolder.HasArrived() && creature.IsStopped()) { // Timer has elapsed, meaning this part controlled it if (i_nextMoveTime.Passed()) { SetStoppedByPlayer(false); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); // Now we re-set destination to same node and start travel const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else // if( !i_nextMoveTime.Passed()) { // unexpected end of timer && creature stopped && not at end of segment if (!IsStoppedByPlayer()) { // Put 30 seconds delay i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); SetStoppedByPlayer(true); // Mark we did it } } return true; // Abort here this update } if (creature.IsStopped() && !i_hasDone) // creature is waiting on a waypoint and hasn't done the behavior yet { uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; if (i_path->at(idx).orientation != 100) creature.SetOrientation(i_path->at(idx).orientation); if (WaypointBehavior *behavior = i_path->at(idx).behavior) { if (behavior->emote != 0) creature.HandleEmote(behavior->emote); if (behavior->spell != 0) { creature.CastSpell(&creature, behavior->spell, false); if (!IsActive(creature)) // force stop processing (cast can change movegens list) return true; // not expire now, but already lost } if (behavior->model1 != 0) creature.SetDisplayId(behavior->model1); if (behavior->textid[0]) { // Not only one text is set if (behavior->textid[1]) { // Select one from max 5 texts (0 and 1 already checked) int i = 2; for(; i < MAX_WAYPOINT_TEXT; ++i) { if (!behavior->textid[i]) break; } creature.Say(behavior->textid[rand() % i], 0, 0); } else creature.Say(behavior->textid[0], 0, 0); } } // behavior done i_hasDone = true; MovementInform(creature); if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost // prevent a crash at empty waypoint path. if (!i_path || i_path->empty() || i_currentNode >= i_path->size()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } } // i_creature.IsStopped() // This is at the end of waypoint segment or has been stopped by player if (i_nextMoveTime.Passed()) { // If stopped then begin a new move segment if (creature.IsStopped()) { creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; if (i_path->at(idx).orientation != 100) creature.SetOrientation(i_path->at(idx).orientation); if (WaypointBehavior *behavior = i_path->at(idx).behavior) { if (behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } } else { // If not stopped then stop it and set the reset of TimeTracker to waittime creature.StopMoving(); SetStoppedByPlayer(false); i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); ++i_currentNode; i_hasDone = false; if (i_currentNode >= i_path->size()) i_currentNode = 0; } } return true; }
static bool HandleWpShowCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: on, off, first, last char* show_str = strtok((char*)args, " "); if (!show_str) return false; // second arg: GUID (optional, if a creature is selected) char* guid_str = strtok((char*)NULL, " "); uint32 pathid = 0; Creature* target = handler->getSelectedCreature(); // Did player provide a PathID? if (!guid_str) { // No PathID provided // -> Player must have selected a creature if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pathid = target->GetWaypointPath(); } else { // PathID provided // Warn if player also selected a creature // -> Creature selection is ignored <- if (target) handler->SendSysMessage(LANG_WAYPOINT_CREATSELECTED); pathid = atoi((char*)guid_str); } std::string show = show_str; uint32 Maxpoint; //handler->PSendSysMessage("wpshow - show: %s", show); // Show info for the selected waypoint if (show == "info") { // Check if the user did specify a visual waypoint if (target->GetEntry() != VISUAL_WAYPOINT) { handler->PSendSysMessage(LANG_WAYPOINT_VP_SELECT); handler->SetSentErrorMessage(true); return false; } QueryResult result = WorldDatabase.PQuery("SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow()); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM); return true; } handler->SendSysMessage("|cff00ffffDEBUG: wp show info:|r"); do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); uint32 point = fields[1].GetUInt32(); uint32 delay = fields[2].GetUInt32(); uint32 flag = fields[3].GetUInt32(); uint32 ev_id = fields[4].GetUInt32(); uint32 ev_chance = fields[5].GetUInt32(); handler->PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid); handler->PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay); handler->PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag); handler->PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id); handler->PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance); } while (result->NextRow()); return true; } if (show == "on") { QueryResult result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z FROM waypoint_data WHERE id = '%u'", pathid); if (!result) { handler->SendSysMessage("|cffff33ffPath no found.|r"); handler->SetSentErrorMessage(true); return false; } handler->PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid); // Delete all visuals for this NPC QueryResult result2 = WorldDatabase.PQuery("SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid); if (result2) { bool hasError = false; do { Field* fields = result2->Fetch(); uint32 wpguid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid); hasError = true; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, wpguid); WorldDatabase.Execute(stmt); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result2->NextRow()); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } } do { Field* fields = result->Fetch(); uint32 point = fields[0].GetUInt32(); float x = fields[1].GetFloat(); float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); float o = chr->GetOrientation(); Creature* wpCreature = new Creature; if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } // Set "wpguid" column to the visual waypoint PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); stmt->setInt32(0, int32(wpCreature->GetGUIDLow())); stmt->setUInt32(1, pathid); stmt->setUInt32(2, point); WorldDatabase.Execute(stmt); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } if (target) { wpCreature->SetDisplayId(target->GetDisplayId()); wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); wpCreature->SetLevel(point > STRONG_MAX_LEVEL ? STRONG_MAX_LEVEL : point); } } while (result->NextRow()); handler->SendSysMessage("|cff00ff00Showing the current creature's path.|r"); return true; } if (show == "first") { handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid); QueryResult result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z FROM waypoint_data WHERE point='1' AND id = '%u'", pathid); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); float o = chr->GetOrientation(); Map* map = chr->GetMap(); Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); } return true; } if (show == "last") { handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid); QueryResult result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'", pathid); if (result) Maxpoint = (*result)[0].GetUInt32(); else Maxpoint = 0; result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z, orientation FROM waypoint_data WHERE point ='%u' AND id = '%u'", Maxpoint, pathid); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); float o = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); } return true; } if (show == "off") { QueryResult result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND); handler->SetSentErrorMessage(true); return false; } bool hasError = false; do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid); hasError = true; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, guid); WorldDatabase.Execute(stmt); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result->NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WOLRD_UPD_ALL_WAYPOINT_DATA_WPGUID); WorldDatabase.Execute(stmt); //WorldDatabase.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } handler->SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED); return true; } handler->PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r"); return true; }
void TowerDefenseInstanceScript::TowerDefenseMapInstanceScript::UpgradeGuard(uint64 guid) { if(!guid) return; Player* player = GetPlayer(); if(!player) return; Creature* creature = player->GetMap()->GetCreature(guid); if(!creature) return; uint32 currentLevel = 0; uint32 entry = GUID_ENPART(guid); if (Guards.find(guid) != Guards.end()) { GuardInfo* guard = Guards[guid]; currentLevel = guard->Level; uint32 newLevel = currentLevel +1; if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT creatureName, creatureEntry, creatureCost FROM custom_td_base_stats WHERE creatureEntry = '%u'", entry)) { uint32 UpgradeCost = guard->GetUpgradeCost(); switch(GetEventMode()) { case TD_EVENT_MODE_HARD: UpgradeCost = UpgradeCost + (UpgradeCost/4); break; case TD_EVENT_MODE_EXTREME: UpgradeCost = UpgradeCost + (UpgradeCost/2); break; } if(GetResources() < UpgradeCost){ SendMessageToPlayer(TD_SYSTEM_MSG_MORE_RESOURCES_UPG, UpgradeCost - GetResources()); return; } if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT * FROM custom_td_base_levels WHERE creatureEntry = '%u' AND creatureLevel = '%u'", entry, newLevel)) { creature->CastSpell(creature, GetSpellIdByUniqueId(4),true); // upgrade level visual guard->SetLevel(newLevel); UpdateResources(TD_EVENT_DEC,UpgradeCost); // remove resource cost from player creature->RemoveAllAuras(); // remove all auras to apply new ones. SendMessageToPlayer(TD_SYSTEM_MSG_UPGRADED_TOWER_FOR, creature->GetName(),UpgradeCost); Field* Fields = queryResult->Fetch(); uint32 newDefaultSpell = Fields[4].GetUInt32(); if(newDefaultSpell) guard->SetDefSpell(newDefaultSpell); uint32 newAttackSpeed = Fields[9].GetUInt32(); if (newAttackSpeed) guard->SetAttSpeed(newAttackSpeed); float newAttackDistance = Fields[8].GetFloat(); if(newAttackDistance) guard->SetAttackDistance(newAttackDistance); uint32 newAura = Fields[7].GetUInt32(); if(newAura) creature->CastSpell(creature,newAura,true); uint32 newDisplay = Fields[6].GetUInt32(); if(newDisplay) creature->SetDisplayId(newDisplay); float newScale = Fields[5].GetFloat(); if(newScale) creature->SetObjectScale(newScale); uint32 newDamage = Fields[10].GetUInt32(); if (newDamage) guard->SetDamage(newDamage); uint32 newIsAntiAir = Fields[11].GetBool(); if (newIsAntiAir) guard->SetIsAntiAir(newIsAntiAir); uint32 newIsAntiGround = Fields[12].GetBool(); if (newIsAntiGround) guard->SetIsAntiGround(newIsAntiGround); } } } }