/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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 3 of the License, or
* 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, see .
*
* GameMonkey Script License
* Copyright (c) 2003 Auran Development Ltd.
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
*/
#include "StdAfx.h"
int ScriptEngine_RegisterAreaTriggerEvent(gmThread * a_thread)
{
// Param 1: Areatrigger ID
// Param 2: Function to execute
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_FUNCTION_PARAM(func, 1);
// Get 'this' pointer pointing to scriptengine
ScriptEngine * eng = GetThisPointer(a_thread);
eng->AddAreaTriggerEvent(entry, func);
return GM_OK;
}
int ScriptEngine_RegisterGameObjectEvent(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(3);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_INT_PARAM(event, 1);
GM_CHECK_FUNCTION_PARAM(func, 2);
GetThisPointer(a_thread)->AddGameObjectEvent(entry, event, func);
return GM_OK;
}
int ScriptEngine_RegisterSpellEvent(gmThread * a_thread)
{
return GM_OK;
}
int ScriptEngine_RegisterUnitEvent(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(3);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_INT_PARAM(event, 1);
GM_CHECK_FUNCTION_PARAM(func, 2);
GetThisPointer(a_thread)->AddCreatureEvent(entry, event, func);
return GM_OK;
}
int ScriptEngine_RegisterPlayerEvent(gmThread * a_thread)
{
return GM_OK;
}
int ScriptEngine_RegisterQuestEvent(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(3);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_INT_PARAM(event, 1);
GM_CHECK_FUNCTION_PARAM(func, 2);
GetThisPointer(a_thread)->AddQuestEvent(entry, event, func);
return GM_OK;
}
// Player Functions
int Player_Teleport(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(4);
GM_CHECK_INT_PARAM(mapId, 0);
GM_CHECK_FLOAT_PARAM(posX, 1);
GM_CHECK_FLOAT_PARAM(posY, 2);
GM_CHECK_FLOAT_PARAM(posZ, 3);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
GetThisPointer(a_thread)->SafeTeleport(mapId, 0, posX, posY, posZ, 0);
return GM_OK;
}
int Player_GetLevel(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
a_thread->PushInt((int)GetThisPointer(a_thread)->getLevel());
return GM_OK;
}
int Player_GetClass(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
a_thread->PushInt((int)GetThisPointer(a_thread)->getClass());
return GM_OK;
}
int Player_GetRace(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
a_thread->PushInt((int)GetThisPointer(a_thread)->getRace());
return GM_OK;
}
int Player_SendAreaTriggerMessage(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(message, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
GetThisPointer(a_thread)->SendAreaTriggerMessage(message);
return GM_OK;
}
int Player_BroadcastMessage(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(message, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
GetThisPointer(a_thread)->BroadcastMessage(message);
return GM_OK;
}
int Player_GetReputationRank(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(faction, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
a_thread->PushInt(GetThisPointer(a_thread)->GetStandingRank(faction));
return GM_OK;
}
int Player_GetReputationValue(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(faction, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
a_thread->PushInt(GetThisPointer(a_thread)->GetStanding(faction));
return GM_OK;
}
int Player_HasFinishedQuest(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(questid, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
Player *p = GetThisPointer(a_thread);
if(p->HasFinishedQuest(questid))
a_thread->PushInt(1);
else
a_thread->PushInt(0);
return GM_OK;
}
int Player_IsGroupLeader(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
Player * p = GetThisPointer(a_thread);
if(p->InGroup() && p->IsGroupLeader())
a_thread->PushInt(1);
else
a_thread->PushInt(0);
return GM_OK;
}
int Player_JoinInstance(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(5);
GM_CHECK_INT_PARAM(mapId, 0);
GM_CHECK_FLOAT_PARAM(posX, 1);
GM_CHECK_FLOAT_PARAM(posY, 2);
GM_CHECK_FLOAT_PARAM(posZ, 3);
GM_CHECK_FLOAT_PARAM(posO, 4);
MapInfo *pMapinfo = NULL;
pMapinfo = WorldMapInfoStorage.LookupEntry(mapId);
bool result = sWorldCreator.CheckInstanceForObject(static_cast(GetThisPointer(a_thread)), pMapinfo);
if(result)
{
GetThisPointer(a_thread)->SaveEntryPoint(mapId);
GetThisPointer(a_thread)->SafeTeleport(mapId, 0, LocationVector(posX, posY, posZ, posO));
}
return GM_OK;
}
/* Areatrigger events */
int AreaTrigger_GetEntry(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
a_thread->PushInt(GetThisPointer(a_thread)->AreaTriggerID);
return GM_OK;
}
/* Unit events */
int Unit_Despawn(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(delay, 0);
GM_CHECK_INT_PARAM(respawntime, 1);
Unit * pUnit = GetThisPointer(a_thread);
if(pUnit->GetTypeId() != TYPEID_UNIT)
return GM_EXCEPTION;
Creature * pCreature = ((Creature*)pUnit);
pCreature->Despawn(delay, respawntime);
return GM_OK;
}
int Unit_Emote(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(emote, 0);
Unit * pUnit = GetThisPointer(a_thread);
pUnit->Emote((EmoteType)emote);
return GM_OK;
}
int Unit_SendChatMessage(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(msg, 0);
Unit * pUnit = GetThisPointer(a_thread);
pUnit->SendChatMessage(CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, msg);
return GM_OK;
}
int Unit_CastSpell(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(spellid, 0);
Unit * pUnit = GetThisPointer(a_thread);
pUnit->CastSpell(pUnit, sSpellStore.LookupEntry(spellid), true);
return GM_OK;
}
int Unit_SetStandState(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(stateid, 0);
Unit * pUnit = GetThisPointer(a_thread);
pUnit->SetStandState(stateid);
return GM_OK;
}
int Player_AddItem(gmThread * a_thread)
{
bool push = false;
if(a_thread->GetNumParams() == 2)
{
// Assume to send an item push
push = true;
}
else if(a_thread->GetNumParams() == 3)
{
// Choice for push
GM_CHECK_INT_PARAM(push_, 2);
push = (push_ > 0) ? true : false;
}
else
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(itemid, 0);
GM_CHECK_INT_PARAM(count, 1);
Player * pPlayer = GetThisPointer(a_thread);
if(pPlayer->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
ItemPrototype * proto = ItemPrototypeStorage.LookupEntry(itemid);
if(!proto)
return GM_EXCEPTION;
if(pPlayer->GetItemInterface()->CanReceiveItem(proto, count) == 0)
{
int acount;
int bcount;
if(proto->MaxCount && proto->MaxCount <= (uint32)count)
{
acount = 1;
bcount = count;
}
else
{
acount = count;
bcount = 0;
}
for(int i = 0; i < acount; ++i)
{
Item * pItem = objmgr.CreateItem(itemid, pPlayer);
if(!pPlayer->GetItemInterface()->AddItemToFreeSlot(pItem))
{
delete pItem;
break;
}
}
if(push)
{
WorldPacket data(45);
pPlayer->GetSession()->BuildItemPushResult(&data, pPlayer->GetGUID(), ITEM_PUSH_TYPE_RECEIVE, count, itemid, 0);
pPlayer->GetSession()->SendPacket(&data);
}
}
return GM_OK;
}
int Player_RemoveItem(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(itemid, 0);
GM_CHECK_INT_PARAM(count, 1);
Player * pPlayer = GetThisPointer(a_thread);
if(pPlayer->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
pPlayer->GetItemInterface()->RemoveItemAmt(itemid, count);
return GM_OK;
}
int Player_LearnSpell(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(spellid, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
GetThisPointer(a_thread)->addSpell(spellid);
return GM_OK;
}
int Player_RemoveSpell(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(spellid, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
GetThisPointer(a_thread)->removeSpell(spellid, false, false, 0);
return GM_OK;
}
int Unit_CastSpellOnTarget(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(spellid, 0);
Unit * pTarget = (Unit*)a_thread->ParamUser_NoCheckTypeOrParam(1);
Unit * pThis = GetThisPointer(a_thread);
if(!pTarget)
return GM_OK;
SpellEntry * pSpellEntry = sSpellStore.LookupEntry(spellid);
pThis->CastSpell(pTarget, pSpellEntry, true);
return GM_OK;
}
int Unit_TimedEmote(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(emoteid, 0);
GM_CHECK_INT_PARAM(timer, 1);
Unit * pThis = GetThisPointer(a_thread);
if(timer)
pThis->EventAddEmote((EmoteType)emoteid, timer);
else
pThis->SetUInt32Value(UNIT_NPC_EMOTESTATE, emoteid);
return GM_OK;
}
int Unit_RegisterTimer(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(3);
GM_CHECK_INT_PARAM(delay, 0);
GM_CHECK_FUNCTION_PARAM(func, 1);
GM_CHECK_INT_PARAM(repeats, 2);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() != TYPEID_UNIT)
return GM_EXCEPTION;
sEventMgr.AddEvent(((Creature*)pThis), &Creature::TriggerScriptEvent, ((void*)func), EVENT_SCRIPT_UPDATE_EVENT, delay, repeats,0);
return GM_OK;
}
int Unit_DeregisterTimer(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() != TYPEID_UNIT)
return GM_EXCEPTION;
sEventMgr.RemoveEvents(((Creature*)pThis), EVENT_SCRIPT_UPDATE_EVENT);
return GM_OK;
}
int Unit_SpawnMonster(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(4);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_FLOAT_PARAM(posX, 1);
GM_CHECK_FLOAT_PARAM(posY, 2);
GM_CHECK_FLOAT_PARAM(posZ, 3);
Unit * pThis = GetThisPointer(a_thread);
CreatureProto * p = CreatureProtoStorage.LookupEntry(entry);
if(!p)
return GM_EXCEPTION;
Creature * pCreature = pThis->GetMapMgr()->CreateCreature();
pCreature->spawnid = 0;
pCreature->m_spawn = 0;
pCreature->Load(p, posX, posY, posZ);
pCreature->SetMapId(pThis->GetMapId());
pCreature->SetInstanceID(pThis->GetInstanceID());
pCreature->PushToWorld(pThis->GetMapMgr());
return GM_OK;
}
/* Base function */
int Unit_RemoveAura(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(spid, 0);
GetThisPointer(a_thread)->RemoveAura(spid);
return GM_OK;
}
int Player_HasQuest(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(questid, 0);
if(GetThisPointer(a_thread)->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
Player *p = GetThisPointer(a_thread);
if(p->GetQuestLogForEntry(questid))
a_thread->PushInt(1);
else
a_thread->PushInt(0);
return GM_OK;
}
int Player_HasItem(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(itemid, 0);
Player * pPlayer = GetThisPointer(a_thread);
if(pPlayer->GetTypeId() != TYPEID_PLAYER)
return GM_EXCEPTION;
if(pPlayer->GetItemInterface()->GetItemCount(itemid, 0))
a_thread->PushInt(1);
else
a_thread->PushInt(0);
return GM_OK;
}
int GameObject_Despawn(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(timer, 0);
GameObject * pThis = GetThisPointer(a_thread);
pThis->Despawn(timer);
return GM_OK;
}
int GM_RAND(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(min, 0);
GM_CHECK_INT_PARAM(max, 1);
a_thread->PushInt(sRand.randInt(max-min)+min);
return GM_OK;
}
int Quest_GetID(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Quest * pThis = GetThisPointer(a_thread);
a_thread->PushInt(pThis->id);
return GM_OK;
}
int GM_RegisterEvent(gmThread * a_thread)
{
Object * pThis = GetThisPointer(a_thread);
if(a_thread->GetNumParams() < 2)
return GM_EXCEPTION;
if(a_thread->ParamType(0) != GM_INT || a_thread->ParamType(1) != GM_FUNCTION)
return GM_EXCEPTION;
uint32 argc = a_thread->GetNumParams() - 2;
uint32 * argv = argc ? new uint32[argc] : 0;
uint32 * argt = argc ? new uint32[argc] : 0;
/* see if any of the arguments are our user types -> if so we need to convert the pointers. */
for(uint32 i = 0; i < argc; ++i)
{
void * pointer = 0;
uint32 t = 0;
for(list::iterator itr = ScriptSystem->m_allowedTypes.begin(); itr != ScriptSystem->m_allowedTypes.end(); ++itr)
{
pointer = a_thread->Param(2+i).GetUserSafe((*itr));
if(pointer)
{
t = *itr;
break;
}
}
if(pointer)
{
argt[i] = uint32( (t << 16) | uint32(GM_USER) );
argv[i] = (uint32)pointer;
}
else
{
argt[i] = 0 | uint32( ( uint32(a_thread->ParamType(2+i)) << 16) );
argv[i] = *(uint32*)&a_thread->Param(2+i).m_value;
}
}
/* set up the event :) */
sEventMgr.AddEvent(pThis, &Object::GMScriptEvent, (void*)a_thread->ParamRef(1), argc, argv, argt, EVENT_GMSCRIPT_EVENT, a_thread->ParamInt(0), 1, 0);
return GM_OK;
}
void Object::GMScriptEvent(void * function, uint32 argc, uint32 * argv, uint32 * argt)
{
ScriptSystem->GetLock().Acquire();
gmFunctionObject * func = (gmFunctionObject*)function;
ASSERT(func->GetType() == GM_FUNCTION);
/* strange if we had a function without any arguments, that means no 'this' pointer :P *shrugs* */
ScriptSystem->m_userObjectCounter = argc;
/*if(argc)
{
ASSERT((uint16)argt != 0); // is a user pointer
ScriptSystem->SetVariable(0, (void*)argv[0], (gmType)(argt[0] >> 16));
}*/
gmCall call;
if(!call.BeginFunction(ScriptSystem->GetMachine(), func, /*argc ? ScriptSystem->m_variables[0] : */gmVariable::s_null, false))
{
printf("Could not execute delayed function.");
ScriptSystem->DumpErrors();
}
else
{
/* the rest of the arguments */
if(argc)
{
for(uint32 i = 0; i < argc; ++i)
{
if((uint16)argt[i] != 0) // user pointer
{
ScriptSystem->SetVariable(i, (void*)argv[i], (gmType)(argt[i] >> 16));
call.AddParam(ScriptSystem->m_variables[i]);
}
else // normal param
{
ScriptSystem->m_variables[i].m_type = UINT32_HIPART(argt[i]);
*(uint32*)&ScriptSystem->m_variables[i].m_value = argv[i];
// push it!
call.AddParam(ScriptSystem->m_variables[i]);
}
}
}
/* fly away! */
call.End();
ScriptSystem->DumpErrors();
}
ScriptSystem->GetLock().Release();
delete [] argt;
delete [] argv;
}
// Escort Quest System
int Unit_CreateCustomWaypointMap(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Creature * pCreature = GetThisPointer(a_thread);
if(pCreature->GetTypeId() != TYPEID_UNIT)
return GM_EXCEPTION;
if(pCreature->m_custom_waypoint_map)
{
for(WayPointMap::iterator itr = pCreature->m_custom_waypoint_map->begin(); itr != pCreature->m_custom_waypoint_map->end(); ++itr)
delete (*itr);
delete pCreature->m_custom_waypoint_map;
}
pCreature->m_custom_waypoint_map = new WayPointMap;
pCreature->GetAIInterface()->SetWaypointMap(pCreature->m_custom_waypoint_map);
return GM_OK;
}
int Unit_CreateWaypoint(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(7);
GM_CHECK_FLOAT_PARAM(x, 0);
GM_CHECK_FLOAT_PARAM(y, 1);
GM_CHECK_FLOAT_PARAM(z, 2);
GM_CHECK_FLOAT_PARAM(o, 3);
GM_CHECK_INT_PARAM(waittime, 4);
GM_CHECK_INT_PARAM(flags, 5);
GM_CHECK_INT_PARAM(modelid, 6);
Creature * pCreature = GetThisPointer(a_thread);
if(pCreature->GetTypeId() != TYPEID_UNIT)
return GM_EXCEPTION;
if(!pCreature->m_custom_waypoint_map)
{
pCreature->m_custom_waypoint_map = new WayPointMap;
pCreature->GetAIInterface()->SetWaypointMap(pCreature->m_custom_waypoint_map);
}
if(!modelid)
modelid = pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID);
WayPoint * wp = new WayPoint;
wp->id = pCreature->m_custom_waypoint_map->size() + 1;
wp->x = x;
wp->y = y;
wp->z = z;
wp->o = o;
wp->flags = flags;
wp->backwardskinid = modelid;
wp->forwardskinid = modelid;
wp->backwardemoteid = wp->forwardemoteid = 0;
wp->backwardemoteoneshot = wp->forwardemoteoneshot = false;
wp->waittime = waittime;
pCreature->m_custom_waypoint_map->push_back(wp);
return GM_OK;
}
int Unit_SpawnWithoutWorld(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(4);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_FLOAT_PARAM(posX, 1);
GM_CHECK_FLOAT_PARAM(posY, 2);
GM_CHECK_FLOAT_PARAM(posZ, 3);
Unit * pThis = GetThisPointer(a_thread);
CreatureProto * p = CreatureProtoStorage.LookupEntry(entry);
if(!p)
return GM_EXCEPTION;
Creature * pCreature = pThis->GetMapMgr()->CreateCreature();
pCreature->spawnid = 0;
pCreature->m_spawn = 0;
pCreature->Load(p, posX, posY, posZ);
pCreature->SetMapId(pThis->GetMapId());
pCreature->SetInstanceID(pThis->GetInstanceID());
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)pCreature;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_GetHealthPct(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
a_thread->PushFloat((float) pThis->GetUInt32Value(UNIT_FIELD_HEALTH) * 100.0f / pThis->GetUInt32Value(UNIT_FIELD_MAXHEALTH));
return GM_OK;
}
int Unit_AddToWorld(gmThread * a_thread)
{
/* we need to provide a mapmgr to "leech" from. */
GM_CHECK_NUM_PARAMS(1);
/*if(a_thread->ParamType(0) != ScriptSystem->m_unitType)
{
a_thread->GetMachine()->GetLog().LogEntry("expecting param %d as user type Unit", 0);
return GM_EXCEPTION;
}
Object * leech = (Object*)a_thread->ParamUser_NoCheckTypeOrParam(0);*/
GM_CHECK_USER_PARAM(Object*, ScriptSystem->m_unitType, leech, 0);
Unit * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
{
pThis->PushToWorld(leech->GetMapMgr());
}
return GM_OK;
}
int Unit_MoveToWaypoint(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(wp, 0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
pThis->MoveToWaypoint(wp);
return GM_OK;
}
int Unit_Delete(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
((Creature*)pThis)->SafeDelete();
return GM_OK;
}
int Unit_SetCombatCapable(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(capable, 0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
pThis->GetAIInterface()->disable_melee = (capable > 0) ? true : false;
return GM_OK;
}
int Unit_HaltMovement(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(timer, 0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
pThis->GetAIInterface()->StopMovement(timer);
return GM_OK;
}
int Player_MarkQuestObjectiveAsComplete(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(questId, 0);
GM_CHECK_INT_PARAM(objective, 1);
Player * pThis = GetThisPointer(a_thread);
QuestLogEntry * qle = pThis->GetQuestLogForEntry(questId);
if(!qle)
return GM_OK;
Quest * q = qle->GetQuest();
qle->SetMobCount(objective, q->required_mobcount[objective]);
qle->SendUpdateAddKill(objective);
if(qle->CanBeFinished())
qle->SendQuestComplete();
return GM_OK;
}
int Unit_SetMovementType(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(mtype, 0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
pThis->GetAIInterface()->setMoveType(mtype);
return GM_OK;
}
int Unit_SetEscortTarget(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_USER_PARAM(Player*, ScriptSystem->m_playerType, leech, 0);
Creature * pThis = GetThisPointer(a_thread);
pThis->m_escorter = leech;
return GM_OK;
}
int Unit_HasEscortTarget(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Creature * pThis = GetThisPointer(a_thread);
if(pThis->m_escorter != 0)
a_thread->PushInt(1);
else
a_thread->PushInt(0);
return GM_OK;
}
int Unit_GetEscortTarget(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Creature * pThis = GetThisPointer(a_thread);
if(pThis->m_escorter == 0)
return GM_EXCEPTION;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)pThis->m_escorter;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_playerType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Player_SendNotification(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(msg, 0);
Player * pThis = GetThisPointer(a_thread);
pThis->GetSession()->SendNotification(msg);
return GM_OK;
}
int Player_SendSystemMessage(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(msg, 0);
Player * pThis = GetThisPointer(a_thread);
sChatHandler.SystemMessage(pThis->GetSession(), msg);
return GM_OK;
}
int Unit_SetNPCFlags(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(mtype, 0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
pThis->SetUInt32Value(UNIT_NPC_FLAGS, mtype);
return GM_OK;
}
int Unit_DestroyCustomWaypointMap(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
((Creature*)pThis)->DestroyCustomWaypointMap();
return GM_OK;
}
int Unit_ClearEscortTarget(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
if(pThis->GetTypeId() == TYPEID_UNIT)
((Creature*)pThis)->m_escorter = 0;
return GM_OK;
}
int GameObject_PlayCustomAnim(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(anim, 0);
GameObject * pThis = GetThisPointer(a_thread);
WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM, 12);
data << pThis->GetGUID() << uint32(anim);
pThis->SendMessageToSet(&data, true, false);
return GM_OK;
}
int GameObject_SetActive(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(state, 0);
GameObject * pThis = GetThisPointer(a_thread);
pThis->SetUInt32Value(GAMEOBJECT_DYN_FLAGS, state);
return GM_OK;
}
int Player_Knockback(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(4);
GM_CHECK_FLOAT_PARAM(dx, 0);
GM_CHECK_FLOAT_PARAM(dy, 1);
GM_CHECK_FLOAT_PARAM(affect1, 2);
GM_CHECK_FLOAT_PARAM(affect2, 3);
Player * pThis = GetThisPointer(a_thread);
WorldPacket data(SMSG_MOVE_KNOCK_BACK, 30);
data << pThis->GetNewGUID();
data << getMSTime();
data << dx << dy << affect1 << affect2;
pThis->SendMessageToSet(&data, true);
return GM_OK;
}
int Unit_GetGuid(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
a_thread->PushInt(pThis->GetGUIDLow());
return GM_OK;
}
int Unit_GetPlayer(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(guid, 0);
Object * pThis = GetThisPointer(a_thread);
Player * plr = pThis->GetMapMgr() ? pThis->GetMapMgr()->GetPlayer(guid) : 0;
if(!plr)
return GM_EXCEPTION;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)plr;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_playerType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_GetUnit(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(guid, 0);
Object * pThis = GetThisPointer(a_thread);
Unit * plr = pThis->GetMapMgr() ? pThis->GetMapMgr()->GetUnit(guid) : 0;
if(!plr)
return GM_EXCEPTION;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)plr;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_GetGameObject(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(guid, 0);
Object * pThis = GetThisPointer(a_thread);
GameObject * plr = pThis->GetMapMgr() ? pThis->GetMapMgr()->GetGameObject(guid) : 0;
if(!plr)
return GM_EXCEPTION;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)plr;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_gameObjectType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_ChangeEntry(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(entry, 0);
Unit * pThis = GetThisPointer(a_thread);
WorldPacket data(200);
pThis->BuildFieldUpdatePacket(&data, OBJECT_FIELD_ENTRY, entry);
pThis->SendMessageToSet(&data, true);
return GM_OK;
}
int Unit_ChangeModel(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(model, 0);
Unit * pThis = GetThisPointer(a_thread);
pThis->SetUInt32Value(UNIT_FIELD_DISPLAYID, model);
return GM_OK;
}
int Unit_ChangeScale(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_FLOAT_PARAM(scale, 0);
Unit * pThis = GetThisPointer(a_thread);
pThis->SetFloatValue(OBJECT_FIELD_SCALE_X, scale);
return GM_OK;
}
int Unit_ChangeFaction(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(meh, 0);
Unit * pThis = GetThisPointer(a_thread);
pThis->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, meh);
pThis->_setFaction();
pThis->UpdateOppFactionSet();
return GM_OK;
}
int Unit_TextEmote(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(msg, 0);
Unit * pUnit = GetThisPointer(a_thread);
pUnit->SendChatMessage(CHAT_MSG_MONSTER_EMOTE, LANG_UNIVERSAL, msg);
return GM_OK;
}
int Unit_SendChatMessageAltEntry(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_STRING_PARAM(msg, 1);
Unit * pUnit = GetThisPointer(a_thread);
pUnit->SendChatMessageAlternateEntry(entry, CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, msg);
return GM_OK;
}
int GM_GetUnitBySqlId(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(id, 0);
Creature * pc = objmgr.GetCreatureBySqlId(id);
if(!pc)
{
GM_EXCEPTION_MSG("could not find entrysqlid");
return GM_EXCEPTION;
}
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)pc;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_PlaySoundToSet(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(id, 0);
Object * pThis = GetThisPointer(a_thread);
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << uint32(id);
pThis->SendMessageToSet(&data, true);
return GM_OK;
}
/**
* Updates a player to the specified level
*/
int Player_SetLevel(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(level, 0);
Player * p = GetThisPointer(a_thread);
uint32 curLevel = p->getLevel();
if ( curLevel >= level ) // player has already reached or exceeded the requested level
return GM_OK;
// deny the setting of level above server limits
if ( p->GetSession()->HasFlag(ACCOUNT_FLAG_XPACK_01) )
{
if ( level > sWorld.Expansion1LevelCap )
level = sWorld.Expansion1LevelCap;
} else {
if ( level > sWorld.LevelCap )
level = sWorld.LevelCap;
}
for( ; curLevel < level ; curLevel++ )
{
p->GiveXP(p->GetUInt32Value(PLAYER_NEXT_LEVEL_XP) - p->GetUInt32Value(PLAYER_XP), p->GetGUID(), true);
}
sSocialMgr.SendUpdateToFriends( p );
return GM_OK;
}
/**
* Updates player level by the specified amount
*/
int Player_LevelUp(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(amount, 0);
if (amount < 1)
amount = 1;
Player * p = GetThisPointer(a_thread);
uint32 curLevel = p->getLevel(); // current level
uint32 endLevel = curLevel + amount; // result level
if ( p->GetSession()->HasFlag(ACCOUNT_FLAG_XPACK_01) )
{
if ( endLevel > sWorld.Expansion1LevelCap )
endLevel = sWorld.Expansion1LevelCap;
} else {
if ( endLevel > sWorld.LevelCap )
endLevel = sWorld.LevelCap;
};
for( ; curLevel < endLevel; curLevel++ )
{
p->GiveXP(p->GetUInt32Value(PLAYER_NEXT_LEVEL_XP) - p->GetUInt32Value(PLAYER_XP), p->GetGUID(), true);
}
sSocialMgr.SendUpdateToFriends( p );
return GM_OK;
}
/**
* Player_Kick()
*
* Kicks the player from the server
*
* @param int Delay in seconds before kicking
*/
int Player_Kick(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(delay, 0); // delay seconds
if (delay < 0)
delay = 0;
GetThisPointer(a_thread)->Kick(delay * 1000);
return GM_OK;
}
int Unit_SendYellMessage(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_STRING_PARAM(text, 0);
GetThisPointer(a_thread)->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, text);
return GM_OK;
}
/*int Player_GetSelectedCreature(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(show_message, 0);
Player * pThis = GetThisPointer(a_thread);
Creature * pCreature = sChatHandler.getSelectedCreature(pThis->GetSession(), show_message);
if(ScriptSystem->m_userObjectCounter == 9)
return GM_EXCEPTION;
gmUserObject * obj = ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter++];
obj->m_userType = ScriptSystem->m_unitType;
obj->m_user = pCreature;
a_thread->PushUser(obj);
}
*/
int GM_SPRINTF(gmThread * a_thread)
{
if(a_thread->GetNumParams() < 1)
return GM_EXCEPTION;
char buffer[2048];
int param_count = a_thread->GetNumParams()-1;
char** params = param_count ? new char*[param_count] : NULL;
GM_CHECK_STRING_PARAM(format,0);
for(int i = 0; i < param_count; ++i)
{
if(a_thread->Param(i).m_type == GM_STRING)
params[i] = (char*)a_thread->ParamString(i, "INVALID_STRING");
else
params[i] = (char*)a_thread->Param(i).m_value.m_ref;
}
/* this is the ugly bit. */
char ** p = params;
switch(param_count)
{
case 0:
snprintf(buffer, 2048, format);
break;
case 1:
snprintf(buffer, 2048, format, params[0]);
break;
case 2:
snprintf(buffer, 2048, format, params[0], params[1]);
break;
case 3:
snprintf(buffer, 2048, format, p[0], p[1], p[2]);
break;
case 4:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3]);
break;
case 5:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3], p[4]);
break;
case 6:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3], p[4], p[5]);
break;
case 7:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
break;
case 8:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
break;
case 9:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
break;
case 10:
snprintf(buffer, 2048, format, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[10]);
break;
default:
delete [] p;
GM_EXCEPTION_MSG("Expecting less than 10 arguments to sprintf.");
return GM_EXCEPTION;
break;
}
a_thread->PushNewString(buffer, strlen(buffer));
delete [] params;
return GM_OK;
}
int Unit_GetName(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * obj = GetThisPointer(a_thread);
if(!obj) return GM_EXCEPTION;
switch(obj->GetTypeId())
{
case TYPEID_PLAYER:
a_thread->PushNewString(((Player*)obj)->GetName());
break;
case TYPEID_UNIT:
{
/* are we a pet ? */
if(obj->GetGUIDHigh() == HIGHGUID_PET)
a_thread->PushNewString(((Pet*)obj)->GetName().c_str());
else
a_thread->PushNewString(((Creature*)obj)->GetCreatureName() ? ((Creature*)obj)->GetCreatureName()->Name : "Unknown Entity");
}break;
default:
GM_EXCEPTION_MSG("Unknown typeid.");
return GM_EXCEPTION;
}
return GM_OK;
}
int GM_GetDistance(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_USER_PARAM(Object*, ScriptSystem->m_unitType, obj1, 0);
GM_CHECK_USER_PARAM(Object*, ScriptSystem->m_unitType, obj2, 1);
if(!obj1->IsInWorld() || !obj2->IsInWorld())
{
GM_EXCEPTION_MSG("Objects not in world.");
return GM_EXCEPTION;
}
a_thread->PushFloat(obj1->GetDistance2dSq(obj2));
return GM_OK;
}
int Unit_GetClosestPlayer(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
{
GM_EXCEPTION_MSG("Unit is not in world!");
return GM_EXCEPTION;
}
Player * closest = NULL;
for(set::iterator itr = pThis->GetInRangePlayerSetBegin(); itr != pThis->GetInRangePlayerSetEnd(); ++itr)
{
if(closest == NULL || closest->GetDistance2dSq(pThis) > (*itr)->GetDistance2dSq(pThis) && pThis != (*itr))
closest = (*itr);
}
if(closest == NULL)
{
return GM_EXCEPTION;
}
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)closest;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_GetRandomPlayer(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
{
GM_EXCEPTION_MSG("Unit is not in world!");
return GM_EXCEPTION;
}
uint32 count= 0;
for(set::iterator itr = pThis->GetInRangePlayerSetBegin(); itr != pThis->GetInRangePlayerSetEnd(); ++itr)
count++;
if (count==0)
return GM_EXCEPTION;
uint32 r = rand() %count;
count=0;
Player* result = NULL;
for(set::iterator itr = pThis->GetInRangePlayerSetBegin(); itr != pThis->GetInRangePlayerSetEnd(); ++itr)
{
if (count!=r)
count++;
else
{
result = (*itr);
break;
}
}
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)result;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_GetClosestUnit(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
{
GM_EXCEPTION_MSG("Unit is not in world!");
return GM_EXCEPTION;
}
Unit * closest = NULL;
for(set::iterator itr = pThis->GetInRangeSetBegin(); itr != pThis->GetInRangeSetEnd(); ++itr)
{
if(closest == NULL || closest->GetDistance2dSq(pThis) > (*itr)->GetDistance2dSq(pThis) && pThis != (*itr) && (*itr)->GetTypeId() != TYPEID_GAMEOBJECT)
closest = (Unit*)(*itr);
}
if(closest == NULL)
{
return GM_EXCEPTION;
}
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)closest;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_InCombat(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
{
return GM_EXCEPTION;
}
if(pThis->isInCombat())
a_thread->PushInt(1);
else
a_thread->PushInt(0);
return GM_OK;
}
int Unit_GetClosestUnitByEntry(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_INT_PARAM(entry, 0);
Object * pThis = GetThisPointer(a_thread);
Creature * closest = NULL;
for(set::iterator itr = pThis->GetInRangeSetBegin(); itr != pThis->GetInRangeSetEnd(); ++itr)
{
if(closest == NULL || closest->GetDistance2dSq(pThis) > (*itr)->GetDistance2dSq(pThis) && pThis != (*itr) && (*itr)->GetTypeId() != TYPEID_GAMEOBJECT && (*itr)->GetTypeId() != TYPEID_PLAYER && ((Creature*)(*itr))->GetEntry() == entry)
closest = (Creature*)(*itr);
}
if(closest == NULL)
{
a_thread->PushNull();
return GM_OK;
}
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_user = (void*)closest;
ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]->m_userType = ScriptSystem->m_unitType;
a_thread->PushUser(ScriptSystem->m_userObjects[ScriptSystem->m_userObjectCounter]);
ScriptSystem->m_userObjectCounter++;
return GM_OK;
}
int Unit_GetPositionX(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
return GM_EXCEPTION;
a_thread->PushFloat(pThis->GetPositionX());
return GM_OK;
}
int Unit_GetPositionY(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
return GM_EXCEPTION;
a_thread->PushFloat(pThis->GetPositionY());
return GM_OK;
}
int Unit_GetPositionZ(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
return GM_EXCEPTION;
a_thread->PushFloat(pThis->GetPositionZ());
return GM_OK;
}
int Unit_GetFacing(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Object * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
return GM_EXCEPTION;
a_thread->PushFloat(pThis->GetOrientation());
return GM_OK;
}
int Unit_AddToHated(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(1);
GM_CHECK_USER_PARAM(Object*, ScriptSystem->m_unitType, victim, 0);
Unit * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
return GM_OK;
if(pThis->GetTypeId() == TYPEID_GAMEOBJECT) // WTF YOU NEWB?
return GM_OK;
((Creature*)pThis)->GetAIInterface()->AttackReaction(static_cast(victim), 1, 0);
return GM_OK;
}
int Unit_ReturnToSpawn(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(0);
Unit * pThis = GetThisPointer(a_thread);
if(!pThis->IsInWorld())
return GM_OK;
Creature * pCreature = static_cast(pThis);
pCreature->GetAIInterface()->SetAIState(STATE_IDLE);
pCreature->GetAIInterface()->WipeHateList();
pCreature->GetAIInterface()->WipeTargetList();
pCreature->GetAIInterface()->MoveTo(pCreature->m_spawn->x, pCreature->m_spawn->y, pCreature->m_spawn->z, pCreature->m_spawn->o);
return GM_OK;
}
int Unit_AddThreat(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(2);
GM_CHECK_USER_PARAM(Object*, ScriptSystem->m_unitType, target, 0);
GM_CHECK_INT_PARAM(damage, 1);
if(target->GetTypeId() == TYPEID_GAMEOBJECT) // Come on, wtf are you smoking?
return GM_OK;
Unit * pThis = GetThisPointer(a_thread);
pThis->GetAIInterface()->AttackReaction((Unit*)target, damage, 0);
return GM_OK;
}
int Unit_Spawngameobject(gmThread * a_thread)
{
GM_CHECK_NUM_PARAMS(6);
GM_CHECK_INT_PARAM(entry, 0);
GM_CHECK_INT_PARAM(mapID, 1);
GM_CHECK_FLOAT_PARAM(posX, 2);
GM_CHECK_FLOAT_PARAM(posY, 3);
GM_CHECK_FLOAT_PARAM(posZ, 4);
GM_CHECK_FLOAT_PARAM(facing, 5);
Unit * pThis = GetThisPointer(a_thread);
GameObjectInfo * p = GameObjectNameStorage.LookupEntry(entry);
if(!p)
return GM_EXCEPTION;
GameObject * pGameObject = pThis->GetMapMgr()->CreateGameObject();
pGameObject->spawnid = 0;
pGameObject->m_spawn = 0;
if(!pGameObject->CreateFromProto(entry,mapID,posX,posY,posZ,facing))
{
delete pGameObject;
return 0;
}
pGameObject->SetUInt32Value(GAMEOBJECT_DYN_FLAGS,1);
pGameObject->SetMapId(pThis->GetMapId());
pGameObject->SetInstanceID(pThis->GetInstanceID());
pGameObject->PushToWorld(pThis->GetMapMgr());
return GM_OK;
}