Files
mod-ale/CreatureMethods.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

662 lines
16 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 CREATUREMETHODS_H
#define CREATUREMETHODS_H
namespace LuaCreature
{
/* BOOLEAN */
int IsReputationGainDisabled(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsReputationGainDisabled());
return 1;
}
int IsRegeneratingHealth(lua_State* L, Creature* creature)
{
#ifdef MANGOS
Eluna::Push(L, creature->IsRegeneratingHealth());
#else
Eluna::Push(L, creature->isRegeneratingHealth());
#endif
return 1;
}
int HasInvolvedQuest(lua_State* L, Creature* creature)
{
uint32 quest_id = Eluna::CHECKVAL<uint32>(L, 2);
#ifdef MANGOS
Eluna::Push(L, creature->HasInvolvedQuest(quest_id));
#else
Eluna::Push(L, creature->hasInvolvedQuest(quest_id));
#endif
return 1;
}
int IsTargetAcceptable(lua_State* L, Creature* creature)
{
Unit* target = Eluna::CHECKOBJ<Unit>(L, 2);
Eluna::Push(L, creature->isTargetableForAttack(target));
return 1;
}
int CanAssistTo(lua_State* L, Creature* creature)
{
Unit* u = Eluna::CHECKOBJ<Unit>(L, 2);
Unit* enemy = Eluna::CHECKOBJ<Unit>(L, 3);
bool checkfaction = Eluna::CHECKVAL<bool>(L, 4, true);
Eluna::Push(L, creature->CanAssistTo(u, enemy, checkfaction));
return 1;
}
int HasSearchedAssistance(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->HasSearchedAssistance());
return 1;
}
int IsTappedBy(lua_State* L, Creature* creature)
{
Player* player = Eluna::CHECKOBJ<Player>(L, 2);
Eluna::Push(L, creature->isTappedBy(player));
return 1;
}
int HasLootRecipient(lua_State* L, Creature* creature)
{
#ifdef MANGOS
Eluna::Push(L, creature->HasLootRecipient());
#else
Eluna::Push(L, creature->hasLootRecipient());
#endif
return 1;
}
int IsCombatAllowed(lua_State* L, Creature* creature)
{
#ifdef MANGOS
if (CreatureAI* ai = creature->AI())
Eluna::Push(L, ai->IsCombatMovement());
else
Eluna::Push(L, false);
#else
Eluna::Push(L, !creature->HasReactState(REACT_PASSIVE));
#endif
return 1;
}
int CanSwim(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->CanSwim());
return 1;
}
int CanWalk(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->CanWalk());
return 1;
}
int IsInEvadeMode(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsInEvadeMode());
return 1;
}
int IsElite(lua_State* L, Creature* creature)
{
#ifdef MANGOS
Eluna::Push(L, creature->IsElite());
#else
Eluna::Push(L, creature->isElite());
#endif
return 1;
}
int IsGuard(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsGuard());
return 1;
}
int IsCivilian(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsCivilian());
return 1;
}
int IsRacialLeader(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsRacialLeader());
return 1;
}
int IsWorldBoss(lua_State* L, Creature* creature)
{
#ifdef MANGOS
Eluna::Push(L, creature->IsWorldBoss());
#else
Eluna::Push(L, creature->isWorldBoss());
#endif
return 1;
}
int HasCategoryCooldown(lua_State* L, Creature* creature)
{
uint32 spell = Eluna::CHECKVAL<uint32>(L, 2);
Eluna::Push(L, creature->HasCategoryCooldown(spell));
return 1;
}
int HasSpell(lua_State* L, Creature* creature)
{
uint32 id = Eluna::CHECKVAL<uint32>(L, 2);
Eluna::Push(L, creature->HasSpell(id));
return 1;
}
int HasQuest(lua_State* L, Creature* creature)
{
uint32 questId = Eluna::CHECKVAL<uint32>(L, 2);
#ifdef MANGOS
Eluna::Push(L, creature->HasQuest(questId));
#else
Eluna::Push(L, creature->hasQuest(questId));
#endif
return 1;
}
int HasSpellCooldown(lua_State* L, Creature* creature)
{
uint32 spellId = Eluna::CHECKVAL<uint32>(L, 2);
Eluna::Push(L, creature->HasSpellCooldown(spellId));
return 1;
}
int CanFly(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->CanFly());
return 1;
}
/*int IsTrigger(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsTrigger());
return 1;
}*/
/*int IsDamageEnoughForLootingAndReward(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->IsDamageEnoughForLootingAndReward());
return 1;
}*/
/*int CanStartAttack(lua_State* L, Creature* creature) // TODO: Implement core side
{
Unit* target = Eluna::CHECKOBJ<Unit>(L, 2);
bool force = Eluna::CHECKVAL<bool>(L, 3, true);
Eluna::Push(L, creature->CanStartAttack(target, force));
return 1;
}*/
/*int HasLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features
{
uint16 lootMode = Eluna::CHECKVAL<uint16>(L, 2);
Eluna::Push(L, creature->HasLootMode(lootMode));
return 1;
}*/
/* GETTERS */
int GetRespawnDelay(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetRespawnDelay());
return 1;
}
int GetRespawnRadius(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetRespawnRadius());
return 1;
}
int GetDefaultMovementType(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetDefaultMovementType());
return 1;
}
int GetAggroRange(lua_State* L, Creature* creature)
{
Unit* target = Eluna::CHECKOBJ<Unit>(L, 2);
Eluna::Push(L, creature->GetAttackDistance(target));
return 1;
}
int GetAttackDistance(lua_State* L, Creature* creature)
{
Unit* target = Eluna::CHECKOBJ<Unit>(L, 2);
Eluna::Push(L, creature->GetAttackDistance(target));
return 1;
}
int GetLootRecipientGroup(lua_State* L, Creature* creature)
{
#ifdef MANGOS
Eluna::Push(L, creature->GetGroupLootRecipient());
#else
Eluna::Push(L, creature->GetLootRecipientGroup());
#endif
return 1;
}
int GetLootRecipient(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetLootRecipient());
return 1;
}
int GetScriptName(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetScriptName());
return 1;
}
int GetAIName(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetAIName());
return 1;
}
int GetScriptId(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetScriptId());
return 1;
}
int GetCreatureSpellCooldownDelay(lua_State* L, Creature* creature)
{
uint32 spell = Eluna::CHECKVAL<uint32>(L, 2);
Eluna::Push(L, creature->GetCreatureSpellCooldownDelay(spell));
return 1;
}
int GetCorpseDelay(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetCorpseDelay());
return 1;
}
int GetHomePosition(lua_State* L, Creature* creature)
{
float x, y, z, o;
#ifdef MANGOS
creature->GetRespawnCoord(x, y, z, &o);
#else
creature->GetHomePosition(x, y, z, o);
#endif
Eluna::Push(L, x);
Eluna::Push(L, y);
Eluna::Push(L, z);
Eluna::Push(L, o);
return 4;
}
int GetAITarget(lua_State* L, Creature* creature)
{
uint32 targetType = Eluna::CHECKVAL<uint32>(L, 2);
bool playerOnly = Eluna::CHECKVAL<bool>(L, 3, false);
uint32 position = Eluna::CHECKVAL<uint32>(L, 4, 0);
float dist = Eluna::CHECKVAL<float>(L, 5, -1.0f);
int32 aura = Eluna::CHECKVAL<int32>(L, 6, 0);
ThreatList const& threatlist = creature->getThreatManager().getThreatList();
if (position >= threatlist.size())
return 1;
std::list<Unit*> targetList;
for (ThreatList::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
{
Unit* target = (*itr)->getTarget();
if (!target)
continue;
if (playerOnly && target->GetTypeId() != TYPEID_PLAYER)
continue;
if (aura > 0 && !target->HasAura(aura))
continue;
else if (aura < 0 && target->HasAura(-aura))
continue;
if (dist > 0.0f && !creature->IsWithinDist(target, dist))
continue;
targetList.push_back(target);
}
if (position >= targetList.size())
return 1;
if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
targetList.sort(Eluna::ObjectDistanceOrderPred(creature));
switch (targetType)
{
case SELECT_TARGET_NEAREST:
case SELECT_TARGET_TOPAGGRO:
{
std::list<Unit*>::const_iterator itr = targetList.begin();
std::advance(itr, position);
Eluna::Push(L, *itr);
}
case SELECT_TARGET_FARTHEST:
case SELECT_TARGET_BOTTOMAGGRO:
{
std::list<Unit*>::reverse_iterator ritr = targetList.rbegin();
std::advance(ritr, position);
Eluna::Push(L, *ritr);
}
case SELECT_TARGET_RANDOM:
{
std::list<Unit*>::const_iterator itr = targetList.begin();
std::advance(itr, urand(position, targetList.size() - 1));
Eluna::Push(L, *itr);
}
default:
luaL_argerror(L, 2, "SelectAggroTarget expected");
}
return 1;
}
int GetAITargets(lua_State* L, Creature* creature)
{
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 i = 0;
ThreatList const& threatList = creature->getThreatManager().getThreatList();
ThreatList::const_iterator itr;
for (itr = threatList.begin(); itr != threatList.end(); ++itr)
{
Unit* target = (*itr)->getTarget();
if (!target)
continue;
++i;
Eluna::Push(L, i);
Eluna::Push(L, target);
lua_settable(L, tbl);
}
lua_settop(L, tbl);
return 1;
}
int GetAITargetsCount(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->getThreatManager().getThreatList().size());
return 1;
}
int GetNPCFlags(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetUInt32Value(UNIT_NPC_FLAGS));
return 1;
}
#ifndef CATA
int GetShieldBlockValue(lua_State* L, Creature* creature)
{
Eluna::Push(L, creature->GetShieldBlockValue());
return 1;
}
#endif
/*int GetLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features
{
Eluna::Push(L, creature->GetLootMode());
return 1;
}*/
/* SETTERS */
int SetNPCFlags(lua_State* L, Creature* creature)
{
uint32 flags = Eluna::CHECKVAL<uint32>(L, 2);
creature->SetUInt32Value(UNIT_NPC_FLAGS, flags);
return 0;
}
int SetDeathState(lua_State* L, Creature* creature)
{
int32 state = Eluna::CHECKVAL<int32>(L, 2);
#ifdef MANGOS
creature->SetDeathState((DeathState)state);
#else
creature->setDeathState((DeathState)state);
#endif
return 0;
}
int SetWalk(lua_State* L, Creature* creature) // TODO: Move same to Player ?
{
bool enable = Eluna::CHECKVAL<bool>(L, 2, true);
creature->SetWalk(enable);
return 0;
}
int SetAllowedCombat(lua_State* L, Creature* creature)
{
bool allow = Eluna::CHECKVAL<bool>(L, 2);
#ifdef MANGOS
if (CreatureAI* ai = creature->AI())
ai->SetCombatMovement(allow);
#else
creature->SetReactState(allow ? REACT_AGGRESSIVE : REACT_PASSIVE);
#endif
return 0;
}
int SetDisableReputationGain(lua_State* L, Creature* creature)
{
bool disable = Eluna::CHECKVAL<bool>(L, 2, true);
creature->SetDisableReputationGain(disable);
return 0;
}
int SetInCombatWithZone(lua_State* L, Creature* creature)
{
creature->SetInCombatWithZone();
return 0;
}
int SetRespawnRadius(lua_State* L, Creature* creature)
{
float dist = Eluna::CHECKVAL<float>(L, 2);
creature->SetRespawnRadius(dist);
return 0;
}
int SetRespawnDelay(lua_State* L, Creature* creature)
{
uint32 delay = Eluna::CHECKVAL<uint32>(L, 2);
creature->SetRespawnDelay(delay);
return 0;
}
int SetDefaultMovementType(lua_State* L, Creature* creature)
{
int32 type = Eluna::CHECKVAL<int32>(L, 2);
creature->SetDefaultMovementType((MovementGeneratorType)type);
return 0;
}
int SetNoSearchAssistance(lua_State* L, Creature* creature)
{
bool val = Eluna::CHECKVAL<bool>(L, 2, true);
creature->SetNoSearchAssistance(val);
return 0;
}
int SetNoCallAssistance(lua_State* L, Creature* creature)
{
bool val = Eluna::CHECKVAL<bool>(L, 2, true);
creature->SetNoCallAssistance(val);
return 0;
}
int SetHover(lua_State* L, Creature* creature)
{
bool enable = Eluna::CHECKVAL<bool>(L, 2, true);
#ifdef MANGOS
creature->SetLevitate(enable);
#else
creature->SetHover(enable);
#endif
return 0;
}
/*int SetLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features
{
uint16 lootMode = Eluna::CHECKVAL<uint16>(L, 2);
creature->SetLootMode(lootMode);
return 0;
}*/
/*int SetDisableGravity(lua_State* L, Creature* creature)
{
bool disable = Eluna::CHECKVAL<bool>(L, 2, true);
bool packetOnly = Eluna::CHECKVAL<bool>(L, 3, false);
Eluna::Push(L, creature->SetDisableGravity(disable, packetOnly));
return 1;
}*/
/* OTHER */
int DespawnOrUnsummon(lua_State* L, Creature* creature)
{
uint32 msTimeToDespawn = Eluna::CHECKVAL<uint32>(L, 2, 0);
#ifdef MANGOS
creature->ForcedDespawn(msTimeToDespawn);
#else
creature->DespawnOrUnsummon(msTimeToDespawn);
#endif
return 0;
}
int Respawn(lua_State* L, Creature* creature)
{
creature->Respawn();
return 0;
}
int RemoveCorpse(lua_State* L, Creature* creature)
{
creature->RemoveCorpse();
return 0;
}
int MoveWaypoint(lua_State* L, Creature* creature)
{
#ifdef MANGOS
creature->GetMotionMaster()->MoveWaypoint();
#else
creature->GetMotionMaster()->MovePath(creature->GetWaypointPath(), true);
#endif
return 0;
}
int CallAssistance(lua_State* L, Creature* creature)
{
creature->CallAssistance();
return 0;
}
int CallForHelp(lua_State* L, Creature* creature)
{
float radius = Eluna::CHECKVAL<float>(L, 2);
creature->CallForHelp(radius);
return 0;
}
int FleeToGetAssistance(lua_State* L, Creature* creature)
{
creature->DoFleeToGetAssistance();
return 0;
}
int AttackStart(lua_State* L, Creature* creature)
{
Unit* target = Eluna::CHECKOBJ<Unit>(L, 2);
creature->AI()->AttackStart(target);
return 0;
}
int SaveToDB(lua_State* L, Creature* creature)
{
creature->SaveToDB();
return 0;
}
int SelectVictim(lua_State* L, Creature* creature)
{
#ifdef MANGOS
Eluna::Push(L, creature->SelectHostileTarget());
#else
Eluna::Push(L, creature->SelectVictim());
#endif
return 1;
}
/*int ResetLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features
{
creature->ResetLootMode();
return 0;
}*/
/*int RemoveLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features
{
uint16 lootMode = Eluna::CHECKVAL<uint16>(L, 2);
creature->RemoveLootMode(lootMode);
return 0;
}*/
/*int AddLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features
{
uint16 lootMode = Eluna::CHECKVAL<uint16>(L, 2);
creature->AddLootMode(lootMode);
return 0;
}*/
};
#endif