aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps/Map.cpp
diff options
context:
space:
mode:
authorazazel <none@none>2010-09-22 18:13:57 +0600
committerazazel <none@none>2010-09-22 18:13:57 +0600
commiteae0e5c822d979694f5d686269391c4643bc9fcf (patch)
tree45fa2324df331c0a43bd2a16efe74591dfeef196 /src/server/game/Maps/Map.cpp
parent562a8c272d2402a870a0f7a51b0742cc1e4d9192 (diff)
Scripts/DB_Scripts: massive cleanup of SCRIPT_COMMAND_* related staff
* add union into ScriptInfo structure (thanks NoFantasy for the idea); * move scripts methods from Map.cpp to new file MapScripts.cpp; * remove magic numbers and introduce eScriptFlags enumeration. It's just a beginning and more changes to come. Stay tuned! --HG-- branch : trunk
Diffstat (limited to 'src/server/game/Maps/Map.cpp')
-rw-r--r--src/server/game/Maps/Map.cpp949
1 files changed, 7 insertions, 942 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 085c9957c66..c5698b41584 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -18,33 +18,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "MapManager.h"
-#include "Player.h"
-#include "Vehicle.h"
-#include "GridNotifiers.h"
-#include "Log.h"
+#include "Map.h"
#include "GridStates.h"
+#include "ScriptMgr.h"
+#include "VMapFactory.h"
+#include "MapInstanced.h"
#include "CellImpl.h"
-#include "InstanceScript.h"
-#include "Map.h"
+#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
-#include "Config.h"
#include "Transport.h"
+#include "InstanceScript.h"
#include "ObjectAccessor.h"
+#include "MapManager.h"
#include "ObjectMgr.h"
-#include "World.h"
-#include "Group.h"
-#include "MapRefManager.h"
-#include "Vehicle.h"
-#include "WaypointManager.h"
-#include "DBCEnums.h"
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "GossipDef.h"
-#include "ScriptMgr.h"
-#include "MapInstanced.h"
-#include "InstanceSaveMgr.h"
-#include "VMapFactory.h"
#define DEFAULT_GRID_EXPIRY 300
#define MAX_GRID_LOAD_TIME 50
@@ -52,14 +38,6 @@
GridState* si_GridStates[MAX_GRID_STATE];
-struct ScriptAction
-{
- uint64 sourceGUID;
- uint64 targetGUID;
- uint64 ownerGUID; // owner of source if source is item
- ScriptInfo const* script; // pointer to static script data
-};
-
Map::~Map()
{
sScriptMgr.OnDestroyMap(this);
@@ -2677,919 +2655,6 @@ void BattlegroundMap::RemoveAllPlayers()
}
-/// Put scripts in the execution queue
-void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
-{
- ///- Find the script map
- ScriptMapMap::const_iterator s = scripts.find(id);
- if (s == scripts.end())
- return;
-
- // prepare static data
- uint64 sourceGUID = source ? source->GetGUID() : (uint64)0; //some script commands doesn't have source
- uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
- uint64 ownerGUID = (source->GetTypeId() == TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
-
- ///- Schedule script execution for all scripts in the script map
- ScriptMap const *s2 = &(s->second);
- bool immedScript = false;
- for (ScriptMap::const_iterator iter = s2->begin(); iter != s2->end(); ++iter)
- {
- ScriptAction sa;
- sa.sourceGUID = sourceGUID;
- sa.targetGUID = targetGUID;
- sa.ownerGUID = ownerGUID;
-
- sa.script = &iter->second;
- m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(time_t(sWorld.GetGameTime() + iter->first), sa));
- if (iter->first == 0)
- immedScript = true;
-
- sWorld.IncreaseScheduledScriptsCount();
- }
- ///- If one of the effects should be immediate, launch the script execution
- if (/*start &&*/ immedScript && !i_scriptLock)
- {
- i_scriptLock = true;
- ScriptsProcess();
- i_scriptLock = false;
- }
-}
-
-void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target)
-{
- // NOTE: script record _must_ exist until command executed
-
- // prepare static data
- uint64 sourceGUID = source ? source->GetGUID() : (uint64)0;
- uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
- uint64 ownerGUID = (source->GetTypeId() == TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
-
- ScriptAction sa;
- sa.sourceGUID = sourceGUID;
- sa.targetGUID = targetGUID;
- sa.ownerGUID = ownerGUID;
-
- sa.script = &script;
- m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(time_t(sWorld.GetGameTime() + delay), sa));
-
- sWorld.IncreaseScheduledScriptsCount();
-
- ///- If effects should be immediate, launch the script execution
- if (delay == 0 && !i_scriptLock)
- {
- i_scriptLock = true;
- ScriptsProcess();
- i_scriptLock = false;
- }
-}
-
-// Helpers for ScriptProcess method.
-inline Player* Map::_GetScriptPlayerSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo) const
-{
- Player *pPlayer = NULL;
- if (!source && !target)
- sLog.outError("%s source and target objects are NULL.", scriptInfo->GetDebugInfo().c_str());
- else
- {
- // Check target first, then source.
- if (target)
- pPlayer = target->ToPlayer();
- if (!pPlayer && source)
- pPlayer = source->ToPlayer();
-
- if (!pPlayer)
- sLog.outError("%s neither source nor target object is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.",
- scriptInfo->GetDebugInfo().c_str(),
- source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUIDLow() : 0,
- target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUIDLow() : 0);
- }
- return pPlayer;
-}
-
-inline Creature* Map::_GetScriptCreatureSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo, bool bReverse) const
-{
- Creature *pCreature = NULL;
- if (!source && !target)
- sLog.outError("%s source and target objects are NULL.", scriptInfo->GetDebugInfo().c_str());
- else
- {
- if (bReverse)
- {
- // Check target first, then source.
- if (target)
- pCreature = target->ToCreature();
- if (!pCreature && source)
- pCreature = source->ToCreature();
- }
- else
- {
- // Check source first, then target.
- if (source)
- pCreature = source->ToCreature();
- if (!pCreature && target)
- pCreature = target->ToCreature();
- }
-
- if (!pCreature)
- sLog.outError("%s neither source nor target are creatures (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.",
- scriptInfo->GetDebugInfo().c_str(),
- source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUIDLow() : 0,
- target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUIDLow() : 0);
- }
- return pCreature;
-}
-
-inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const
-{
- Unit* pUnit = NULL;
- if (!obj)
- sLog.outError("%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target");
- else if (!obj->isType(TYPEMASK_UNIT))
- sLog.outError("%s %s object is not unit (TypeId: %u, Entry: %u, GUID: %u), skipping.",
- scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow());
- else
- {
- pUnit = dynamic_cast<Unit*>(obj);
- if (!pUnit)
- sLog.outError("%s %s object could not be casted to unit.",
- scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target");
- }
- return pUnit;
-}
-
-inline Player* Map::_GetScriptPlayer(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const
-{
- Player* pPlayer = NULL;
- if (!obj)
- sLog.outError("%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target");
- else
- {
- pPlayer = obj->ToPlayer();
- if (!pPlayer)
- sLog.outError("%s %s object is not a player (TypeId: %u, Entry: %u, GUID: %u).",
- scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow());
- }
- return pPlayer;
-}
-
-inline Creature* Map::_GetScriptCreature(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const
-{
- Creature* pCreature = NULL;
- if (!obj)
- sLog.outError("%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target");
- else
- {
- pCreature = obj->ToCreature();
- if (!pCreature)
- sLog.outError("%s %s object is not a creature (TypeId: %u, Entry: %u, GUID: %u).", scriptInfo->GetDebugInfo().c_str(),
- isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow());
- }
- return pCreature;
-}
-
-inline WorldObject* Map::_GetScriptWorldObject(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const
-{
- WorldObject* pWorldObject = NULL;
- if (!obj)
- sLog.outError("%s %s object is NULL.",
- scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target");
- else
- {
- pWorldObject = dynamic_cast<WorldObject*>(obj);
- if (!pWorldObject)
- sLog.outError("%s %s object is not a world object (TypeId: %u, Entry: %u, GUID: %u).",
- scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow());
- }
- return pWorldObject;
-}
-
-inline void Map::_ScriptProcessDoor(Object* source, Object* target, const ScriptInfo* scriptInfo) const
-{
- bool bOpen = false;
- uint32 guid = scriptInfo->datalong;
- int32 nTimeToToggle = (int32) scriptInfo->datalong2;
- switch (scriptInfo->command)
- {
- case SCRIPT_COMMAND_OPEN_DOOR: bOpen = true; break;
- case SCRIPT_COMMAND_CLOSE_DOOR: break;
- default:
- sLog.outError("%s unknown command for _ScriptProcessDoor.", scriptInfo->GetDebugInfo().c_str());
- return;
- }
- if (!guid)
- sLog.outError("%s door guid is not specified.", scriptInfo->GetDebugInfo().c_str());
- else if (!source)
- sLog.outError("%s source object is NULL.", scriptInfo->GetDebugInfo().c_str());
- else if (!source->isType(TYPEMASK_UNIT))
- sLog.outError("%s source object is not unit (TypeId: %u, Entry: %u, GUID: %u), skipping.", scriptInfo->GetDebugInfo().c_str(),
- source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
- else
- {
- WorldObject* wSource = dynamic_cast <WorldObject*> (source);
- if (!wSource)
- sLog.outError("%s source object could not be casted to world object (TypeId: %u, Entry: %u, GUID: %u), skipping.",
- scriptInfo->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
- else
- {
- GameObject *pDoor = _FindGameObject(wSource, guid);
- if (!pDoor)
- sLog.outError("%s gameobject was not found (guid: %u).", scriptInfo->GetDebugInfo().c_str(), guid);
- else if (pDoor->GetGoType() != GAMEOBJECT_TYPE_DOOR)
- sLog.outError("%s gameobject is not a door (GoType: %u, Entry: %u, GUID: %u).",
- scriptInfo->GetDebugInfo().c_str(), pDoor->GetGoType(), pDoor->GetEntry(), pDoor->GetGUIDLow());
- else if (bOpen == (pDoor->GetGoState() == GO_STATE_READY))
- {
- if (nTimeToToggle < 15)
- nTimeToToggle = 15;
-
- pDoor->UseDoorOrButton(nTimeToToggle);
-
- if (target && target->isType(TYPEMASK_GAMEOBJECT))
- {
- GameObject* goTarget = dynamic_cast<GameObject*>(target);
- if (goTarget && goTarget->GetGoType() == GAMEOBJECT_TYPE_BUTTON)
- goTarget->UseDoorOrButton(nTimeToToggle);
- }
- }
- }
- }
-}
-
-inline GameObject* Map::_FindGameObject(WorldObject* pSearchObject, uint32 guid) const
-{
- GameObject *pGameObject = NULL;
-
- CellPair p(Trinity::ComputeCellPair(pSearchObject->GetPositionX(), pSearchObject->GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- Trinity::GameObjectWithDbGUIDCheck goCheck(*pSearchObject, guid);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(pSearchObject, pGameObject, goCheck);
-
- TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > objectChecker(checker);
- cell.Visit(p, objectChecker, *pSearchObject->GetMap());
-
- return pGameObject;
-}
-
-/// Process queued scripts
-void Map::ScriptsProcess()
-{
- if (m_scriptSchedule.empty())
- return;
-
- ///- Process overdue queued scripts
- std::multimap<time_t, ScriptAction>::iterator iter = m_scriptSchedule.begin();
- // ok as multimap is a *sorted* associative container
- while (!m_scriptSchedule.empty() && (iter->first <= sWorld.GetGameTime()))
- {
- ScriptAction const& step = iter->second;
-
- Object* source = NULL;
-
- if (step.sourceGUID)
- {
- switch (GUID_HIPART(step.sourceGUID))
- {
- case HIGHGUID_ITEM:
- // case HIGHGUID_CONTAINER: == HIGHGUID_ITEM
- {
- Player* player = HashMapHolder<Player>::Find(step.ownerGUID);
- if (player)
- source = player->GetItemByGuid(step.sourceGUID);
- break;
- }
- case HIGHGUID_UNIT:
- source = HashMapHolder<Creature>::Find(step.sourceGUID);
- break;
- case HIGHGUID_PET:
- source = HashMapHolder<Pet>::Find(step.sourceGUID);
- break;
- case HIGHGUID_PLAYER:
- source = HashMapHolder<Player>::Find(step.sourceGUID);
- break;
- case HIGHGUID_GAMEOBJECT:
- source = HashMapHolder<GameObject>::Find(step.sourceGUID);
- break;
- case HIGHGUID_CORPSE:
- source = HashMapHolder<Corpse>::Find(step.sourceGUID);
- break;
- case HIGHGUID_MO_TRANSPORT:
- for (MapManager::TransportSet::iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter)
- {
- if ((*iter)->GetGUID() == step.sourceGUID)
- {
- source = reinterpret_cast<Object*>(*iter);
- break;
- }
- }
- break;
- default:
- sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.sourceGUID));
- break;
- }
- }
-
- //if (source && !source->IsInWorld()) source = NULL;
-
- Object* target = NULL;
-
- if (step.targetGUID)
- {
- switch (GUID_HIPART(step.targetGUID))
- {
- case HIGHGUID_UNIT:
- target = HashMapHolder<Creature>::Find(step.targetGUID);
- break;
- case HIGHGUID_PET:
- target = HashMapHolder<Pet>::Find(step.targetGUID);
- break;
- //case HIGHGUID_VEHICLE:
- // target = HashMapHolder<Vehicle>::Find(step.targetGUID);
- // break;
- case HIGHGUID_PLAYER: // empty GUID case also
- target = HashMapHolder<Player>::Find(step.targetGUID);
- break;
- case HIGHGUID_GAMEOBJECT:
- target = HashMapHolder<GameObject>::Find(step.targetGUID);
- break;
- case HIGHGUID_CORPSE:
- target = HashMapHolder<Corpse>::Find(step.targetGUID);
- break;
- default:
- sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.targetGUID));
- break;
- }
- }
-
- //if (target && !target->IsInWorld()) target = NULL;
-
- std::string tableName = GetScriptsTableNameByType(step.script->type);
- std::string commandName = GetScriptCommandName(step.script->command);
- switch (step.script->command)
- {
- case SCRIPT_COMMAND_TALK:
- if (step.script->datalong > CHAT_TYPE_WHISPER && step.script->datalong != CHAT_MSG_RAID_BOSS_WHISPER)
- {
- sLog.outError("%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->datalong);
- break;
- }
- if (step.script->datalong2 & 0x1)
- {
- if (Player *pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script))
- {
- uint64 targetGUID = target ? target->GetGUID() : 0;
- LocaleConstant loc_idx = pSource->GetSession()->GetSessionDbLocaleIndex();
- const std::string text(sObjectMgr.GetTrinityString(step.script->dataint, loc_idx));
-
- switch (step.script->datalong)
- {
- case CHAT_TYPE_SAY:
- pSource->Say(text, LANG_UNIVERSAL);
- break;
- case CHAT_TYPE_YELL:
- pSource->Yell(text, LANG_UNIVERSAL);
- break;
- case CHAT_TYPE_TEXT_EMOTE:
- case CHAT_TYPE_BOSS_EMOTE:
- pSource->TextEmote(text);
- break;
- case CHAT_TYPE_WHISPER:
- if (!targetGUID || !IS_PLAYER_GUID(targetGUID))
- {
- sLog.outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
- break;
- }
- pSource->Whisper(text, LANG_UNIVERSAL, targetGUID);
- break;
- default:
- break; // must be already checked at load
- }
- }
- }
- else
- {
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- uint64 targetGUID = target ? target->GetGUID() : 0;
- switch (step.script->datalong)
- {
- case CHAT_TYPE_SAY:
- cSource->Say(step.script->dataint, LANG_UNIVERSAL, targetGUID);
- break;
- case CHAT_TYPE_YELL:
- cSource->Yell(step.script->dataint, LANG_UNIVERSAL, targetGUID);
- break;
- case CHAT_TYPE_TEXT_EMOTE:
- cSource->TextEmote(step.script->dataint, targetGUID);
- break;
- case CHAT_TYPE_BOSS_EMOTE:
- cSource->MonsterTextEmote(step.script->dataint, targetGUID, true);
- break;
- case CHAT_TYPE_WHISPER:
- if (!targetGUID || !IS_PLAYER_GUID(targetGUID))
- {
- sLog.outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
- break;
- }
- cSource->Whisper(step.script->dataint, targetGUID);
- break;
- case CHAT_MSG_RAID_BOSS_WHISPER: //42
- if (!targetGUID || !IS_PLAYER_GUID(targetGUID))
- {
- sLog.outError("%s attempt to raidbosswhisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
- break;
- }
- cSource->MonsterWhisper(step.script->dataint, targetGUID, true);
- break;
- default:
- break; // must be already checked at load
- }
- }
- }
- break;
-
- case SCRIPT_COMMAND_EMOTE:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- if (step.script->datalong2)
- cSource->SetUInt32Value(UNIT_NPC_EMOTESTATE, step.script->datalong);
- else
- cSource->HandleEmoteCommand(step.script->datalong);
- }
- break;
-
- case SCRIPT_COMMAND_FIELD_SET:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- // Validate field number.
- if (step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= cSource->GetValuesCount())
- sLog.outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.",
- step.script->GetDebugInfo().c_str(), step.script->datalong,
- cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow());
- else
- cSource->SetUInt32Value(step.script->datalong, step.script->datalong2);
- }
- break;
-
- case SCRIPT_COMMAND_MOVE_TO:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- cSource->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2);
- cSource->GetMap()->CreatureRelocation(cSource, step.script->x, step.script->y, step.script->z, 0);
- }
- break;
-
- case SCRIPT_COMMAND_FLAG_SET:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- // Validate field number.
- if (step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= cSource->GetValuesCount())
- sLog.outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.",
- step.script->GetDebugInfo().c_str(), step.script->datalong,
- source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
- else
- cSource->SetFlag(step.script->datalong, step.script->datalong2);
- }
- break;
-
- case SCRIPT_COMMAND_FLAG_REMOVE:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- // Validate field number.
- if (step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= cSource->GetValuesCount())
- sLog.outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.",
- step.script->GetDebugInfo().c_str(), step.script->datalong,
- source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
- else
- cSource->RemoveFlag(step.script->datalong, step.script->datalong2);
- }
- break;
-
- case SCRIPT_COMMAND_TELEPORT_TO:
- switch (step.script->datalong2)
- {
- case 0:
- // Source or target must be Player.
- if (Player *pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script))
- pSource->TeleportTo(step.script->datalong, step.script->x, step.script->y, step.script->z, step.script->o);
- break;
- case 1:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true))
- cSource->NearTeleportTo(step.script->x, step.script->y, step.script->z, step.script->o);
- break;
- default:
- sLog.outError("%s unknown datalong2 flag (%u), skipping.",
- step.script->GetDebugInfo().c_str(), step.script->datalong2);
- }
- break;
-
- case SCRIPT_COMMAND_KILL_CREDIT:
- // Source or target must be Player.
- if (Player *pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script))
- {
- if (step.script->datalong2)
- pSource->RewardPlayerAndGroupAtEvent(step.script->datalong, pSource);
- else
- pSource->KilledMonsterCredit(step.script->datalong, 0);
- }
- break;
-
- case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
- {
- // Source must be WorldObject.
- if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script))
- {
- if (!step.script->datalong)
- sLog.outError("%s creature entry (datalong) is not specified.", step.script->GetDebugInfo().c_str());
- else
- {
- float x = step.script->x;
- float y = step.script->y;
- float z = step.script->z;
- float o = step.script->o;
-
- if (!pSummoner->SummonCreature(step.script->datalong, x, y, z, o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, step.script->datalong2))
- sLog.outError("%s creature was not spawned (entry: %u).", step.script->GetDebugInfo().c_str(), step.script->datalong);
- }
- }
- break;
- }
-
- case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
- if (!step.script->datalong)
- {
- sLog.outError("%s gameobject entry (datalong) is not specified.", step.script->GetDebugInfo().c_str());
- break;
- }
-
- // Source or target must be WorldObject.
- if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script))
- {
- GameObject *pGO = _FindGameObject(pSummoner, step.script->datalong);
- if (!pGO)
- {
- sLog.outError("%s gameobject was not found (guid: %u).", step.script->GetDebugInfo().c_str(), step.script->datalong);
- break;
- }
-
- if (pGO->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE ||
- pGO->GetGoType() == GAMEOBJECT_TYPE_DOOR ||
- pGO->GetGoType() == GAMEOBJECT_TYPE_BUTTON ||
- pGO->GetGoType() == GAMEOBJECT_TYPE_TRAP)
- {
- sLog.outError("%s can not be used with gameobject of type %u (guid: %u).",
- step.script->GetDebugInfo().c_str(), uint32(pGO->GetGoType()), step.script->datalong);
- break;
- }
-
- // Check that GO is not spawned
- if (!pGO->isSpawned())
- {
- int32 nTimeToDespawn = step.script->datalong2 < 5 ? 5 : (int32) step.script->datalong2;
- pGO->SetLootState(GO_READY);
- pGO->SetRespawnTime(nTimeToDespawn);
-
- pGO->GetMap()->Add(pGO);
- }
- }
- break;
-
- case SCRIPT_COMMAND_OPEN_DOOR:
- case SCRIPT_COMMAND_CLOSE_DOOR:
- _ScriptProcessDoor(source, target, step.script);
- break;
-
- case SCRIPT_COMMAND_QUEST_EXPLORED:
- {
- if (!source)
- {
- sLog.outError("%s source object is NULL.", step.script->GetDebugInfo().c_str());
- break;
- }
- if (!target)
- {
- sLog.outError("%s target object is NULL.", step.script->GetDebugInfo().c_str());
- break;
- }
-
- // when script called for item spell casting then target == (unit or GO) and source is player
- WorldObject* worldObject;
- Player* pTarget = target->ToPlayer();
- if (pTarget)
- {
- if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER)
- {
- sLog.outError("%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.",
- step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow());
- break;
- }
- worldObject = dynamic_cast<WorldObject*>(source);
- }
- else
- {
- pTarget = source->ToPlayer();
- if (pTarget)
- {
- if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER)
- {
- sLog.outError("%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.",
- step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow());
- break;
- }
- worldObject = dynamic_cast<WorldObject*>(target);
- }
- else
- {
- sLog.outError("%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.",
- step.script->GetDebugInfo().c_str(),
- source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUIDLow() : 0,
- target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUIDLow() : 0);
- break;
- }
- }
-
- // quest id and flags checked at script loading
- if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) &&
- (step.script->datalong2 == 0 || worldObject->IsWithinDistInMap(pTarget, float(step.script->datalong2))))
- pTarget->AreaExploredOrEventHappens(step.script->datalong);
- else
- pTarget->FailQuest(step.script->datalong);
-
- break;
- }
-
- case SCRIPT_COMMAND_ACTIVATE_OBJECT:
- // Source must be Unit.
- if (Unit *pSource = _GetScriptUnit(source, true, step.script))
- {
- // Target must be GameObject.
- if (!target)
- {
- sLog.outError("%s target object is NULL.", step.script->GetDebugInfo().c_str());
- break;
- }
-
- if (target->GetTypeId() != TYPEID_GAMEOBJECT)
- {
- sLog.outError("%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping.",
- step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow());
- break;
- }
-
- if (GameObject *pGO = dynamic_cast<GameObject*>(target))
- pGO->Use(pSource);
- }
- break;
-
- case SCRIPT_COMMAND_REMOVE_AURA:
- // Source (datalong2 != 0) or target (datalong2 == 0) must be Unit.
- if (Unit *pTarget = _GetScriptUnit(step.script->datalong2 ? source : target, step.script->datalong2, step.script))
- pTarget->RemoveAurasDueToSpell(step.script->datalong);
- break;
-
- case SCRIPT_COMMAND_CAST_SPELL:
- {
- // TODO: Allow gameobjects to be targets and casters
- if (!source && !target)
- {
- sLog.outError("%s source and target objects are NULL.", step.script->GetDebugInfo().c_str());
- break;
- }
-
- Unit* uSource = NULL;
- Unit* uTarget = NULL;
- // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
- switch (step.script->datalong2)
- {
- case 0: // source -> target
- uSource = dynamic_cast<Unit*>(source);
- uTarget = dynamic_cast<Unit*>(target);
- break;
- case 1: // source -> source
- uSource = dynamic_cast<Unit*>(source);
- uTarget = uSource;
- break;
- case 2: // target -> target
- uSource = dynamic_cast<Unit*>(target);
- uTarget = uSource;
- break;
- case 3: // target -> source
- uSource = dynamic_cast<Unit*>(target);
- uTarget = dynamic_cast<Unit*>(source);
- break;
- case 4: // source -> creature with entry
- uSource = dynamic_cast<Unit*>(source);
- uTarget = GetClosestCreatureWithEntry(uSource, abs(step.script->dataint), step.script->x);
- break;
- }
-
- if (!uSource || !uSource->isType(TYPEMASK_UNIT))
- {
- sLog.outError("%s no source unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->datalong);
- break;
- }
-
- if (!uTarget || !uTarget->isType(TYPEMASK_UNIT))
- {
- sLog.outError("%s no target unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->datalong);
- break;
- }
-
- bool triggered = (step.script->datalong2 != 4) ? step.script->dataint & 0x1 : step.script->dataint < 0;
- uSource->CastSpell(uTarget, step.script->datalong, triggered);
- break;
- }
-
- case SCRIPT_COMMAND_PLAY_SOUND:
- // Source must be WorldObject.
- if (WorldObject* pSource = _GetScriptWorldObject(source, true, step.script))
- {
- // datalong2 bitmask: 0/1=anyone/target
- Player* pTarget = NULL;
- if (step.script->datalong2 & 1)
- {
- // Target must be Player.
- pTarget = _GetScriptPlayer(target, false, step.script);
- if (!pTarget)
- break;
- }
-
- // datalong2 bitmask: 0/2=without/with distance dependent
- if (step.script->datalong2 & 2)
- pSource->PlayDistanceSound(step.script->datalong, pTarget);
- else
- pSource->PlayDirectSound(step.script->datalong, pTarget);
- }
- break;
-
- case SCRIPT_COMMAND_CREATE_ITEM:
- // Target or source must be Player.
- if (Player* pReceiver = _GetScriptPlayerSourceOrTarget(source, target, step.script))
- {
- ItemPosCountVec dest;
- uint8 msg = pReceiver->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, step.script->datalong, step.script->datalong2);
- if (msg == EQUIP_ERR_OK)
- {
- if (Item* item = pReceiver->StoreNewItem(dest, step.script->datalong, true))
- pReceiver->SendNewItem(item, step.script->datalong2, false, true);
- }
- else
- pReceiver->SendEquipError(msg, NULL, NULL, step.script->datalong);
- }
- break;
-
- case SCRIPT_COMMAND_DESPAWN_SELF:
- // Target or source must be Creature.
- if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true))
- cSource->ForcedDespawn(step.script->datalong);
- break;
-
- case SCRIPT_COMMAND_LOAD_PATH:
- // Source must be Unit.
- if (Unit* pSource = _GetScriptUnit(source, true, step.script))
- {
- if (!sWaypointMgr->GetPath(step.script->datalong))
- sLog.outError("%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->datalong);
- else
- pSource->GetMotionMaster()->MovePath(step.script->datalong, step.script->datalong2);
- }
- break;
-
- case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT:
- {
- if (!step.script->datalong)
- {
- sLog.outError("%s creature entry is not specified, skipping.", step.script->GetDebugInfo().c_str());
- break;
- }
- if (!step.script->datalong2)
- {
- sLog.outError("%s script id is not specified, skipping.", step.script->GetDebugInfo().c_str());
- break;
- }
-
- Creature* cTarget;
- if (source) //using grid searcher
- {
- WorldObject* wSource = dynamic_cast <WorldObject*> (source);
-
- CellPair p(Trinity::ComputeCellPair(wSource->GetPositionX(), wSource->GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- Trinity::CreatureWithDbGUIDCheck target_check(wSource, step.script->datalong);
- Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(wSource, cTarget, target_check);
-
- TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
- cell.Visit(p, unit_checker, *wSource->GetMap());
- }
- else //check hashmap holders
- {
- if (CreatureData const* data = sObjectMgr.GetCreatureData(step.script->datalong))
- cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->datalong, data->id, HIGHGUID_UNIT), cTarget);
- }
-
- if (!cTarget)
- {
- sLog.outError("%s target was not found (entry: %u)", step.script->GetDebugInfo().c_str(), step.script->datalong);
- break;
- }
-
- //Lets choose our ScriptMap map
- ScriptMapMap *datamap = GetScriptsMapByType(ScriptsType(step.script->dataint));
- //if no scriptmap present...
- if (!datamap)
- {
- sLog.outError("%s unknown scriptmap (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->dataint);
- break;
- }
-
- // Insert script into schedule but do not start it
- ScriptsStart(*datamap, step.script->datalong2, cTarget, NULL);
- break;
- }
-
- case SCRIPT_COMMAND_KILL:
- // Source or target must be Creature.
- if (Creature *cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
- {
- if (cSource->isDead())
- sLog.outError("%s creature is already dead (Entry: %u, GUID: %u)",
- step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUIDLow());
- else
- {
- cSource->setDeathState(JUST_DIED);
- if (step.script->dataint == 1)
- cSource->RemoveCorpse();
- }
- }
- break;
-
- case SCRIPT_COMMAND_ORIENTATION:
- // Source must be Unit.
- if (Unit *pSource = _GetScriptUnit(source, true, step.script))
- {
- if (!step.script->datalong)
- pSource->SetOrientation(step.script->o);
- else
- {
- // Target must be Unit.
- Unit* pTarget = _GetScriptUnit(target, false, step.script);
- if (!pTarget)
- break;
-
- pSource->SetInFront(pTarget);
- }
-
- pSource->SendMovementFlagUpdate();
- }
- break;
-
- case SCRIPT_COMMAND_EQUIP:
- // Source must be Creature.
- if (Creature *cSource = _GetScriptCreature(source, true, step.script))
- cSource->LoadEquipment(step.script->datalong);
- break;
-
- case SCRIPT_COMMAND_MODEL:
- // Source must be Creature.
- if (Creature *cSource = _GetScriptCreature(source, true, step.script))
- cSource->SetDisplayId(step.script->datalong);
- break;
-
- case SCRIPT_COMMAND_CLOSE_GOSSIP:
- // Source must be Player.
- if (Player *pSource = _GetScriptPlayer(source, true, step.script))
- pSource->PlayerTalkClass->CloseGossip();
- break;
-
- case SCRIPT_COMMAND_PLAYMOVIE:
- // Source must be Player.
- if (Player *pSource = _GetScriptPlayer(source, true, step.script))
- pSource->SendMovieStart(step.script->datalong);
- break;
-
- default:
- sLog.outError("Unknown script command %s.", step.script->GetDebugInfo().c_str());
- break;
- }
-
- m_scriptSchedule.erase(iter);
- sWorld.DecreaseScheduledScriptCount();
-
- iter = m_scriptSchedule.begin();
- }
-}
-
Creature*
Map::GetCreature(uint64 guid)
{