root/Trunk/src/LuaEngine/LUAEngine.cpp @ 1144

Revision 1144, 90.6 kB (checked in by Paroxysm, 7 months ago)

ADDED: New commands.
UNIT :

-GetSelectedGO() - gets the current targeted go through .go select.
-IsInGroup?() - used by players.

GAMEOBJECT:

  • Fixed SpawnGameObject/Creature? functions they should properly spawn and return creature userdata.
  • GetByte?(index,index2) - similar to Object::GetByte?(..) function.
  • SetByte?(index,index2,value) - similar to Object::SetByte?(..)
  • ChangeScale?(float newscale, bool updatenow) - changes the gameobject's scale, updatenow boolean makes it respawn the gameobject.
  • CustomAnimate?(0 or 1) - activates the gameobject's custom animation. 0 turns on, 1 turns off.
Line 
1/*
2 * ArcScript Scripts for Arcemu MMORPG Server
3 * Copyright (C) 2008-2009 Arcemu Team
4 * Copyright (C) 2007 Moon++ <http://www.moonplusplus.com/>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "StdAfx.h"
21#include "LUAEngine.h"
22#include <ScriptSetup.h>
23
24#ifdef WIN32
25#pragma warning(disable:4129)
26#pragma warning(disable:4244)
27#endif
28
29#if PLATFORM != PLATFORM_WIN32
30#include <dirent.h>
31#endif
32
33ScriptMgr * m_scriptMgr = NULL;
34LuaEngine g_luaMgr;
35       
36
37extern "C" SCRIPT_DECL uint32 _exp_get_script_type()
38{ 
39        return SCRIPT_TYPE_SCRIPT_ENGINE | SCRIPT_TYPE_SCRIPT_ENGINE_LUA;
40}
41
42extern "C" SCRIPT_DECL void _exp_script_register(ScriptMgr* mgr)
43{
44        m_scriptMgr = mgr;
45        sLuaMgr.Startup();
46}
47extern "C" SCRIPT_DECL void _export_engine_reload()
48{
49        sLuaMgr.Restart();
50}
51
52template<typename T> const char * GetTClassName() { return "UNKNOWN"; }
53template<> const char * GetTClassName<Unit>() { return "Unit"; }
54template<> const char * GetTClassName<Item>() { return "Item"; }
55template<> const char * GetTClassName<GameObject>() { return "GameObject"; }
56template<> const char * GetTClassName<WorldPacket>() { return "LuaPacket"; }
57template<> const char * GetTClassName<TaxiPath>() { return "LuaTaxi"; }
58template<> const char * GetTClassName<Spell>() { return "Spell"; }
59template<> const char * GetTClassName<Field>() { return "SQL_Field"; }
60template<> const char * GetTClassName<QueryResult>() { return "SQL_QResult"; }
61
62template<typename T> RegType<T>* GetMethodTable();
63template<> RegType<Unit>* GetMethodTable<Unit>();
64template<> RegType<Item>* GetMethodTable<Item>();
65template<> RegType<GameObject>* GetMethodTable<GameObject>();
66template<> RegType<WorldPacket>* GetMethodTable<WorldPacket>();
67template<> RegType<TaxiPath>* GetMethodTable<TaxiPath>();
68template<> RegType<Spell>* GetMethodTable<Spell>();
69template<> RegType<Field>* GetMethodTable<Field>();
70template<> RegType<QueryResult>* GetMethodTable<QueryResult>();
71
72void report(lua_State * L)
73{
74        uint32 count = 20;
75        const char * msg= lua_tostring(L,-1);
76        while(msg && count > 0)
77        {
78                lua_pop(L,-1);
79                printf("\t%s\n", msg);
80                msg=lua_tostring(L,-1);
81                count--;
82        }
83}
84
85void LuaEngine::ScriptLoadDir(char* Dirname, LUALoadScripts *pak)
86{
87        #ifdef WIN32
88                Log.Success("LuaEngine", "Scanning Directory %s", Dirname);
89                HANDLE hFile;
90                WIN32_FIND_DATA FindData;
91                memset(&FindData,0,sizeof(FindData));
92
93                char SearchName[MAX_PATH];
94               
95                strcpy(SearchName,Dirname);
96                strcat(SearchName,"\\*.*");
97
98                hFile = FindFirstFile(SearchName,&FindData);
99                FindNextFile(hFile, &FindData);
100           
101                while( FindNextFile(hFile, &FindData) )
102                {
103                        if( FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) //Credits for this 'if' go to Cebernic from ArcScripts Team. Thanks, you saved me some work ;-)
104                        {
105                                strcpy(SearchName,Dirname);
106                                strcat(SearchName,"\\");
107                                strcat(SearchName,FindData.cFileName);
108                                ScriptLoadDir(SearchName, pak);
109                        }
110                        else
111                        {
112                                                string fname = Dirname;
113                                                fname += "\\";
114                                                fname += FindData.cFileName;
115
116                                        int len = strlen(fname.c_str());
117                                          int i=0;
118                                          char ext[MAX_PATH];
119                                         
120                                          while(len > 0)
121                                          { 
122                                           ext[i++] = fname[--len];
123                                           if(fname[len] == '.')
124                                   break;
125                                  }
126                                  ext[i++] = '\0';
127                                  if ( !_stricmp(ext,"aul.") ) pak->luaFiles.insert(fname);
128                        }
129                }
130          FindClose(hFile);
131        #else
132                char *pch=strrchr(Dirname,'/');
133                if (strcmp(Dirname, "..")==0 || strcmp(Dirname, ".")==0) return; //Against Endless-Loop
134                if (pch != NULL && (strcmp(pch, "/..")==0 || strcmp(pch, "/.")==0 || strcmp(pch, "/.svn")==0)) return;
135                struct dirent ** list;
136                int filecount = scandir(Dirname, &list, 0, 0);
137
138                if(filecount <= 0 || !list)
139                        return;
140
141                struct stat attributes;
142                bool err;
143                Log.Success("LuaEngine", "Scanning Directory %s", Dirname);
144                while(filecount--)
145                {
146                        char dottedrelpath[200];
147                        sprintf(dottedrelpath, "%s/%s", Dirname, list[filecount]->d_name);
148                        if(stat(dottedrelpath, &attributes) == -1) {
149                                err=true;
150                                Log.Error("LuaEngine","Error opening %s: %s\n", dottedrelpath, strerror(errno));
151                        } else err=false;
152
153                        if (!err && S_ISDIR(attributes.st_mode))
154                        {
155                                ScriptLoadDir((char *)dottedrelpath, pak); //Subdirectory
156                        } else {
157                                char* ext = strrchr(list[filecount]->d_name, '.');
158                                if(ext != NULL && !strcmp(ext, ".lua"))
159                                {
160                                        pak->luaFiles.insert(dottedrelpath);
161                                }
162                        }
163
164                        free(list[filecount]);
165                }
166                free(list);
167        #endif
168}
169
170void LuaEngine::LoadScripts()
171{
172        LUALoadScripts rtn;
173        Log.Notice("LuaEngine", "Scanning Script-Directories...");
174        ScriptLoadDir((char*)"scripts", &rtn);
175
176        unsigned int cnt_uncomp=0;
177
178        luaL_openlibs(lu);
179        RegisterCoreFunctions();
180        Log.Notice("LuaEngine", "Loading Scripts...");
181
182        char filename[200];
183
184        for(set<string>::iterator itr = rtn.luaFiles.begin(); itr != rtn.luaFiles.end(); ++itr)
185        { 
186                strcpy(filename, itr->c_str());
187                if(luaL_loadfile(lu, filename) != 0)
188                {
189#ifdef WIN32
190                        Log.Error("LuaEngine", "loading %s failed.(could not load)", itr->c_str());
191                        SetConsoleTextAttribute(stdout_handle, (WORD)TRED);
192#else
193                        Log.Notice("LuaEngine", "\033[22;31m loading %s failed.(could not load)", itr->c_str());
194                        printf("\033[22;31m");
195#endif
196                        report(lu);
197#ifdef WIN32
198                        SetConsoleTextAttribute(stdout_handle, (WORD)TWHITE);
199#else
200                        printf("\033[01;37m");
201#endif
202                }
203                else
204                {
205                        if(lua_pcall(lu, 0, 0, 0) != 0)
206                        {
207#ifdef WIN32
208                                Log.Error("LuaEngine", "%s failed.(could not run)", itr->c_str());
209                                SetConsoleTextAttribute(stdout_handle, (WORD)TRED);
210#else
211                                Log.Notice("LuaEngine", "\033[22;31m %s failed.(could not run)", itr->c_str());
212                                printf("\033[22;31m");
213
214#endif
215
216                                report(lu);
217#ifdef WIN32
218                                SetConsoleTextAttribute(stdout_handle, (WORD)TWHITE);
219#else
220                                printf("\033[01;37m");
221#endif
222                        }
223                        else
224                                        Log.Debug("LuaEngine", "loaded %s.", itr->c_str());
225                }
226                cnt_uncomp++;
227        }
228        Log.Notice("LuaEngine","Loaded %u Lua scripts.", cnt_uncomp);
229}
230
231
232/*******************************************************************************
233        FUNCTION CALL METHODS
234*******************************************************************************/
235
236bool LuaEngine::BeginCall(const char * func) 
237{
238        string sFuncName = string(func);
239        char * copy = strdup(func);
240        char * token = strtok(copy,".:");
241        bool colon = false;
242        if (strpbrk(func,".:") == NULL )
243                lua_getglobal(lu,func);
244        else
245        {
246                lua_getglobal(lu, "_G"); //start out with the global table.
247                int top = 1;
248                while (token != NULL)
249                {
250                        lua_getfield(lu, -1, token); //get the (hopefully) table/func
251                        if ((int)sFuncName.find(token)-1 > 0) //if it isn't the first token
252                        {
253                                if (sFuncName.at(sFuncName.find(token)-1) == '.') //if it was a .
254                                        colon = false;
255                                else if (sFuncName.at(sFuncName.find(token)-1) == ':')
256                                        colon = true;
257                        }
258                        else //if it IS the first token, we're OK to remove the "_G" from the stack
259                                colon = false;
260
261                        if (lua_isfunction(lu,-1) && !lua_iscfunction(lu,-1)) //if it's a Lua function
262                        {
263                                lua_replace(lu,top);
264                                if (colon)
265                                {
266                                        lua_pushvalue(lu, -1); //make the table the first arg
267                                        lua_replace(lu,top+1);
268                                        lua_settop(lu,top+1);
269                                }
270                                else
271                                        lua_settop(lu,top);
272                                break; //we don't need anything else
273                        }
274                        else if(lua_istable(lu,-1) )
275                                token = strtok(NULL,".:");
276                }
277        }
278        return colon;
279}
280bool LuaEngine::ExecuteCall(uint8 params, uint8 res)
281{
282        bool ret = true;
283        if(lua_pcall(lu,params,res,0) )
284        {
285                report(lu);
286                ret = false;
287        }
288        return ret;
289}
290void LuaEngine::EndCall(uint8 res) 
291{
292        for(int i = res; i > 0; i--)
293        {
294                if(!lua_isnone(lu,res))
295                        lua_remove(lu,res);
296        }
297}
298/*******************************************************************************
299        END FUNCTION CALL METHODS
300*******************************************************************************/
301
302/******************************************************************************
303        PUSH METHODS
304******************************************************************************/
305
306void LuaEngine::PUSH_UNIT(Object * unit, lua_State * L) 
307{
308        Unit * pUnit = NULL;
309        if(unit != NULL && unit->IsUnit() ) 
310                pUnit = TO_UNIT(unit);
311        if(L == NULL)
312                ArcLuna<Unit>::push(lu,pUnit);
313        else
314                ArcLuna<Unit>::push(L,pUnit);
315}
316void LuaEngine::PUSH_GO(Object *go, lua_State *L)
317{
318        GameObject * pGo = NULL;
319        if(go != NULL && go->IsGameObject() )
320                pGo = static_cast<GameObject*>(go);
321        if(L == NULL)
322                ArcLuna<GameObject>::push(lu,pGo);
323        else
324                ArcLuna<GameObject>::push(L,pGo);
325}
326void LuaEngine::PUSH_ITEM(Object * item, lua_State *L)
327{
328        Item * pItem = NULL;
329        if(item != NULL && (item->GetTypeId() == TYPEID_ITEM || item->GetTypeId() == TYPEID_CONTAINER))
330                pItem = static_cast<Item*>(item);
331        if(L == NULL)
332                ArcLuna<Item>::push(lu,pItem);
333        else
334                ArcLuna<Item>::push(L,pItem);
335}
336void LuaEngine::PUSH_GUID(uint64 guid, lua_State * L) 
337{
338        if(L == NULL)
339                GUID_MGR::push(lu,guid);
340        else
341                GUID_MGR::push(L,guid);
342}
343void LuaEngine::PUSH_PACKET(WorldPacket * pack, lua_State * L) 
344{
345        if(L == NULL)
346                ArcLuna<WorldPacket>::push(lu,pack,true);
347        else
348                ArcLuna<WorldPacket>::push(L,pack,true);
349}
350void LuaEngine::PUSH_TAXIPATH(TaxiPath * tp, lua_State * L) 
351{
352        if(L == NULL)
353                ArcLuna<TaxiPath>::push(lu,tp,true);
354        else
355                ArcLuna<TaxiPath>::push(L,tp,true);
356}
357void LuaEngine::PUSH_SPELL(Spell * sp, lua_State * L) 
358{
359        if(L == NULL)
360                ArcLuna<Spell>::push(lu,sp);
361        else
362                ArcLuna<Spell>::push(L,sp);
363}
364void LuaEngine::PUSH_SQLFIELD(Field *field, lua_State *L)
365{
366        if(L == NULL)
367                ArcLuna<Field>::push(lu,field);
368        else
369                ArcLuna<Field>::push(L,field);
370}
371void LuaEngine::PUSH_SQLRESULT(QueryResult * res, lua_State * L)
372{
373        if(L == NULL)
374                ArcLuna<QueryResult>::push(lu,res,true);
375        else
376                ArcLuna<QueryResult>::push(L,res,true);
377}
378
379/*******************************************************************************
380        END PUSH METHODS
381*******************************************************************************/
382
383void LuaEngine::HyperCallFunction(const char * FuncName, int ref) //hyper as in hypersniper :3
384{
385        //m_Lock.Acquire();
386        int top = lua_gettop(lu);
387        int args = 0;
388        string sFuncName = string(FuncName); //for convenience of string funcs
389        char * copy = strdup(FuncName);
390        char * token = strtok(copy, ".:"); //we should strtok on the copy
391        bool colon = false; //whether we should keep or remove the previous table
392        if (strpbrk(FuncName,".:") == NULL)
393                lua_getglobal(lu,FuncName);
394        else
395        {
396                lua_getglobal(lu, "_G"); //start out with the global table.
397                while (token != NULL)
398                {
399                        lua_getfield(lu, -1, token); //get the (hopefully) table/func
400                        if ((int)sFuncName.find(token)-1 > 0) //if it isn't the first token
401                        {
402                                if (sFuncName.at(sFuncName.find(token)-1) == '.') //if it was a .
403                                        colon = false;
404                                else if (sFuncName.at(sFuncName.find(token)-1) == ':')
405                                        colon = true;
406                        }
407                        else //if it IS the first token, we're OK to remove the "_G" from the stack
408                                colon = false;
409
410                        if (lua_isfunction(lu,-1) && !lua_iscfunction(lu,-1)) //if it's a Lua function
411                        {
412                                if (colon)
413                                {
414                                        lua_pushvalue(lu, -2); //make the table the first arg
415                                        lua_remove(lu, -3); //remove the thing we copied from (just to keep stack nice)
416                                        ++args;
417                                }
418                                else
419                                {
420                                        lua_remove(lu, -2);
421                                }
422                                break; //we don't need anything else
423                        }
424                        else if (lua_istable(lu,-1))
425                        {
426                                        token = strtok(NULL, ".:");
427                        }
428                }
429        }
430        lua_rawgeti(lu, LUA_REGISTRYINDEX, ref);
431        lua_State * M = lua_tothread(lu, -1); //repeats, args
432        int thread = lua_gettop(lu);
433        int repeats = luaL_checkinteger(M, 1); //repeats, args
434        int nargs = lua_gettop(M)-1;
435        if (nargs != 0) //if we HAVE args...
436        {
437                for (int i = 2; i <= nargs+1; i++)
438                {
439                        lua_pushvalue(M,i);
440                }
441                lua_xmove(M, lu, nargs);
442        }
443        if (--repeats == 0) //free stuff, then
444        {
445                free((void*)FuncName);
446                luaL_unref(lu, LUA_REGISTRYINDEX, ref);
447        }
448        else
449        {
450                lua_remove(M, 1); //args
451                lua_pushinteger(M, repeats); //args, repeats
452                lua_insert(M, 1); //repeats, args
453        }
454        lua_remove(lu, thread); //now we can remove the thread object
455        int r = lua_pcall(lu,nargs+args,0,0);
456        if (r)
457                report(lu);
458
459        free((void*)copy);
460        lua_settop(lu,top);
461        //m_Lock.Release();
462}
463
464static int RegisterServerHook(lua_State * L);
465static int RegisterUnitEvent(lua_State * L);
466static int RegisterQuestEvent(lua_State * L);
467static int RegisterGameObjectEvent(lua_State * L);
468static int RegisterUnitGossipEvent(lua_State * L);
469static int RegisterItemGossipEvent(lua_State * L);
470static int RegisterGOGossipEvent(lua_State * L);
471static int SuspendLuaThread(lua_State * L);
472static int RegisterTimedEvent(lua_State * L);
473static int RegisterDummySpell(lua_State * L);
474void RegisterGlobalFunctions(lua_State*);
475
476void LuaEngine::RegisterCoreFunctions()
477{
478        lua_register(lu,"RegisterUnitEvent",RegisterUnitEvent);
479        lua_register(lu,"RegisterGameObjectEvent",RegisterGameObjectEvent);
480        lua_register(lu,"RegisterQuestEvent",RegisterQuestEvent);
481        lua_register(lu,"RegisterUnitGossipEvent",RegisterUnitGossipEvent);
482        lua_register(lu,"RegisterItemGossipEvent",RegisterItemGossipEvent);
483        lua_register(lu,"RegisterGOGossipEvent",RegisterGOGossipEvent);
484        lua_register(lu,"RegisterServerHook",RegisterServerHook);
485        lua_register(lu,"SuspendThread",&SuspendLuaThread);
486        lua_register(lu,"RegisterTimedEvent",&RegisterTimedEvent);
487        lua_register(lu,"RegisterDummySpell",&RegisterDummySpell);
488
489        RegisterGlobalFunctions(lu);
490
491        ArcLuna<Unit>::Register(lu);
492        ArcLuna<Item>::Register(lu);
493        ArcLuna<GameObject>::Register(lu);
494        ArcLuna<WorldPacket>::Register(lu);
495        ArcLuna<TaxiPath>::Register(lu);
496        ArcLuna<Spell>::Register(lu);
497        ArcLuna<Field>::Register(lu);
498        ArcLuna<QueryResult>::Register(lu);
499
500        GUID_MGR::Register(lu);
501
502        //set the suspendluathread a coroutine function
503        lua_getglobal(lu,"coroutine");
504        if(lua_istable(lu,-1) )
505        {
506                lua_pushcfunction(lu,SuspendLuaThread);
507                lua_setfield(lu,-2,"wait");
508                lua_pushcfunction(lu,SuspendLuaThread);
509                lua_setfield(lu,-2,"WAIT");
510        }
511        lua_pop(lu,1);
512}
513
514static int RegisterServerHook(lua_State * L)
515{
516        uint32 ev = luaL_checkint(L, 1);
517        const char * str = luaL_checkstring(L, 2);
518
519        if(!ev || !str)
520                return 0;
521        //Lets validate the string here so the scripter doesn't have to wait until the script event fires just to be slapped with an error
522        //such as a typo or non function passed in.
523        int top = lua_gettop(L);
524        char * copy = strdup(str);
525        char * token = strtok(copy,".:");
526        if(strpbrk(str,".:") == NULL)
527        {
528                lua_getglobal(L,str);
529                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
530                        sLuaMgr.RegisterEvent(REGTYPE_SERVHOOK,0,ev,str);
531                else
532                {
533                        Log.Color(TRED);
534                        luaL_error(L,"LuaEngineMgr : RegisterServerHook failed! %s is not a valid Lua function.\n",str);
535                        Log.Color(TWHITE);
536                }
537        }
538        else
539        {
540                lua_getglobal(L,"_G");
541                while(token != NULL)
542                {
543                        lua_getfield(L,-1,token);
544                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
545                        {
546                                sLuaMgr.RegisterEvent(REGTYPE_SERVHOOK,0,ev,str);
547                                break;
548                        }
549                        else if(lua_istable(L,-1) )
550                        {
551                                token = strtok(NULL,".:");
552                                continue;
553                        }
554                        else
555                        {
556                                Log.Color(TRED);
557                                luaL_error(L,"LuaEngineMgr : RegisterServerHook failed! %s is not a valid Lua function. \n",token);
558                                Log.Color(TWHITE);
559                        }
560                }
561        }
562        free((void*)copy);
563        lua_settop(L,top);
564        return 0;
565}
566
567static int RegisterDummySpell(lua_State * L)
568{
569        uint32 entry = luaL_checkint(L, 1);
570        const char * str = luaL_checkstring(L, 2);
571       
572        if(!entry || !str)
573                return 0;
574
575        if (m_luaDummySpells.find(entry) != m_luaDummySpells.end())
576        {
577                Log.Color(TRED);
578                luaL_error(L,"LuaEngineMgr : RegisterDummySpell failed! Spell %d already has a registered Lua function!",entry);
579                Log.Color(TWHITE);
580        }
581        int top = lua_gettop(L);
582        char * copy = strdup(str);
583        char * token = strtok(copy, ".:");
584        if (strpbrk(str,".:") == NULL)
585        {
586                lua_getglobal(L,str);
587                if (lua_isfunction(L,-1) && !lua_iscfunction(L,-1))
588                        sLuaMgr.RegisterEvent(REGTYPE_DUMMYSPELL,entry,1,str);
589                else
590                {
591                        Log.Color(TRED);
592                        luaL_error(L,"LuaEngineMgr : RegisterDummySpell failed! %s is not a valid Lua function. \n",str);
593                        Log.Color(TWHITE);
594                }
595        }
596        else
597        {
598                lua_getglobal(L,"_G");
599                while (token != NULL)
600                {
601                        lua_getfield(L,-1,token);
602                        if (lua_isfunction(L,-1) && !lua_iscfunction(L,-1))
603                        {
604                                sLuaMgr.RegisterEvent(REGTYPE_DUMMYSPELL,entry,1,str);
605                                break;
606                        }
607                        else if (lua_istable(L,-1) )
608                        {
609                                token = strtok(NULL,".:");
610                                continue;
611                        }
612                        else
613                        {
614                                Log.Color(TRED);
615                                luaL_error(L,"LuaEngineMgr : RegisterDummySpell failed! %s is not a valid Lua function. \n",token);
616                                Log.Color(TWHITE);
617                                break;
618                        }
619                }
620        }
621        free((void*)copy);
622        lua_settop(L,top);
623        return 0;
624}
625
626static int RegisterUnitEvent(lua_State * L)
627{
628        int entry = luaL_checkint(L, 1);
629        int ev = luaL_checkint(L, 2);
630        const char * str = luaL_checkstring(L, 3);
631
632        if(!entry || !ev || !str)
633                return 0;
634        int top = lua_gettop(L);
635        char * copy = strdup(str);
636        char * token = strtok(copy, ".:");
637        if( strpbrk(str,".:") == NULL)
638        {
639                lua_getglobal(L,str);
640                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
641                        sLuaMgr.RegisterEvent(REGTYPE_UNIT,entry,ev,str);
642                else
643                {
644                        Log.Color(TRED);
645                        luaL_error(L,"LuaEngineMgr : RegisterUnitEvent failed! %s is not a valid Lua function. \n",str);
646                        Log.Color(TWHITE);
647                }
648        }
649        else
650        {
651                lua_getglobal(L,"_G");
652                while(token != NULL)
653                {
654                        lua_getfield(L,-1,token);
655                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
656                        {
657                                sLuaMgr.RegisterEvent(REGTYPE_UNIT,entry,ev,str);
658                                break;
659                        }
660                        else if(lua_istable(L,-1) )
661                        {
662                                token = strtok(NULL,".:");
663                                continue;
664                        }
665                        else
666                        {
667                                Log.Color(TRED);
668                                luaL_error(L,"LuaEngineMgr : RegisterUnitEvent failed! %s is not a valid Lua function. \n",token);
669                                Log.Color(TWHITE);
670                                break;
671                        }
672                }
673        }
674        free((void*)copy);
675        lua_settop(L,top);
676        return 0;
677}
678
679static int RegisterQuestEvent(lua_State * L)
680{
681        int entry = luaL_checkint(L, 1);
682        int ev = luaL_checkint(L, 2);
683        const char * str = luaL_checkstring(L, 3);
684
685        if(!entry || !ev || !str)
686                return 0;
687        int top = lua_gettop(L);
688        char * copy = strdup(str);
689        char * token = strtok(copy, ".:");
690        if(strpbrk(str,".:") == NULL)
691        {
692                lua_getglobal(L,str);
693                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
694                        sLuaMgr.RegisterEvent(REGTYPE_QUEST,entry,ev,str);
695                else
696                {
697                        Log.Color(TRED);
698                        luaL_error(L,"LuaEngineMgr : RegisterQuestEvent failed! %s is not a valid Lua function. \n",copy);
699                        Log.Color(TWHITE);
700                }
701        }
702        else
703        {
704                lua_getglobal(L,"_G");
705                while(token != NULL)
706                {
707                        lua_getfield(L,-1,token);
708                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
709                        {
710                                sLuaMgr.RegisterEvent(REGTYPE_QUEST,entry,ev,str);
711                                break;
712                        }
713                        else if(lua_istable(L,-1) )
714                        {
715                                token = strtok(NULL,".:");
716                                continue;
717                        }
718                        else
719                        {
720                                Log.Color(TRED);
721                                luaL_error(L,"LuaEngineMgr : RegisterQuestEvent failed! %s is not a valid Lua function. \n",token);
722                                Log.Color(TWHITE);
723                                break;
724                        }
725                }
726        }
727        free((void*)copy);
728        lua_settop(L,top);
729        return 0;
730}
731
732static int RegisterGameObjectEvent(lua_State * L)
733{
734        int entry = luaL_checkint(L, 1);
735        int ev = luaL_checkint(L, 2);
736        const char * str = luaL_checkstring(L, 3);
737
738        if(!entry || !ev || !str)
739                return 0;
740
741        int top = lua_gettop(L);
742        char * copy = strdup(str);
743        char * token = strtok(copy,".:");
744        if( strpbrk(str,".:") == NULL)
745        {
746                lua_getglobal(L,str);
747                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
748                        sLuaMgr.RegisterEvent(REGTYPE_GO,entry,ev,str);
749                else
750                {
751                        Log.Color(TRED);
752                        luaL_error(L,"LuaEngineMgr : RegisterGameObjectEvent failed! %s is not a valid Lua function. \n",copy);
753                        Log.Color(TWHITE);
754                }
755        }
756        else
757        {
758                lua_getglobal(L,"_G");
759                while(token != NULL)
760                {
761                        lua_getfield(L,-1,token);
762                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
763                        {
764                                sLuaMgr.RegisterEvent(REGTYPE_GO,entry,ev,str);
765                                break;
766                        }
767                        else if(lua_istable(L,-1) )
768                        {
769                                token = strtok(NULL,".:");
770                                continue;
771                        }
772                        else
773                        {
774                                Log.Color(TRED);
775                                luaL_error(L,"LuaEngineMgr : RegisterGameObjectEvent failed! %s is not a valid Lua function. \n",token);
776                                Log.Color(TWHITE);
777                                break;
778                        }
779                }
780        }
781        free((void*)copy);
782        lua_settop(L,top);
783        return 0;
784}
785
786static int RegisterUnitGossipEvent(lua_State * L)
787{
788        int entry = luaL_checkint(L, 1);
789        int ev = luaL_checkint(L, 2);
790        const char * str = luaL_checkstring(L, 3);
791        if(!entry || !ev || !str)
792                return 0;
793        int top = lua_gettop(L);
794        char * copy = strdup(str);
795        char * token = strtok(copy,".:");
796        if( strpbrk(str,".:") == NULL)
797        {
798                lua_getglobal(L,str);
799                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
800                         sLuaMgr.RegisterEvent(REGTYPE_UNIT_GOSSIP,entry, ev, str);
801                else
802                {
803                        Log.Color(TRED);
804                        luaL_error(L,"LuaEngineMgr : RegisterUnitGossipEvent failed! %s is not a valid Lua function. \n",copy);
805                        Log.Color(TWHITE);
806                }
807        }
808        else
809        {
810                lua_getglobal(L,"_G");
811                while(token != NULL)
812                {
813                        lua_getfield(L,-1,token);
814                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
815                        {
816                                sLuaMgr.RegisterEvent(REGTYPE_UNIT_GOSSIP,entry, ev, str);
817                                break;
818                        }
819                        else if(lua_istable(L,-1) )
820                        {
821                                token = strtok(NULL,".:");
822                                continue;
823                        }
824                        else
825                        {
826                                Log.Color(TRED);
827                                luaL_error(L,"LuaEngineMgr : RegisterUnitGossipEvent failed! %s is not a valid Lua function. \n",token);
828                                Log.Color(TWHITE);
829                                break;
830                        }
831                }
832        }
833        free((void*)copy);
834        lua_settop(L,top);
835        return 0;
836}
837static int RegisterItemGossipEvent(lua_State * L)
838 {
839        int entry = luaL_checkint(L, 1);
840        int ev = luaL_checkint(L, 2);
841        const char * str = luaL_checkstring(L, 3);
842
843        if(!entry || !ev || !str)
844                return 0;
845
846        int top = lua_gettop(L);
847        char * copy = strdup(str);
848        char * token  = strtok(copy,".:");
849
850        if( strpbrk(str,".:") == NULL)
851        {
852                lua_getglobal(L,str);
853                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
854                        sLuaMgr.RegisterEvent(REGTYPE_ITEM_GOSSIP,entry, ev, str);
855                else
856                {
857                        Log.Color(TRED);
858                        luaL_error(L,"LuaEngineMgr : RegisterItemGossipEvent failed! %s is not a valid Lua function. \n",copy);
859                        Log.Color(TWHITE);
860                }
861        }
862        else
863        {
864                lua_getglobal(L,"_G");
865                while(token != NULL)
866                {
867                        lua_getfield(L,-1,token);
868                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
869                        {
870                                sLuaMgr.RegisterEvent(REGTYPE_ITEM_GOSSIP,entry, ev, str);
871                                break;
872                        }
873                        else if(lua_istable(L,-1) ) {
874                                token = strtok(NULL,".:");
875                                continue;
876                        }
877                        else {
878                                Log.Color(TRED);
879                                luaL_error(L,"LuaEngineMgr : RegisterItemGossipEvent failed! %s is not a valid Lua function. \n",token);
880                                Log.Color(TWHITE);
881                        }
882                }
883        }
884        free((void*)copy);
885        lua_settop(L,top);
886        return 0;
887 }
888static int RegisterGOGossipEvent(lua_State * L)
889{
890        int entry = luaL_checkint(L, 1);
891        int ev = luaL_checkint(L, 2);
892        const char * str = luaL_checkstring(L, 3);
893
894        if(!entry || !ev || !str)
895                return 0;
896        int top = lua_gettop(L);
897        char * copy = strdup(str);
898        char * token  = strtok(copy,".:");
899        if( strpbrk(str,".:") == NULL)
900        {
901                lua_getglobal(L,str);
902                if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
903                        sLuaMgr.RegisterEvent(REGTYPE_GO_GOSSIP,entry, ev, str);
904                else
905                {
906                        Log.Color(TRED);
907                        luaL_error(L,"LuaEngineMgr : RegisterGOGossipEvent failed! %s is not a valid Lua function. \n",copy);
908                        Log.Color(TWHITE);
909                }
910        }
911        else
912        {
913                lua_getglobal(L,"_G");
914                while(token != NULL)
915                {
916                        lua_getfield(L,-1,token);
917                        if(lua_isfunction(L,-1) && !lua_iscfunction(L,-1) )
918                        {
919                                sLuaMgr.RegisterEvent(REGTYPE_GO_GOSSIP,entry, ev, str);
920                                break;
921                        }
922                        else if(lua_istable(L,-1)) {
923                                token = strtok(NULL,".:");
924                                continue;
925                        }
926                        else {
927                                Log.Color(TRED);
928                                luaL_error(L,"LuaEngineMgr : RegisterGOGossipEvent failed! %s is not a valid Lua function. \n",token);
929                                Log.Color(TWHITE);
930                        }
931                }
932        }
933        free((void*)copy);
934        lua_settop(L,top);
935        return 0;
936}
937
938static int SuspendLuaThread(lua_State * L) {
939        lua_State * thread = (lua_isthread(L,1)) ? lua_tothread(L,1) : NULL;
940        if(thread == NULL) {
941                return luaL_error(L,"LuaEngineMgr","SuspendLuaThread expected Lua coroutine, got NULL. \n");
942        }
943        int waitime = luaL_checkinteger(L,2);
944        if(waitime <= 0) {
945                return luaL_error(L,"LuaEngineMgr","SuspendLuaThread expected timer > 0 instead got (%d) \n",waitime);
946        }
947        lua_pushvalue(L,1);
948        int ref = luaL_ref(L,LUA_REGISTRYINDEX);
949        if(ref == LUA_REFNIL || ref == LUA_NOREF)
950                return luaL_error(L,"Error in SuspendLuaThread! Failed to create a valid reference.");
951        TimedEvent * evt = TimedEvent::Allocate(thread,new CallbackP1<LuaEngine,int>(&g_luaMgr,&LuaEngine::ResumeLuaThread,ref),0,waitime,1);
952        sWorld.event_AddEvent(evt);
953        lua_remove(L,1); // remove thread object
954        lua_remove(L,1); // remove timer.
955        //All that remains now are the extra arguments passed to this function.
956        lua_xmove(L,thread,lua_gettop(L));
957        g_luaMgr.getThreadRefs().insert(ref);
958        return lua_yield(thread,lua_gettop(L));
959}
960
961static int RegisterTimedEvent(lua_State * L) //in this case, L == lu
962{
963        const char * funcName = strdup(luaL_checkstring(L,1));
964        int delay = luaL_checkint(L,2);
965        int repeats = luaL_checkint(L,3);
966        if (!delay || !repeats || !funcName)
967                return 0;
968        lua_remove(L, 1); 
969        lua_remove(L, 1);//repeats, args
970        lua_State * thread = lua_newthread(L); //repeats, args, thread
971        lua_insert(L,1); //thread, repeats, args
972        lua_xmove(L,thread,lua_gettop(L)-1); //thread
973        int ref = luaL_ref(L, LUA_REGISTRYINDEX); //empty
974        TimedEvent *te = TimedEvent::Allocate(&sLuaMgr, new CallbackP2<LuaEngine, const char*, int>(&sLuaMgr, &LuaEngine::HyperCallFunction, funcName, ref), 0, delay, repeats);
975        sWorld.event_AddEvent(te);
976        return 0;
977}
978
979
980
981//all of these run similarly, they execute OnServerHook for all the functions in their respective event's list.
982bool LuaHookOnNewCharacter(uint32 Race, uint32 Class, WorldSession * Session, const char * Name)
983{
984        GET_LOCK
985        bool result = true;
986        for(vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_NEW_CHARACTER].begin(); itr != EventAsToFuncName[SERVER_HOOK_NEW_CHARACTER].end(); ++itr) {
987                uint8 args = 0;
988                if(sLuaMgr.BeginCall(itr->c_str()) )
989                        ++args;
990                sLuaMgr.PUSH_INT(SERVER_HOOK_NEW_CHARACTER);
991                sLuaMgr.PUSH_STRING(Name);
992                sLuaMgr.PUSH_UINT(Race);
993                sLuaMgr.PUSH_UINT(Class);
994                args+=4;
995                if(sLuaMgr.ExecuteCall(args,1) )
996                {
997                        lua_State * L = sLuaMgr.getluState();
998                        if(!lua_isnoneornil(L,1) && !lua_toboolean(L,1) )
999                                result = false;
1000                        sLuaMgr.EndCall(1);
1001                }
1002        }
1003        RELEASE_LOCK
1004        return result;
1005}
1006
1007void LuaHookOnKillPlayer(Player * pPlayer, Player * pVictim)
1008{
1009        GET_LOCK
1010        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_KILL_PLAYER].begin(); itr != EventAsToFuncName[SERVER_HOOK_KILL_PLAYER].end(); ++itr)
1011        {
1012                uint8 args = 0;
1013                if( sLuaMgr.BeginCall(itr->c_str()))
1014                        ++args;
1015                sLuaMgr.PUSH_INT(SERVER_HOOK_KILL_PLAYER);
1016                sLuaMgr.PUSH_UNIT(pPlayer);
1017                sLuaMgr.PUSH_UNIT(pVictim);
1018                args+=3;
1019                sLuaMgr.ExecuteCall(args);
1020        }
1021        RELEASE_LOCK
1022}
1023
1024void LuaHookOnFirstEnterWorld(Player * pPlayer)
1025{
1026        GET_LOCK
1027        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_FIRST_ENTER_WORLD].begin(); itr != EventAsToFuncName[SERVER_HOOK_FIRST_ENTER_WORLD].end(); ++itr)
1028        {
1029                uint8 args = 0;
1030                if( sLuaMgr.BeginCall(itr->c_str()))
1031                        ++args;
1032                sLuaMgr.PUSH_INT(SERVER_HOOK_FIRST_ENTER_WORLD);
1033                sLuaMgr.PUSH_UNIT(pPlayer);
1034                args+=2;
1035                sLuaMgr.ExecuteCall(args);
1036        }
1037        RELEASE_LOCK
1038}
1039
1040void LuaHookOnEnterWorld(Player * pPlayer)
1041{
1042        GET_LOCK
1043        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_ENTER_WORLD].begin(); itr != EventAsToFuncName[SERVER_HOOK_ENTER_WORLD].end(); ++itr)
1044        {
1045                uint8 args = 0;
1046                if( sLuaMgr.BeginCall(itr->c_str()))
1047                        ++args;
1048                sLuaMgr.PUSH_INT(SERVER_HOOK_ENTER_WORLD);
1049                sLuaMgr.PUSH_UNIT(pPlayer);
1050                args+=2;
1051                sLuaMgr.ExecuteCall(args);
1052        }
1053        RELEASE_LOCK
1054}
1055
1056void LuaHookOnGuildJoin(Player * pPlayer, Guild * pGuild)
1057{
1058        GET_LOCK
1059        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_GUILD_JOIN].begin(); itr != EventAsToFuncName[SERVER_HOOK_GUILD_JOIN].end(); ++itr)
1060        {
1061                uint8 args = 0;
1062                if( sLuaMgr.BeginCall(itr->c_str()))
1063                        ++args;
1064                sLuaMgr.PUSH_INT(SERVER_HOOK_GUILD_JOIN);
1065                sLuaMgr.PUSH_UNIT(pPlayer);
1066                sLuaMgr.PUSH_STRING(pGuild->GetGuildName());
1067                args+=3;
1068                sLuaMgr.ExecuteCall(args);
1069        }
1070        RELEASE_LOCK
1071}
1072
1073void LuaHookOnDeath(Player * pPlayer)
1074{
1075        GET_LOCK
1076        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_DEATH].begin(); itr != EventAsToFuncName[SERVER_HOOK_DEATH].end(); ++itr)
1077        {
1078                uint8 args = 0;
1079                if( sLuaMgr.BeginCall(itr->c_str()))
1080                        ++args;
1081                sLuaMgr.PUSH_INT(SERVER_HOOK_DEATH);
1082                sLuaMgr.PUSH_UNIT(pPlayer);
1083                args+=2;
1084                sLuaMgr.ExecuteCall(args);
1085        }
1086        RELEASE_LOCK
1087}
1088
1089bool LuaHookOnRepop(Player * pPlayer)
1090{
1091        GET_LOCK
1092        bool result = true;
1093        for(vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_REPOP].begin(); itr != EventAsToFuncName[SERVER_HOOK_REPOP].end(); ++itr) {
1094                uint8 args = 0;
1095                if( sLuaMgr.BeginCall(itr->c_str()))
1096                        ++args;
1097                sLuaMgr.PUSH_INT(SERVER_HOOK_REPOP);
1098                sLuaMgr.PUSH_UNIT(pPlayer);
1099                args+=2;
1100                if (sLuaMgr.ExecuteCall(args,1)) {
1101                        lua_State * L = sLuaMgr.getluState();
1102                        if(!lua_isnoneornil(L,1) && !lua_toboolean(L,1) )
1103                                result = false;
1104                        sLuaMgr.EndCall(1);
1105                }
1106        }
1107        RELEASE_LOCK
1108        return result;
1109}
1110
1111void LuaHookOnEmote(Player * pPlayer, uint32 Emote, Unit * pUnit)
1112{
1113        GET_LOCK
1114        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_EMOTE].begin(); itr != EventAsToFuncName[SERVER_HOOK_EMOTE].end(); ++itr)
1115        {
1116                uint8 args = 0;
1117                if( sLuaMgr.BeginCall(itr->c_str()))
1118                        ++args;
1119                sLuaMgr.PUSH_INT(SERVER_HOOK_EMOTE);
1120                sLuaMgr.PUSH_UNIT(pPlayer);
1121                sLuaMgr.PUSH_UNIT(pUnit);
1122                sLuaMgr.PUSH_UINT(Emote);
1123                args+=4;
1124                sLuaMgr.ExecuteCall(args);
1125        }
1126        RELEASE_LOCK
1127}
1128
1129void LuaHookOnEnterCombat(Player * pPlayer, Unit * pTarget)
1130{
1131        GET_LOCK
1132        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_ENTER_COMBAT].begin(); itr != EventAsToFuncName[SERVER_HOOK_ENTER_COMBAT].end(); ++itr)
1133        {
1134                uint8 args = 0;
1135                if( sLuaMgr.BeginCall(itr->c_str()))
1136                        ++args;
1137                sLuaMgr.PUSH_INT(SERVER_HOOK_ENTER_COMBAT);
1138                sLuaMgr.PUSH_UNIT(pPlayer);
1139                sLuaMgr.PUSH_UNIT(pTarget);
1140                args+=3;
1141                sLuaMgr.ExecuteCall(args);
1142        }
1143        RELEASE_LOCK
1144}
1145
1146bool LuaHookOnCastSpell(Player * pPlayer, SpellEntry* pSpell)
1147{
1148        GET_LOCK
1149        bool result = true;
1150        for(vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_CAST_SPELL].begin(); itr != EventAsToFuncName[SERVER_HOOK_CAST_SPELL].end(); ++itr)
1151        {
1152                uint8 args = 0;
1153                if( sLuaMgr.BeginCall(itr->c_str()))
1154                        ++args;
1155                sLuaMgr.PUSH_INT(SERVER_HOOK_CAST_SPELL);
1156                sLuaMgr.PUSH_UNIT(pPlayer);
1157                sLuaMgr.PUSH_UINT(pSpell->Id);
1158                args+=3;
1159                if( sLuaMgr.ExecuteCall(args,1) ) {
1160                        lua_State * L = sLuaMgr.getluState();
1161                        if(!lua_isnoneornil(L,1) && !lua_toboolean(L,1) )
1162                                result = false;
1163                        sLuaMgr.EndCall(1);
1164                }
1165        }
1166        RELEASE_LOCK
1167        return result;
1168}
1169
1170void LuaHookOnTick()
1171{
1172        GET_LOCK
1173        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_TICK].begin(); itr != EventAsToFuncName[SERVER_HOOK_TICK].end(); ++itr)
1174        {
1175                uint8 args = 0;
1176                if( sLuaMgr.BeginCall(itr->c_str()))
1177                        ++args;
1178                sLuaMgr.ExecuteCall(args);
1179        }
1180        RELEASE_LOCK
1181}
1182
1183bool LuaHookOnLogoutRequest(Player * pPlayer)
1184{
1185        GET_LOCK
1186        bool result = true;
1187        for(vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_LOGOUT_REQUEST].begin(); itr != EventAsToFuncName[SERVER_HOOK_LOGOUT_REQUEST].end(); itr++)
1188        {
1189                uint8 args = 0;
1190                if( sLuaMgr.BeginCall(itr->c_str()))
1191                        ++args;
1192                sLuaMgr.PUSH_INT(SERVER_HOOK_LOGOUT_REQUEST);
1193                sLuaMgr.PUSH_UNIT(pPlayer);
1194                args+=2;
1195                if(sLuaMgr.ExecuteCall(args,1) )
1196                {
1197                        lua_State * L = sLuaMgr.getluState();
1198                        if(!lua_isnoneornil(L,1) && !lua_toboolean(L,1) )
1199                                result = false;
1200                        sLuaMgr.EndCall(1);
1201                }
1202        }
1203        RELEASE_LOCK
1204        return result;
1205}
1206
1207void LuaHookOnLogout(Player * pPlayer)
1208{
1209        GET_LOCK
1210        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_LOGOUT].begin(); itr != EventAsToFuncName[SERVER_HOOK_LOGOUT].end(); ++itr)
1211        {
1212                uint8 args = 0;
1213                if( sLuaMgr.BeginCall(itr->c_str()))
1214                        ++args;
1215                sLuaMgr.PUSH_INT(SERVER_HOOK_LOGOUT);
1216                sLuaMgr.PUSH_UNIT(pPlayer);
1217                args+=2;
1218                sLuaMgr.ExecuteCall(args);
1219        }
1220        RELEASE_LOCK
1221}
1222
1223void LuaHookOnQuestAccept(Player * pPlayer, Quest * pQuest, Object * pQuestGiver)
1224{
1225        GET_LOCK
1226        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_QUEST_ACCEPT].begin(); itr != EventAsToFuncName[SERVER_HOOK_QUEST_ACCEPT].end(); ++itr)
1227        {
1228                uint8 args = 0;
1229                if( sLuaMgr.BeginCall(itr->c_str()))
1230                        ++args;
1231                sLuaMgr.PUSH_INT(SERVER_HOOK_QUEST_ACCEPT);
1232                sLuaMgr.PUSH_UNIT(pPlayer);
1233                sLuaMgr.PUSH_UINT(pQuest->id);
1234                if(pQuestGiver->IsUnit() )
1235                        sLuaMgr.PUSH_UNIT(pQuestGiver);
1236                else if(pQuestGiver->IsGameObject() )
1237                        sLuaMgr.PUSH_GO(pQuestGiver);
1238                else if(pQuestGiver->GetTypeId() == TYPEID_ITEM)
1239                        sLuaMgr.PUSH_ITEM(pQuestGiver);
1240                else
1241                        sLuaMgr.PUSH_NIL();
1242                args+=4;
1243                sLuaMgr.ExecuteCall(args);
1244        }
1245        RELEASE_LOCK
1246}
1247
1248void LuaHookOnZone(Player * pPlayer, uint32 Zone)
1249{
1250        GET_LOCK
1251        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_ZONE].begin(); itr != EventAsToFuncName[SERVER_HOOK_ZONE].end(); ++itr)
1252        {
1253                uint8 args = 0;
1254                if( sLuaMgr.BeginCall(itr->c_str()))
1255                        ++args;
1256                sLuaMgr.PUSH_INT(SERVER_HOOK_ZONE);
1257                sLuaMgr.PUSH_UNIT(pPlayer);
1258                sLuaMgr.PUSH_UINT(Zone);
1259                args+=3;
1260                sLuaMgr.ExecuteCall(args);
1261        }
1262        RELEASE_LOCK
1263}
1264
1265bool LuaHookOnChat(Player * pPlayer, uint32 Type, uint32 Lang, const char * Message, const char * Misc)
1266{
1267        GET_LOCK
1268        bool result = true;
1269        for(vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_CHAT].begin(); itr != EventAsToFuncName[SERVER_HOOK_CHAT].end(); ++itr)
1270        {
1271                uint8 args = 0;
1272                if( sLuaMgr.BeginCall(itr->c_str()))
1273                        ++args;
1274                sLuaMgr.PUSH_INT(SERVER_HOOK_CHAT);
1275                sLuaMgr.PUSH_UNIT(pPlayer);
1276                sLuaMgr.PUSH_STRING(Message);
1277                sLuaMgr.PUSH_UINT(Type);
1278                sLuaMgr.PUSH_UINT(Lang);
1279                sLuaMgr.PUSH_STRING(Misc);
1280                args+=6;
1281                if( sLuaMgr.ExecuteCall(args,1)) {
1282                        lua_State * L = sLuaMgr.getluState();
1283                        if(!lua_isnoneornil(L,1) && !lua_toboolean(L,1) )
1284                                result = false;
1285                        sLuaMgr.EndCall(1);
1286                }
1287        }
1288        RELEASE_LOCK
1289        return result;
1290}
1291
1292void LuaHookOnLoot(Player * pPlayer, Unit * pTarget, uint32 Money, uint32 ItemId)
1293{
1294        GET_LOCK
1295        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_LOOT].begin(); itr != EventAsToFuncName[SERVER_HOOK_LOOT].end(); ++itr)
1296        {
1297                uint8 args = 0;
1298                if( sLuaMgr.BeginCall(itr->c_str()))
1299                        ++args;
1300                sLuaMgr.PUSH_INT(SERVER_HOOK_LOOT);
1301                sLuaMgr.PUSH_UNIT(pPlayer);
1302                sLuaMgr.PUSH_UNIT(pTarget);
1303                sLuaMgr.PUSH_UINT(Money);
1304                sLuaMgr.PUSH_UINT(ItemId);
1305                args+=5;
1306                sLuaMgr.ExecuteCall(args);
1307        }
1308        RELEASE_LOCK
1309}
1310
1311void LuaHookOnGuildCreate(Player * pLeader, Guild * pGuild)
1312{
1313        GET_LOCK
1314        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_GUILD_CREATE].begin(); itr != EventAsToFuncName[SERVER_HOOK_GUILD_CREATE].end(); ++itr)
1315        {
1316                uint8 args = 0;
1317                if( sLuaMgr.BeginCall(itr->c_str()))
1318                        ++args;
1319                sLuaMgr.PUSH_INT(SERVER_HOOK_GUILD_CREATE);
1320                sLuaMgr.PUSH_UNIT(pLeader);
1321                sLuaMgr.PUSH_STRING(pGuild->GetGuildName());
1322                args+=3;
1323                sLuaMgr.ExecuteCall(args);
1324        }
1325        RELEASE_LOCK
1326}
1327
1328void LuaHookOnEnterWorld2(Player * pPlayer)
1329{
1330        GET_LOCK
1331        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_ENTER_WORLD_2].begin(); itr != EventAsToFuncName[SERVER_HOOK_ENTER_WORLD_2].end(); ++itr)
1332        {
1333                uint8 args = 0;
1334                if( sLuaMgr.BeginCall(itr->c_str()))
1335                        ++args;
1336                sLuaMgr.PUSH_INT(SERVER_HOOK_ENTER_WORLD_2);
1337                sLuaMgr.PUSH_UNIT(pPlayer);
1338                args+=2;
1339                sLuaMgr.ExecuteCall(args);
1340        }
1341        RELEASE_LOCK
1342}
1343
1344void LuaHookOnCharacterCreate(Player * pPlayer)
1345{
1346        GET_LOCK
1347        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_CHARACTER_CREATE].begin(); itr != EventAsToFuncName[SERVER_HOOK_CHARACTER_CREATE].end(); ++itr)
1348        {
1349                uint8 args = 0;
1350                if( sLuaMgr.BeginCall(itr->c_str()))
1351                        ++args;
1352                sLuaMgr.PUSH_INT(SERVER_HOOK_CHARACTER_CREATE);
1353                sLuaMgr.PUSH_UNIT(pPlayer);
1354                args+=2;
1355                sLuaMgr.ExecuteCall(args);
1356        }
1357        RELEASE_LOCK
1358}
1359
1360void LuaHookOnQuestCancelled(Player * pPlayer, Quest * pQuest)
1361{
1362        GET_LOCK
1363        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_QUEST_CANCELLED].begin(); itr != EventAsToFuncName[SERVER_HOOK_QUEST_CANCELLED].end(); ++itr)
1364        {
1365                uint8 args = 0;
1366                if( sLuaMgr.BeginCall(itr->c_str()))
1367                        ++args;
1368                sLuaMgr.PUSH_INT(SERVER_HOOK_QUEST_CANCELLED);
1369                sLuaMgr.PUSH_UNIT(pPlayer);
1370                sLuaMgr.PUSH_UINT(pQuest->id);
1371                args+=3;
1372                sLuaMgr.ExecuteCall(args);
1373        }
1374        RELEASE_LOCK
1375}
1376
1377void LuaHookOnQuestFinished(Player * pPlayer, Quest * pQuest, Object * pQuestGiver)
1378{
1379        GET_LOCK
1380        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_QUEST_FINISHED].begin(); itr != EventAsToFuncName[SERVER_HOOK_QUEST_FINISHED].end(); ++itr)
1381        {
1382                uint8 args = 0;
1383                if( sLuaMgr.BeginCall(itr->c_str()))
1384                        ++args;
1385                sLuaMgr.PUSH_INT(SERVER_HOOK_QUEST_FINISHED);
1386                sLuaMgr.PUSH_UNIT(pPlayer);
1387                sLuaMgr.PUSH_UINT(pQuest->id);
1388                if(pQuestGiver->IsUnit() )
1389                        sLuaMgr.PUSH_UNIT(pQuestGiver);
1390                else if(pQuestGiver->IsGameObject() )
1391                        sLuaMgr.PUSH_GO(pQuestGiver);
1392                else if(pQuestGiver->GetTypeId() == TYPEID_ITEM)
1393                        sLuaMgr.PUSH_ITEM(pQuestGiver);
1394                else
1395                        sLuaMgr.PUSH_NIL();
1396                args+=4;
1397                sLuaMgr.ExecuteCall(args);
1398        }
1399        RELEASE_LOCK
1400}
1401
1402void LuaHookOnHonorableKill(Player * pPlayer, Player * pKilled)
1403{
1404        GET_LOCK
1405        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_HONORABLE_KILL].begin(); itr != EventAsToFuncName[SERVER_HOOK_HONORABLE_KILL].end(); ++itr)
1406        {
1407                uint8 args = 0;
1408                if( sLuaMgr.BeginCall(itr->c_str()))
1409                        ++args;
1410                sLuaMgr.PUSH_INT(SERVER_HOOK_HONORABLE_KILL);
1411                sLuaMgr.PUSH_UNIT(pPlayer);
1412                sLuaMgr.PUSH_UNIT(pKilled);
1413                args+=3;
1414                sLuaMgr.ExecuteCall(args);
1415        }
1416        RELEASE_LOCK
1417}
1418
1419void LuaHookOnArenaFinish(Player * pPlayer, ArenaTeam* pTeam, bool victory, bool rated)
1420{
1421        GET_LOCK
1422        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_ARENA_FINISH].begin(); itr != EventAsToFuncName[SERVER_HOOK_ARENA_FINISH].end(); ++itr)
1423        {
1424                uint8 args = 0;
1425                if( sLuaMgr.BeginCall(itr->c_str()))
1426                        ++args;
1427                sLuaMgr.PUSH_INT(SERVER_HOOK_ARENA_FINISH);
1428                sLuaMgr.PUSH_UNIT(pPlayer);
1429                sLuaMgr.PUSH_STRING(pTeam->m_name.c_str());
1430                sLuaMgr.PUSH_BOOL(victory);
1431                sLuaMgr.PUSH_BOOL(rated);
1432                args+=5;
1433                sLuaMgr.ExecuteCall(args);
1434        }
1435        RELEASE_LOCK
1436}
1437
1438void LuaHookOnObjectLoot(Player * pPlayer, Object * pTarget, uint32 Money, uint32 ItemId)
1439{
1440        GET_LOCK
1441        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_OBJECTLOOT].begin(); itr != EventAsToFuncName[SERVER_HOOK_OBJECTLOOT].end(); ++itr)
1442        {
1443                uint8 args = 0;
1444                if( sLuaMgr.BeginCall(itr->c_str()))
1445                        ++args;
1446                sLuaMgr.PUSH_INT(SERVER_HOOK_OBJECTLOOT);
1447                sLuaMgr.PUSH_UNIT(pPlayer);
1448                sLuaMgr.PUSH_UNIT(pTarget);
1449                sLuaMgr.PUSH_UINT(Money);
1450                sLuaMgr.PUSH_UINT(ItemId);
1451                args+=5;
1452                sLuaMgr.ExecuteCall(args);
1453        }
1454        RELEASE_LOCK
1455}
1456
1457void LuaHookOnAreaTrigger(Player * pPlayer, uint32 areaTrigger)
1458{
1459        GET_LOCK
1460        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_AREATRIGGER].begin(); itr != EventAsToFuncName[SERVER_HOOK_AREATRIGGER].end(); ++itr)
1461        {
1462                uint8 args = 0;
1463                if( sLuaMgr.BeginCall(itr->c_str()))
1464                        ++args;
1465                sLuaMgr.PUSH_INT(SERVER_HOOK_AREATRIGGER);
1466                sLuaMgr.PUSH_UNIT(pPlayer);
1467                sLuaMgr.PUSH_UINT(areaTrigger);
1468                args+=3;
1469                sLuaMgr.ExecuteCall(args);
1470        }
1471        RELEASE_LOCK
1472}
1473
1474void LuaHookOnPostLevelUp(Player * pPlayer)
1475{
1476        GET_LOCK
1477        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_POST_LEVELUP].begin(); itr != EventAsToFuncName[SERVER_HOOK_POST_LEVELUP].end(); ++itr)
1478        {
1479                uint8 args = 0;
1480                if( sLuaMgr.BeginCall(itr->c_str()))
1481                        ++args;
1482                sLuaMgr.PUSH_INT(SERVER_HOOK_POST_LEVELUP);
1483                sLuaMgr.PUSH_UNIT(pPlayer);
1484                args+=2;
1485                sLuaMgr.ExecuteCall(args);
1486        }
1487        RELEASE_LOCK
1488}
1489
1490void LuaHookOnPreUnitDie(Unit *Killer, Unit *Victim)
1491{
1492        GET_LOCK
1493        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_PRE_DIE].begin(); itr != EventAsToFuncName[SERVER_HOOK_PRE_DIE].end(); ++itr)
1494        {
1495                uint8 args = 0;
1496                if( sLuaMgr.BeginCall(itr->c_str()))
1497                        ++args;
1498                sLuaMgr.PUSH_INT(SERVER_HOOK_PRE_DIE);
1499                sLuaMgr.PUSH_UNIT(Killer);
1500                sLuaMgr.PUSH_UNIT(Victim);
1501                args+=3;
1502                sLuaMgr.ExecuteCall(args);
1503        }
1504        RELEASE_LOCK
1505}
1506
1507void LuaHookOnAdvanceSkillLine(Player * pPlayer, uint32 SkillLine, uint32 Current)
1508{
1509        GET_LOCK
1510        for(std::vector<string>::iterator itr = EventAsToFuncName[SERVER_HOOK_ADVANCE_SKILLLINE].begin(); itr != EventAsToFuncName[SERVER_HOOK_ADVANCE_SKILLLINE].end(); ++itr)
1511        {
1512                uint8 args = 0;
1513                if( sLuaMgr.BeginCall(itr->c_str()))
1514                        ++args;
1515                sLuaMgr.PUSH_INT(SERVER_HOOK_ADVANCE_SKILLLINE);
1516                sLuaMgr.PUSH_UNIT(pPlayer);
1517                sLuaMgr.PUSH_UINT(SkillLine);
1518                sLuaMgr.PUSH_UINT(Current);
1519                args+=4;
1520                sLuaMgr.ExecuteCall(args);
1521        }
1522        RELEASE_LOCK
1523}
1524
1525bool LuaOnDummySpell(uint32 effectIndex, Spell * pSpell)
1526{
1527        GET_LOCK
1528        uint8 args = 0;
1529        if ( sLuaMgr.BeginCall(m_luaDummySpells[pSpell->GetProto()->Id]) )
1530                ++args;
1531        sLuaMgr.PUSH_UINT(effectIndex);
1532        sLuaMgr.PUSH_SPELL(pSpell);
1533        args += 2;
1534        sLuaMgr.ExecuteCall(args);
1535        RELEASE_LOCK
1536        return true;
1537}
1538
1539class LuaCreature : public CreatureAIScript
1540{
1541public:
1542        LuaCreature(Creature* creature) : CreatureAIScript(creature) {};
1543        ~LuaCreature()
1544        {
1545                typedef std::multimap<uint32,LuaCreature*> CMAP;
1546                CMAP & cMap = sLuaMgr.getLuCreatureMap();
1547                CMAP::iterator itr = cMap.find(_unit->GetEntry());
1548                CMAP::iterator itend = cMap.upper_bound(_unit->GetEntry());
1549                CMAP::iterator it;
1550                for(;itr != cMap.end() && itr != itend;)
1551                {
1552                        it = itr++;
1553                        if(it->second != NULL && it->second == this)
1554                                cMap.erase(it);
1555                }
1556        }
1557        ARCEMU_INLINE void SetUnit(Creature * ncrc) { _unit = ncrc; }
1558        void OnCombatStart(Unit* mTarget)
1559        {
1560                CHECK_BINDING_ACQUIRELOCK
1561                if (m_binding->Functions[CREATURE_EVENT_ON_ENTER_COMBAT] != NULL)
1562                {
1563                        uint8 args = 0;
1564                        if( sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_ENTER_COMBAT]) )
1565                                args++;
1566                        sLuaMgr.PUSH_UNIT(_unit);
1567                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_ENTER_COMBAT);
1568                        sLuaMgr.PUSH_UNIT(mTarget);
1569                        args+=3;
1570                        sLuaMgr.ExecuteCall(args);
1571                }
1572                RELEASE_LOCK
1573        }
1574
1575        void OnCombatStop(Unit* mTarget)
1576        {
1577                CHECK_BINDING_ACQUIRELOCK
1578                if (m_binding->Functions[CREATURE_EVENT_ON_LEAVE_COMBAT] != NULL)
1579                {
1580                        uint8 args = 0;
1581                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_LEAVE_COMBAT]))
1582                                args++;
1583                        sLuaMgr.PUSH_UNIT(_unit);
1584                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_LEAVE_COMBAT);
1585                        sLuaMgr.PUSH_UNIT(mTarget);
1586                        args+=3;
1587                        sLuaMgr.ExecuteCall(args);
1588                }
1589                RELEASE_LOCK
1590        }
1591
1592        void OnTargetDied(Unit* mTarget)
1593        {
1594                CHECK_BINDING_ACQUIRELOCK
1595                if (m_binding->Functions[CREATURE_EVENT_ON_TARGET_DIED] != NULL)
1596                {
1597                        uint8 args = 0;
1598                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_TARGET_DIED]) )
1599                                args++;
1600                        sLuaMgr.PUSH_UNIT(_unit);
1601                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_TARGET_DIED);
1602                        sLuaMgr.PUSH_UNIT(mTarget);
1603                        args+=3;
1604                        sLuaMgr.ExecuteCall(args);
1605                }
1606                RELEASE_LOCK
1607        }
1608
1609        void OnDied(Unit *mKiller)
1610        {
1611                CHECK_BINDING_ACQUIRELOCK
1612                if (m_binding->Functions[CREATURE_EVENT_ON_DIED] != NULL)
1613                {
1614                        uint8 args = 0;
1615                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_DIED]) )
1616                                args++;
1617                        sLuaMgr.PUSH_UNIT(_unit);
1618                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_DIED);
1619                        sLuaMgr.PUSH_UNIT(mKiller);
1620                        args+=3;
1621                        sLuaMgr.ExecuteCall(args);
1622                }
1623                RELEASE_LOCK
1624        }
1625        void OnTargetParried(Unit* mTarget)
1626        {
1627                CHECK_BINDING_ACQUIRELOCK
1628                if (m_binding->Functions[CREATURE_EVENT_ON_TARGET_PARRIED] != NULL)
1629                {
1630                        uint8 args = 0;
1631                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_TARGET_PARRIED]))
1632                                args++;
1633                        sLuaMgr.PUSH_UNIT(_unit);
1634                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_TARGET_PARRIED);
1635                        sLuaMgr.PUSH_UNIT(mTarget);
1636                        args+=3;
1637                        sLuaMgr.ExecuteCall(args);
1638                }
1639                RELEASE_LOCK
1640        }
1641        void OnTargetDodged(Unit* mTarget)
1642        {
1643                CHECK_BINDING_ACQUIRELOCK
1644                if (m_binding->Functions[CREATURE_EVENT_ON_TARGET_DODGED] != NULL)
1645                {
1646                        uint8 args = 0;
1647                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_TARGET_DODGED]))
1648                                args++;
1649                        sLuaMgr.PUSH_UNIT(_unit);
1650                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_TARGET_DODGED);
1651                        sLuaMgr.PUSH_UNIT(mTarget);
1652                        args+=3;
1653                        sLuaMgr.ExecuteCall(args);
1654                }
1655                RELEASE_LOCK
1656        }
1657        void OnTargetBlocked(Unit* mTarget, int32 iAmount)
1658        {
1659                CHECK_BINDING_ACQUIRELOCK
1660                if (m_binding->Functions[CREATURE_EVENT_ON_TARGET_BLOCKED] != NULL)
1661                {
1662                        uint8 args = 0;
1663                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_TARGET_BLOCKED]) )
1664                                ++args;
1665                        sLuaMgr.PUSH_UNIT(_unit);
1666                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_TARGET_BLOCKED);
1667                        sLuaMgr.PUSH_UNIT(mTarget);
1668                        sLuaMgr.PUSH_INT(iAmount);
1669                        args+=4;
1670                        sLuaMgr.ExecuteCall(args);
1671                }
1672                RELEASE_LOCK
1673        }
1674        void OnTargetCritHit(Unit* mTarget, float fAmount)
1675        {
1676                CHECK_BINDING_ACQUIRELOCK
1677                if (m_binding->Functions[CREATURE_EVENT_ON_TARGET_CRIT_HIT] != NULL)
1678                {
1679                        uint8 args = 0;
1680                        if( sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_TARGET_CRIT_HIT]) )
1681                                args++;
1682                        sLuaMgr.PUSH_UNIT(_unit);
1683                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_TARGET_CRIT_HIT);
1684                        sLuaMgr.PUSH_UNIT(mTarget);
1685                        sLuaMgr.PUSH_FLOAT(fAmount);
1686                        args+=4;
1687                        sLuaMgr.ExecuteCall(args);
1688                }
1689                RELEASE_LOCK
1690        }
1691        void OnParried(Unit* mTarget)
1692        {
1693                CHECK_BINDING_ACQUIRELOCK
1694                if (m_binding->Functions[CREATURE_EVENT_ON_PARRY] != NULL)
1695                {
1696                        uint8 args = 0;
1697                        if( sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_PARRY]))
1698                                args++;
1699                        sLuaMgr.PUSH_UNIT(_unit);
1700                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_PARRY);
1701                        sLuaMgr.PUSH_UNIT(mTarget);
1702                        args+=3;
1703                        sLuaMgr.ExecuteCall(args);
1704                }
1705                RELEASE_LOCK
1706        }
1707        void OnDodged(Unit* mTarget)
1708        {
1709                CHECK_BINDING_ACQUIRELOCK
1710                if (m_binding->Functions[CREATURE_EVENT_ON_DODGED] != NULL)
1711                {
1712                        uint8 args = 0;
1713                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_DODGED]))
1714                                ++args;
1715                        sLuaMgr.PUSH_UNIT(_unit);
1716                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_DODGED);
1717                        sLuaMgr.PUSH_UNIT(mTarget);
1718                        args+=3;
1719                        sLuaMgr.ExecuteCall(3);
1720                }
1721                RELEASE_LOCK
1722        }
1723        void OnBlocked(Unit* mTarget, int32 iAmount)
1724        {
1725                CHECK_BINDING_ACQUIRELOCK
1726                if (m_binding->Functions[CREATURE_EVENT_ON_BLOCKED] != NULL)
1727                {
1728                        uint8 args = 0;
1729                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_BLOCKED]) )
1730                                args++;
1731                        sLuaMgr.PUSH_UNIT(_unit);
1732                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_BLOCKED);
1733                        sLuaMgr.PUSH_UNIT(mTarget);
1734                        sLuaMgr.PUSH_INT(iAmount);
1735                        args+=4;
1736                        sLuaMgr.ExecuteCall(args);
1737                }
1738                RELEASE_LOCK
1739        }
1740        void OnCritHit(Unit* mTarget, float fAmount)
1741        {
1742                CHECK_BINDING_ACQUIRELOCK
1743                if (m_binding->Functions[CREATURE_EVENT_ON_CRIT_HIT] != NULL)
1744                {
1745                        uint8 args = 0;
1746                        if( sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_CRIT_HIT]))
1747                                ++args;
1748                        sLuaMgr.PUSH_UNIT(_unit);
1749                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_CRIT_HIT);
1750                        sLuaMgr.PUSH_UNIT(mTarget);
1751                        sLuaMgr.PUSH_FLOAT(fAmount);
1752                        args+=4;
1753                        sLuaMgr.ExecuteCall(args);
1754                }
1755                RELEASE_LOCK
1756        }
1757        void OnHit(Unit* mTarget, float fAmount)
1758        {
1759                CHECK_BINDING_ACQUIRELOCK
1760                if (m_binding->Functions[CREATURE_EVENT_ON_HIT] != NULL)
1761                {
1762                        uint8 args = 0;
1763                        if( sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_HIT]) )
1764                                ++args;
1765                        sLuaMgr.PUSH_UNIT(_unit);
1766                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_HIT);
1767                        sLuaMgr.PUSH_UNIT(mTarget);
1768                        sLuaMgr.PUSH_FLOAT(fAmount);
1769                        args+=4;
1770                        sLuaMgr.ExecuteCall(args);
1771                }
1772                RELEASE_LOCK
1773        }
1774        void OnAssistTargetDied(Unit* mAssistTarget)
1775        {
1776               
1777                CHECK_BINDING_ACQUIRELOCK
1778                if (m_binding->Functions[CREATURE_EVENT_ON_ASSIST_TARGET_DIED] != NULL)
1779                {
1780                        uint8 args = 0;
1781                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_ASSIST_TARGET_DIED]))
1782                                ++args;
1783                        sLuaMgr.PUSH_UNIT(_unit);
1784                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_ASSIST_TARGET_DIED);
1785                        sLuaMgr.PUSH_UNIT(mAssistTarget);
1786                        args+=3;
1787                        sLuaMgr.ExecuteCall(args);
1788                }
1789                RELEASE_LOCK
1790        }
1791        void OnFear(Unit* mFeared, uint32 iSpellId)
1792        {
1793                CHECK_BINDING_ACQUIRELOCK
1794                if (m_binding->Functions[CREATURE_EVENT_ON_FEAR] != NULL)
1795                {
1796                        uint8 args = 0;
1797                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_FEAR]))
1798                                ++args;
1799                        sLuaMgr.PUSH_UNIT(_unit);
1800                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_FEAR);
1801                        sLuaMgr.PUSH_UNIT(mFeared);
1802                        sLuaMgr.PUSH_UINT(iSpellId);
1803                        args+=4;
1804                        sLuaMgr.ExecuteCall(args);
1805                }
1806                RELEASE_LOCK
1807        }
1808        void OnFlee(Unit* mFlee)
1809        {
1810                CHECK_BINDING_ACQUIRELOCK
1811                if (m_binding->Functions[CREATURE_EVENT_ON_FLEE] != NULL)
1812                {
1813                        uint8 args = 0;
1814                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_FLEE]))
1815                                ++args;
1816                        sLuaMgr.PUSH_UNIT(_unit);
1817                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_FLEE);
1818                        sLuaMgr.PUSH_UNIT(mFlee);
1819                        args+=3;
1820                        sLuaMgr.ExecuteCall(args);
1821                }
1822                RELEASE_LOCK
1823        }
1824        void OnCallForHelp()
1825        {
1826                CHECK_BINDING_ACQUIRELOCK
1827                if (m_binding->Functions[CREATURE_EVENT_ON_CALL_FOR_HELP] != NULL)
1828                {
1829                        uint8 args = 0;
1830                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_CALL_FOR_HELP]))
1831                                ++args;
1832                        sLuaMgr.PUSH_UNIT(_unit);
1833                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_CALL_FOR_HELP);
1834                        args+=2;
1835                        sLuaMgr.ExecuteCall(args);
1836                }
1837                RELEASE_LOCK
1838        }
1839        void OnLoad()
1840        {
1841                CHECK_BINDING_ACQUIRELOCK
1842                if (m_binding->Functions[CREATURE_EVENT_ON_LOAD] != NULL)
1843                {
1844                        uint8 args = 0;
1845                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_LOAD]))
1846                                ++args;
1847                        sLuaMgr.PUSH_UNIT(_unit);
1848                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_LOAD);
1849                        args+=2;
1850                        sLuaMgr.ExecuteCall(args);
1851                }
1852                RELEASE_LOCK
1853        }
1854        void OnReachWP(uint32 iWaypointId, bool bForwards)
1855        {
1856                CHECK_BINDING_ACQUIRELOCK
1857                if (m_binding->Functions[CREATURE_EVENT_ON_REACH_WP] != NULL)
1858                {
1859                        uint8 args = 0;
1860                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_REACH_WP]))
1861                                ++args;
1862                        sLuaMgr.PUSH_UNIT(_unit);
1863                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_REACH_WP);
1864                        sLuaMgr.PUSH_UINT(iWaypointId);
1865                        sLuaMgr.PUSH_BOOL(bForwards);
1866                        args+=4;
1867                        sLuaMgr.ExecuteCall(args);
1868                }
1869                RELEASE_LOCK
1870        }
1871        void OnLootTaken(Player* pPlayer, ItemPrototype *pItemPrototype)
1872        {
1873                CHECK_BINDING_ACQUIRELOCK
1874                if (m_binding->Functions[CREATURE_EVENT_ON_LOOT_TAKEN] != NULL)
1875                {
1876                        uint8 args = 0;
1877                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_LOOT_TAKEN]))
1878                                ++args;
1879                        sLuaMgr.PUSH_UNIT(_unit);
1880                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_LOOT_TAKEN);
1881                        sLuaMgr.PUSH_UNIT(pPlayer);
1882                        sLuaMgr.PUSH_UINT(pItemPrototype->ItemId);
1883                        args+=4;
1884                        sLuaMgr.ExecuteCall(args);
1885                }
1886                RELEASE_LOCK
1887        }
1888        void AIUpdate()
1889        {
1890                CHECK_BINDING_ACQUIRELOCK
1891                if (m_binding->Functions[CREATURE_EVENT_ON_AIUPDATE] != NULL)
1892                {
1893                        uint8 args = 0;
1894                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_AIUPDATE]))
1895                                ++args;
1896                        sLuaMgr.PUSH_UNIT(_unit);
1897                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_AIUPDATE);
1898                        args+=2;
1899                        sLuaMgr.ExecuteCall(args);
1900                }
1901                RELEASE_LOCK
1902        }
1903        void OnEmote(Player * pPlayer, EmoteType Emote)
1904        {
1905                CHECK_BINDING_ACQUIRELOCK
1906                if (m_binding->Functions[CREATURE_EVENT_ON_EMOTE] != NULL)
1907                {
1908                        uint8 args = 0;
1909                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_EMOTE]))
1910                                ++args;
1911                        sLuaMgr.PUSH_UNIT(_unit);
1912                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_EMOTE);
1913                        sLuaMgr.PUSH_UNIT(pPlayer);
1914                        sLuaMgr.PUSH_INT((int32)Emote);
1915                        args+=4;
1916                        sLuaMgr.ExecuteCall(args);
1917                }
1918                RELEASE_LOCK
1919        }
1920        void OnDamageTaken(Unit* mAttacker, float fAmount)
1921        {
1922                CHECK_BINDING_ACQUIRELOCK
1923                if (m_binding->Functions[CREATURE_EVENT_ON_DAMAGE_TAKEN] != NULL)
1924                {
1925                        uint8 args = 0;
1926                        if(sLuaMgr.BeginCall(m_binding->Functions[CREATURE_EVENT_ON_DAMAGE_TAKEN]))
1927                                ++args;
1928                        sLuaMgr.PUSH_UNIT(_unit);
1929                        sLuaMgr.PUSH_INT(CREATURE_EVENT_ON_DAMAGE_TAKEN);
1930                        sLuaMgr.PUSH_UNIT(mAttacker);
1931                        sLuaMgr.PUSH_FLOAT(fAmount);
1932                        args+=4;
1933                        sLuaMgr.ExecuteCall(args);
1934                }
1935                RELEASE_LOCK
1936        }
1937        void StringFunctionCall(const char * pFunction)
1938        {
1939               
1940                CHECK_BINDING_ACQUIRELOCK
1941                uint8 args = 0;
1942                if(sLuaMgr.BeginCall(pFunction))
1943                        ++args;
1944                sLuaMgr.PUSH_UNIT(_unit);
1945                ++args;
1946                sLuaMgr.ExecuteCall(args);
1947                RELEASE_LOCK
1948        }
1949        LuaUnitBinding * m_binding;
1950};
1951
1952class LuaGameObject : public GameObjectAIScript
1953{
1954public:
1955        LuaGameObject(GameObject * go) : GameObjectAIScript(go) {}
1956        ~LuaGameObject() {}
1957        ARCEMU_INLINE GameObject * getGO() { return _gameobject; }
1958        void OnCreate()
1959        {
1960                CHECK_BINDING_ACQUIRELOCK
1961                if (m_binding->Functions[GAMEOBJECT_EVENT_ON_CREATE] != NULL)
1962                {
1963                        uint8 args = 0;
1964                        if(sLuaMgr.BeginCall(m_binding->Functions[GAMEOBJECT_EVENT_ON_CREATE]))
1965                                ++args;
1966                        sLuaMgr.PUSH_GO(_gameobject);
1967                        args++;
1968                        sLuaMgr.ExecuteCall(args);
1969                }
1970                RELEASE_LOCK
1971        }
1972        void OnSpawn()
1973        {
1974               
1975                CHECK_BINDING_ACQUIRELOCK
1976                if (m_binding->Functions[GAMEOBJECT_EVENT_ON_SPAWN] != NULL)
1977                {
1978                        uint8 args = 0;
1979                        if( sLuaMgr.BeginCall(m_binding->Functions[GAMEOBJECT_EVENT_ON_SPAWN]))
1980                                ++args;
1981                        sLuaMgr.PUSH_GO(_gameobject);
1982                        ++args;
1983                        sLuaMgr.ExecuteCall(args);
1984                }
1985                RELEASE_LOCK
1986        }
1987        void OnDespawn()
1988        {
1989                CHECK_BINDING_ACQUIRELOCK
1990                if (m_binding->Functions[GAMEOBJECT_EVENT_ON_DESPAWN] != NULL)
1991                {
1992                        uint8 args = 0;
1993                        if(sLuaMgr.BeginCall(m_binding->Functions[GAMEOBJECT_EVENT_ON_DESPAWN]) )
1994                                ++args;
1995                        sLuaMgr.PUSH_GO(_gameobject);
1996                        ++args;
1997                        sLuaMgr.ExecuteCall(args);
1998                }
1999                RELEASE_LOCK
2000        }
2001        void OnLootTaken(Player * pLooter, ItemPrototype *pItemInfo)
2002        {
2003               
2004                CHECK_BINDING_ACQUIRELOCK
2005                if (m_binding->Functions[GAMEOBJECT_EVENT_ON_LOOT_TAKEN] != NULL)
2006                {
2007                        uint8 args = 0;
2008                        if(sLuaMgr.BeginCall(m_binding->Functions[GAMEOBJECT_EVENT_ON_LOOT_TAKEN]))
2009                                ++args;
2010                        sLuaMgr.PUSH_GO(_gameobject);
2011                        sLuaMgr.PUSH_UINT(GAMEOBJECT_EVENT_ON_LOOT_TAKEN);
2012                        sLuaMgr.PUSH_UNIT(pLooter);
2013                        sLuaMgr.PUSH_UINT(pItemInfo->ItemId);
2014                        args+=4;
2015                        sLuaMgr.ExecuteCall(args);
2016                }
2017                RELEASE_LOCK
2018        }
2019        void OnActivate(Player * pPlayer)
2020        {
2021                CHECK_BINDING_ACQUIRELOCK
2022                if (m_binding->Functions[GAMEOBJECT_EVENT_ON_USE] != NULL)
2023                {
2024                        uint8 args = 0;
2025                        sLuaMgr.BeginCall(m_binding->Functions[GAMEOBJECT_EVENT_ON_USE]);
2026                        sLuaMgr.PUSH_GO(_gameobject);
2027                        sLuaMgr.PUSH_UINT(GAMEOBJECT_EVENT_ON_USE);
2028                        sLuaMgr.PUSH_UNIT(pPlayer);
2029                        args+=3;
2030                        sLuaMgr.ExecuteCall(args);
2031                }
2032                RELEASE_LOCK
2033        }
2034       
2035        void AIUpdate()
2036        {
2037                CHECK_BINDING_ACQUIRELOCK
2038                if (m_binding->Functions[GAMEOBJECT_EVENT_AIUPDATE] != NULL)
2039                {
2040                        uint8 args = 0;
2041                        sLuaMgr.BeginCall(m_binding->Functions[GAMEOBJECT_EVENT_AIUPDATE]);
2042                        sLuaMgr.PUSH_GO(_gameobject);
2043                        ++args;
2044                        sLuaMgr.ExecuteCall(args);
2045                }
2046                RELEASE_LOCK
2047        }
2048        void Destroy ()
2049        {
2050                typedef std::multimap<uint32,LuaGameObject*> GMAP;
2051                GMAP & gMap = sLuaMgr.getLuGameObjectMap();
2052                GMAP::iterator itr = gMap.find(_gameobject->GetEntry());
2053                GMAP::iterator itend = gMap.upper_bound(_gameobject->GetEntry());
2054                GMAP::iterator it;
2055                //uint64 guid = _gameobject->GetGUID(); Unused?
2056                for(; itr != itend;)
2057                {
2058                        it = itr++;
2059                        if(it->second != NULL && it->second == this)
2060                                gMap.erase(it);
2061                }
2062                delete this;
2063        }
2064        LuaGameObjectBinding * m_binding;
2065};
2066
2067class LuaGossip : public GossipScript
2068{
2069public:
2070        LuaGossip() : GossipScript() {}
2071        ~LuaGossip() {
2072                typedef HM_NAMESPACE::hash_map<uint32, LuaGossip*> MapType;
2073                MapType gMap;
2074                if(this->m_go_gossip_binding != NULL)
2075                {
2076                        gMap = g_luaMgr.getGameObjectGossipInterfaceMap();
2077                        for(MapType::iterator itr = gMap.begin(); itr != gMap.end(); ++itr)
2078                        {
2079                                if(itr->second == this) {
2080                                        gMap.erase(itr);
2081                                        break;
2082                                }
2083                        }
2084                }
2085                else if(this->m_unit_gossip_binding != NULL)
2086                {
2087                        gMap = g_luaMgr.getUnitGossipInterfaceMap();
2088                        for(MapType::iterator itr = gMap.begin(); itr != gMap.end(); ++itr)
2089                        {
2090                                if(itr->second == this)
2091                                {
2092                                        gMap.erase(itr);
2093                                        break;
2094                                }
2095                        }
2096                }
2097                else if(this->m_item_gossip_binding != NULL)
2098                {
2099                        gMap = g_luaMgr.getItemGossipInterfaceMap();
2100                        for(MapType::iterator itr = gMap.begin(); itr != gMap.end(); ++itr)
2101                        {
2102                                if(itr->second == this)
2103                                {
2104                                        gMap.erase(itr);
2105                                        break;
2106                                }
2107                        }
2108                }
2109        }
2110
2111        void GossipHello(Object* pObject, Player* Plr, bool AutoSend)
2112        {
2113                GET_LOCK
2114                if(pObject->GetTypeId() == TYPEID_UNIT)
2115        {
2116                        if(m_unit_gossip_binding == NULL) { RELEASE_LOCK; return; }
2117                        uint8 args = 0;
2118                        if(sLuaMgr.BeginCall(m_unit_gossip_binding->Functions[GOSSIP_EVENT_ON_TALK]))
2119                                ++args;
2120                        sLuaMgr.PUSH_UNIT(pObject);
2121                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_TALK);
2122                        sLuaMgr.PUSH_UNIT(Plr);
2123                        sLuaMgr.PUSH_BOOL(AutoSend);
2124                        args+=4;
2125                        sLuaMgr.ExecuteCall(args);
2126        }
2127        else if(pObject->GetTypeId() == TYPEID_ITEM)
2128        {
2129                        if(m_item_gossip_binding == NULL) { RELEASE_LOCK; return; }
2130                        uint8 args = 0;
2131                        if(sLuaMgr.BeginCall(m_item_gossip_binding->Functions[GOSSIP_EVENT_ON_TALK]))
2132                                ++args;
2133                        sLuaMgr.PUSH_ITEM(pObject);
2134                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_TALK);
2135                        sLuaMgr.PUSH_UNIT(Plr);
2136                        sLuaMgr.PUSH_BOOL(AutoSend);
2137                        args+=4;
2138                        sLuaMgr.ExecuteCall(args);
2139        }
2140                else if(pObject->GetTypeId() == TYPEID_GAMEOBJECT)
2141        {
2142                        if(m_go_gossip_binding == NULL) { RELEASE_LOCK; return; }
2143                        uint8 args = 0;
2144            if(sLuaMgr.BeginCall(m_go_gossip_binding->Functions[GOSSIP_EVENT_ON_TALK]))
2145                                ++args;
2146                        sLuaMgr.PUSH_GO(pObject);
2147                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_TALK);
2148                        sLuaMgr.PUSH_UNIT(Plr);
2149                        sLuaMgr.PUSH_BOOL(AutoSend);
2150                        args+=4;
2151                        sLuaMgr.ExecuteCall(args);
2152        }
2153                RELEASE_LOCK
2154        }
2155
2156        void GossipSelectOption(Object* pObject, Player* Plr, uint32 Id, uint32 IntId, const char * EnteredCode)
2157        {
2158                GET_LOCK
2159                if(pObject->GetTypeId() == TYPEID_UNIT)
2160        {
2161                        if(m_unit_gossip_binding == NULL) { RELEASE_LOCK; return; }
2162                        uint8 args = 0;
2163                        if(sLuaMgr.BeginCall(m_unit_gossip_binding->Functions[GOSSIP_EVENT_ON_SELECT_OPTION]))
2164                                ++args;
2165                        sLuaMgr.PUSH_UNIT(pObject);
2166                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_SELECT_OPTION);
2167                        sLuaMgr.PUSH_UNIT(Plr);
2168                        sLuaMgr.PUSH_UINT(Id);
2169                        sLuaMgr.PUSH_UINT(IntId);
2170                        sLuaMgr.PUSH_STRING(EnteredCode);
2171                        args+=6;
2172                        sLuaMgr.ExecuteCall(args);
2173        }
2174        else if(pObject->GetTypeId() == TYPEID_ITEM)
2175        {
2176                        if(m_item_gossip_binding == NULL) { RELEASE_LOCK; return; }
2177                        uint8 args = 0;
2178           if( sLuaMgr.BeginCall(m_item_gossip_binding->Functions[GOSSIP_EVENT_ON_SELECT_OPTION]))
2179                           ++args;
2180                        sLuaMgr.PUSH_ITEM(pObject);
2181                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_SELECT_OPTION);
2182                        sLuaMgr.PUSH_UNIT(Plr);
2183                        sLuaMgr.PUSH_UINT(Id);
2184                        sLuaMgr.PUSH_UINT(IntId);
2185                        sLuaMgr.PUSH_STRING(EnteredCode);
2186                        args+=6;
2187                        sLuaMgr.ExecuteCall(args);
2188        }
2189        else if(pObject->GetTypeId() == TYPEID_GAMEOBJECT)
2190        {
2191                        if(m_go_gossip_binding == NULL) { RELEASE_LOCK; return; }
2192                        uint8 args = 0;
2193            if(sLuaMgr.BeginCall(m_go_gossip_binding->Functions[GOSSIP_EVENT_ON_SELECT_OPTION]))
2194                                ++args;
2195                        sLuaMgr.PUSH_GO(pObject);
2196                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_SELECT_OPTION);
2197                        sLuaMgr.PUSH_UNIT(Plr);
2198                        sLuaMgr.PUSH_UINT(Id);
2199                        sLuaMgr.PUSH_UINT(IntId);
2200                        sLuaMgr.PUSH_STRING(EnteredCode);
2201                        args+=6;
2202                        sLuaMgr.ExecuteCall(args);
2203        }
2204                RELEASE_LOCK
2205        }
2206
2207        void GossipEnd(Object* pObject, Player* Plr)
2208        {
2209                GET_LOCK
2210                if(pObject->GetTypeId() == TYPEID_UNIT)
2211        {
2212                        if(m_unit_gossip_binding == NULL) { RELEASE_LOCK; return; }
2213                        uint8 args = 0;
2214                        if(sLuaMgr.BeginCall(m_unit_gossip_binding->Functions[GOSSIP_EVENT_ON_END]))
2215                                ++args;
2216                        sLuaMgr.PUSH_UNIT(pObject);
2217                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_END);
2218                        sLuaMgr.PUSH_UNIT(Plr);
2219                        args+=3;
2220                        sLuaMgr.ExecuteCall(args);
2221        }
2222        else if(pObject->GetTypeId() == TYPEID_ITEM)
2223        {
2224                        if(m_item_gossip_binding == NULL) { RELEASE_LOCK; return; }
2225                        uint8 args = 0;
2226                        if(sLuaMgr.BeginCall(m_item_gossip_binding->Functions[GOSSIP_EVENT_ON_END]))
2227                                ++args;
2228                        sLuaMgr.PUSH_ITEM(pObject);
2229                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_END);
2230                        sLuaMgr.PUSH_UNIT(Plr);
2231                        args+=3;
2232                        sLuaMgr.ExecuteCall(args);
2233        }
2234        else if(pObject->GetTypeId() == TYPEID_GAMEOBJECT)
2235        {
2236                        if(m_go_gossip_binding == NULL) { RELEASE_LOCK; return; }
2237                        uint8 args = 0;
2238            if(sLuaMgr.BeginCall(m_go_gossip_binding->Functions[GOSSIP_EVENT_ON_END]))
2239                                ++args;
2240                        sLuaMgr.PUSH_GO(pObject);
2241                        sLuaMgr.PUSH_UINT(GOSSIP_EVENT_ON_END);
2242                        sLuaMgr.PUSH_UNIT(Plr);
2243                        args+=3;
2244                        sLuaMgr.ExecuteCall(args);
2245        }
2246                RELEASE_LOCK
2247        }
2248
2249        LuaUnitGossipBinding * m_unit_gossip_binding;
2250        LuaItemGossipBinding * m_item_gossip_binding;
2251    LuaGOGossipBinding * m_go_gossip_binding;
2252};
2253
2254class LuaQuest : public QuestScript
2255{
2256public:
2257        LuaQuest() : QuestScript() {}
2258        ~LuaQuest()
2259        {
2260                typedef HM_NAMESPACE::hash_map<uint32,LuaQuest*> QuestType;
2261                QuestType qMap = g_luaMgr.getLuQuestMap();
2262                for(QuestType::iterator itr = qMap.begin(); itr != qMap.end(); ++itr)
2263                {
2264                        if(itr->second == this)
2265                        {
2266                                qMap.erase(itr);
2267                                break;
2268                        }
2269                }
2270        }
2271
2272        void OnQuestStart(Player* mTarget, QuestLogEntry *qLogEntry)
2273        {
2274               
2275                CHECK_BINDING_ACQUIRELOCK
2276                if (m_binding->Functions[QUEST_EVENT_ON_ACCEPT] == NULL) { RELEASE_LOCK; return; }
2277                uint8 args = 0;
2278                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_ON_ACCEPT]))
2279                        args++;
2280                sLuaMgr.PUSH_UNIT(mTarget);
2281                sLuaMgr.PUSH_UINT(qLogEntry->GetQuest()->id);
2282                args+=2;
2283                sLuaMgr.ExecuteCall(args);
2284                RELEASE_LOCK
2285        }
2286
2287        void OnQuestComplete(Player* mTarget, QuestLogEntry *qLogEntry)
2288        {
2289               
2290                CHECK_BINDING_ACQUIRELOCK
2291                if (m_binding->Functions[QUEST_EVENT_ON_COMPLETE] == NULL) { RELEASE_LOCK; return; }
2292                uint8 args = 0;
2293                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_ON_COMPLETE]))
2294                        ++args;
2295                sLuaMgr.PUSH_UNIT(mTarget);
2296                sLuaMgr.PUSH_UINT(qLogEntry->GetQuest()->id);
2297                args+=2;
2298                sLuaMgr.ExecuteCall(args);
2299                RELEASE_LOCK
2300        }
2301        void OnQuestCancel(Player* mTarget)
2302        {
2303                CHECK_BINDING_ACQUIRELOCK
2304                if (m_binding->Functions[QUEST_EVENT_ON_CANCEL] == NULL) { RELEASE_LOCK; return; }
2305                uint8 args = 0;
2306                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_ON_CANCEL]))
2307                        ++args;
2308                sLuaMgr.PUSH_UNIT(mTarget);
2309                ++args;
2310                sLuaMgr.ExecuteCall(args);
2311                RELEASE_LOCK
2312        }
2313        void OnGameObjectActivate(uint32 entry, Player* mTarget, QuestLogEntry *qLogEntry)
2314        {
2315                CHECK_BINDING_ACQUIRELOCK
2316                if (m_binding->Functions[QUEST_EVENT_GAMEOBJECT_ACTIVATE] == NULL) { RELEASE_LOCK; return; }
2317                uint8 args = 0;
2318                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_GAMEOBJECT_ACTIVATE]))
2319                        ++args;
2320                sLuaMgr.PUSH_UINT(entry);
2321                sLuaMgr.PUSH_UNIT(mTarget);
2322                sLuaMgr.PUSH_UINT(qLogEntry->GetQuest()->id);
2323                args+=3;
2324                sLuaMgr.ExecuteCall(args);
2325                RELEASE_LOCK
2326        }
2327        void OnCreatureKill(uint32 entry, Player* mTarget, QuestLogEntry *qLogEntry)
2328        {
2329                CHECK_BINDING_ACQUIRELOCK
2330                if (m_binding->Functions[QUEST_EVENT_ON_CREATURE_KILL] == NULL) { RELEASE_LOCK; return; }
2331                uint8 args = 0;
2332                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_ON_CREATURE_KILL]))
2333                        ++args;
2334                sLuaMgr.PUSH_UINT(entry);
2335                sLuaMgr.PUSH_UNIT(mTarget);
2336                sLuaMgr.PUSH_UINT(qLogEntry->GetQuest()->id);
2337                args+=3;
2338                sLuaMgr.ExecuteCall(args);
2339                RELEASE_LOCK
2340        }
2341        void OnExploreArea(uint32 areaId, Player* mTarget, QuestLogEntry *qLogEntry)
2342        {
2343                CHECK_BINDING_ACQUIRELOCK
2344                if (m_binding->Functions[QUEST_EVENT_ON_EXPLORE_AREA] == NULL) { RELEASE_LOCK; return; }
2345                uint8 args = 0;
2346                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_ON_EXPLORE_AREA]))
2347                        ++args;
2348                sLuaMgr.PUSH_UINT(areaId);
2349                sLuaMgr.PUSH_UNIT(mTarget);
2350                sLuaMgr.PUSH_UINT(qLogEntry->GetQuest()->id);
2351                args+=3;
2352                sLuaMgr.ExecuteCall(args);
2353                RELEASE_LOCK
2354        }
2355        void OnPlayerItemPickup(uint32 itemId, uint32 totalCount, Player* mTarget, QuestLogEntry *qLogEntry)
2356        {
2357                CHECK_BINDING_ACQUIRELOCK
2358                if (m_binding->Functions[QUEST_EVENT_ON_PLAYER_ITEMPICKUP] == NULL) { RELEASE_LOCK; return; }
2359                uint8 args = 0;
2360                if(sLuaMgr.BeginCall(m_binding->Functions[QUEST_EVENT_ON_PLAYER_ITEMPICKUP]))
2361                        ++args;
2362                sLuaMgr.PUSH_UINT(itemId);
2363                sLuaMgr.PUSH_UINT(totalCount);
2364                sLuaMgr.PUSH_UNIT(mTarget);
2365                sLuaMgr.PUSH_UINT(qLogEntry->GetQuest()->id);
2366                args+=4;
2367                sLuaMgr.ExecuteCall(args);
2368                RELEASE_LOCK
2369        }
2370        LuaQuestBinding * m_binding;
2371};
2372
2373CreatureAIScript * CreateLuaCreature(Creature * src)
2374{
2375        LuaCreature * script = NULL;
2376        if(src != NULL)
2377        {
2378                uint32 id = src->GetEntry();
2379                uint64 guid = src->GetGUID();
2380                LuaUnitBinding * pBinding = sLuaMgr.getUnitBinding(id);
2381                if( pBinding != NULL)
2382                {
2383                        typedef std::multimap<uint32,LuaCreature*> CRCMAP;
2384                        CRCMAP & cMap = sLuaMgr.getLuCreatureMap();
2385                        CRCMAP::iterator itr = cMap.find(id);
2386                        CRCMAP::iterator itend = cMap.upper_bound(id);
2387                        for(; itr != cMap.end() && itr != itend; ++itr)
2388                        {
2389                                //grab the 1st and initalize
2390                                if(itr->second == NULL)
2391                                {
2392                                        script = itr->second = new LuaCreature(src);
2393                                        break;
2394                                }
2395                                if(itr->second != NULL && itr->second->GetUnit() != NULL && itr->second->GetUnit()->GetGUID() == guid)
2396                                        script = itr->second;
2397                        }
2398                        if(script == NULL)
2399                        {
2400                                script = new LuaCreature(src);
2401                                cMap.insert(make_pair(id,script));
2402                        }
2403                        script->m_binding = pBinding;
2404                }
2405        }
2406        return script;
2407}
2408
2409GameObjectAIScript * CreateLuaGameObject(GameObject * src)
2410{
2411        LuaGameObject * script = NULL;
2412        if(src != NULL) 
2413        {
2414                uint32 id = src->GetInfo()->ID;
2415                uint64 guid = src->GetGUID();
2416                LuaGameObjectBinding * pBinding = NULL;
2417                pBinding = sLuaMgr.getGameObjectBinding(id);
2418                if( pBinding != NULL) 
2419                {
2420                        typedef multimap<uint32,LuaGameObject*> GMAP;
2421                        GMAP & gMap = sLuaMgr.getLuGameObjectMap();
2422                        GMAP::iterator itr = gMap.find(id);
2423                        GMAP::iterator itend = gMap.upper_bound(id);
2424                        for(; itr != gMap.end() && itr != itend; ++itr)
2425                        {
2426                                if(itr->second != NULL && itr->second->getGO() != NULL && itr->second->getGO()->GetGUID() == guid)
2427                                        script = itr->second;
2428                        }
2429                        if(script == NULL)
2430                        {
2431                                script = new LuaGameObject(src);
2432                                gMap.insert(make_pair(id,script));
2433                        }
2434                        script->m_binding = pBinding;
2435                       
2436                }
2437        }
2438        return script;
2439}
2440
2441QuestScript * CreateLuaQuestScript(uint32 id)
2442{
2443        LuaQuest * pLua = NULL;
2444        LuaQuestBinding * pBinding = sLuaMgr.getQuestBinding( id );
2445        if(pBinding != NULL)
2446        {
2447                typedef HM_NAMESPACE::hash_map<uint32,LuaQuest*> QMAP;
2448                QMAP & qMap = sLuaMgr.getLuQuestMap();
2449                QMAP::iterator itr = qMap.find(id);
2450                if(itr != qMap.end() )
2451                {
2452                        if(itr->second == NULL)
2453                                pLua = itr->second = new LuaQuest();
2454                        else
2455                                pLua = itr->second;
2456                }
2457                else
2458                {
2459                        pLua = new LuaQuest();
2460                        qMap.insert(make_pair(id,pLua));
2461                }
2462                pLua->m_binding = pBinding;
2463        }
2464        return pLua;
2465}
2466
2467GossipScript * CreateLuaUnitGossipScript(uint32 id)
2468{
2469        LuaGossip * pLua = NULL;
2470    LuaUnitGossipBinding * pBinding = sLuaMgr.getLuaUnitGossipBinding( id );
2471        if( pBinding != NULL )
2472        {
2473                typedef HM_NAMESPACE::hash_map<uint32,LuaGossip*> GMAP;
2474                GMAP & gMap = sLuaMgr.getUnitGossipInterfaceMap();
2475                GMAP::iterator itr = gMap.find(id);
2476                if(itr != gMap.end() )
2477                {
2478                        if(itr->second == NULL)
2479                                pLua = itr->second = new LuaGossip();
2480                        else
2481                                pLua = itr->second;
2482                }
2483                else
2484                {
2485                        pLua = new LuaGossip();
2486                        gMap.insert(make_pair(id,pLua));
2487                }
2488                pLua->m_unit_gossip_binding = pBinding;
2489        }
2490        return pLua;
2491}
2492GossipScript * CreateLuaItemGossipScript(uint32 id)
2493 {
2494        LuaGossip * pLua = NULL;
2495    LuaItemGossipBinding * pBinding = sLuaMgr.getLuaItemGossipBinding( id );
2496        if( pBinding != NULL )
2497        {
2498                typedef HM_NAMESPACE::hash_map<uint32,LuaGossip*> GMAP;
2499                GMAP & gMap = sLuaMgr.getItemGossipInterfaceMap();
2500                GMAP::iterator itr = gMap.find(id);
2501                if(itr != gMap.end() )
2502                {
2503                        if(itr->second == NULL)
2504                                pLua = itr->second = new LuaGossip();
2505                        else
2506                                pLua = itr->second;
2507                }
2508                else
2509                {
2510                        pLua = new LuaGossip();
2511                        gMap.insert(make_pair(id,pLua));
2512
2513                }
2514                pLua->m_item_gossip_binding = pBinding;
2515        }
2516        return pLua;
2517 }
2518GossipScript * CreateLuaGOGossipScript(uint32 id)
2519{
2520        LuaGossip * pLua = NULL;
2521    LuaGOGossipBinding * pBinding = g_luaMgr.getLuaGOGossipBinding( id );
2522        if( pBinding != NULL )
2523        {
2524                typedef HM_NAMESPACE::hash_map<uint32,LuaGossip*> GMAP;
2525                GMAP & gMap = sLuaMgr.getGameObjectGossipInterfaceMap();
2526                GMAP::iterator itr = gMap.find(id);
2527                if(itr != gMap.end() )
2528                {
2529                        if(itr->second == NULL)
2530                                pLua = itr->second = new LuaGossip();
2531                        else
2532                                pLua = itr->second;
2533                }
2534                else
2535                {
2536                        pLua = new LuaGossip();
2537                        gMap.insert(make_pair(id,pLua));
2538                }
2539                pLua->m_go_gossip_binding = pBinding;
2540        }
2541        return pLua;
2542}
2543
2544void LuaEngine::Startup()
2545{
2546        Log.Notice("LuaEngineMgr", "Spawning Lua Engine...");
2547        #ifdef WIN32
2548        Log.Color(TGREEN);
2549        printf(" \_\_                        \_\_  \_\_                  \_\_\_\_\_\_                 \n");
2550        Log.Color(TGREEN);
2551        printf("/\\ \\                      /\\ \\/\\ \\                /\\  \_  \\                 \n");
2552        Log.Color(TGREEN);
2553        printf("\\ \\ \\      \_\_  \_\_     \_\_  \\ \\ \\\_\\ \\  \_\_  \_\_  \_\_\_\_\_\\ \\ \\\_\\ \\  \_\_\_\_\_  \_\_\_    \n");
2554        Log.Color(TGREEN);
2555        printf(" \\ \\ \\  \_\_/\\ \\/\\ \\  /'\_\_`\\ \\ \\  \_  \\/\\ \\/\\ \\/\\  \_\_`\\ \\  \_\_ \\/\\  \_\_\\/'\_\_\_\\  \n");
2556        Log.Color(TGREEN);
2557        printf(\\ \\ \\\_\\ \\ \\ \\\_\\ \\/\\ \\\_\\.\\\_\\ \\ \\ \\ \\ \\ \\\_\\ \\ \\ \\\_\\ \\ \\ \\/\\ \\ \\ \\//\\ \\\_\_/  \n");
2558        Log.Color(TGREEN);
2559        printf("   \\ \\\_\_\_\_/\\ \\\_\_\_\_/\\ \\\_\_/ \\\_\\\\ \\\_\\ \\\_\\/`\_\_\_\_ \\ \\  \_\_/\\ \\\_\\ \\\_\\ \\\_\\\\ \\\_\_\_\_\\ \n");
2560        Log.Color(TGREEN);
2561        printf("    \\/\_\_\_/  \\/\_\_\_/  \\/\_\_/\\/\_/ \\/\_/\\/\_/`/\_\_\_// \\ \\ \\\\/\_/\\/\_/\\/\_/ \\/\_\_\_\_/ \n");
2562        Log.Color(TGREEN);
2563        printf("                                         /\\\_\_\_/\\ \\\_\\                       \n");
2564        Log.Color(TGREEN);
2565        printf("                                         \\/\_\_/  \\/\_/                      \n");
2566        #else
2567        Log.Color(TGREEN);
2568        printf("~~~LuaHypArc~~~");
2569        #endif
2570        Log.Line();
2571        Log.Notice("LuaEngineMgr", "LuaHypArc Lua Engine %s: Loaded", ARCH);
2572        Log.Color(TNORMAL);
2573        Log.Line();
2574        Sleep(1200);
2575        //Create a new global state that will server as the lua universe.
2576        lu = lua_open();
2577
2578        LoadScripts();
2579
2580        // stuff is registered, so lets go ahead and make our emulated C++ scripted lua classes.
2581        for(UnitBindingMap::iterator itr = m_unitBinding.begin(); itr != m_unitBinding.end(); ++itr)
2582        {
2583                m_scriptMgr->register_creature_script( itr->first, CreateLuaCreature );
2584                sLuaMgr.getLuCreatureMap().insert(make_pair(itr->first,(LuaCreature*)NULL));
2585        }
2586
2587        for(GameObjectBindingMap::iterator itr = m_gameobjectBinding.begin(); itr != m_gameobjectBinding.end(); ++itr)
2588        {
2589                m_scriptMgr->register_gameobject_script( itr->first, CreateLuaGameObject );
2590                sLuaMgr.getLuGameObjectMap().insert(make_pair(itr->first,(LuaGameObject*)NULL));
2591        }
2592
2593        for(QuestBindingMap::iterator itr = m_questBinding.begin(); itr != m_questBinding.end(); ++itr)
2594        {
2595                QuestScript * qs = CreateLuaQuestScript( itr->first );
2596                if( qs != NULL )
2597                {
2598                        m_scriptMgr->register_quest_script( itr->first, qs );
2599                        sLuaMgr.getLuQuestMap().insert(make_pair(itr->first,(LuaQuest*)NULL));
2600                }
2601        }
2602
2603    for(GossipUnitScriptsBindingMap::iterator itr = m_unit_gossipBinding.begin(); itr != m_unit_gossipBinding.end(); ++itr)
2604        {
2605                GossipScript * gs = CreateLuaUnitGossipScript( itr->first );
2606                if( gs != NULL )
2607                {
2608                        m_scriptMgr->register_gossip_script( itr->first, gs );
2609                        sLuaMgr.getUnitGossipInterfaceMap().insert(make_pair(itr->first,(LuaGossip*)NULL));
2610                }
2611        }
2612
2613    for(GossipItemScriptsBindingMap::iterator itr = m_item_gossipBinding.begin(); itr != m_item_gossipBinding.end(); ++itr)
2614        {
2615                GossipScript * gs = CreateLuaItemGossipScript( itr->first );
2616                if( gs != NULL )
2617                {
2618                        m_scriptMgr->register_item_gossip_script( itr->first, gs );
2619                        sLuaMgr.getItemGossipInterfaceMap().insert(make_pair(itr->first,(LuaGossip*)NULL));
2620                }
2621    }
2622
2623    for(GossipGOScriptsBindingMap::iterator itr = m_go_gossipBinding.begin(); itr != m_go_gossipBinding.end(); ++itr)
2624        {
2625                GossipScript * gs = CreateLuaGOGossipScript( itr->first );
2626                if( gs != NULL )
2627                {
2628                        m_scriptMgr->register_go_gossip_script( itr->first, gs );
2629                        sLuaMgr.getGameObjectGossipInterfaceMap().insert(make_pair(itr->first,(LuaGossip*)NULL));
2630                }
2631    }
2632
2633        //big server hook chunk. it only hooks if there are functions present to save on unnecessary processing.
2634
2635        RegisterHook(SERVER_HOOK_NEW_CHARACTER,(void*)LuaHookOnNewCharacter)
2636        RegisterHook(SERVER_HOOK_KILL_PLAYER,(void*)LuaHookOnKillPlayer)
2637        RegisterHook(SERVER_HOOK_FIRST_ENTER_WORLD,(void*)LuaHookOnFirstEnterWorld)
2638        RegisterHook(SERVER_HOOK_ENTER_WORLD,(void*)LuaHookOnEnterWorld)
2639        RegisterHook(SERVER_HOOK_GUILD_JOIN,(void*)LuaHookOnGuildJoin)
2640        RegisterHook(SERVER_HOOK_DEATH,(void*)LuaHookOnDeath)
2641        RegisterHook(SERVER_HOOK_REPOP,(void*)LuaHookOnRepop)
2642        RegisterHook(SERVER_HOOK_EMOTE,(void*)LuaHookOnEmote)
2643        RegisterHook(SERVER_HOOK_ENTER_COMBAT,(void*)LuaHookOnEnterCombat)
2644        RegisterHook(SERVER_HOOK_CAST_SPELL,(void*)LuaHookOnCastSpell)
2645        RegisterHook(SERVER_HOOK_TICK,(void*)LuaHookOnTick)
2646        RegisterHook(SERVER_HOOK_LOGOUT_REQUEST,(void*)LuaHookOnLogoutRequest)
2647        RegisterHook(SERVER_HOOK_LOGOUT,(void*)LuaHookOnLogout)
2648        RegisterHook(SERVER_HOOK_QUEST_ACCEPT,(void*)LuaHookOnQuestAccept)
2649        RegisterHook(SERVER_HOOK_ZONE,(void*)LuaHookOnZone)
2650        RegisterHook(SERVER_HOOK_CHAT,(void*)LuaHookOnChat)
2651        RegisterHook(SERVER_HOOK_LOOT,(void*)LuaHookOnLoot)
2652        RegisterHook(SERVER_HOOK_GUILD_CREATE,(void*)LuaHookOnGuildCreate)
2653        RegisterHook(SERVER_HOOK_ENTER_WORLD_2,(void*)LuaHookOnEnterWorld2)
2654        RegisterHook(SERVER_HOOK_CHARACTER_CREATE,(void*)LuaHookOnCharacterCreate)
2655        RegisterHook(SERVER_HOOK_QUEST_CANCELLED,(void*)LuaHookOnQuestCancelled)
2656        RegisterHook(SERVER_HOOK_QUEST_FINISHED,(void*)LuaHookOnQuestFinished)
2657        RegisterHook(SERVER_HOOK_HONORABLE_KILL,(void*)LuaHookOnHonorableKill)
2658        RegisterHook(SERVER_HOOK_ARENA_FINISH,(void*)LuaHookOnArenaFinish)
2659        RegisterHook(SERVER_HOOK_OBJECTLOOT,(void*)LuaHookOnObjectLoot)
2660        RegisterHook(SERVER_HOOK_AREATRIGGER,(void*)LuaHookOnAreaTrigger)
2661        RegisterHook(SERVER_HOOK_POST_LEVELUP,(void*)LuaHookOnPostLevelUp)
2662        RegisterHook(SERVER_HOOK_PRE_DIE,(void*)LuaHookOnPreUnitDie)
2663        RegisterHook(SERVER_HOOK_ADVANCE_SKILLLINE,(void*)LuaHookOnAdvanceSkillLine)
2664
2665        for (std::map<uint32,const char*>::iterator itr = m_luaDummySpells.begin(); itr != m_luaDummySpells.end(); ++itr)
2666        {
2667                m_scriptMgr->register_dummy_spell(itr->first, &LuaOnDummySpell);
2668                sLuaMgr.HookInfo.dummyHooks.push_back(itr->first);
2669        }
2670}
2671void LuaEngine::RegisterEvent(uint8 regtype, uint32 id, uint32 evt, const char *func) 
2672{
2673        if(func != NULL && evt) 
2674        {
2675                switch(regtype) 
2676                {
2677                        case REGTYPE_UNIT: 
2678                                {
2679                                        if(id && evt < CREATURE_EVENT_COUNT) {
2680                                                LuaUnitBinding * bind = getUnitBinding(id);
2681                                                if(bind == NULL) {
2682                                                        LuaUnitBinding nbind;
2683                                                        memset(&nbind,0,sizeof(LuaUnitBinding));
2684                                                        nbind.Functions[evt] = strdup(func);
2685                                                        m_unitBinding.insert(make_pair(id,nbind));
2686                                                }
2687                                                else
2688                                                {
2689                                                        if(bind->Functions[evt] != NULL)
2690                                                                free((void*)bind->Functions[evt]);
2691                                                        bind->Functions[evt] = strdup(func);
2692                                                }
2693                                        }
2694                                }break;
2695                        case REGTYPE_GO:
2696                                {
2697                                        if(id && evt < GAMEOBJECT_EVENT_COUNT) {
2698                                                LuaGameObjectBinding * bind = getGameObjectBinding(id);
2699                                                if(bind == NULL) {
2700                                                        LuaGameObjectBinding nbind;
2701                                                        memset(&nbind,0,sizeof(LuaGameObjectBinding));
2702                                                        nbind.Functions[evt] = strdup(func);
2703                                                        m_gameobjectBinding.insert(make_pair(id,nbind));
2704                                                }
2705                                                else {
2706                                                        if(bind->Functions[evt] != NULL)
2707                                                                free( (void*)bind->Functions[evt]);
2708                                                        bind->Functions[evt] = strdup(func);
2709                                                }
2710                                        }
2711                                }break;
2712                        case REGTYPE_QUEST:
2713                                {
2714                                        if(id && evt < QUEST_EVENT_COUNT) {
2715                                                LuaQuestBinding * bind = getQuestBinding(id);
2716                                                if(bind == NULL) {
2717                                                        LuaQuestBinding nbind;
2718                                                        memset(&nbind,0,sizeof(LuaQuestBinding));
2719                                                        nbind.Functions[evt] = strdup(func);
2720                                                        m_questBinding.insert(make_pair(id,nbind));
2721                                                }
2722                                                else
2723                                                {
2724                                                        if(bind->Functions[evt] != NULL)
2725                                                                free( (void*)bind->Functions[evt]);
2726                                                        bind->Functions[evt] = strdup(func);
2727                                                }
2728                                        }
2729                                }break;
2730                        case REGTYPE_SERVHOOK:
2731                                {
2732                                        if(evt < SERVER_HOOK_COUNT)
2733                                                EventAsToFuncName[evt].push_back(string(func));
2734                                }break;
2735                        case REGTYPE_DUMMYSPELL:
2736                                {
2737                                        if (id)
2738                                                m_luaDummySpells.insert( make_pair<uint32,const char*>(id,strdup(func)) );
2739                                }break;
2740                        case REGTYPE_UNIT_GOSSIP:
2741                                {
2742                                        if(id && evt < GOSSIP_EVENT_COUNT) {
2743                                                LuaUnitGossipBinding * bind = getLuaUnitGossipBinding(id);
2744                                                if(bind == NULL) {
2745                                                        LuaUnitGossipBinding nbind;
2746                                                        memset(&nbind,0,sizeof(LuaUnitGossipBinding));
2747                                                        nbind.Functions[evt] = strdup(func);
2748                                                        m_unit_gossipBinding.insert(make_pair(id,nbind));
2749                                                }
2750                                                else {
2751                                                        if(bind->Functions[evt] != NULL)
2752                                                                free( (void*)bind->Functions[evt]);
2753                                                        bind->Functions[evt] = strdup(func);
2754                                                }
2755                                        }
2756                                }break;
2757                                case REGTYPE_ITEM_GOSSIP:
2758                                {
2759                                        if(id && evt < GOSSIP_EVENT_COUNT) {
2760                                                LuaItemGossipBinding * bind = getLuaItemGossipBinding(id);
2761                                                if(bind == NULL) {
2762                                                        LuaItemGossipBinding nbind;
2763                                                        memset(&nbind,0,sizeof(LuaItemGossipBinding));
2764                                                        nbind.Functions[evt] = strdup(func);
2765                                                        m_item_gossipBinding.insert(make_pair(id,nbind));
2766                                                }
2767                                                else {
2768                                                        if(bind->Functions[evt] != NULL)
2769                                                                free( (void*)bind->Functions[evt]);
2770                                                        bind->Functions[evt] = strdup(func);
2771                                                }
2772                                        }
2773                                }break;
2774                                case REGTYPE_GO_GOSSIP:
2775                                {
2776                                        if(id && evt < GOSSIP_EVENT_COUNT) {
2777                                                LuaGOGossipBinding * bind = getLuaGOGossipBinding(id);
2778                                                if(bind == NULL) {
2779                                                        LuaGOGossipBinding nbind;
2780                                                        memset(&nbind,0,sizeof(LuaGOGossipBinding));
2781                                                        nbind.Functions[evt] = strdup(func);
2782                                                        m_go_gossipBinding.insert(make_pair(id,nbind));
2783                                                }
2784                                                else {
2785                                                        if(bind->Functions[evt] != NULL)
2786                                                                free( (void*)bind->Functions[evt]);
2787                                                        bind->Functions[evt] = strdup(func);
2788                                                }
2789                                        }
2790                                }break;
2791                }
2792        }
2793}
2794
2795void LuaEngine::Unload()
2796{
2797        // clean up the engine of any existing defined variables
2798        {
2799                UnitBindingMap::iterator itr = this->m_unitBinding.begin();
2800                for(; itr != m_unitBinding.end(); ++itr)
2801                {
2802                        for(int i = 0; i < CREATURE_EVENT_COUNT; ++i) 
2803                        {
2804                                if(itr->second.Functions[i] != NULL)
2805                                        free((void*)itr->second.Functions[i]);
2806                        }
2807                }
2808                m_unitBinding.clear();
2809        }
2810        {
2811                GameObjectBindingMap::iterator itr = this->m_gameobjectBinding.begin();
2812                for(; itr != m_gameobjectBinding.end(); ++itr)
2813                {
2814                        for(int i = 0; i < GAMEOBJECT_EVENT_COUNT; ++i) 
2815                        {
2816                                if(itr->second.Functions[i] != NULL)
2817                                        free((void*)itr->second.Functions[i]);
2818                        }
2819                }
2820                m_gameobjectBinding.clear();
2821        }
2822        {
2823                QuestBindingMap::iterator itr = this->m_questBinding.begin();
2824                for(; itr != m_questBinding.end(); ++itr)
2825                {
2826                        for(int i = 0; i < 8; ++i) 
2827                        {
2828                                if(itr->second.Functions[i] != NULL)
2829                                        free((void*)itr->second.Functions[i]);
2830                        }
2831                }
2832                m_questBinding.clear();
2833        }
2834        {
2835                GossipUnitScriptsBindingMap::iterator itr = m_unit_gossipBinding.begin();
2836                for(; itr != m_unit_gossipBinding.end(); ++itr)
2837                {
2838                        for(int i = 0; i < GOSSIP_EVENT_COUNT; ++i)
2839                        {
2840                                if(itr->second.Functions[i] != NULL)
2841                                        free((void*)itr->second.Functions[i]);
2842                        }
2843                }
2844                m_unit_gossipBinding.clear();
2845        }
2846        {
2847                GossipItemScriptsBindingMap::iterator itr = m_item_gossipBinding.begin();
2848                for(; itr != m_item_gossipBinding.end(); ++itr)
2849                {
2850                        for(int i = 0; i < GOSSIP_EVENT_COUNT; ++i)
2851                        {
2852                                if(itr->second.Functions[i] != NULL)
2853                                        free((void*)itr->second.Functions[i]);
2854                        }
2855                }
2856                m_item_gossipBinding.clear();
2857        }
2858        {
2859                GossipGOScriptsBindingMap::iterator itr = m_go_gossipBinding.begin();
2860                for(; itr != m_go_gossipBinding.end(); ++itr)
2861                {
2862                        for(int i = 0; i < GOSSIP_EVENT_COUNT; ++i)
2863                        {
2864                                if(itr->second.Functions[i] != NULL)
2865                                        free((void*)itr->second.Functions[i]);
2866                        }
2867                }
2868                m_go_gossipBinding.clear();
2869        }
2870        //Serv hooks : had forgotten these.
2871        {
2872                for(int i = 0; i < SERVER_HOOK_COUNT; ++i)
2873                {
2874                        vector<string> & next = EventAsToFuncName[i];
2875                        next.clear();
2876                }
2877        }
2878        {
2879                std::map<uint32, const char*>::iterator itr = m_luaDummySpells.begin();
2880                for (; itr != m_luaDummySpells.end(); ++itr)
2881                {
2882                        free((void*)itr->second);
2883                }
2884        }
2885        set<int>::iterator itr = m_pendingThreads.begin();
2886        for(; itr != m_pendingThreads.end(); ++itr)
2887        {
2888                lua_unref(lu,(*itr));
2889        }
2890        m_pendingThreads.erase(m_pendingThreads.begin(),m_pendingThreads.end());
2891
2892        lua_close(lu);
2893}
2894void LuaEngine::Restart()
2895{
2896        Log.Notice("LuaEngineMgr","Restarting Engine.");
2897        if(getLock().AttemptAcquire() && getcoLock().AttemptAcquire() )
2898        {
2899                Unload();
2900                lu = lua_open();
2901                LoadScripts();
2902                for(UnitBindingMap::iterator itr = m_unitBinding.begin(); itr != m_unitBinding.end(); ++itr)
2903                {
2904                        typedef multimap<uint32,LuaCreature*> CMAP;
2905                        CMAP & cMap = sLuaMgr.getLuCreatureMap();
2906                        CMAP::iterator it = cMap.find(itr->first);
2907                        CMAP::iterator itend = cMap.upper_bound(itr->first);
2908                        if(it == cMap.end() )
2909                        {
2910                                m_scriptMgr->register_creature_script(itr->first,CreateLuaCreature);
2911                                cMap.insert(make_pair(itr->first,(LuaCreature*)NULL));
2912                        }
2913                        else
2914                        {
2915                                for(;it != itend; ++it) 
2916                                {
2917                                        if(it->second != NULL)
2918                                                it->second->m_binding = &itr->second;
2919                                }
2920                        }
2921                }
2922                for(GameObjectBindingMap::iterator itr = m_gameobjectBinding.begin(); itr != m_gameobjectBinding.end(); ++itr)
2923                {
2924                        typedef multimap<uint32,LuaGameObject*> GMAP;
2925                        GMAP & gMap = sLuaMgr.getLuGameObjectMap();
2926                        GMAP::iterator it = gMap.find(itr->first);
2927                        GMAP::iterator itend = gMap.upper_bound(itr->first);
2928                        if(it == gMap.end() )
2929                        {
2930                                m_scriptMgr->register_gameobject_script(itr->first,CreateLuaGameObject);
2931                                gMap.insert(make_pair(itr->first,(LuaGameObject*)NULL));
2932                        }
2933                        else
2934                        {
2935                                for(;it != itend; ++it)
2936                                {
2937                                        if(it->second != NULL)
2938                                                it->second->m_binding = &itr->second;
2939                                }
2940                        }
2941                }
2942                for(QuestBindingMap::iterator itr = m_questBinding.begin(); itr != m_questBinding.end(); ++itr)
2943                {
2944                        typedef HM_NAMESPACE::hash_map<uint32,LuaQuest*> QMAP;
2945                        QMAP & qMap = sLuaMgr.getLuQuestMap();
2946                        QMAP::iterator it = qMap.find(itr->first);
2947                        if(it == qMap.end())
2948                        {
2949                                m_scriptMgr->register_quest_script(itr->first,CreateLuaQuestScript(itr->first));
2950                                qMap.insert(make_pair(itr->first,(LuaQuest*)NULL));
2951                        }
2952                        else
2953                        {
2954                                LuaQuest * q_interface = it->second;
2955                                if(q_interface != NULL)
2956                                        q_interface->m_binding = &itr->second;
2957                        }
2958                }
2959                for(GossipUnitScriptsBindingMap::iterator itr = this->m_unit_gossipBinding.begin(); itr != m_unit_gossipBinding.end(); ++itr)
2960                {
2961                        typedef HM_NAMESPACE::hash_map<uint32,LuaGossip*> GMAP;
2962                        GMAP & gMap = sLuaMgr.getUnitGossipInterfaceMap();
2963                        GMAP::iterator it = gMap.find(itr->first);
2964                        if(it == gMap.end() ) 
2965                        {
2966                                GossipScript * gs = CreateLuaUnitGossipScript(itr->first);
2967                                if(gs != NULL)
2968                                {
2969                                        m_scriptMgr->register_gossip_script(itr->first,gs);
2970                                        gMap.insert(make_pair(itr->first,(LuaGossip*)NULL));
2971                                }
2972                        }
2973                        else
2974                        {
2975                                LuaGossip * u_gossip = it->second;
2976                                if(u_gossip != NULL)
2977                                        u_gossip->m_unit_gossip_binding = &itr->second;
2978                        }
2979                }
2980                for(GossipItemScriptsBindingMap::iterator itr = this->m_item_gossipBinding.begin(); itr != m_item_gossipBinding.end(); ++itr)
2981                {
2982                        typedef HM_NAMESPACE::hash_map<uint32,LuaGossip*> GMAP;
2983                        GMAP & gMap = sLuaMgr.getItemGossipInterfaceMap();
2984                        GMAP::iterator it = gMap.find(itr->first);
2985                        if(it == gMap.end() ) 
2986                        {
2987                                GossipScript * gs = CreateLuaItemGossipScript(itr->first);
2988                                if(gs != NULL)
2989                                {
2990                                        m_scriptMgr->register_item_gossip_script(itr->first,gs);
2991                                        gMap.insert(make_pair(itr->first,(LuaGossip*)NULL));
2992                                }
2993                        }
2994                        else
2995                        {
2996                                LuaGossip * i_gossip = it->second;
2997                                if(i_gossip != NULL)
2998                                        i_gossip->m_item_gossip_binding = &itr->second;
2999                        }
3000                }
3001                for(GossipGOScriptsBindingMap::iterator itr = this->m_go_gossipBinding.begin(); itr != m_go_gossipBinding.end(); ++itr)
3002                {
3003                        typedef HM_NAMESPACE::hash_map<uint32,LuaGossip*> GMAP;
3004                        GMAP & gMap = sLuaMgr.getGameObjectGossipInterfaceMap();
3005                        GMAP::iterator it = gMap.find(itr->first);
3006                        if(it == gMap.end() ) 
3007                        {
3008                                GossipScript * gs = CreateLuaGOGossipScript(itr->first);
3009                                if(gs != NULL)
3010                                {
3011                                        m_scriptMgr->register_go_gossip_script(itr->first,gs);
3012                                        gMap.insert(make_pair(itr->first,(LuaGossip*)NULL));
3013                                }
3014                        }
3015                        else
3016                        {
3017                                LuaGossip * g_gossip = it->second;
3018                                if(g_gossip != NULL)
3019                                        g_gossip->m_go_gossip_binding = &itr->second;
3020                        }
3021                }
3022                /*
3023                        BIG SERV HOOK CHUNK EEK
3024                        */
3025                RegisterHook(SERVER_HOOK_NEW_CHARACTER,(void*)LuaHookOnNewCharacter)
3026                RegisterHook(SERVER_HOOK_KILL_PLAYER,(void*)LuaHookOnKillPlayer)
3027                RegisterHook(SERVER_HOOK_FIRST_ENTER_WORLD,(void*)LuaHookOnFirstEnterWorld)
3028                RegisterHook(SERVER_HOOK_ENTER_WORLD,(void*)LuaHookOnEnterWorld)
3029                RegisterHook(SERVER_HOOK_GUILD_JOIN,(void*)LuaHookOnGuildJoin)
3030                RegisterHook(SERVER_HOOK_DEATH,(void*)LuaHookOnDeath)
3031                RegisterHook(SERVER_HOOK_REPOP,(void*)LuaHookOnRepop)
3032                RegisterHook(SERVER_HOOK_EMOTE,(void*)LuaHookOnEmote)
3033                RegisterHook(SERVER_HOOK_ENTER_COMBAT,(void*)LuaHookOnEnterCombat)
3034                RegisterHook(SERVER_HOOK_CAST_SPELL,(void*)LuaHookOnCastSpell)
3035                RegisterHook(SERVER_HOOK_TICK,(void*)LuaHookOnTick)
3036                RegisterHook(SERVER_HOOK_LOGOUT_REQUEST,(void*)LuaHookOnLogoutRequest)
3037                RegisterHook(SERVER_HOOK_LOGOUT,(void*)LuaHookOnLogout)
3038                RegisterHook(SERVER_HOOK_QUEST_ACCEPT,(void*)LuaHookOnQuestAccept)
3039                RegisterHook(SERVER_HOOK_ZONE,(void*)LuaHookOnZone)
3040                RegisterHook(SERVER_HOOK_CHAT,(void*)LuaHookOnChat)
3041                RegisterHook(SERVER_HOOK_LOOT,(void*)LuaHookOnLoot)
3042                RegisterHook(SERVER_HOOK_GUILD_CREATE,(void*)LuaHookOnGuildCreate)
3043                RegisterHook(SERVER_HOOK_ENTER_WORLD_2,(void*)LuaHookOnEnterWorld2)
3044                RegisterHook(SERVER_HOOK_CHARACTER_CREATE,(void*)LuaHookOnCharacterCreate)
3045                RegisterHook(SERVER_HOOK_QUEST_CANCELLED,(void*)LuaHookOnQuestCancelled)
3046                RegisterHook(SERVER_HOOK_QUEST_FINISHED,(void*)LuaHookOnQuestFinished)
3047                RegisterHook(SERVER_HOOK_HONORABLE_KILL,(void*)LuaHookOnHonorableKill)
3048                RegisterHook(SERVER_HOOK_ARENA_FINISH,(void*)LuaHookOnArenaFinish)
3049                RegisterHook(SERVER_HOOK_OBJECTLOOT,(void*)LuaHookOnObjectLoot)
3050                RegisterHook(SERVER_HOOK_AREATRIGGER,(void*)LuaHookOnAreaTrigger)
3051                RegisterHook(SERVER_HOOK_POST_LEVELUP,(void*)LuaHookOnPostLevelUp)
3052                RegisterHook(SERVER_HOOK_PRE_DIE,(void*)LuaHookOnPreUnitDie)
3053                RegisterHook(SERVER_HOOK_ADVANCE_SKILLLINE,(void*)LuaHookOnAdvanceSkillLine)
3054
3055                for (std::map<uint32,const char*>::iterator itr = m_luaDummySpells.begin(); itr != m_luaDummySpells.end(); ++itr)
3056                {
3057                        if (std::find(sLuaMgr.HookInfo.dummyHooks.begin(), sLuaMgr.HookInfo.dummyHooks.end(), itr->first) 
3058                                != sLuaMgr.HookInfo.dummyHooks.end())
3059                        {
3060                                m_scriptMgr->register_dummy_spell(itr->first, &LuaOnDummySpell);
3061                                sLuaMgr.HookInfo.dummyHooks.push_back(itr->first);
3062                        }
3063                }
3064                getLock().Release();
3065                getcoLock().Release();
3066        }
3067        Log.Notice("LuaEngineMgr","Done restarting engine.");
3068}
3069
3070void LuaEngine::ResumeLuaThread(int ref) {
3071        getcoLock().Acquire();
3072        lua_State * expectedThread = NULL;
3073        lua_rawgeti(lu,LUA_REGISTRYINDEX,ref);
3074        if(lua_isthread(lu,-1) )
3075                expectedThread = lua_tothread(lu,-1);
3076        if(expectedThread != NULL) 
3077        {
3078                //push ourself on the stack
3079                lua_pushthread(expectedThread);
3080                //move the thread to the main lu state(and pop it off)
3081                lua_xmove(expectedThread,lu,1);
3082                if(lua_rawequal(lu,-1,-2) )
3083                {
3084                        lua_pop(lu,2);
3085                        int res = lua_resume(expectedThread,lua_gettop(expectedThread));
3086                        if(res != LUA_YIELD && res)
3087                                report(expectedThread);
3088                }
3089                else
3090                        lua_pop(lu,2);
3091                luaL_unref(lu,LUA_REGISTRYINDEX,ref);
3092        }
3093        getcoLock().Release();
3094}
3095
3096
3097/************************************************************************/
3098/* SCRIPT FUNCTION IMPLEMENTATION                                       */
3099/************************************************************************/
3100#define CHECK_TYPEID(expected_type) if(!ptr || !ptr->IsInWorld() || ptr->GetTypeId() != expected_type) { return 0; }
3101#define CHECK_TYPEID_RET(expected_type) if(!ptr || !ptr->IsInWorld() || ptr->GetTypeId() != expected_type) { lua_pushboolean(L,0); return 1; }
3102#define CHECK_TYPEID_RETINT(expected_type) if(!ptr || !ptr->IsInWorld() || ptr->GetTypeId() != expected_type) { lua_pushinteger(L,0); return 1; }
3103#define CHECK_TYPEID_RETNIL(expected_type) if(!ptr || !ptr->IsInWorld() || ptr->GetTypeId() != expected_type) { lua_pushnil(L); return 1; } (void*)0
3104#define RET_NIL { lua_pushnil(L); return 1; } (void*)0
3105#define RET_BOOL(exp) { (exp) ? lua_pushboolean(L,1) : lua_pushboolean(L,0); return 1; } (void*)0
3106#define RET_STRING(str) { lua_pushstring(L,(str)); return 1; } (void*)0
3107#define RET_NUMBER(number) { lua_pushnumber(L,(number)); return 1; } (void*)0
3108#define RET_INT(integer) { lua_pushinteger(L,(integer)); return 1; } (void*)0
3109
3110// Simplicity macros.
3111#define CHECK_UNIT(L,narg) sLuaMgr.CHECK_UNIT(L,narg)
3112#define CHECK_PLAYER(L,narg) TO_PLAYER(CHECK_UNIT(L,narg))
3113#define CHECK_GO(L,narg) sLuaMgr.CHECK_GO(L,narg)
3114#define CHECK_ITEM(L,narg) sLuaMgr.CHECK_ITEM(L,narg)
3115#define CHECK_PACKET(L,narg) sLuaMgr.CHECK_PACKET(L,narg)
3116#define CHECK_GUID(L, narg) sLuaMgr.CHECK_GUID(L,narg)
3117#define CHECK_OBJECT(L, narg) sLuaMgr.CHECK_OBJECT(L,narg)
3118#define CHECK_TAXIPATH(L, narg) sLuaMgr.CHECK_TAXIPATH(L,narg)
3119#define CHECK_SPELL(L, narg) sLuaMgr.CHECK_SPELL(L,narg)
3120
3121//Its coming soon ^.^
3122//#define CHECK_SPELL(L,narg) ArcLuna<Spell>::check(L),(narg))
3123//This is used alot when checking for coords but Lua handles only doubles.
3124#define CHECK_FLOAT(L,narg) (lua_isnoneornil(L,(narg)) ) ? 0.00f : (float)luaL_checknumber(L,(narg));
3125#define CHECK_ULONG(L,narg) (uint32)luaL_checknumber((L),(narg))
3126#define CHECK_USHORT(L, narg) (uint16)luaL_checkinteger((L),(narg))
3127#define CHECK_BOOL(L,narg) (lua_toboolean((L),(narg)) > 0) ? true : false
3128
3129#define PUSH_UNIT(L, unit) sLuaMgr.PUSH_UNIT(TO_UNIT(unit),L)
3130#define PUSH_GO(L, go) sLuaMgr.PUSH_GO(static_cast<GameObject*>(go),L)
3131#define PUSH_PACKET(L,pack) sLuaMgr.PUSH_PACKET(pack,L)
3132#define PUSH_ITEM(L,item) sLuaMgr.PUSH_ITEM(static_cast<Item*>(item),L)
3133#define PUSH_GUID(L, obj) sLuaMgr.PUSH_GUID(obj,L)
3134#define PUSH_TAXIPATH(L, tp) sLuaMgr.PUSH_TAXIPATH(tp,L)
3135#define PUSH_SPELL(L, sp) sLuaMgr.PUSH_SPELL(sp,L)
3136#define PUSH_SQLFIELD(L, field) sLuaMgr.PUSH_SQLFIELD(field,L)
3137#define PUSH_SQLRESULT(L, res) sLuaMgr.PUSH_SQLRESULT(res,L)
3138
3139//I know its not a good idea to do it like that BUT it is the easiest way. I will make it better in steps:
3140#include "LUAFunctions.h"
3141#include "FunctionTables.h"
Note: See TracBrowser for help on using the browser.