All pastes #388292 Raw Edit

Someone

public text v1 · immutable
·published 2007-03-09 23:40 UTC
rendered paste body
/*         /\/\   __ _ _ __   __ _  ___ / _\ ___ _ __(_)_ __ | |_
 *        /    \ / _` | '_ \ / _` |/ _ \\ \ / __| '__| | '_ \| __|
 *       / /\/\ \ (_| | | | | (_| | (_) |\ \ (__| |  | | |_) | |_
 *       \/    \/\__,_|_| |_|\__, |\___/\__/\___|_|  |_| .__/ \__|
 *                           |___/                     |_|
 *                        A WHOLE NEW WORLD
 *         MangoScript - Bringing a whole new world to MaNGOS
 *
 *      Lua_Creature.cpp - Exports Creature related functions to LUA
 *
 *      (c) Copyright 2006-2007 by the MangoScript Team <http://www.mangoscript.org>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *      $Id: Lua_Creature.cpp 136 2007-02-26 01:51:38Z andrejkw $
 */

#include "luainc.h"
#include "Lua_Creature.h"
#include "WorldPacket.h"
#include "Player.h"
#include "Creature.h"
#include "GossipDef.h"
#include "SpellAuras.h"
#include "DynamicObject.h"
#include "Lua_uint64.h"
#include "Lua_AI.h"
#include "ObjectMgr.h"
#include "MapManager.h"
#include "Chat.h"
#include "CppScriptMgr.h"


const char* lb_Creature_GetScriptName(Creature* m_creature)
{
	return m_creature->GetCreatureInfo()->ScriptName;
}

uint32 lb_Creature_QUEST_DIALOG_STATUS(Creature* m_creature, Player *pPlayer, uint32 defstatus)
{
	return m_creature->getDialogStatus(pPlayer, defstatus);
}

void lb_Creature_MonsterSay(Creature* m_creature, char const *text, uint32 language)
{
	m_creature->MonsterSay(text, language, m_creature->GetGUID());
}

LuaAI_Proxy* lb_Creature_GetLuaAI(Creature* m_creature)
{
	debug_log("lb_Creature_GetLuaAI");
	if (isRegistered_LuaAI(m_creature))
		return ((LuaAI*)&m_creature->AI())->m_proxy;
	error_log("[Lua] : AI : WARNING : Trying to get LuaAI of creature that doesn't have such");
	return NULL;
}

void lb_Creature_reachWithSpellAttack(Creature* cr , Unit* target )
{
	if(!target) return;
	const SpellEntry* spellinfo = cr->reachWithSpellAttack(target);
	if (spellinfo) cr->CastSpell(target, spellinfo, true);
}

void lb_Ressurect(Creature* m_creature, bool goToRespawn)
{
	if (!m_creature || m_creature->isAlive() || !m_creature->IsInWorld()) return;

    CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(m_creature->GetEntry());

	switch (m_creature->getDeathState())
	{
        case DEAD:
			{
                DEBUG_LOG("Respawning...");

                m_creature->SelectLevel(cinfo);
                m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);
                m_creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);

                m_creature->SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag);
                m_creature->SetHealth(m_creature->GetMaxHealth());
                m_creature->setDeathState( ALIVE );
                m_creature->clearUnitState(UNIT_STAT_ALL_STATE);
                (*m_creature)->Clear();
                MapManager::Instance().GetMap(m_creature->GetMapId())->Add(m_creature);

				/*WE ARE AWREADY MOVED TO RESS PLACE ... SO goToRespawn IS USELESS FOR HERE*/
			}
			break;

        case CORPSE:
			{
                ObjectAccessor::Instance().RemoveCreatureCorpseFromPlayerView(m_creature);
                m_creature->loot.clear();
                m_creature->setDeathState(DEAD);

                m_creature->SelectLevel(cinfo);
                m_creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);
                m_creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);

                m_creature->SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag);
                m_creature->SetHealth(m_creature->GetMaxHealth());
                m_creature->setDeathState(ALIVE);
                m_creature->clearUnitState(UNIT_STAT_ALL_STATE);

			    if (goToRespawn)
				{
					float x, y, z;
					m_creature->GetRespawnCoord(x, y, z);
					MapManager::Instance().GetMap(m_creature->GetMapId())->CreatureRelocation(m_creature, x, y, z, m_creature->GetOrientation());
				}
			}
			break;

        default:
            break;
    }
}

void lb_Creature_MoveTo(Creature* m_creature, const float& X, const float& Y, const float& Z, bool Run, const uint32& Time)
{
	float dx = X - m_creature->GetPositionX();
	float dy = Y - m_creature->GetPositionY();
	float orientation = (float)atan2((double)dy, (double)dx);
	m_creature->SendMoveToPacket(X, Y, Z, Run, Time);

	MapManager::Instance().GetMap(m_creature->GetMapId())->CreatureRelocation(m_creature, X, Y, Z, orientation);
}

bool lb_Creature_DoCast(Creature* m_creature, Unit* Victim, uint32 spellId)
{
	SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);

    if (!spellInfo)
    {
        sLog.outError("WORLD: unknown spell id %i\n", spellId);
        return false;
    }
    
    //No triggered spells for now
    Spell *spell = new Spell(m_creature, spellInfo, false, 0);
    WPAssert(spell);

    SpellCastTargets targets;
    targets.setUnitTarget(Victim);
    spell->m_CastItem = NULL;
	uint8 castresult = spell->CanCast();
    spell->prepare(&targets);
    m_creature->m_canMove = false;

	return (castresult == 0);
}

void lb_Creature_DoYell(Creature* m_creature, char const* text, uint32 language, Unit* target)
{
    WorldPacket data(30 + strlen(text) + strlen(m_creature->GetCreatureInfo()->Name) + 2);//30 bytes + text size + name size + 2(nulls at end of string)
    data.SetOpcode(SMSG_MESSAGECHAT);
    data << (uint8)CHAT_MSG_MONSTER_YELL;
    data << language;

    data << (uint64)m_creature->GetGUID();
    data << (uint32)(strlen(m_creature->GetCreatureInfo()->Name) + 1);
    data << m_creature->GetCreatureInfo()->Name;
    
    if (target)
		data << uint64(target->GetGUID());
    else 
		data << uint64(m_creature->GetGUID());

    data << uint32(strlen(text)+1);
    data << text;
    data << uint8(0);

    m_creature->SendMessageToSet(&data, false);
}

SpellEntry const* lb_Creature_SelectSpell(Creature* m_creature, Unit* Target, uint32 School, uint32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects)
{
    //No target so we can't cast
    if (!Target)
        return false;

    //Silenced so we can't cast
    if (m_creature->m_silenced)
        return false;

    //Using the extended script system we first create a list of viable spells
    SpellEntry const* Spell[4];
    Spell[0] = 0;
    Spell[1] = 0;
    Spell[2] = 0;
    Spell[3] = 0;

    uint32 SpellCount = 0;

    SpellEntry const* TempSpell;
    SpellRangeEntry const* TempRange;

    //Check if each spell is viable(set it to null if not)
    for (uint32 i = 0; i < 4; i++)
    {
        TempSpell = sSpellStore.LookupEntry(m_creature->m_spells[i]);

        //This spell doesn't exist
        if (!TempSpell)
            continue;

        //Check for school if specified
        if (School && TempSpell->School != School)
            continue;

        //Check for spell mechanic if specified
        if (Mechanic && TempSpell->Mechanic != Mechanic)
            continue;

        //Check the spell targets if specified
        if (Targets)
        {
            bool bSkipThisSpell = true;

            switch (Targets)
            {
                //Spell targets self
                case SELECT_TARGET_SELF:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_SELF)
                            bSkipThisSpell = false;
                break;

                //Spell targets a single enemy
                case SELECT_TARGET_SINGLE_ENEMY:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_CURRENT_SELECTED_ENEMY)
                            bSkipThisSpell = false;
                break;


                //Spell targets AoE at enemy
                case SELECT_TARGET_AOE_ENEMY:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMIES_AROUND_CASTER ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                            bSkipThisSpell = false;
                break;

                //Spell targets an enemy
                case SELECT_TARGET_ANY_ENEMY:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_CURRENT_SELECTED_ENEMY ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMIES_AROUND_CASTER ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                            bSkipThisSpell = false;
                break;

                //Spell targets a single friend(or self)
                case SELECT_TARGET_SINGLE_FRIEND:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_SELF ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND_2)
                            bSkipThisSpell = false;
                break;

                //Spell targets aoe friends
                case SELECT_TARGET_AOE_FRIEND:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_PARTY_AROUND_CASTER ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_PARTY)
                            bSkipThisSpell = false;
                break;

                //Spell targets any friend(or self)
                case SELECT_TARGET_ANY_FRIEND:
                    for (uint32 i = 0; i < 3; i++)
                        if (TempSpell->EffectImplicitTargetA[i] == TARGET_SELF ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND_2 ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_ALL_PARTY_AROUND_CASTER ||
                            TempSpell->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_PARTY)
                            bSkipThisSpell = false;
                break;
            }

            if (bSkipThisSpell)
                continue;
        }

        //Make sure that the spell uses the requested amount of power
        if (PowerCostMin)
            if (TempSpell->manaCost < PowerCostMin)
                continue;

        if (PowerCostMax)
            if (TempSpell->manaCost > PowerCostMax)
                continue;

        //Continue if we don't have the mana to actually cast this spell
        if (TempSpell->manaCost > m_creature->GetPower((Powers)TempSpell->powerType))
            continue;

        //Get the Range
        TempRange = sSpellRangeStore.LookupEntry(TempSpell->rangeIndex);

        //Spell has invalid range store so we can't use it
        if (!TempRange)
            continue;

        //Check if the spell meets our range requirements
        if (RangeMin)
            if (TempRange->maxRange < RangeMin)
                continue;
        if (RangeMax)
            if (TempRange->maxRange > RangeMax)
                continue;

        //Check if our target is in range
        if (m_creature->GetDistanceSq(Target) < TempRange->minRange * TempRange->minRange || m_creature->GetDistanceSq(Target) > TempRange->maxRange * TempRange->maxRange)
            continue;

        //Check the type of spell if we are looking for a specific spell type
        if (Effects)
        {
            bool bSkipThisSpell = true;

            switch (Effects)
            {
                //Make sure that this spell includes a damage effect
                case SELECT_EFFECT_DAMAGE:
                for (uint32 j = 0; j < 3; j++)
                    if (TempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || 
                        TempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL || 
                        TempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE || 
                        TempSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH)
                        bSkipThisSpell = false;
                break;

                //Make sure that this spell includes a healing effect
                case SELECT_EFFECT_HEALING:
                for (uint32 j = 0; j < 3; j++)
                    if (TempSpell->Effect[j] == SPELL_EFFECT_HEAL || 
                        TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH || 
                        TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL)
                        bSkipThisSpell = false;
                break;

                //Make sure that this spell applies an aura
                case SELECT_EFFECT_AURA:
                for (uint32 j = 0; j < 3; j++)
                    if (TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA)
                        bSkipThisSpell = false;
                break;

                default:
                bSkipThisSpell = false;
                break;
            }

            if (bSkipThisSpell)
                continue;
        }

        //All good so lets add it to the spell list
        Spell[SpellCount] = TempSpell;
        SpellCount++;
    }

    //We got our usable spells so now lets randomly pick one
    if (!SpellCount)
        return NULL;

    return Spell[rand()%SpellCount];
}

int lb_Export_Creature(lua_State* L)
{
	using namespace luabind;

	module(L)
	[
		def("Ressurect", lb_Ressurect)
	];

	module(L)
	[
		class_<Creature, Unit, WorldObject, Object>("Creature")
		.def("GetLuaAI", &lb_Creature_GetLuaAI)
		.def("DoYell", &lb_Creature_DoYell)
		.def("DoCast", &lb_Creature_DoCast)
		.def("MoveTo", &lb_Creature_MoveTo)
		.def("SelectSpell", &lb_Creature_SelectSpell)
		.def("reachWithSpellAttack", &lb_Creature_reachWithSpellAttack)
		.def("GetScriptName", &lb_Creature_GetScriptName)
		.def("QUEST_DIALOG_STATUS", &lb_Creature_QUEST_DIALOG_STATUS)
		/* from Creature.h */
		.def("isPet", &Creature::isPet)
		.def("isTotem", &Creature::isTotem)
		.def("isCivilian", &Creature::isCivilian)
		.def("isCanSwimOrFly", &Creature::isCanSwimOrFly)
		.def("isCanWalkOrFly", &Creature::isCanWalkOrFly)
		.def("isCanTrainingOf", &Creature::isCanTrainingOf)
		.def("isCanTrainingAndResetTalentsOf", &Creature::isCanTrainingAndResetTalentsOf)
		.def("isElite", &Creature::isElite)
		.def("GetOwner", &Creature::GetOwner)
		/*.def("setMoveRandomFlag", &Creature::setMoveRandomFlag)*/
		.def("setMoveRunFlag", &Creature::setMoveRunFlag)
		/*.def("getMoveRandomFlag", &Creature::getMoveRandomFlag)*/
		.def("getMoveRunFlag", &Creature::getMoveRunFlag)
		.def("IsStopped", &Creature::IsStopped)
		.def("StopMoving", &Creature::StopMoving)
		.def("GetBlockValue", &Creature::GetBlockValue)
		.def("GetItemCount", (uint32 (Creature::*)(uint32) const)&Creature::GetItemCount)
		.def("GetItemCount", (uint8 (Creature::*)(void) const)&Creature::GetItemCount)
		.def("GetItemId", &Creature::GetItemId)
		.def("GetMaxItemCount", &Creature::GetMaxItemCount)
		.def("GetItemIncrTime", &Creature::GetItemIncrTime)
		.def("GetItemLastIncr", &Creature::GetItemLastIncr)
		.def("SetItemCount", &Creature::SetItemCount)
		.def("SetItemLastIncr", &Creature::SetItemLastIncr)
		.def("AddItem", &Creature::AddItem)
		.def("GetTrainerSpellsSize", &Creature::GetTrainerSpellsSize)
		.def("getDialogStatus", &Creature::getDialogStatus)
		.def("prepareGossipMenu", &Creature::prepareGossipMenu)
		.def("sendPreparedGossip", &Creature::sendPreparedGossip)
		.def("OnGossipSelect", &Creature::OnGossipSelect)
		.def("OnPoiSelect", &Creature::OnPoiSelect)
		.def("GetGossipTextId", &Creature::GetGossipTextId)
		.def("GetNpcTextId", &Creature::GetNpcTextId)
		.def("LoadGossipOptions", &Creature::LoadGossipOptions)
		.def("GetGossipTitle", &Creature::GetGossipTitle)
		.def("GetGossipCount", &Creature::GetGossipCount)
		.def("addGossipOption", &Creature::addGossipOption)
		.def("setEmoteState", &Creature::setEmoteState)
		.def("setDeathState", &Creature::setDeathState)
		.def("Say", &Creature::Say)
		.def("MonsterSay", &lb_Creature_MonsterSay)
		.def("getloyalty", &Creature::getloyalty)
		.def("getUsedTrainPoint", &Creature::getUsedTrainPoint)
		/*.def("GivePetLevel",&Creature::GivePetLevel)*/
		.def("GetDefaultMovementType", &Creature::GetDefaultMovementType)
		.def("SetDefaultMovementType", &Creature::SetDefaultMovementType)
	];

	return 0;
}