From 8b10ac9474a0d5b06157c3de119089ab30b9b80f Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Wed, 15 Sep 2010 11:48:12 +0200 Subject: [PATCH] [10487] Implement SCRIPT_COMMAND_MOVEMENT(20) to start/change movement datalong can be 0:idle, 2:random, 3:waypoint. In case 3, creature must have a existing creature_movement_template. Command start movement for source of script. If source is not creature but target is, it will apply to target. Optionally creature entry can be defined (datalong2) and start movement for this if found nearby (search radius defined in datalong3). Signed-off-by: NoFantasy --- src/game/Map.cpp | 60 ++++++++++++++++++++++++++++++++++++++++ src/game/ObjectMgr.cpp | 23 ++++++++++++++- src/game/World.h | 2 ++ src/shared/revision_nr.h | 2 +- 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 28ab92b86..0744cb43a 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -2876,6 +2876,66 @@ void Map::ScriptsProcess() break; } + case SCRIPT_COMMAND_MOVEMENT: + { + if (!source) + { + sLog.outError("SCRIPT_COMMAND_MOVEMENT (script id %u) call for NULL source.", step.script->id); + break; + } + + if (!source->isType(TYPEMASK_WORLDOBJECT)) + { + sLog.outError("SCRIPT_COMMAND_MOVEMENT (script id %u) call for unsupported non-worldobject (TypeId: %u), skipping.", step.script->id, source->GetTypeId()); + break; + } + + WorldObject* pSource = (WorldObject*)source; + Creature* pMover = NULL; + + if (!step.script->datalong2) // No buddy defined, so try use source (or target where source is player) + { + if (pSource->GetTypeId() != TYPEID_UNIT) + { + // we can't move source being non-creature, so see if target is creature + if (target && target->GetTypeId() == TYPEID_UNIT) + pMover = (Creature*)target; + } + else if (pSource->GetTypeId() == TYPEID_UNIT) + pMover = (Creature*)pSource; + } + else // If step has a buddy entry defined, search for it + { + MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSource, step.script->datalong2, true, step.script->datalong3); + MaNGOS::CreatureLastSearcher searcher(pSource, pMover, u_check); + + Cell::VisitGridObjects(pSource, searcher, step.script->datalong3); + } + + if (!pMover) + { + sLog.outError("SCRIPT_COMMAND_MOVEMENT (script id %u) call for non-creature (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", step.script->id, source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0); + break; + } + + // Consider add additional checks for cases where creature should not change movementType + // (pet? in combat? already using same MMgen as script try to apply?) + + switch(step.script->datalong) + { + case IDLE_MOTION_TYPE: + pMover->GetMotionMaster()->MoveIdle(); + break; + case RANDOM_MOTION_TYPE: + pMover->GetMotionMaster()->MoveRandom(); + break; + case WAYPOINT_MOTION_TYPE: + pMover->GetMotionMaster()->MoveWaypoint(); + break; + } + + break; + } default: sLog.outError("Unknown SCRIPT_COMMAND_ %u called for script id %u.",step.script->command, step.script->id); break; diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index c3f4b9263..950c8d20a 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -4663,7 +4663,28 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) continue; } break; - } + } + case SCRIPT_COMMAND_MOVEMENT: + { + if (tmp.datalong >= MAX_DB_MOTION_TYPE) + { + sLog.outErrorDb("Table `%s` SCRIPT_COMMAND_MOVEMENT has invalid MovementType %u for script id %u", + tablename, tmp.datalong, tmp.id); + continue; + } + if (tmp.datalong2 && !GetCreatureTemplate(tmp.datalong2)) + { + sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_MOVEMENT for script id %u, but this creature_template does not exist.", tablename, tmp.datalong2, tmp.id); + continue; + } + if (tmp.datalong2 && !tmp.datalong3) + { + sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_MOVEMENT for script id %u, but search radius is too small (datalong3 = %u).", tablename, tmp.datalong2, tmp.id, tmp.datalong3); + continue; + } + + break; + } } if (scripts.find(tmp.id) == scripts.end()) diff --git a/src/game/World.h b/src/game/World.h index 723ecc89e..edee8b9b1 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -417,6 +417,8 @@ enum RealmZone #define SCRIPT_COMMAND_CREATE_ITEM 17 // source or target must be player, datalong = item entry, datalong2 = amount #define SCRIPT_COMMAND_DESPAWN_SELF 18 // source or target must be creature, datalong = despawn delay #define SCRIPT_COMMAND_PLAY_MOVIE 19 // target can only be a player, datalog = movie id +#define SCRIPT_COMMAND_MOVEMENT 20 // source or target must be creature. datalong = MovementType (0:idle, 1:random or 2:waypoint) + // datalong2 = creature entry (searching for a buddy, closest to source), datalong3 = creature search radius /// Storage class for commands issued for delayed execution struct CliCommandHolder diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c7d82f3a0..bfdc1a86c 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 "10486" + #define REVISION_NR "10487" #endif // __REVISION_NR_H__