/* * Copyright (C) 2010 - 2014 Eluna Lua Engine * This program is free software licensed under GPL version 3 * Please see the included DOCS/LICENSE.md for more information */ #ifndef WORLDOBJECTMETHODS_H #define WORLDOBJECTMETHODS_H namespace LuaWorldObject { /** * Returns the name of the [WorldObject] * * @return string name */ int GetName(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetName()); return 1; } /** * Returns the current [Map] object of the [WorldObject] * * @return [Map] mapObject */ int GetMap(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetMap()); return 1; } #if (!defined(TBC) && !defined(CLASSIC)) /** * Returns the current phase of the [WorldObject] * * @return uint32 phase */ int GetPhaseMask(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetPhaseMask()); return 1; } #endif /** * Returns the current instance ID of the [WorldObject] * * @return uint32 instanceId */ int GetInstanceId(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetInstanceId()); return 1; } /** * Returns the current area ID of the [WorldObject] * * @return uint32 areaId */ int GetAreaId(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetAreaId()); return 1; } /** * Returns the current zone ID of the [WorldObject] * * @return uint32 zoneId */ int GetZoneId(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetZoneId()); return 1; } /** * Returns the current map ID of the [WorldObject] * * @return uint32 mapId */ int GetMapId(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetMapId()); return 1; } /** * Returns the current X coordinate of the [WorldObject] * * @return float x */ int GetX(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetPositionX()); return 1; } /** * Returns the current Y coordinate of the [WorldObject] * * @return float y */ int GetY(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetPositionY()); return 1; } /** * Returns the current Z coordinate of the [WorldObject] * * @return float z */ int GetZ(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetPositionZ()); return 1; } /** * Returns the current orientation of the [WorldObject] * * @return float orientation / facing */ int GetO(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetOrientation()); return 1; } /** * Returns the coordinates and orientation of the [WorldObject] * * @return float x : x coordinate of the [WorldObject] * @return float y : y coordinate of the [WorldObject] * @return float z : z coordinate (height) of the [WorldObject] * @return float o : facing / orientation of the [WorldObject] */ int GetLocation(lua_State* L, WorldObject* obj) { Eluna::Push(L, obj->GetPositionX()); Eluna::Push(L, obj->GetPositionY()); Eluna::Push(L, obj->GetPositionZ()); Eluna::Push(L, obj->GetOrientation()); return 4; } /** * Returns the nearest [Player] object in sight of the [WorldObject] or within the given range * * @param float range = 533.33333 : optionally set range. Default range is grid size * * @return [Player] nearestPlayer */ int GetNearestPlayer(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); Unit* target = NULL; ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_PLAYER); #ifndef TRINITY MaNGOS::UnitLastSearcher searcher(target, checker); Cell::VisitWorldObjects(obj, searcher, range); #else Trinity::UnitLastSearcher searcher(obj, target, checker); obj->VisitNearbyObject(range, searcher); #endif Eluna::Push(L, target); return 1; } /** * Returns the nearest [GameObject] object in sight of the [WorldObject] or within the given range and/or with a specific entry ID * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of game object to find * * @return [GameObject] nearestGameObject */ int GetNearestGameObject(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); GameObject* target = NULL; ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_GAMEOBJECT, entry); #ifndef TRINITY MaNGOS::GameObjectLastSearcher searcher(target, checker); Cell::VisitGridObjects(obj, searcher, range); #else Trinity::GameObjectLastSearcher searcher(obj, target, checker); obj->VisitNearbyObject(range, searcher); #endif Eluna::Push(L, target); return 1; } /** * Returns the nearest [Creature] object in sight of the [WorldObject] or within the given range and/or with a specific entry ID * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of creature to find * * @return [Creature] nearestCreature */ int GetNearestCreature(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); Creature* target = NULL; ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_UNIT, entry); #ifndef TRINITY MaNGOS::CreatureLastSearcher searcher(target, checker); Cell::VisitGridObjects(obj, searcher, range); #else Trinity::CreatureLastSearcher searcher(obj, target, checker); obj->VisitNearbyObject(range, searcher); #endif Eluna::Push(L, target); return 1; } /** * Returns a table of [Player] objects in sight of the [WorldObject] or within the given range * * @param float range = 533.33333 : optionally set range. Default range is grid size * * @return table playersInRange : table of [Player]s */ int GetPlayersInRange(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); std::list list; ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_PLAYER); #ifndef TRINITY MaNGOS::PlayerListSearcher searcher(list, checker); Cell::VisitWorldObjects(obj, searcher, range); #else Trinity::PlayerListSearcher searcher(obj, list, checker); obj->VisitNearbyObject(range, searcher); #endif lua_newtable(L); int tbl = lua_gettop(L); uint32 i = 0; for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) { Eluna::Push(L, ++i); Eluna::Push(L, *it); lua_settable(L, tbl); } lua_settop(L, tbl); return 1; } /** * Returns a table of [Creature] objects in sight of the [WorldObject] or within the given range and/or with a specific entry ID * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of creatures to find * * @return table creaturesInRange : table of [Creature]s */ int GetCreaturesInRange(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); std::list list; ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry); #ifndef TRINITY MaNGOS::CreatureListSearcher searcher(list, checker); Cell::VisitGridObjects(obj, searcher, range); #else Trinity::CreatureListSearcher searcher(obj, list, checker); obj->VisitNearbyObject(range, searcher); #endif lua_newtable(L); int tbl = lua_gettop(L); uint32 i = 0; for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) { Eluna::Push(L, ++i); Eluna::Push(L, *it); lua_settable(L, tbl); } lua_settop(L, tbl); return 1; } /** * Returns a table of [GameObject] objects in sight of the [WorldObject] or within the given range and/or with a specific entry ID * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of game objects to find * * @return table gameObjectsInRange : table of [GameObject]s */ int GetGameObjectsInRange(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); std::list list; ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_GAMEOBJECT, entry); #ifndef TRINITY MaNGOS::GameObjectListSearcher searcher(list, checker); Cell::VisitGridObjects(obj, searcher, range); #else Trinity::GameObjectListSearcher searcher(obj, list, checker); obj->VisitNearbyObject(range, searcher); #endif lua_newtable(L); int tbl = lua_gettop(L); uint32 i = 0; for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) { Eluna::Push(L, ++i); Eluna::Push(L, *it); lua_settable(L, tbl); } lua_settop(L, tbl); return 1; } /** * Returns nearest [WorldObject] in sight of the [WorldObject]. * The distance, type, entry and hostility requirements the [WorldObject] must match can be passed. * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param [TypeMask] type = 0 : the [TypeMask] that the [WorldObject] must be. This can contain multiple types. 0 will be ingored * @param uint32 entry = 0 : the entry of the [WorldObject], 0 will be ingored * @param uint32 hostile = 0 : specifies whether the [WorldObject] needs to be 1 hostile, 2 friendly or 0 either * * @return [WorldObject] worldObject */ int GetNearObject(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint16 type = Eluna::CHECKVAL(L, 3, 0); // TypeMask uint32 entry = Eluna::CHECKVAL(L, 4, 0); uint32 hostile = Eluna::CHECKVAL(L, 5, 0); // 0 none, 1 hostile, 2 friendly float x, y, z; obj->GetPosition(x, y, z); ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, type, entry, hostile); WorldObject* target = NULL; #ifndef TRINITY MaNGOS::WorldObjectLastSearcher searcher(target, checker); Cell::VisitAllObjects(obj, searcher, range); #else Trinity::WorldObjectLastSearcher searcher(obj, target, checker); obj->VisitNearbyObject(range, searcher); #endif Eluna::Push(L, target); return 1; } /** * Returns a table of [WorldObject]s in sight of the [WorldObject]. * The distance, type, entry and hostility requirements the [WorldObject] must match can be passed. * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param [TypeMask] type = 0 : the [TypeMask] that the [WorldObject] must be. This can contain multiple types. 0 will be ingored * @param uint32 entry = 0 : the entry of the [WorldObject], 0 will be ingored * @param uint32 hostile = 0 : specifies whether the [WorldObject] needs to be 1 hostile, 2 friendly or 0 either * * @return table worldObjectList : table of [WorldObject]s */ int GetNearObjects(lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint16 type = Eluna::CHECKVAL(L, 3, 0); // TypeMask uint32 entry = Eluna::CHECKVAL(L, 4, 0); uint32 hostile = Eluna::CHECKVAL(L, 5, 0); // 0 none, 1 hostile, 2 friendly float x, y, z; obj->GetPosition(x, y, z); ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, type, entry, hostile); std::list list; #ifndef TRINITY MaNGOS::WorldObjectListSearcher searcher(list, checker); Cell::VisitAllObjects(obj, searcher, range); #else Trinity::WorldObjectListSearcher searcher(obj, list, checker); obj->VisitNearbyObject(range, searcher); #endif lua_newtable(L); int tbl = lua_gettop(L); uint32 i = 0; for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) { Eluna::Push(L, ++i); Eluna::Push(L, *it); lua_settable(L, tbl); } lua_settop(L, tbl); return 1; } /** * Returns a [WorldObject] based on it's guid if it is spawned * * @param uint64 guid * * @return [WorldObject] worldObject */ int GetWorldObject(lua_State* L, WorldObject* obj) { uint64 guid = Eluna::CHECKVAL(L, 2); #ifndef TRINITY switch (GUID_HIPART(guid)) { case HIGHGUID_PLAYER: Eluna::Push(L, obj->GetMap()->GetPlayer(ObjectGuid(guid))); break; case HIGHGUID_TRANSPORT: case HIGHGUID_MO_TRANSPORT: case HIGHGUID_GAMEOBJECT: Eluna::Push(L, obj->GetMap()->GetGameObject(ObjectGuid(guid))); break; #if (!defined(TBC) && !defined(CLASSIC)) case HIGHGUID_VEHICLE: #endif case HIGHGUID_UNIT: case HIGHGUID_PET: Eluna::Push(L, obj->GetMap()->GetAnyTypeCreature(ObjectGuid(guid))); break; } #else switch (GUID_HIPART(guid)) { case HIGHGUID_PLAYER: Eluna::Push(L, eObjectAccessor->GetPlayer(*obj, ObjectGuid(guid))); break; case HIGHGUID_TRANSPORT: case HIGHGUID_MO_TRANSPORT: case HIGHGUID_GAMEOBJECT: Eluna::Push(L, eObjectAccessor->GetGameObject(*obj, ObjectGuid(guid))); break; case HIGHGUID_VEHICLE: case HIGHGUID_UNIT: Eluna::Push(L, eObjectAccessor->GetCreature(*obj, ObjectGuid(guid))); break; case HIGHGUID_PET: Eluna::Push(L, eObjectAccessor->GetPet(*obj, ObjectGuid(guid))); break; } #endif return 1; } /** * Returns the distance from this [WorldObject] to another [WorldObject], or from this [WorldObject] to a point. * * @proto dist = (obj) * @proto dist = (x, y, z) * * @param [WorldObject] obj * @param float x : the X-coordinate of the point * @param float y : the Y-coordinate of the point * @param float z : the Z-coordinate of the point * * @return float dist : the distance in yards */ int GetDistance(lua_State* L, WorldObject* obj) { WorldObject* target = Eluna::CHECKOBJ(L, 2, false); if (target && target->IsInWorld()) Eluna::Push(L, obj->GetDistance(target)); else { float X = Eluna::CHECKVAL(L, 2); float Y = Eluna::CHECKVAL(L, 3); float Z = Eluna::CHECKVAL(L, 4); Eluna::Push(L, obj->GetDistance(X, Y, Z)); } return 1; } /** * Returns a point relative to the [WorldObject]. * With distance set to 1 and angle set to 0, this will return a point 1 yard in front of the [WorldObject] * * @param [WorldObject] object * @param float distance : specifies the distance of the point from the [WorldObject] in yards * @param float angle : specifies the angle of the point relative to the orientation / facing of the [WorldObject] in radians * * @return float x * @return float y * @return float z */ int GetRelativePoint(lua_State* L, WorldObject* obj) { float dist = Eluna::CHECKVAL(L, 2); float rad = Eluna::CHECKVAL(L, 3); float x, y, z; obj->GetClosePoint(x, y, z, 0.0f, dist, rad); Eluna::Push(L, x); Eluna::Push(L, y); Eluna::Push(L, z); return 3; } /** * Returns the angle between this [WorldObject] and another [WorldObject] or a point. * The angle is the angle between two points and orientation will be ignored. * * @proto dist = (obj) * @proto dist = (x, y) * * @param [WorldObject] object * @param float x * @param float y * * @return float angle : angle in radians in range 0..2*pi */ int GetAngle(lua_State* L, WorldObject* obj) { WorldObject* target = Eluna::CHECKOBJ(L, 2, false); if (target && target->IsInWorld()) Eluna::Push(L, obj->GetAngle(target)); else { float x = Eluna::CHECKVAL(L, 2); float y = Eluna::CHECKVAL(L, 3); Eluna::Push(L, obj->GetAngle(x, y)); } return 1; } /** * Sends a [WorldPacket] to [Player]s in sight of the [WorldObject]. * * @param [WorldPacket] packet */ int SendPacket(lua_State* L, WorldObject* obj) { WorldPacket* data = Eluna::CHECKOBJ(L, 2); obj->SendMessageToSet(data, true); return 0; } /** * Spawns a [GameObject] at specified location. * * @param uint32 entry : [GameObject] entry ID * @param float x * @param float y * @param float z * @param float o * @param uint32 respawnDelay = 30 : respawn time in seconds * @return [GameObject] gameObject */ int SummonGameObject(lua_State* L, WorldObject* obj) { uint32 entry = Eluna::CHECKVAL(L, 2); float x = Eluna::CHECKVAL(L, 3); float y = Eluna::CHECKVAL(L, 4); float z = Eluna::CHECKVAL(L, 5); float o = Eluna::CHECKVAL(L, 6); uint32 respawnDelay = Eluna::CHECKVAL(L, 7, 30); #ifndef TRINITY Eluna::Push(L, obj->SummonGameObject(entry, x, y, z, o, respawnDelay)); #else Eluna::Push(L, obj->SummonGameObject(entry, x, y, z, o, 0, 0, 0, 0, respawnDelay)); #endif return 1; } /** * Spawns the creature at specified location. * * @param uint32 entry : [Creature]'s entry ID * @param float x * @param float y * @param float z * @param float o * @param TempSummonType spawnType : defines how and when the creature despawns * @param uint32 despawnTimer : despawn time in seconds * @return [Creature] spawnedCreature */ int SpawnCreature(lua_State* L, WorldObject* obj) { uint32 entry = Eluna::CHECKVAL(L, 2); float x = Eluna::CHECKVAL(L, 3); float y = Eluna::CHECKVAL(L, 4); float z = Eluna::CHECKVAL(L, 5); float o = Eluna::CHECKVAL(L, 6); uint32 spawnType = Eluna::CHECKVAL(L, 7, 8); uint32 despawnTimer = Eluna::CHECKVAL(L, 8, 0); TempSummonType type; switch (spawnType) { case 1: type = TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; break; case 2: type = TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN; break; case 3: type = TEMPSUMMON_TIMED_DESPAWN; break; case 5: type = TEMPSUMMON_CORPSE_DESPAWN; break; case 6: type = TEMPSUMMON_CORPSE_TIMED_DESPAWN; break; case 7: type = TEMPSUMMON_DEAD_DESPAWN; break; case 8: type = TEMPSUMMON_MANUAL_DESPAWN; break; default: return luaL_argerror(L, 7, "valid SpawnType expected"); } Eluna::Push(L, obj->SummonCreature(entry, x, y, z, o, type, despawnTimer)); return 1; } }; #endif