diff --git a/src/game/Maps/Map.h b/src/game/Maps/Map.h index 4d9c05517..590a573dc 100644 --- a/src/game/Maps/Map.h +++ b/src/game/Maps/Map.h @@ -828,6 +828,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj bool ScriptCommand_SetMapEventData(const ScriptInfo& script, WorldObject* source, WorldObject* target); bool ScriptCommand_SendMapEvent(const ScriptInfo& script, WorldObject* source, WorldObject* target); bool ScriptCommand_SetDefaultMovement(const ScriptInfo& script, WorldObject* source, WorldObject* target); + bool ScriptCommand_StartScriptForAll(const ScriptInfo& script, WorldObject* source, WorldObject* target); // Add any new script command functions to the array. const ScriptCommandFunction m_ScriptCommands[SCRIPT_COMMAND_MAX] = @@ -900,6 +901,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj &Map::ScriptCommand_SetMapEventData, // 65 &Map::ScriptCommand_SendMapEvent, // 66 &Map::ScriptCommand_SetDefaultMovement, // 67 + &Map::ScriptCommand_StartScriptForAll, // 68 }; public: diff --git a/src/game/Maps/ScriptCommands.cpp b/src/game/Maps/ScriptCommands.cpp index 53dfc29c2..5ca74c8f4 100644 --- a/src/game/Maps/ScriptCommands.cpp +++ b/src/game/Maps/ScriptCommands.cpp @@ -384,20 +384,7 @@ bool Map::ScriptCommand_SummonCreature(const ScriptInfo& script, WorldObject* so } } - float orientation = o; - - if ((script.summonCreature.facingLogic == SO_SUMMONCREATURE_FACE_SUMMONER) || (script.summonCreature.facingLogic == SO_SUMMONCREATURE_FACE_TARGET)) - { - WorldObject* facingTarget = ((script.summonCreature.facingLogic == SO_SUMMONCREATURE_FACE_TARGET) && target && target->isType(TYPEMASK_WORLDOBJECT)) ? static_cast(target) : pSummoner; - - float dx = facingTarget->GetPositionX() - x; - float dy = facingTarget->GetPositionY() - y; - - orientation = atan2(dy, dx); - orientation = (orientation >= 0) ? orientation : 2 * M_PI_F + orientation; - } - - Creature* pCreature = pSummoner->SummonCreature(script.summonCreature.creatureEntry, x, y, z, orientation, + Creature* pCreature = pSummoner->SummonCreature(script.summonCreature.creatureEntry, x, y, z, o, TempSummonType(script.summonCreature.despawnType), script.summonCreature.despawnDelay, script.summonCreature.flags & SF_SUMMONCREATURE_ACTIVE); if (!pCreature) @@ -431,6 +418,9 @@ bool Map::ScriptCommand_SummonCreature(const ScriptInfo& script, WorldObject* so } } + if (script.summonCreature.scriptId) + ScriptsStart(sEventScripts, script.summonCreature.scriptId, pCreature, target); + return false; } @@ -1840,5 +1830,61 @@ bool Map::ScriptCommand_SetDefaultMovement(const ScriptInfo& script, WorldObject if (pSource->isAlive()) pSource->GetMotionMaster()->InitializeNewDefault(script.setDefaultMovement.alwaysReplace); + return false; +} + +// SCRIPT_COMMAND_START_SCRIPT_FOR_ALL (68) +bool Map::ScriptCommand_StartScriptForAll(const ScriptInfo& script, WorldObject* source, WorldObject* target) +{ + if (!source) + { + sLog.outError("SCRIPT_COMMAND_START_SCRIPT_FOR_ALL (script id %u) call for a NULL source, skipping.", script.id); + return ShouldAbortScript(script); + } + + std::list targets; + + MaNGOS::AllWorldObjectsInRange u_check(source, script.startScriptForAll.searchRadius); + MaNGOS::WorldObjectListSearcher searcher(targets, u_check); + + Cell::VisitAllObjects(source, searcher, script.startScriptForAll.searchRadius); + + for (auto pWorldObject : targets) + { + if (!pWorldObject) + continue; + + switch (script.startScriptForAll.objectType) + { + case SO_STARTFORALL_GAMEOBJECTS: + { + if (!pWorldObject->IsGameObject()) + continue; + break; + } + case SO_STARTFORALL_UNITS: + { + if (!pWorldObject->IsUnit()) + continue; + break; + } + case SO_STARTFORALL_CREATURES: + { + if (!pWorldObject->IsCreature()) + continue; + break; + } + case SO_STARTFORALL_PLAYERS: + { + if (!pWorldObject->IsPlayer()) + continue; + break; + } + } + + if (!script.startScriptForAll.objectEntry || (pWorldObject->GetEntry() == script.startScriptForAll.objectEntry)) + ScriptsStart(sEventScripts, script.startScriptForAll.scriptId, pWorldObject, target); + } + return false; } \ No newline at end of file diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index b8dc716cf..64d4429dc 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -1002,6 +1002,62 @@ void ScriptMgr::LoadScripts(ScriptMapMap& scripts, const char* tablename) } break; } + case SCRIPT_COMMAND_START_SCRIPT_FOR_ALL: + { + if (!tmp.startScriptForAll.searchRadius) + { + sLog.outErrorDb("Table `%s` has datalong4 = %u in SCRIPT_COMMAND_START_SCRIPT_FOR_ALL for script id %u.", tablename, tmp.startScriptForAll.searchRadius, tmp.id); + continue; + } + switch (tmp.startScriptForAll.objectType) + { + case SO_STARTFORALL_GAMEOBJECTS: + { + if (tmp.startScriptForAll.objectEntry) + { + if (!ObjectMgr::GetGameObjectInfo(tmp.startScriptForAll.objectEntry)) + { + if (!sObjectMgr.IsExistingGameObjectId(tmp.startScriptForAll.objectEntry)) + { + sLog.outErrorDb("Table `%s` has gameobject with invalid entry (datalong3: %u) in SCRIPT_COMMAND_START_SCRIPT_FOR_ALL for script id %u", tablename, tmp.startScriptForAll.objectEntry, tmp.id); + continue; + } + else + DisableScriptAction(tmp); + } + } + break; + } + case SO_STARTFORALL_CREATURES: + { + if (tmp.startScriptForAll.objectEntry) + { + if (!ObjectMgr::GetCreatureTemplate(tmp.startScriptForAll.objectEntry)) + { + if (!sObjectMgr.IsExistingCreatureId(tmp.startScriptForAll.objectEntry)) + { + sLog.outErrorDb("Table `%s` has invalid creature (datalong3: %u) in SCRIPT_COMMAND_START_SCRIPT_FOR_ALL for script id %u", tablename, tmp.startScriptForAll.objectEntry, tmp.id); + continue; + } + else + DisableScriptAction(tmp); + } + } + break; + } + case SO_STARTFORALL_UNITS: + case SO_STARTFORALL_PLAYERS: + { + break; + } + default: + { + sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_START_SCRIPT_FOR_ALL for script id %u.", tablename, tmp.startScriptForAll.objectType, tmp.id); + continue; + } + } + break; + } } if (scripts.find(tmp.id) == scripts.end()) @@ -2058,6 +2114,7 @@ void ScriptMgr::CollectPossibleEventIds(std::set& eventIds) for (uint8 i = 0; i < 9; i++) { + // From SCRIPT_COMMAND_START_SCRIPT. result = WorldDatabase.PQuery("SELECT datalong, datalong2, datalong3, datalong4 FROM %s WHERE command=39", script_tables[i]); if (result) @@ -2080,6 +2137,36 @@ void ScriptMgr::CollectPossibleEventIds(std::set& eventIds) } while (result->NextRow()); delete result; } + + //From SCRIPT_COMMAND_TEMP_SUMMON_CREATURE. + result = WorldDatabase.PQuery("SELECT dataint2 FROM %s WHERE command=10 && dataint2!=0", script_tables[i]); + + if (result) + { + do + { + fields = result->Fetch(); + uint32 event1 = fields[0].GetUInt32(); + if (event1) + eventIds.insert(event1); + } while (result->NextRow()); + delete result; + } + + // From SCRIPT_COMMAND_START_SCRIPT_FOR_ALL. + result = WorldDatabase.PQuery("SELECT datalong FROM %s WHERE command=68", script_tables[i]); + + if (result) + { + do + { + fields = result->Fetch(); + uint32 event1 = fields[0].GetUInt32(); + if (event1) + eventIds.insert(event1); + } while (result->NextRow()); + delete result; + } } } diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index 5d4580ebc..1992a5abc 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -98,7 +98,7 @@ enum eScriptCommand // datalong3 = unique_limit // datalong4 = unique_distance // dataint = eSummonCreatureFlags - // dataint2 = eSummonCreatureFacingOptions + // dataint2 = script_id // dataint3 = attack_target (see enum Target) // dataint4 = despawn_type (see enum TempSummonType) // x/y/z/o = coordinates @@ -284,8 +284,13 @@ enum eScriptCommand // datalong3 = eSendMapEventOptions SCRIPT_COMMAND_SET_DEFAULT_MOVEMENT = 67, // source = Creature // datalong = movement_type - // datalong = (bool) always_replace + // datalong2 = (bool) always_replace // datalong3 = param1 + SCRIPT_COMMAND_START_SCRIPT_FOR_ALL = 68, // source = WorldObject + // datalong = script_id + // datalong2 = eStartScriptForAllOptions + // datalong3 = object_entry + // datalong4 = search_radius SCRIPT_COMMAND_MAX, @@ -330,13 +335,6 @@ enum eSummonCreatureFlags SF_SUMMONCREATURE_UNIQUE_TEMP = 0x8 // same as 0x10 but check for TempSummon only creatures }; -// Possible dataint2 values for SCRIPT_COMMAND_TEMP_SUMMON_CREATURE -enum eSummonCreatureFacingOptions -{ - SO_SUMMONCREATURE_FACE_SUMMONER = 1, // Creature will face the summoner. - SO_SUMMONCREATURE_FACE_TARGET = 2 // Creature will face the provided target object. -}; - // Flags used by SCRIPT_COMMAND_PLAY_SOUND enum ePlaySoundFlags { @@ -439,6 +437,17 @@ enum eSendMapEventOptions SO_SENDMAPEVENT_MAX }; +// Possible datalong2 values for SCRIPT_COMMAND_START_SCRIPT_FOR_ALL +enum eStartScriptForAllOptions +{ + SO_STARTFORALL_GAMEOBJECTS = 0, + SO_STARTFORALL_UNITS = 1, + SO_STARTFORALL_CREATURES = 2, + SO_STARTFORALL_PLAYERS = 3, + + SO_STARTFORALL_MAX +}; + enum eDataFlags { SF_GENERAL_SWAP_INITIAL_TARGETS = 0x1, // Swaps the provided source and target, before buddy is checked. @@ -537,7 +546,7 @@ struct ScriptInfo uint32 uniqueDistance; // datalong4 uint32 unused; // data_flags int32 flags; // dataint - int32 facingLogic; // dataint2 + int32 scriptId; // dataint2 int32 attackTarget; // dataint3 int32 despawnType; // dataint4 } summonCreature; @@ -882,6 +891,14 @@ struct ScriptInfo uint32 param1; // datalong3 } setDefaultMovement; + struct // SCRIPT_COMMAND_START_SCRIPT_FOR_ALL (68) + { + uint32 scriptId; // datalong + uint32 objectType; // datalong2 + uint32 objectEntry; // datalong3 + uint32 searchRadius; // datalong4 + } startScriptForAll; + struct { uint32 data[9];