bool WorldSession::CheckMailBox(ObjectGuid guid) { // GM case if (guid == GetPlayer()->GetObjectGuid()) { // command case will return only if player have real access to command if (!ChatHandler(GetPlayer()).FindCommand("mailbox")) { DEBUG_LOG("%s attempt open mailbox in cheating way.", guid.GetString().c_str()); return false; } } // mailbox case else if (guid.IsGameObject()) { if (!GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_MAILBOX)) { DEBUG_LOG("Mailbox %s not found or %s can't interact with him.", guid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str()); return false; } } // squire case else if (guid.IsAnyTypeCreature()) { Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!creature) { DEBUG_LOG("%s not found or %s can't interact with him.", creature->GetGuidStr().c_str(), GetPlayer()->GetGuidStr().c_str()); return false; } if (!(creature->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_SQUIRE)) { DEBUG_LOG("%s not have access to mailbox.", creature->GetGuidStr().c_str()); return false; } if (creature->GetOwnerGuid() != GetPlayer()->GetObjectGuid()) { DEBUG_LOG("%s not owned by %s for access to mailbox.", creature->GetGuidStr().c_str(), GetPlayer()->GetGuidStr().c_str()); return false; } } else return false; return true; }
//-----------------------------------------------// void WaypointMovementGenerator<Creature>::LoadPath(Creature& creature, int32 pathId, WaypointPathOrigin wpOrigin, uint32 overwriteEntry) { DETAIL_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "LoadPath: loading waypoint path for %s", creature.GetGuidStr().c_str()); if (!overwriteEntry) overwriteEntry = creature.GetEntry(); if (wpOrigin == PATH_NO_PATH && pathId == 0) i_path = sWaypointMgr.GetDefaultPath(overwriteEntry, creature.GetGUIDLow(), &m_PathOrigin); else { m_PathOrigin = wpOrigin == PATH_NO_PATH ? PATH_FROM_ENTRY : wpOrigin; i_path = sWaypointMgr.GetPathFromOrigin(overwriteEntry, creature.GetGUIDLow(), pathId, m_PathOrigin); } m_pathId = pathId; // No movement found for entry nor guid if (!i_path) { if (m_PathOrigin == PATH_FROM_EXTERNAL) sLog.outErrorScriptLib("WaypointMovementGenerator::LoadPath: %s doesn't have waypoint path %i", creature.GetGuidStr().c_str(), pathId); else sLog.outErrorDb("WaypointMovementGenerator::LoadPath: %s doesn't have waypoint path %i", creature.GetGuidStr().c_str(), pathId); return; } if (i_path->empty()) { return; } // Initialize the i_currentNode to point to the first node i_currentNode = i_path->begin()->first; m_lastReachedWaypoint = 0; }
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 WaypointMovementGenerator<Creature>::LoadPath(Creature& creature) { DETAIL_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "LoadPath: loading waypoint path for %s", creature.GetGuidStr().c_str()); i_path = sWaypointMgr.GetPath(creature.GetGUIDLow()); // We may LoadPath() for several occasions: // 1: When creature.MovementType=2 // 1a) Path is selected by creature.guid == creature_movement.id // 1b) Path for 1a) does not exist and then use path from creature.GetEntry() == creature_movement_template.entry // 2: When creature_template.MovementType=2 // 2a) Creature is summoned and has creature_template.MovementType=2 // Creators need to be sure that creature_movement_template is always valid for summons. // Mob that can be summoned anywhere should not have creature_movement_template for example. // No movement found for guid if (!i_path) { i_path = sWaypointMgr.GetPathTemplate(creature.GetEntry()); // No movement found for entry if (!i_path) { sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path", creature.GetName(), creature.GetEntry(), creature.GetGUIDLow()); return; } } StartMoveNow(creature); }
void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature) { if (!i_path || i_path->empty()) return; if (m_isArrivalDone) return; creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); m_isArrivalDone = true; 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 %s.", i_path->at(i_currentNode).script_id, i_currentNode, creature.GetGuidStr().c_str()); 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 (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.MonsterSay(behavior->textid[rand() % i], LANG_UNIVERSAL); } else creature.MonsterSay(behavior->textid[0], LANG_UNIVERSAL); } } // Inform script MovementInform(creature); Stop(i_path->at(i_currentNode).delay); }
//-----------------------------------------------// void WaypointMovementGenerator<Creature>::LoadPath(Creature &creature) { DETAIL_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "LoadPath: loading waypoint path for %s", creature.GetGuidStr().c_str()); i_path = sWaypointMgr.GetPath(creature.GetGUIDLow()); // We may LoadPath() for several occasions: // 1: When creature.MovementType=2 // 1a) Path is selected by creature.guid == creature_movement.id // 1b) Path for 1a) does not exist and then use path from creature.GetEntry() == creature_movement_template.entry // 2: When creature_template.MovementType=2 // 2a) Creature is summoned and has creature_template.MovementType=2 // Creators need to be sure that creature_movement_template is always valid for summons. // Mob that can be summoned anywhere should not have creature_movement_template for example. // No movement found for guid if (!i_path) { i_path = sWaypointMgr.GetPathTemplate(creature.GetEntry()); // No movement found for entry if (!i_path) { sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path", creature.GetName(), creature.GetEntry(), creature.GetGUIDLow()); return; } } // We have to set the destination here (for the first point), right after Initialize. Without, we may not have valid xyz for GetResetPosition CreatureTraveller traveller(creature); if (creature.CanFly()) creature.AddSplineFlag(SPLINEFLAG_FLYING); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); }
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_FLYING); // 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 %s.", i_path->at(i_currentNode).script_id, i_currentNode, creature.GetGuidStr().c_str()); 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.MonsterSay(behavior->textid[rand() % i], LANG_UNIVERSAL); } else creature.MonsterSay(behavior->textid[0], LANG_UNIVERSAL); } } // 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_FLYING); 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; }
//-----------------------------------------------// void WaypointMovementGenerator<Creature>::LoadPath(Creature& creature) { DETAIL_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "LoadPath: loading waypoint path for %s", creature.GetGuidStr().c_str()); i_path = sWaypointMgr.GetDefaultPath(creature.GetEntry(), creature.GetGUIDLow()); // No movement found for entry nor guid if (!i_path) { sLog.outErrorDb("WaypointMovementGenerator::LoadPath: %s doesn't have waypoint path", creature.GetGuidStr().c_str()); return; } if (i_path->empty()) return; // Initialize the i_currentNode to point to the first node i_currentNode = i_path->begin()->first; m_lastReachedWaypoint = 0; }