Files
mod-ale/WorldObjectMethods.h
Rochet2 b1f85bfc21 Eluna
Improved pushing so that a single userdata is used per object pushed.
Made everything use the singleton less, allowing more free code and easier to implement multithreading later.
Made macros for hookmgr and fixed the issue with hooks called inside hooks.
2014-06-29 21:28:49 +02:00

431 lines
13 KiB
C++

/*
* Copyright (C) 2010 - 2014 Eluna Lua Engine <http://emudevs.com/>
* 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
{
/* GETTERS */
int GetName(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetName());
return 1;
}
int GetMap(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetMap());
return 1;
}
#if (!defined(TBC) && !defined(CLASSIC))
int GetPhaseMask(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetPhaseMask());
return 1;
}
#endif
int GetInstanceId(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetInstanceId());
return 1;
}
int GetAreaId(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetAreaId());
return 1;
}
int GetZoneId(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetZoneId());
return 1;
}
int GetMapId(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetMapId());
return 1;
}
int GetX(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetPositionX());
return 1;
}
int GetY(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetPositionY());
return 1;
}
int GetZ(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetPositionZ());
return 1;
}
int GetO(lua_State* L, WorldObject* obj)
{
Eluna::Push(L, obj->GetOrientation());
return 1;
}
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;
}
int GetNearestPlayer(lua_State* L, WorldObject* obj)
{
float range = Eluna::CHECKVAL<float>(L, 2, SIZE_OF_GRIDS);
Unit* target = NULL;
Eluna::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_PLAYER);
#ifdef MANGOS
MaNGOS::UnitLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(target, checker);
Cell::VisitWorldObjects(obj, searcher, range);
#else
Trinity::UnitLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, target, checker);
obj->VisitNearbyObject(range, searcher);
#endif
Eluna::Push(L, target);
return 1;
}
int GetNearestGameObject(lua_State* L, WorldObject* obj)
{
float range = Eluna::CHECKVAL<float>(L, 2, SIZE_OF_GRIDS);
uint32 entry = Eluna::CHECKVAL<uint32>(L, 3, 0);
GameObject* target = NULL;
Eluna::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_GAMEOBJECT, entry);
#ifdef MANGOS
MaNGOS::GameObjectLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(target, checker);
Cell::VisitGridObjects(obj, searcher, range);
#else
Trinity::GameObjectLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, target, checker);
obj->VisitNearbyObject(range, searcher);
#endif
Eluna::Push(L, target);
return 1;
}
int GetNearestCreature(lua_State* L, WorldObject* obj)
{
float range = Eluna::CHECKVAL<float>(L, 2, SIZE_OF_GRIDS);
uint32 entry = Eluna::CHECKVAL<uint32>(L, 3, 0);
Creature* target = NULL;
Eluna::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_UNIT, entry);
#ifdef MANGOS
MaNGOS::CreatureLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(target, checker);
Cell::VisitGridObjects(obj, searcher, range);
#else
Trinity::CreatureLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, target, checker);
obj->VisitNearbyObject(range, searcher);
#endif
Eluna::Push(L, target);
return 1;
}
int GetPlayersInRange(lua_State* L, WorldObject* obj)
{
float range = Eluna::CHECKVAL<float>(L, 2, SIZE_OF_GRIDS);
std::list<Player*> list;
Eluna::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_PLAYER);
#ifdef MANGOS
MaNGOS::PlayerListSearcher<Eluna::WorldObjectInRangeCheck> searcher(list, checker);
Cell::VisitWorldObjects(obj, searcher, range);
#else
Trinity::PlayerListSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, list, checker);
obj->VisitNearbyObject(range, searcher);
#endif
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 i = 0;
for (std::list<Player*>::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;
}
int GetCreaturesInRange(lua_State* L, WorldObject* obj)
{
float range = Eluna::CHECKVAL<float>(L, 2, SIZE_OF_GRIDS);
uint32 entry = Eluna::CHECKVAL<uint32>(L, 3, 0);
std::list<Creature*> list;
Eluna::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry);
#ifdef MANGOS
MaNGOS::CreatureListSearcher<Eluna::WorldObjectInRangeCheck> searcher(list, checker);
Cell::VisitGridObjects(obj, searcher, range);
#else
Trinity::CreatureListSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, list, checker);
obj->VisitNearbyObject(range, searcher);
#endif
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 i = 0;
for (std::list<Creature*>::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;
}
int GetGameObjectsInRange(lua_State* L, WorldObject* obj)
{
float range = Eluna::CHECKVAL<float>(L, 2, SIZE_OF_GRIDS);
uint32 entry = Eluna::CHECKVAL<uint32>(L, 3, 0);
std::list<GameObject*> list;
Eluna::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_GAMEOBJECT, entry);
#ifdef MANGOS
MaNGOS::GameObjectListSearcher<Eluna::WorldObjectInRangeCheck> searcher(list, checker);
Cell::VisitGridObjects(obj, searcher, range);
#else
Trinity::GameObjectListSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, list, checker);
obj->VisitNearbyObject(range, searcher);
#endif
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 i = 0;
for (std::list<GameObject*>::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;
}
int GetNearObject(lua_State* L, WorldObject* obj)
{
bool nearest = Eluna::CHECKVAL<bool>(L, 2, true);
float range = Eluna::CHECKVAL<float>(L, 3, SIZE_OF_GRIDS);
uint16 type = Eluna::CHECKVAL<uint16>(L, 4, 0); // TypeMask
uint32 entry = Eluna::CHECKVAL<uint32>(L, 5, 0);
uint32 hostile = Eluna::CHECKVAL<uint32>(L, 6, 0); // 0 none, 1 hostile, 2 friendly
float x, y, z;
obj->GetPosition(x, y, z);
Eluna::WorldObjectInRangeCheck checker(nearest, obj, range, type, entry, hostile);
if (nearest)
{
WorldObject* target = NULL;
#ifdef MANGOS
MaNGOS::WorldObjectLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(target, checker);
Cell::VisitAllObjects(obj, searcher, range);
#else
Trinity::WorldObjectLastSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, target, checker);
obj->VisitNearbyObject(range, searcher);
#endif
Eluna::Push(L, target);
return 1;
}
else
{
std::list<WorldObject*> list;
#ifdef MANGOS
MaNGOS::WorldObjectListSearcher<Eluna::WorldObjectInRangeCheck> searcher(list, checker);
Cell::VisitAllObjects(obj, searcher, range);
#else
Trinity::WorldObjectListSearcher<Eluna::WorldObjectInRangeCheck> searcher(obj, list, checker);
obj->VisitNearbyObject(range, searcher);
#endif
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 i = 0;
for (std::list<WorldObject*>::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;
}
return 1;
}
int GetWorldObject(lua_State* L, WorldObject* obj)
{
uint64 guid = Eluna::CHECKVAL<uint64>(L, 2);
#ifdef MANGOS
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, sObjectAccessor->GetPlayer(*obj, ObjectGuid(guid))); break;
case HIGHGUID_TRANSPORT:
case HIGHGUID_MO_TRANSPORT:
case HIGHGUID_GAMEOBJECT: Eluna::Push(L, sObjectAccessor->GetGameObject(*obj, ObjectGuid(guid))); break;
case HIGHGUID_VEHICLE:
case HIGHGUID_UNIT: Eluna::Push(L, sObjectAccessor->GetCreature(*obj, ObjectGuid(guid))); break;
case HIGHGUID_PET: Eluna::Push(L, sObjectAccessor->GetPet(*obj, ObjectGuid(guid))); break;
}
#endif
return 1;
}
int GetDistance(lua_State* L, WorldObject* obj)
{
WorldObject* target = Eluna::CHECKOBJ<WorldObject>(L, 2, false);
if (target && target->IsInWorld())
Eluna::Push(L, obj->GetDistance(target));
else
{
float X = Eluna::CHECKVAL<float>(L, 2);
float Y = Eluna::CHECKVAL<float>(L, 3);
float Z = Eluna::CHECKVAL<float>(L, 4);
Eluna::Push(L, obj->GetDistance(X, Y, Z));
}
return 1;
}
int GetRelativePoint(lua_State* L, WorldObject* obj)
{
float dist = Eluna::CHECKVAL<float>(L, 2);
float rad = Eluna::CHECKVAL<float>(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;
}
int GetAngle(lua_State* L, WorldObject* obj)
{
WorldObject* target = Eluna::CHECKOBJ<WorldObject>(L, 2, false);
if (target && target->IsInWorld())
Eluna::Push(L, obj->GetAngle(target));
else
{
float x = Eluna::CHECKVAL<float>(L, 2);
float y = Eluna::CHECKVAL<float>(L, 3);
Eluna::Push(L, obj->GetAngle(x, y));
}
return 1;
}
/* OTHER */
int SendPacket(lua_State* L, WorldObject* obj)
{
WorldPacket* data = Eluna::CHECKOBJ<WorldPacket>(L, 2);
obj->SendMessageToSet(data, true);
return 0;
}
int SummonGameObject(lua_State* L, WorldObject* obj)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
float x = Eluna::CHECKVAL<float>(L, 3);
float y = Eluna::CHECKVAL<float>(L, 4);
float z = Eluna::CHECKVAL<float>(L, 5);
float o = Eluna::CHECKVAL<float>(L, 6);
uint32 respawnDelay = Eluna::CHECKVAL<uint32>(L, 7, 30);
#ifdef MANGOS
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;
}
int SpawnCreature(lua_State* L, WorldObject* obj)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
float x = Eluna::CHECKVAL<float>(L, 3);
float y = Eluna::CHECKVAL<float>(L, 4);
float z = Eluna::CHECKVAL<float>(L, 5);
float o = Eluna::CHECKVAL<float>(L, 6);
uint32 spawnType = Eluna::CHECKVAL<uint32>(L, 7, 8);
uint32 despawnTimer = Eluna::CHECKVAL<uint32>(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