From c93256e4771253c8d74ce296f00fdd20af09725c Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sun, 3 Apr 2011 17:55:13 +0200 Subject: [PATCH] [11309] Extend SCRIPT_COMMAND_EMOTE, allow search for nearby creature to do the emote Also allow play emote on Player when player is source. Gameobject may be source of script but are only allowed as searcher for creature when defined. Signed-off-by: NoFantasy --- doc/script_commands.txt | 5 ++++- src/game/Map.cpp | 44 ++++++++++++++++++++++++++++++++++++---- src/game/ScriptMgr.cpp | 10 +++++++++ src/game/ScriptMgr.h | 9 +++++++- src/shared/revision_nr.h | 2 +- 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index bf6b71c0b..6d4ab0477 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -101,8 +101,11 @@ spell_scripts flag_buddy_as_target = 0x04 * dataint = text entry from db_script_string -table. dataint2-dataint4 optionally, for random selection of text - 1 SCRIPT_COMMAND_EMOTE source = unit + 1 SCRIPT_COMMAND_EMOTE source = Unit (or WorldObject when creature entry defined), target = Unit (or none) * datalong = emote_id + * datalong2 = creature entry (searching for a buddy, closest to source) + * datalong3 = creature search radius + * data_flags = flag_target_as_source = 0x01 2 SCRIPT_COMMAND_FIELD_SET source = any * datalong = field_id diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 3c0dbf7cd..9f6315517 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1912,20 +1912,56 @@ void Map::ScriptsProcess() break; } case SCRIPT_COMMAND_EMOTE: + { if (!source) { - sLog.outError("SCRIPT_COMMAND_EMOTE (script id %u) call for NULL creature.", step.script->id); + sLog.outError("SCRIPT_COMMAND_EMOTE (script id %u) call for NULL source.", step.script->id); break; } - if (source->GetTypeId()!=TYPEID_UNIT) + if (!source->isType(TYPEMASK_WORLDOBJECT)) { - sLog.outError("SCRIPT_COMMAND_EMOTE (script id %u) call for non-creature (TypeId: %u), skipping.", step.script->id, source->GetTypeId()); + sLog.outError("SCRIPT_COMMAND_EMOTE (script id %u) call for non-worldobject (TypeId: %u), skipping.", step.script->id, source->GetTypeId()); break; } + // When creatureEntry is not defined, GameObject can not be source + else if (!step.script->emote.creatureEntry) + { + if (!source->isType(TYPEMASK_UNIT)) + { + sLog.outError("SCRIPT_COMMAND_EMOTE (script id %u) are missing datalong2 (creature entry). Unsupported call for non-unit (TypeId: %u), skipping.", step.script->id, source->GetTypeId()); + break; + } + } - ((Creature*)source)->HandleEmote(step.script->emote.emoteId); + WorldObject* pSource = (WorldObject*)source; + Creature* pBuddy = NULL; + + // flag_target_as_source 0x01 + + // If target is Unit* and should do the emote (or should be source of searcher below) + if (target && target->isType(TYPEMASK_UNIT) && step.script->emote.flags & 0x01) + pSource = (WorldObject*)target; + + // If step has a buddy entry defined, search for it. + if (step.script->emote.creatureEntry) + { + MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSource, step.script->emote.creatureEntry, true, step.script->emote.searchRadius); + MaNGOS::CreatureLastSearcher searcher(pBuddy, u_check); + + Cell::VisitGridObjects(pSource, searcher, step.script->emote.searchRadius); + + // If buddy found, then use it or break (break since we must assume pBuddy was defined for a reason) + if (pBuddy) + pSource = (WorldObject*)pBuddy; + else + break; + } + + // Must be safe cast to Unit* + ((Unit*)pSource)->HandleEmote(step.script->emote.emoteId); break; + } case SCRIPT_COMMAND_FIELD_SET: if (!source) { diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index 76cbdeb66..c6f2eb8c4 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -175,6 +175,16 @@ void ScriptMgr::LoadScripts(ScriptMapMap& scripts, const char* tablename) sLog.outErrorDb("Table `%s` has invalid emote id (datalong = %u) in SCRIPT_COMMAND_EMOTE for script id %u", tablename, tmp.emote.emoteId, tmp.id); continue; } + if (tmp.emote.creatureEntry && !ObjectMgr::GetCreatureTemplate(tmp.emote.creatureEntry)) + { + sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_EMOTE for script id %u, but this creature_template does not exist.", tablename, tmp.emote.creatureEntry, tmp.id); + continue; + } + if (tmp.emote.creatureEntry && !tmp.emote.searchRadius) + { + sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_EMOTE for script id %u, but search radius is too small (datalong3 = %u).", tablename, tmp.emote.creatureEntry, tmp.id, tmp.emote.searchRadius); + continue; + } break; } case SCRIPT_COMMAND_TELEPORT_TO: diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index 33b5766fb..41e6af166 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -48,7 +48,10 @@ enum eScriptCommand // flag_original_source_as_target = 0x02 // flag_buddy_as_target = 0x04 // dataint = text entry from db_script_string -table. dataint2-4 optional for random selected text. - SCRIPT_COMMAND_EMOTE = 1, // source = unit, datalong = emote_id + SCRIPT_COMMAND_EMOTE = 1, // source = Unit (or WorldObject when creature entry defined), target = Unit (or none) + // datalong = emote_id + // datalong2 = creature entry (searching for a buddy, closest to source), datalong3 = creature search radius + // data_flags = flag_target_as_source = 0x01 SCRIPT_COMMAND_FIELD_SET = 2, // source = any, datalong = field_id, datalong2 = value SCRIPT_COMMAND_MOVE_TO = 3, // source = Creature, datalong2 = time, x/y/z SCRIPT_COMMAND_FLAG_SET = 4, // source = any, datalong = field_id, datalong2 = bitmask @@ -112,6 +115,10 @@ struct ScriptInfo struct // SCRIPT_COMMAND_EMOTE (1) { uint32 emoteId; // datalong + uint32 creatureEntry; // datalong2 + uint32 searchRadius; // datalong3 + uint32 unused1; // datalong4 + uint32 flags; // data_flags } emote; struct // SCRIPT_COMMAND_FIELD_SET (2) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0c5d82109..1fa9d3cb3 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11308" + #define REVISION_NR "11309" #endif // __REVISION_NR_H__