├── docs ├── ElunaDoc │ ├── __init__.py │ ├── .gitignore │ ├── templates │ │ ├── enum.html │ │ ├── date.js │ │ ├── sidebar.js │ │ ├── search-index.js │ │ ├── class.html │ │ ├── index.html │ │ ├── method.html │ │ └── _base.html │ └── static │ │ ├── favicon.ico │ │ ├── eluna-logo.png │ │ ├── FiraSans-Medium.woff │ │ ├── FiraSans-Regular.woff │ │ ├── Heuristica-Italic.woff │ │ ├── SourceCodePro-Regular.woff │ │ ├── SourceSerifPro-Bold.woff │ │ ├── SourceCodePro-Semibold.woff │ │ ├── SourceSerifPro-Regular.woff │ │ ├── theme.js │ │ ├── normalize.css │ │ └── lua.min.js ├── .gitignore ├── Eluna.png ├── CONTRIBUTING.md ├── MERGING.md ├── INSTALL.md └── DOC_GEN.md ├── modules ├── .gitignore └── readme.md ├── .gitignore ├── extensions ├── StackTracePlus │ ├── LICENSE │ └── README.md ├── _Misc.ext └── ObjectVariables.ext ├── .editorconfig ├── .github └── workflows │ ├── pr-on-label.yml │ ├── create-pr.sh │ └── documentation.yml ├── lmarshal.h ├── methods ├── CustomMethodsInterface.h ├── README.md ├── TrinityCore │ ├── CorpseMethods.h │ ├── VehicleMethods.h │ ├── BigIntMethods.h │ ├── SpellMethods.h │ └── AuraMethods.h ├── CMangos │ ├── CorpseMethods.h │ ├── VehicleMethods.h │ ├── BigIntMethods.h │ └── SpellMethods.h ├── Mangos │ ├── CorpseMethods.h │ ├── VehicleMethods.h │ ├── BigIntMethods.h │ └── SpellMethods.h ├── VMangos │ ├── CorpseMethods.h │ ├── VehicleMethods.h │ ├── BigIntMethods.h │ ├── SpellMethods.h │ └── AuraMethods.h └── Methods.cpp ├── hooks ├── SpellHooks.cpp ├── BattleGroundHooks.cpp ├── VehicleHooks.cpp ├── GroupHooks.cpp ├── InstanceHooks.cpp ├── HookHelpers.h ├── GameObjectHooks.cpp ├── PacketHooks.cpp └── ItemHooks.cpp ├── ElunaCompat.h ├── ElunaTemplate.cpp ├── ElunaCompat.cpp ├── ElunaConfig.h ├── ElunaLoader.h ├── CMakeLists.txt ├── ElunaEventMgr.h ├── README.md ├── ElunaConfig.cpp ├── ElunaEventMgr.cpp ├── ElunaInstanceAI.h ├── LuaValue.h ├── ElunaIncludes.h └── ElunaUtility.h /docs/ElunaDoc/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/ElunaDoc/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea -------------------------------------------------------------------------------- /modules/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !readme.md -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the temporary "build" folder. 2 | build -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/enum.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.orig 2 | *.rej 3 | *.bak 4 | *.patch 5 | *.diff 6 | -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/date.js: -------------------------------------------------------------------------------- 1 | document.write("{{ currdate }}"); -------------------------------------------------------------------------------- /docs/Eluna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/Eluna.png -------------------------------------------------------------------------------- /docs/ElunaDoc/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/favicon.ico -------------------------------------------------------------------------------- /extensions/StackTracePlus/LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/extensions/StackTracePlus/LICENSE -------------------------------------------------------------------------------- /docs/ElunaDoc/static/eluna-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/eluna-logo.png -------------------------------------------------------------------------------- /docs/ElunaDoc/static/FiraSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/FiraSans-Medium.woff -------------------------------------------------------------------------------- /docs/ElunaDoc/static/FiraSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/FiraSans-Regular.woff -------------------------------------------------------------------------------- /docs/ElunaDoc/static/Heuristica-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/Heuristica-Italic.woff -------------------------------------------------------------------------------- /docs/ElunaDoc/static/SourceCodePro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/SourceCodePro-Regular.woff -------------------------------------------------------------------------------- /docs/ElunaDoc/static/SourceSerifPro-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/SourceSerifPro-Bold.woff -------------------------------------------------------------------------------- /docs/ElunaDoc/static/SourceCodePro-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/SourceCodePro-Semibold.woff -------------------------------------------------------------------------------- /docs/ElunaDoc/static/SourceSerifPro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyfei/Eluna/master/docs/ElunaDoc/static/SourceSerifPro-Regular.woff -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 4 5 | tab_width = 4 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/sidebar.js: -------------------------------------------------------------------------------- 1 | document.write(` 2 | {%- for method in current_class.methods %} 3 | {{ method.name }} 4 | {%- endfor %} 5 | `); -------------------------------------------------------------------------------- /.github/workflows/pr-on-label.yml: -------------------------------------------------------------------------------- 1 | name: PR Build 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: [ labeled ] 7 | 8 | jobs: 9 | call-build: 10 | if: ${{ github.event.label.name == 'build' }} 11 | name: Build 12 | uses: ./.github/workflows/build.yml -------------------------------------------------------------------------------- /lmarshal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | extern "C" { 8 | #include "lua.h" 9 | } 10 | 11 | int mar_encode(lua_State* L); 12 | int mar_decode(lua_State* L); 13 | -------------------------------------------------------------------------------- /methods/CustomMethodsInterface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2025 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CUSTOMMETHODSINT_H 8 | #define CUSTOMMETHODSINT_H 9 | 10 | #ifdef ELUNA_USE_CUSTOM_METHODS 11 | #include "CustomMethods.h" 12 | #else 13 | namespace LuaCustom 14 | { 15 | inline void RegisterCustomMethods([[maybe_unused]] Eluna* E) {} 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /extensions/_Misc.ext: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | -- This program is free software licensed under GPL version 3 4 | -- Please see the included DOCS/LICENSE.md for more information 5 | -- 6 | 7 | -- filename.ext files are loaded before normal .lua files 8 | 9 | -- Randomize random 10 | math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6))) 11 | 12 | -- Set debug.traceback to use StackTracePlus to print full stack trace 13 | local trace = require("StackTracePlus") 14 | debug.traceback = trace.stacktrace 15 | -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/search-index.js: -------------------------------------------------------------------------------- 1 | var searchIndex = {}; 2 | 3 | {% for class in classes -%} 4 | searchIndex["{{ class.name }}"] = { 5 | "items": [ 6 | [0, "", "{{ class.name }}", "{{ class.short_description|replace('\n', ' ')|replace('\"', '"')|parse_links|replace('"', '\\"') }}"], 7 | {%- for method in class.methods %} 8 | [3, "{{ method.name }}", "", "{{ method.short_description|replace('\n', ' ')|replace('\"', '"')|parse_links|replace('"', '\\"') }}"], 9 | {%- endfor %} 10 | ], 11 | "paths": [] 12 | }; 13 | {%- endfor %} 14 | 15 | initSearch(searchIndex); -------------------------------------------------------------------------------- /docs/ElunaDoc/static/theme.js: -------------------------------------------------------------------------------- 1 | const themeToggle = document.getElementById('themeToggle'); 2 | 3 | // Check if user preference exists in local storage 4 | const currentTheme = localStorage.getItem('theme'); 5 | if (currentTheme) { 6 | document.documentElement.classList.add(currentTheme); 7 | } 8 | 9 | themeToggle.addEventListener('click', () => { 10 | document.documentElement.classList.toggle('dark-mode'); 11 | 12 | // Store user preference in local storage 13 | if (document.documentElement.classList.contains('dark-mode')) { 14 | localStorage.setItem('theme', 'dark-mode'); 15 | } else { 16 | localStorage.setItem('theme', ''); 17 | } 18 | 19 | hljs.highlightAll(); 20 | }); 21 | 22 | hljs.highlightAll(); -------------------------------------------------------------------------------- /hooks/SpellHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK(EVENT, SPELL) \ 17 | auto binding = GetBinding>(REGTYPE_SPELL);\ 18 | auto key = EntryKey(EVENT, SPELL->m_spellInfo->Id);\ 19 | if (!binding->HasBindingsFor(key))\ 20 | return; 21 | 22 | #define START_HOOK_WITH_RETVAL(EVENT, SPELL, RETVAL) \ 23 | auto binding = GetBinding>(REGTYPE_SPELL);\ 24 | auto key = EntryKey(EVENT, SPELL->m_spellInfo->Id);\ 25 | if (!binding->HasBindingsFor(key))\ 26 | return RETVAL; 27 | 28 | void Eluna::OnSpellCast(Spell* pSpell, bool skipCheck) 29 | { 30 | START_HOOK(SPELL_EVENT_ON_CAST, pSpell); 31 | HookPush(pSpell); 32 | HookPush(skipCheck); 33 | CallAllFunctions(binding, key); 34 | } 35 | -------------------------------------------------------------------------------- /methods/README.md: -------------------------------------------------------------------------------- 1 | ## How to Add Custom Methods 2 | 3 | You can extend the available methods by creating a directory named `Custom` in the `Methods` directory, and adding a header file named `CustomMethods.h` inside it. 4 | 5 | Once this file is added, re-run cmake and recompile. 6 | 7 | ## Example: `Custom/CustomMethods.h` 8 | 9 | ```cpp 10 | #include "ElunaTemplate.h" 11 | #include "ElunaIncludes.h" 12 | 13 | #ifndef CUSTOMMETHODS_H 14 | #define CUSTOMMETHODS_H 15 | 16 | namespace LuaCustom 17 | { 18 | // Define a custom method that returns the players name 19 | int CustomPlayerMethod(Eluna* E, Player* player) 20 | { 21 | E->Push(player->GetName()); 22 | return 1; 23 | } 24 | 25 | // Create a custom player method registry 26 | ElunaRegister CustomPlayerMethods[] = 27 | { 28 | // Add the custom player method to the registry 29 | { "CustomPlayerMethod", &LuaCustom::CustomPlayerMethod }, 30 | }; 31 | 32 | inline void RegisterCustomMethods([[maybe_unused]] Eluna* E) 33 | { 34 | // Append all the custom Player methods to the Player object 35 | ElunaTemplate::SetMethods(E, CustomPlayerMethods); 36 | }; 37 | }; 38 | 39 | #endif 40 | ``` -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/class.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | 3 | 4 | {% block title -%} 5 | {{ current_class.name }} - {{ super() }} 6 | {%- endblock %} 7 | 8 | 9 | {% block description -%} 10 | API documentation for the {{ current_class.name }} class in the Eluna engine. 11 | {%- endblock %} 12 | 13 | 14 | {% block document_title -%} 15 | Class {{ current_class.name }} 16 | {%- endblock %} 17 | 18 | 19 | {% block sidebar %} 20 | {% endblock %} 21 | 22 | 23 | {% block content %} 24 | {{ current_class.description|parse_links }} 25 | 26 |

Methods

27 | 28 | {%- for method in current_class.methods %} 29 | 30 | 34 | 37 | 38 | {%- endfor %} 39 |
31 | 32 | {{ method.name }} 33 | 35 |

{{ method.short_description|parse_links }}

36 |
40 | {% endblock %} -------------------------------------------------------------------------------- /docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Eluna uses C for the Lua engine, C++ for the server modifications and system code, Lua for scripting side code and scripts, python for the web documentation generation - but you do not have to be able to code to help. 3 | 4 | You can contribute to Eluna in various ways: 5 | * Improve our documentation: [Documentation generation](DOC_GEN.md) 6 | * Create new features or enhance old features: [Eluna source](https://github.com/ElunaLuaEngine/Eluna) 7 | * Notify us about your concerns, problems and needs regarding Eluna: [Issue tracker](https://github.com/ElunaLuaEngine/Eluna/issues) 8 | * Create and improve Lua scripts, systems, releases and guides: [Eluna forum section](https://www.getmangos.eu/forums/forum/118-eluna-lua-engine/) 9 | 10 | ### Features and documentation 11 | To contribute to the source code and documentation within it, create a pull request for our github repository: 12 | 13 | 1. [Set up git](https://help.github.com/articles/set-up-git/) 14 | 2. [Fork](https://help.github.com/articles/fork-a-repo/) our repository: [Eluna repository](https://github.com/ElunaLuaEngine/Eluna) 15 | 3. Create a branch: `git checkout -b mybranch` 16 | 4. Make your contribution changes 17 | 5. Commit your changes `git commit -a -m "commit message"` 18 | 6. Push your commit to github: `git push` 19 | 7. Open a [pull request](https://help.github.com/articles/using-pull-requests/) 20 | -------------------------------------------------------------------------------- /.github/workflows/create-pr.sh: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/paygoc6/action-pull-request-another-repo 2 | 3 | CLONE_DIR=$(mktemp -d) 4 | 5 | echo "Setting git variables" 6 | export GITHUB_TOKEN=$API_TOKEN_GITHUB 7 | git config --global user.email "$USER_EMAIL" 8 | git config --global user.name "$USER_NAME" 9 | 10 | date=$(date '+%Y-%m-%d_%H-%M') 11 | DESTINATION_HEAD_BRANCH="$DESTINATION_HEAD_BRANCH-$date" 12 | 13 | echo "Cloning destination git repository" 14 | git clone "https://$API_TOKEN_GITHUB@github.com/$DESTINATION_REPO.git" "$CLONE_DIR" 15 | cd "$CLONE_DIR" 16 | git checkout "$DESTINATION_BASE_BRANCH" 17 | git pull origin "$DESTINATION_BASE_BRANCH" 18 | git checkout -b "$DESTINATION_HEAD_BRANCH" 19 | 20 | echo "Copying contents to git repo" 21 | mkdir -p "$CLONE_DIR/$DESTINATION_FOLDER" 22 | cp -r "$SOURCE_FOLDER/." "$CLONE_DIR/$DESTINATION_FOLDER/" 23 | 24 | echo "Adding files" 25 | git add . 26 | echo "Git status:" 27 | git status -- ":!date.js" 28 | if git status -- ":!date.js" | grep -q "Changes to be committed" 29 | then 30 | echo "Adding git commit" 31 | git commit -m "$COMMIT_MESSAGE" 32 | echo "Pushing git commit" 33 | git push -u origin "$DESTINATION_HEAD_BRANCH" 34 | echo "Creating a pull request" 35 | gh pr create -t "$PR_TITLE" \ 36 | -B "$DESTINATION_BASE_BRANCH" \ 37 | -b "" \ 38 | -H "$DESTINATION_HEAD_BRANCH" 39 | else 40 | echo "No changes detected" 41 | fi 42 | -------------------------------------------------------------------------------- /.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | name: documentation 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | - 'master' 7 | jobs: 8 | Push-Docs-To-Website: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Check out repository code 12 | uses: actions/checkout@v4 13 | - name: Set up Python 14 | uses: actions/setup-python@v4 15 | with: 16 | python-version: '3.x' 17 | architecture: 'x64' 18 | - name: Install Python dependencies 19 | run: pip install jinja2 typedecorator markdown 20 | - name: Compile documentation 21 | run: | 22 | cd ${{ github.workspace }}/docs/ 23 | python -m ElunaDoc 24 | - name: Create pull request 25 | run: | 26 | chmod +x "${GITHUB_WORKSPACE}/.github/workflows/create-pr.sh" 27 | "${GITHUB_WORKSPACE}/.github/workflows/create-pr.sh" 28 | env: 29 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} 30 | SOURCE_FOLDER: '${{ github.workspace }}/docs/build' 31 | DESTINATION_REPO: 'elunaluaengine/elunaluaengine.github.io' 32 | DESTINATION_FOLDER: '' 33 | DESTINATION_BASE_BRANCH: 'master' 34 | DESTINATION_HEAD_BRANCH: 'master' 35 | PR_TITLE: 'Update Eluna documentation' 36 | COMMIT_MESSAGE: 'Update Eluna documentation' 37 | USER_EMAIL: 'foe@elunatech.com' 38 | USER_NAME: 'Foereaper' 39 | -------------------------------------------------------------------------------- /ElunaCompat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef ELUNACOMPAT_H 8 | #define ELUNACOMPAT_H 9 | 10 | extern "C" 11 | { 12 | #include "lua.h" 13 | #include "lauxlib.h" 14 | }; 15 | 16 | /* Compatibility layer for compiling with Lua 5.1 or LuaJIT */ 17 | #if LUA_VERSION_NUM == 501 18 | int luaL_getsubtable(lua_State* L, int i, const char* name); 19 | const char* luaL_tolstring(lua_State* L, int idx, size_t* len); 20 | int lua_absindex(lua_State* L, int i); 21 | #define lua_pushglobaltable(L) \ 22 | lua_pushvalue((L), LUA_GLOBALSINDEX) 23 | #define lua_rawlen(L, idx) \ 24 | lua_objlen(L, idx) 25 | #define lua_pushunsigned(L, u) \ 26 | lua_pushinteger(L, u) 27 | #define lua_load(L, buf_read, dec_buf, str, NULL) \ 28 | lua_load(L, buf_read, dec_buf, str) 29 | 30 | #if !defined LUAJIT_VERSION 31 | void* luaL_testudata(lua_State* L, int index, const char* tname); 32 | void luaL_setmetatable(lua_State* L, const char* tname); 33 | #define luaL_setfuncs(L, l, n) luaL_register(L, NULL, l) 34 | #endif 35 | #endif 36 | 37 | #if LUA_VERSION_NUM > 502 38 | #define lua_dump(L, writer, data) \ 39 | lua_dump(L, writer, data, 0) 40 | #define lua_pushunsigned(L, u) \ 41 | lua_pushinteger(L, u) 42 | #endif 43 | #endif 44 | -------------------------------------------------------------------------------- /hooks/BattleGroundHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | using namespace Hooks; 14 | 15 | #define START_HOOK(EVENT) \ 16 | auto binding = GetBinding>(REGTYPE_BG);\ 17 | auto key = EventKey(EVENT);\ 18 | if (!binding->HasBindingsFor(key))\ 19 | return; 20 | 21 | void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) 22 | { 23 | START_HOOK(BG_EVENT_ON_START); 24 | HookPush(bg); 25 | HookPush(bgId); 26 | HookPush(instanceId); 27 | CallAllFunctions(binding, key); 28 | } 29 | 30 | void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner) 31 | { 32 | START_HOOK(BG_EVENT_ON_END); 33 | HookPush(bg); 34 | HookPush(bgId); 35 | HookPush(instanceId); 36 | HookPush(winner); 37 | CallAllFunctions(binding, key); 38 | } 39 | 40 | void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) 41 | { 42 | START_HOOK(BG_EVENT_ON_CREATE); 43 | HookPush(bg); 44 | HookPush(bgId); 45 | HookPush(instanceId); 46 | CallAllFunctions(binding, key); 47 | } 48 | 49 | void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) 50 | { 51 | START_HOOK(BG_EVENT_ON_PRE_DESTROY); 52 | HookPush(bg); 53 | HookPush(bgId); 54 | HookPush(instanceId); 55 | CallAllFunctions(binding, key); 56 | } 57 | -------------------------------------------------------------------------------- /hooks/VehicleHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | #if ELUNA_EXPANSION >= EXP_WOTLK 14 | 15 | using namespace Hooks; 16 | 17 | #define START_HOOK(EVENT) \ 18 | auto binding = GetBinding>(REGTYPE_VEHICLE);\ 19 | auto key = EventKey(EVENT);\ 20 | if (!binding->HasBindingsFor(key))\ 21 | return; 22 | 23 | void Eluna::OnInstall(Vehicle* vehicle) 24 | { 25 | START_HOOK(VEHICLE_EVENT_ON_INSTALL); 26 | HookPush(vehicle); 27 | CallAllFunctions(binding, key); 28 | } 29 | 30 | void Eluna::OnUninstall(Vehicle* vehicle) 31 | { 32 | START_HOOK(VEHICLE_EVENT_ON_UNINSTALL); 33 | HookPush(vehicle); 34 | CallAllFunctions(binding, key); 35 | } 36 | 37 | void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) 38 | { 39 | START_HOOK(VEHICLE_EVENT_ON_INSTALL_ACCESSORY); 40 | HookPush(vehicle); 41 | HookPush(accessory); 42 | CallAllFunctions(binding, key); 43 | } 44 | 45 | void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) 46 | { 47 | START_HOOK(VEHICLE_EVENT_ON_ADD_PASSENGER); 48 | HookPush(vehicle); 49 | HookPush(passenger); 50 | HookPush(seatId); 51 | CallAllFunctions(binding, key); 52 | } 53 | 54 | void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) 55 | { 56 | START_HOOK(VEHICLE_EVENT_ON_REMOVE_PASSENGER); 57 | HookPush(vehicle); 58 | HookPush(passenger); 59 | CallAllFunctions(binding, key); 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /docs/ElunaDoc/static/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} 2 | -------------------------------------------------------------------------------- /docs/ElunaDoc/static/lua.min.js: -------------------------------------------------------------------------------- 1 | /*! `lua` grammar compiled for Highlight.js 11.10.0 */ 2 | (()=>{var e=(()=>{"use strict";return e=>{const t="\\[=*\\[",a="\\]=*\\]",n={ 3 | begin:t,end:a,contains:["self"] 4 | },o=[e.COMMENT("--(?!"+t+")","$"),e.COMMENT("--"+t,a,{contains:[n],relevance:10 5 | })];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, 6 | literal:"true false nil", 7 | keyword:"and break do else elseif end for goto if in local not or repeat return then until while", 8 | built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" 9 | },contains:o.concat([{className:"function",beginKeywords:"function",end:"\\)", 10 | contains:[e.inherit(e.TITLE_MODE,{ 11 | begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", 12 | begin:"\\(",endsWithParent:!0,contains:o}].concat(o) 13 | },e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", 14 | begin:t,end:a,contains:[n],relevance:5}])}}})();hljs.registerLanguage("lua",e) 15 | })(); -------------------------------------------------------------------------------- /ElunaTemplate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | // Eluna 8 | #include "LuaEngine.h" 9 | #include "ElunaIncludes.h" 10 | #include "ElunaTemplate.h" 11 | #include "ElunaUtility.h" 12 | 13 | #if defined TRACKABLE_PTR_NAMESPACE 14 | ElunaConstrainedObjectRef GetWeakPtrFor(Aura const* obj) 15 | { 16 | #if defined ELUNA_TRINITY 17 | Map* map = obj->GetOwner()->GetMap(); 18 | #elif defined ELUNA_CMANGOS 19 | Map* map = obj->GetTarget()->GetMap(); 20 | #endif 21 | return { obj->GetWeakPtr(), map }; 22 | } 23 | ElunaConstrainedObjectRef GetWeakPtrFor(BattleGround const* obj) { return { obj->GetWeakPtr(), obj->GetBgMap() }; } 24 | ElunaConstrainedObjectRef GetWeakPtrFor(Group const* obj) { return { obj->GetWeakPtr(), nullptr }; } 25 | ElunaConstrainedObjectRef GetWeakPtrFor(Guild const* obj) { return { obj->GetWeakPtr(), nullptr }; } 26 | ElunaConstrainedObjectRef GetWeakPtrFor(Map const* obj) { return { obj->GetWeakPtr(), obj }; } 27 | ElunaConstrainedObjectRef GetWeakPtrForObjectImpl(Object const* obj) 28 | { 29 | if (obj->isType(TYPEMASK_WORLDOBJECT)) 30 | return { obj->GetWeakPtr(), static_cast(obj)->GetMap() }; 31 | 32 | if (obj->GetTypeId() == TYPEID_ITEM) 33 | if (Player const* player = static_cast(obj)->GetOwner()) 34 | return { obj->GetWeakPtr(), player->GetMap() }; 35 | 36 | // possibly dangerous item 37 | return { obj->GetWeakPtr(), nullptr }; 38 | } 39 | ElunaConstrainedObjectRef GetWeakPtrFor(Quest const* obj) { return { obj->GetWeakPtr(), nullptr }; } 40 | ElunaConstrainedObjectRef GetWeakPtrFor(Spell const* obj) { return { obj->GetWeakPtr(), obj->GetCaster()->GetMap() }; } 41 | #if ELUNA_EXPANSION >= EXP_WOTLK 42 | ElunaConstrainedObjectRef GetWeakPtrFor(Vehicle const* obj) 43 | { 44 | #if defined ELUNA_TRINITY 45 | Map* map = obj->GetBase()->GetMap(); 46 | #elif defined ELUNA_CMANGOS 47 | Map* map = obj->GetOwner()->GetMap(); 48 | #endif 49 | return { obj->GetWeakPtr(), map }; 50 | } 51 | #endif 52 | #endif 53 | -------------------------------------------------------------------------------- /modules/readme.md: -------------------------------------------------------------------------------- 1 | **This directory is used for custom C modules.** 2 | 3 | *Thanks to [@anzz1](https://github.com/anzz1) for the original work!* 4 | 5 | **Quick guide below:** 6 | - Create a subdirectory with your module name. 7 | - Add your module files (.c, .h etc). 8 | - Run cmake, this will automatically add a new project which compiles the appropriate .dll or .so file. 9 | - Place the .dll or .so file inside your lua_scripts directory. 10 | - Use "require modulename" in whichever script you use the module. 11 | 12 | 13 | **Below is an example module:** 14 | 15 | example_module.c 16 | ```C 17 | #include 18 | #include 19 | 20 | #if defined(WIN32) 21 | #define MODULEAPI __declspec(dllexport) int 22 | #else 23 | #define MODULEAPI int 24 | #endif 25 | 26 | /* 27 | * example_module.say_hello() will return the below defined message. 28 | */ 29 | const char MESSAGE[] = "hello world!"; 30 | int say_hello(lua_State *L) { 31 | lua_pushstring(L, MESSAGE); 32 | return 1; 33 | } 34 | 35 | /* 36 | * the unload function will run on the Lua state close. 37 | * this can then be used to save, exit cleanly, etc. 38 | */ 39 | int Unload(lua_State* L) { 40 | luaL_dostring(L, "print('goodbye world!');"); 41 | return 0; 42 | } 43 | 44 | /* 45 | * functions is a list of C functions and their bound function name in the Lua namespace 46 | */ 47 | static const struct luaL_Reg functions [] = { 48 | {"say_hello", say_hello}, 49 | {"unload", Unload}, 50 | {NULL, NULL} 51 | }; 52 | 53 | /* 54 | * all modules need a luaopen_xxxx function, where xxxx is the name of the module. 55 | * this is automatically executed on require. 56 | */ 57 | MODULEAPI luaopen_example_module(lua_State* L) { 58 | // register the example module and its function list in the global namespace 59 | luaL_register(L, "example_module", functions); 60 | 61 | // run the Unload function on ELUNA_EVENT_ON_LUA_STATE_CLOSE 62 | if (luaL_loadstring(L, "RegisterServerEvent(16, example_module.unload)") != 0) 63 | return lua_error(L); 64 | lua_call(L, 0, 0); 65 | return 1; 66 | } 67 | ``` 68 | This would generate into example_module.dll/.so, and you could call this as shown below: 69 | 70 | ```Lua 71 | require "example_module" 72 | 73 | print("Testing say_hello()") 74 | print(example_module.say_hello()) 75 | ``` 76 | -------------------------------------------------------------------------------- /methods/TrinityCore/CorpseMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CORPSEMETHODS_H 8 | #define CORPSEMETHODS_H 9 | 10 | /*** 11 | * The remains of a [Player] that has died. 12 | * 13 | * Inherits all methods from: [Object], [WorldObject] 14 | */ 15 | namespace LuaCorpse 16 | { 17 | /** 18 | * Returns the GUID of the [Player] that left the [Corpse] behind. 19 | * 20 | * @return ObjectGuid ownerGUID 21 | */ 22 | int GetOwnerGUID(Eluna* E, Corpse* corpse) 23 | { 24 | E->Push(corpse->GetOwnerGUID()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the time when the [Player] became a ghost and spawned this [Corpse]. 30 | * 31 | * @return uint32 ghostTime 32 | */ 33 | int GetGhostTime(Eluna* E, Corpse* corpse) 34 | { 35 | E->Push(corpse->GetGhostTime()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the [CorpseType] of a [Corpse]. 41 | * 42 | * @table 43 | * @columns [CorpseType, ID] 44 | * @values [CORPSE_BONES, 0] 45 | * @values [CORPSE_RESURRECTABLE_PVE, 1] 46 | * @values [CORPSE_RESURRECTABLE_PVP, 2] 47 | * 48 | * @return [CorpseType] corpseType 49 | */ 50 | int GetType(Eluna* E, Corpse* corpse) 51 | { 52 | E->Push(corpse->GetType()); 53 | return 1; 54 | } 55 | 56 | /** 57 | * Sets the "ghost time" to the current time. 58 | * 59 | * See [Corpse:GetGhostTime]. 60 | */ 61 | int ResetGhostTime(Eluna* /*E*/, Corpse* corpse) 62 | { 63 | corpse->ResetGhostTime(); 64 | return 0; 65 | } 66 | 67 | /** 68 | * Saves the [Corpse] to the database. 69 | */ 70 | int SaveToDB(Eluna* /*E*/, Corpse* corpse) 71 | { 72 | corpse->SaveToDB(); 73 | return 0; 74 | } 75 | 76 | ElunaRegister CorpseMethods[] = 77 | { 78 | // Getters 79 | { "GetOwnerGUID", &LuaCorpse::GetOwnerGUID }, 80 | { "GetGhostTime", &LuaCorpse::GetGhostTime }, 81 | { "GetType", &LuaCorpse::GetType }, 82 | 83 | // Other 84 | { "ResetGhostTime", &LuaCorpse::ResetGhostTime }, 85 | { "SaveToDB", &LuaCorpse::SaveToDB } 86 | }; 87 | }; 88 | #endif 89 | -------------------------------------------------------------------------------- /methods/CMangos/CorpseMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CORPSEMETHODS_H 8 | #define CORPSEMETHODS_H 9 | 10 | /*** 11 | * The remains of a [Player] that has died. 12 | * 13 | * Inherits all methods from: [Object], [WorldObject] 14 | */ 15 | namespace LuaCorpse 16 | { 17 | /** 18 | * Returns the GUID of the [Player] that left the [Corpse] behind. 19 | * 20 | * @return ObjectGuid ownerGUID 21 | */ 22 | int GetOwnerGUID(Eluna* E, Corpse* corpse) 23 | { 24 | E->Push(corpse->GetOwnerGuid()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the time when the [Player] became a ghost and spawned this [Corpse]. 30 | * 31 | * @return uint32 ghostTime 32 | */ 33 | int GetGhostTime(Eluna* E, Corpse* corpse) 34 | { 35 | E->Push(corpse->GetGhostTime()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the [CorpseType] of a [Corpse]. 41 | * 42 | * enum CorpseType 43 | * { 44 | * CORPSE_BONES = 0, 45 | * CORPSE_RESURRECTABLE_PVE = 1, 46 | * CORPSE_RESURRECTABLE_PVP = 2 47 | * }; 48 | * 49 | * @return [CorpseType] corpseType 50 | */ 51 | int GetType(Eluna* E, Corpse* corpse) 52 | { 53 | E->Push(corpse->GetType()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Sets the "ghost time" to the current time. 59 | * 60 | * See [Corpse:GetGhostTime]. 61 | */ 62 | int ResetGhostTime(Eluna* /*E*/, Corpse* corpse) 63 | { 64 | corpse->ResetGhostTime(); 65 | return 0; 66 | } 67 | 68 | /** 69 | * Saves the [Corpse] to the database. 70 | */ 71 | int SaveToDB(Eluna* /*E*/, Corpse* corpse) 72 | { 73 | corpse->SaveToDB(); 74 | return 0; 75 | } 76 | 77 | ElunaRegister CorpseMethods[] = 78 | { 79 | // Getters 80 | { "GetOwnerGUID", &LuaCorpse::GetOwnerGUID }, 81 | { "GetGhostTime", &LuaCorpse::GetGhostTime }, 82 | { "GetType", &LuaCorpse::GetType }, 83 | 84 | // Other 85 | { "ResetGhostTime", &LuaCorpse::ResetGhostTime }, 86 | { "SaveToDB", &LuaCorpse::SaveToDB } 87 | }; 88 | }; 89 | #endif 90 | -------------------------------------------------------------------------------- /methods/Mangos/CorpseMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CORPSEMETHODS_H 8 | #define CORPSEMETHODS_H 9 | 10 | /*** 11 | * The remains of a [Player] that has died. 12 | * 13 | * Inherits all methods from: [Object], [WorldObject] 14 | */ 15 | namespace LuaCorpse 16 | { 17 | /** 18 | * Returns the GUID of the [Player] that left the [Corpse] behind. 19 | * 20 | * @return ObjectGuid ownerGUID 21 | */ 22 | int GetOwnerGUID(Eluna* E, Corpse* corpse) 23 | { 24 | E->Push(corpse->GetOwnerGuid()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the time when the [Player] became a ghost and spawned this [Corpse]. 30 | * 31 | * @return uint32 ghostTime 32 | */ 33 | int GetGhostTime(Eluna* E, Corpse* corpse) 34 | { 35 | E->Push(corpse->GetGhostTime()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the [CorpseType] of a [Corpse]. 41 | * 42 | * enum CorpseType 43 | * { 44 | * CORPSE_BONES = 0, 45 | * CORPSE_RESURRECTABLE_PVE = 1, 46 | * CORPSE_RESURRECTABLE_PVP = 2 47 | * }; 48 | * 49 | * @return [CorpseType] corpseType 50 | */ 51 | int GetType(Eluna* E, Corpse* corpse) 52 | { 53 | E->Push(corpse->GetType()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Sets the "ghost time" to the current time. 59 | * 60 | * See [Corpse:GetGhostTime]. 61 | */ 62 | int ResetGhostTime(Eluna* /*E*/, Corpse* corpse) 63 | { 64 | corpse->ResetGhostTime(); 65 | return 0; 66 | } 67 | 68 | /** 69 | * Saves the [Corpse] to the database. 70 | */ 71 | int SaveToDB(Eluna* /*E*/, Corpse* corpse) 72 | { 73 | corpse->SaveToDB(); 74 | return 0; 75 | } 76 | 77 | ElunaRegister CorpseMethods[] = 78 | { 79 | // Getters 80 | { "GetOwnerGUID", &LuaCorpse::GetOwnerGUID }, 81 | { "GetGhostTime", &LuaCorpse::GetGhostTime }, 82 | { "GetType", &LuaCorpse::GetType }, 83 | 84 | // Other 85 | { "ResetGhostTime", &LuaCorpse::ResetGhostTime }, 86 | { "SaveToDB", &LuaCorpse::SaveToDB } 87 | }; 88 | }; 89 | #endif 90 | -------------------------------------------------------------------------------- /methods/VMangos/CorpseMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CORPSEMETHODS_H 8 | #define CORPSEMETHODS_H 9 | 10 | /*** 11 | * The remains of a [Player] that has died. 12 | * 13 | * Inherits all methods from: [Object], [WorldObject] 14 | */ 15 | namespace LuaCorpse 16 | { 17 | /** 18 | * Returns the GUID of the [Player] that left the [Corpse] behind. 19 | * 20 | * @return ObjectGuid ownerGUID 21 | */ 22 | int GetOwnerGUID(Eluna* E, Corpse* corpse) 23 | { 24 | E->Push(corpse->GetOwnerGuid()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the time when the [Player] became a ghost and spawned this [Corpse]. 30 | * 31 | * @return uint32 ghostTime 32 | */ 33 | int GetGhostTime(Eluna* E, Corpse* corpse) 34 | { 35 | E->Push(corpse->GetGhostTime()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the [CorpseType] of a [Corpse]. 41 | * 42 | * enum CorpseType 43 | * { 44 | * CORPSE_BONES = 0, 45 | * CORPSE_RESURRECTABLE_PVE = 1, 46 | * CORPSE_RESURRECTABLE_PVP = 2 47 | * }; 48 | * 49 | * @return [CorpseType] corpseType 50 | */ 51 | int GetType(Eluna* E, Corpse* corpse) 52 | { 53 | E->Push(corpse->GetType()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Sets the "ghost time" to the current time. 59 | * 60 | * See [Corpse:GetGhostTime]. 61 | */ 62 | int ResetGhostTime(Eluna* /*E*/, Corpse* corpse) 63 | { 64 | corpse->ResetGhostTime(); 65 | return 0; 66 | } 67 | 68 | /** 69 | * Saves the [Corpse] to the database. 70 | */ 71 | int SaveToDB(Eluna* /*E*/, Corpse* corpse) 72 | { 73 | corpse->SaveToDB(); 74 | return 0; 75 | } 76 | 77 | ElunaRegister CorpseMethods[] = 78 | { 79 | // Getters 80 | { "GetOwnerGUID", &LuaCorpse::GetOwnerGUID }, 81 | { "GetGhostTime", &LuaCorpse::GetGhostTime }, 82 | { "GetType", &LuaCorpse::GetType }, 83 | 84 | // Other 85 | { "ResetGhostTime", &LuaCorpse::ResetGhostTime }, 86 | { "SaveToDB", &LuaCorpse::SaveToDB } 87 | }; 88 | }; 89 | #endif 90 | -------------------------------------------------------------------------------- /hooks/GroupHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | using namespace Hooks; 14 | 15 | #define START_HOOK(EVENT) \ 16 | auto binding = GetBinding>(REGTYPE_GROUP);\ 17 | auto key = EventKey(EVENT);\ 18 | if (!binding->HasBindingsFor(key))\ 19 | return; 20 | 21 | #define START_HOOK_WITH_RETVAL(EVENT, RETVAL) \ 22 | auto binding = GetBinding>(REGTYPE_GROUP);\ 23 | auto key = EventKey(EVENT);\ 24 | if (!binding->HasBindingsFor(key))\ 25 | return RETVAL; 26 | 27 | void Eluna::OnAddMember(Group* group, ObjectGuid guid) 28 | { 29 | START_HOOK(GROUP_EVENT_ON_MEMBER_ADD); 30 | HookPush(group); 31 | HookPush(guid); 32 | CallAllFunctions(binding, key); 33 | } 34 | 35 | void Eluna::OnInviteMember(Group* group, ObjectGuid guid) 36 | { 37 | START_HOOK(GROUP_EVENT_ON_MEMBER_INVITE); 38 | HookPush(group); 39 | HookPush(guid); 40 | CallAllFunctions(binding, key); 41 | } 42 | 43 | void Eluna::OnRemoveMember(Group* group, ObjectGuid guid, uint8 method) 44 | { 45 | START_HOOK(GROUP_EVENT_ON_MEMBER_REMOVE); 46 | HookPush(group); 47 | HookPush(guid); 48 | HookPush(method); 49 | CallAllFunctions(binding, key); 50 | } 51 | 52 | void Eluna::OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid) 53 | { 54 | START_HOOK(GROUP_EVENT_ON_LEADER_CHANGE); 55 | HookPush(group); 56 | HookPush(newLeaderGuid); 57 | HookPush(oldLeaderGuid); 58 | CallAllFunctions(binding, key); 59 | } 60 | 61 | void Eluna::OnDisband(Group* group) 62 | { 63 | START_HOOK(GROUP_EVENT_ON_DISBAND); 64 | HookPush(group); 65 | CallAllFunctions(binding, key); 66 | } 67 | 68 | void Eluna::OnCreate(Group* group, ObjectGuid leaderGuid, GroupType groupType) 69 | { 70 | START_HOOK(GROUP_EVENT_ON_CREATE); 71 | HookPush(group); 72 | HookPush(leaderGuid); 73 | HookPush(groupType); 74 | CallAllFunctions(binding, key); 75 | } 76 | 77 | bool Eluna::OnMemberAccept(Group* group, Player* player) 78 | { 79 | START_HOOK_WITH_RETVAL(GROUP_EVENT_ON_MEMBER_ACCEPT, true); 80 | HookPush(group); 81 | HookPush(player); 82 | return CallAllFunctionsBool(binding, key, true); 83 | } 84 | -------------------------------------------------------------------------------- /ElunaCompat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "ElunaCompat.h" 8 | 9 | #if LUA_VERSION_NUM == 501 10 | const char* luaL_tolstring(lua_State* L, int idx, size_t* len) { 11 | if (!luaL_callmeta(L, idx, "__tostring")) { 12 | int t = lua_type(L, idx), tt = 0; 13 | char const* name = NULL; 14 | switch (t) { 15 | case LUA_TNIL: 16 | lua_pushliteral(L, "nil"); 17 | break; 18 | case LUA_TSTRING: 19 | case LUA_TNUMBER: 20 | lua_pushvalue(L, idx); 21 | break; 22 | case LUA_TBOOLEAN: 23 | if (lua_toboolean(L, idx)) 24 | lua_pushliteral(L, "true"); 25 | else 26 | lua_pushliteral(L, "false"); 27 | break; 28 | default: 29 | tt = luaL_getmetafield(L, idx, "__name"); 30 | name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t); 31 | lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx)); 32 | if (tt != LUA_TNIL) 33 | lua_replace(L, -2); 34 | break; 35 | } 36 | } 37 | else { 38 | if (!lua_isstring(L, -1)) 39 | luaL_error(L, "'__tostring' must return a string"); 40 | } 41 | return lua_tolstring(L, -1, len); 42 | } 43 | 44 | int luaL_getsubtable(lua_State* L, int i, const char* name) { 45 | int abs_i = lua_absindex(L, i); 46 | luaL_checkstack(L, 3, "not enough stack slots"); 47 | lua_pushstring(L, name); 48 | lua_gettable(L, abs_i); 49 | if (lua_istable(L, -1)) 50 | return 1; 51 | lua_pop(L, 1); 52 | lua_newtable(L); 53 | lua_pushstring(L, name); 54 | lua_pushvalue(L, -2); 55 | lua_settable(L, abs_i); 56 | return 0; 57 | } 58 | 59 | int lua_absindex(lua_State* L, int i) { 60 | if (i < 0 && i > LUA_REGISTRYINDEX) 61 | i += lua_gettop(L) + 1; 62 | return i; 63 | } 64 | 65 | #if !defined LUAJIT_VERSION 66 | void* luaL_testudata(lua_State* L, int index, const char* tname) { 67 | void* ud = lua_touserdata(L, index); 68 | if (ud) 69 | { 70 | if (lua_getmetatable(L, index)) 71 | { 72 | luaL_getmetatable(L, tname); 73 | if (!lua_rawequal(L, -1, -2)) 74 | ud = NULL; 75 | lua_pop(L, 2); 76 | return ud; 77 | } 78 | } 79 | return NULL; 80 | } 81 | 82 | void luaL_setmetatable(lua_State* L, const char* tname) { 83 | lua_pushstring(L, tname); 84 | lua_rawget(L, LUA_REGISTRYINDEX); 85 | lua_setmetatable(L, -2); 86 | } 87 | #endif 88 | #endif 89 | -------------------------------------------------------------------------------- /docs/MERGING.md: -------------------------------------------------------------------------------- 1 | # Merging Eluna 2 | Eluna can be added to various sources by applying the core changes required for Eluna to function. 3 | Below you find the guides for merging Eluna with each core or a fork of it. 4 | If you choose to merge you should be able to maintain and update yourself - we do not maintain your core. View Unofficial Merging below. 5 | We also do not fix any merging errors you may have, but you are free to ask about them on the [support forum](../README.md#documentation) and we may assist. 6 | 7 | We recommend using the [installation guide](INSTALL.md) especially if you are not familiar with git and updating the code. 8 | It allows you to simply use `git pull` followed by `git submodule update` to update your source and we will handle the merging and maintenance with the official core source. Naturally you still need to handle updating the database as instructed by the core's wiki or instructions. 9 | 10 | ### Merging Eluna with MaNGOS 11 | Eluna is merged with [official MaNGOS](http://getmangos.eu/) by default. 12 | 13 | ### Merging Eluna with cMaNGOS 14 | ``` 15 | git clone https://github.com/cmangos/mangos-wotlk.git 16 | cd mangos-wotlk 17 | git pull --recurse-submodules https://github.com/ElunaLuaEngine/ElunaMangosWotlk.git 18 | ``` 19 | Steps explained: 20 | 1. clone the core or fork source or get the it by other means 21 | 2. navigate to the source folder 22 | 3. pull the Eluna fork. This will fetch the repository and merge it with your source. 23 | * `--recurse-submodules` will automatically pull the submodules (Eluna repository). You may need to use `git submodule init` followed by `git submodule update` if your Eluna folder is empty 24 | * it is important that you choose the correct Eluna fork for your core andpatch: 25 | * [Eluna cMaNGOS Classic](https://github.com/ElunaLuaEngine/ElunaMangosClassic) 26 | * [Eluna cMaNGOS TBC](https://github.com/ElunaLuaEngine/ElunaMangosTbc) 27 | * [Eluna cMaNGOS WotLK](https://github.com/ElunaLuaEngine/ElunaMangosWotlk) 28 | 29 | ### Merging Eluna with TrinityCore 30 | ``` 31 | git clone https://github.com/TrinityCore/TrinityCore.git -b3.3.5 32 | cd TrinityCore 33 | git pull --recurse-submodules https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git 34 | ``` 35 | Steps explained: 36 | 1. clone the core or fork source or get the it by other means 37 | 2. navigate to the source folder 38 | 3. pull the Eluna fork. This will fetch the repository and merge it with your source. 39 | * `--recurse-submodules` will automatically pull the submodules (Eluna repository). You may need to use `git submodule init` followed by `git submodule update` if your Eluna folder is empty 40 | * it is important that you choose the correct Eluna fork for your core and patch: 41 | * [Eluna TrinityCore WotLK](https://github.com/ElunaLuaEngine/ElunaTrinityWotlk) 42 | * [Eluna TrinityCore Cataclysm](https://github.com/ElunaLuaEngine/ElunaTrinityCata) 43 | -------------------------------------------------------------------------------- /methods/TrinityCore/VehicleMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef VEHICLEMETHODS_H 8 | #define VEHICLEMETHODS_H 9 | 10 | /*** 11 | * Inherits all methods from: none 12 | */ 13 | namespace LuaVehicle 14 | { 15 | /** 16 | * Returns true if the [Unit] passenger is on board 17 | * 18 | * @param [Unit] passenger 19 | * @return bool isOnBoard 20 | */ 21 | int IsOnBoard(Eluna* E, Vehicle* vehicle) 22 | { 23 | Unit* passenger = E->CHECKOBJ(2); 24 | 25 | E->Push(passenger->IsOnVehicle(vehicle->GetBase())); 26 | return 1; 27 | } 28 | 29 | /** 30 | * Returns the [Vehicle]'s owner 31 | * 32 | * @return [Unit] owner 33 | */ 34 | int GetOwner(Eluna* E, Vehicle* vehicle) 35 | { 36 | E->Push(vehicle->GetBase()); 37 | return 1; 38 | } 39 | 40 | /** 41 | * Returns the [Vehicle]'s entry 42 | * 43 | * @return uint32 entry 44 | */ 45 | int GetEntry(Eluna* E, Vehicle* vehicle) 46 | { 47 | E->Push(vehicle->GetVehicleInfo()->ID); 48 | return 1; 49 | } 50 | 51 | /** 52 | * Returns the [Vehicle]'s passenger in the specified seat 53 | * 54 | * @param int8 seat 55 | * @return [Unit] passenger 56 | */ 57 | int GetPassenger(Eluna* E, Vehicle* vehicle) 58 | { 59 | int8 seatId = E->CHECKVAL(2); 60 | E->Push(vehicle->GetPassenger(seatId)); 61 | return 1; 62 | } 63 | 64 | /** 65 | * Adds [Unit] passenger to a specified seat in the [Vehicle] 66 | * 67 | * @param [Unit] passenger 68 | * @param int8 seat 69 | */ 70 | int AddPassenger(Eluna* E, Vehicle* vehicle) 71 | { 72 | Unit* passenger = E->CHECKOBJ(2); 73 | int8 seatId = E->CHECKVAL(3); 74 | 75 | vehicle->AddPassenger(passenger, seatId); 76 | return 0; 77 | } 78 | 79 | /** 80 | * Removes [Unit] passenger from the [Vehicle] 81 | * 82 | * @param [Unit] passenger 83 | */ 84 | int RemovePassenger(Eluna* E, Vehicle* vehicle) 85 | { 86 | Unit* passenger = E->CHECKOBJ(2); 87 | 88 | vehicle->RemovePassenger(passenger); 89 | return 0; 90 | } 91 | 92 | ElunaRegister VehicleMethods[] = 93 | { 94 | // Getters 95 | { "GetOwner", &LuaVehicle::GetOwner }, 96 | { "GetEntry", &LuaVehicle::GetEntry }, 97 | { "GetPassenger", &LuaVehicle::GetPassenger }, 98 | 99 | // Boolean 100 | { "IsOnBoard", &LuaVehicle::IsOnBoard }, 101 | 102 | // Other 103 | { "AddPassenger", &LuaVehicle::AddPassenger }, 104 | { "RemovePassenger", &LuaVehicle::RemovePassenger } 105 | }; 106 | } 107 | 108 | #endif // VEHICLEMETHODS_H 109 | -------------------------------------------------------------------------------- /ElunaConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNACONFIG_H 8 | #define _ELUNACONFIG_H 9 | 10 | #include "ElunaUtility.h" 11 | 12 | enum ElunaConfigBoolValues 13 | { 14 | CONFIG_ELUNA_ENABLED, 15 | CONFIG_ELUNA_TRACEBACK, 16 | CONFIG_ELUNA_SCRIPT_RELOADER, 17 | CONFIG_ELUNA_ENABLE_UNSAFE, 18 | CONFIG_ELUNA_ENABLE_DEPRECATED, 19 | CONFIG_ELUNA_ENABLE_RELOAD_COMMAND, 20 | CONFIG_ELUNA_BOOL_COUNT 21 | }; 22 | 23 | enum ElunaConfigStringValues 24 | { 25 | CONFIG_ELUNA_SCRIPT_PATH, 26 | CONFIG_ELUNA_ONLY_ON_MAPS, 27 | CONFIG_ELUNA_REQUIRE_PATH_EXTRA, 28 | CONFIG_ELUNA_REQUIRE_CPATH_EXTRA, 29 | CONFIG_ELUNA_STRING_COUNT 30 | }; 31 | 32 | enum ElunaConfigUInt32Values 33 | { 34 | CONFIG_ELUNA_RELOAD_SECURITY_LEVEL, 35 | CONFIG_ELUNA_INT_COUNT 36 | }; 37 | 38 | class ElunaConfig 39 | { 40 | private: 41 | ElunaConfig(); 42 | ~ElunaConfig(); 43 | ElunaConfig(ElunaConfig const&) = delete; 44 | ElunaConfig& operator=(ElunaConfig const&) = delete; 45 | 46 | public: 47 | static ElunaConfig* instance(); 48 | 49 | void Initialize(); 50 | 51 | bool GetConfig(ElunaConfigBoolValues index) const { return _configBoolValues[index]; } 52 | const std::string& GetConfig(ElunaConfigStringValues index) const { return _configStringValues[index]; } 53 | const uint32& GetConfig(ElunaConfigUInt32Values index) const { return _configUInt32Values[index]; } 54 | 55 | bool IsElunaEnabled() { return GetConfig(CONFIG_ELUNA_ENABLED); } 56 | bool UnsafeMethodsEnabled() { return GetConfig(CONFIG_ELUNA_ENABLE_UNSAFE); } 57 | bool DeprecatedMethodsEnabled() { return GetConfig(CONFIG_ELUNA_ENABLE_DEPRECATED); } 58 | bool IsReloadCommandEnabled() { return GetConfig(CONFIG_ELUNA_ENABLE_RELOAD_COMMAND); } 59 | AccountTypes GetReloadSecurityLevel() { return static_cast(GetConfig(CONFIG_ELUNA_RELOAD_SECURITY_LEVEL)); } 60 | bool ShouldMapLoadEluna(uint32 mapId); 61 | 62 | private: 63 | bool _configBoolValues[CONFIG_ELUNA_BOOL_COUNT]; 64 | std::string _configStringValues[CONFIG_ELUNA_STRING_COUNT]; 65 | uint32 _configUInt32Values[CONFIG_ELUNA_INT_COUNT]; 66 | 67 | void SetConfig(ElunaConfigBoolValues index, bool value) { _configBoolValues[index] = value; } 68 | void SetConfig(ElunaConfigStringValues index, std::string value) { _configStringValues[index] = value; } 69 | void SetConfig(ElunaConfigUInt32Values index, uint32 value) { _configUInt32Values[index] = value; } 70 | 71 | void SetConfig(ElunaConfigBoolValues index, char const* fieldname, bool defvalue); 72 | void SetConfig(ElunaConfigStringValues index, char const* fieldname, std::string defvalue); 73 | void SetConfig(ElunaConfigUInt32Values index, char const* fieldname, uint32 defvalue); 74 | 75 | void TokenizeAllowedMaps(); 76 | 77 | std::unordered_set m_allowedMaps; 78 | }; 79 | 80 | #define sElunaConfig ElunaConfig::instance() 81 | 82 | #endif //_ELUNACONFIG_H 83 | -------------------------------------------------------------------------------- /docs/INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installing and updating 2 | This page will help you get a cMaNGOS and a TrinityCore source with Eluna. 3 | 4 | If you are looking to get MaNGOS source with Eluna head over to [MaNGOS forum](http://getmangos.eu/) for the installation and updating instructions - however read this page also as it contains important information. 5 | 6 | If you are having trouble with the installation or updating the core source, head over to our [support forum](../README.md#documentation). 7 | If you are looking for a way to merge eluna with a fork of the official repositories see [merging](MERGING.md). 8 | 9 | ### Requirements and dependencies: 10 | **Eluna uses `C++11` so you need a compiler that supports it.** 11 | **Eluna can use ACE or BOOST for filesystem library.** 12 | Additionally see you desired core's documentation and installation instructions for it's requirements and dependencies. 13 | 14 | ### Installation 15 | 1. Open [git bash](http://git-scm.com/) and navigate to where you want the core source 16 | 2. Choose the git address of your desired core and patch below and clone the core with `git clone
`. 17 | For example `git clone https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git` 18 | * TrinityCore WoTLK: `https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git` 19 | * cMaNGOS Classic: `https://github.com/ElunaLuaEngine/ElunaMangosClassic.git` 20 | * cMaNGOS TBC: `https://github.com/ElunaLuaEngine/ElunaMangosTbc.git` 21 | * cMaNGOS WoTLK: `https://github.com/ElunaLuaEngine/ElunaMangosWotlk.git` 22 | 3. Navigate to the newly created source folder with `git bash` 23 | 4. Use the git command `git submodule init` followed by `git submodule update` 24 | * If you really do not get how to use git bash (and do try!) you can navigate to the `LuaEngine` folder and clone the [eluna repository](https://github.com/ElunaLuaEngine/Eluna) there. This is not recommended though. 25 | 4. Continue compiling the core normally using the official instructions 26 | * [TrinityCore](https://trinitycore.info/install/Core-Installation) 27 | * [cMaNGOS](https://github.com/cmangos/issues/wiki/Installation-Instructions) 28 | 29 | __Important!__ After compiling use the new configuration files. They contain Eluna settings and without them Eluna may not function correctly. For example you do not get any error messages or error log. 30 | 31 | After installing Eluna you should check out these: 32 | - [Eluna getting started](USAGE.md) 33 | - [Eluna features](IMPL_DETAILS.md) 34 | 35 | ### Updating 36 | Updating is essentially handled in the same manner as you would normally update the core and database. 37 | To get the newest core source code open `git bash` and navigate to your local source folder. 38 | Then execute use `git pull` followed by `git submodule init` and `git submodule update`. 39 | After updating the source you need to recompile the core normally. Simply use `CMake` if needed and compile. 40 | To update the databases refer to the core's or database's official updating documents: 41 | * [TrinityCore](http://collab.kpsn.org/display/tc/Databases+Installation) 42 | * [cMaNGOS](https://github.com/cmangos/issues/wiki/Installation-Instructions) 43 | -------------------------------------------------------------------------------- /methods/CMangos/VehicleMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef VEHICLEMETHODS_H 8 | #define VEHICLEMETHODS_H 9 | #if ELUNA_EXPANSION >= EXP_WOTLK 10 | 11 | /*** 12 | * Inherits all methods from: none 13 | */ 14 | namespace LuaVehicle 15 | { 16 | /** 17 | * Returns true if the [Unit] passenger is on board 18 | * 19 | * @param [Unit] passenger 20 | * @return bool isOnBoard 21 | */ 22 | int IsOnBoard(Eluna* E, Vehicle* vehicle) 23 | { 24 | Unit* passenger = E->CHECKOBJ(2); 25 | 26 | E->Push(vehicle->HasOnBoard(passenger)); 27 | return 1; 28 | } 29 | 30 | /** 31 | * Returns the [Vehicle]'s owner 32 | * 33 | * @return [Unit] owner 34 | */ 35 | int GetOwner(Eluna* E, Vehicle* vehicle) 36 | { 37 | E->Push(vehicle->GetOwner()); 38 | return 1; 39 | } 40 | 41 | /** 42 | * Returns the [Vehicle]'s entry 43 | * 44 | * @return uint32 entry 45 | */ 46 | int GetEntry(Eluna* E, Vehicle* vehicle) 47 | { 48 | E->Push(vehicle->GetVehicleEntry()->m_ID); 49 | return 1; 50 | } 51 | 52 | /** 53 | * Returns the [Vehicle]'s passenger in the specified seat 54 | * 55 | * @param int8 seat 56 | * @return [Unit] passenger 57 | */ 58 | int GetPassenger(Eluna* E, Vehicle* vehicle) 59 | { 60 | int8 seatId = E->CHECKVAL(2); 61 | E->Push(vehicle->GetPassenger(seatId)); 62 | return 1; 63 | } 64 | 65 | /** 66 | * Adds [Unit] passenger to a specified seat in the [Vehicle] 67 | * 68 | * @param [Unit] passenger 69 | * @param int8 seat 70 | */ 71 | int AddPassenger(Eluna* E, Vehicle* vehicle) 72 | { 73 | Unit* passenger = E->CHECKOBJ(2); 74 | int8 seatId = E->CHECKVAL(3); 75 | 76 | if (vehicle->CanBoard(passenger)) 77 | vehicle->Board(passenger, seatId); 78 | return 0; 79 | } 80 | 81 | /** 82 | * Removes [Unit] passenger from the [Vehicle] 83 | * 84 | * @param [Unit] passenger 85 | */ 86 | int RemovePassenger(Eluna* E, Vehicle* vehicle) 87 | { 88 | Unit* passenger = E->CHECKOBJ(2); 89 | 90 | vehicle->UnBoard(passenger, false); 91 | return 0; 92 | } 93 | 94 | ElunaRegister VehicleMethods[] = 95 | { 96 | // Getters 97 | { "GetOwner", &LuaVehicle::GetOwner }, 98 | { "GetEntry", &LuaVehicle::GetEntry }, 99 | { "GetPassenger", &LuaVehicle::GetPassenger }, 100 | 101 | // Boolean 102 | { "IsOnBoard", &LuaVehicle::IsOnBoard }, 103 | 104 | // Other 105 | { "AddPassenger", &LuaVehicle::AddPassenger }, 106 | { "RemovePassenger", &LuaVehicle::RemovePassenger } 107 | }; 108 | } 109 | 110 | #endif // EXPANSION >= EXP_WOTLK 111 | #endif // VEHICLEMETHODS_H 112 | -------------------------------------------------------------------------------- /methods/Mangos/VehicleMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef VEHICLEMETHODS_H 8 | #define VEHICLEMETHODS_H 9 | #ifndef CLASSIC 10 | #ifndef TBC 11 | 12 | /*** 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaVehicle 16 | { 17 | /** 18 | * Returns true if the [Unit] passenger is on board 19 | * 20 | * @param [Unit] passenger 21 | * @return bool isOnBoard 22 | */ 23 | int IsOnBoard(Eluna* E, Vehicle* vehicle) 24 | { 25 | Unit* passenger = E->CHECKOBJ(2); 26 | 27 | E->Push(vehicle->HasOnBoard(passenger)); 28 | return 1; 29 | } 30 | 31 | /** 32 | * Returns the [Vehicle]'s owner 33 | * 34 | * @return [Unit] owner 35 | */ 36 | int GetOwner(Eluna* E, Vehicle* vehicle) 37 | { 38 | E->Push(vehicle->GetOwner()); 39 | return 1; 40 | } 41 | 42 | /** 43 | * Returns the [Vehicle]'s entry 44 | * 45 | * @return uint32 entry 46 | */ 47 | int GetEntry(Eluna* E, Vehicle* vehicle) 48 | { 49 | E->Push(vehicle->GetVehicleEntry()->m_ID); 50 | return 1; 51 | } 52 | 53 | /** 54 | * Returns the [Vehicle]'s passenger in the specified seat 55 | * 56 | * @param int8 seat 57 | * @return [Unit] passenger 58 | */ 59 | int GetPassenger(Eluna* E, Vehicle* vehicle) 60 | { 61 | int8 seatId = E->CHECKVAL(2); 62 | E->Push(vehicle->GetPassenger(seatId)); 63 | return 1; 64 | } 65 | 66 | /** 67 | * Adds [Unit] passenger to a specified seat in the [Vehicle] 68 | * 69 | * @param [Unit] passenger 70 | * @param int8 seat 71 | */ 72 | int AddPassenger(Eluna* E, Vehicle* vehicle) 73 | { 74 | Unit* passenger = E->CHECKOBJ(2); 75 | int8 seatId = E->CHECKVAL(3); 76 | 77 | if (vehicle->CanBoard(passenger)) 78 | vehicle->Board(passenger, seatId); 79 | 80 | return 0; 81 | } 82 | 83 | /** 84 | * Removes [Unit] passenger from the [Vehicle] 85 | * 86 | * @param [Unit] passenger 87 | */ 88 | int RemovePassenger(Eluna* E, Vehicle* vehicle) 89 | { 90 | Unit* passenger = E->CHECKOBJ(2); 91 | 92 | vehicle->UnBoard(passenger, false); 93 | return 0; 94 | } 95 | 96 | ElunaRegister VehicleMethods[] = 97 | { 98 | // Getters 99 | { "GetOwner", &LuaVehicle::GetOwner }, 100 | { "GetEntry", &LuaVehicle::GetEntry }, 101 | { "GetPassenger", &LuaVehicle::GetPassenger }, 102 | 103 | // Boolean 104 | { "IsOnBoard", &LuaVehicle::IsOnBoard }, 105 | 106 | // Other 107 | { "AddPassenger", &LuaVehicle::AddPassenger }, 108 | { "RemovePassenger", &LuaVehicle::RemovePassenger } 109 | }; 110 | } 111 | 112 | #endif // CLASSIC 113 | #endif // TBC 114 | #endif // VEHICLEMETHODS_H 115 | -------------------------------------------------------------------------------- /ElunaLoader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * Copyright (C) 2022 - 2022 Hour of Twilight 4 | * This program is free software licensed under GPL version 3 5 | * Please see the included DOCS/LICENSE.md for more information 6 | */ 7 | 8 | #ifndef _ELUNALOADER_H 9 | #define _ELUNALOADER_H 10 | 11 | #include "LuaEngine.h" 12 | 13 | #if defined ELUNA_TRINITY 14 | #include 15 | #endif 16 | 17 | extern "C" 18 | { 19 | #include "lua.h" 20 | }; 21 | 22 | enum ElunaReloadActions 23 | { 24 | RELOAD_CACHE_ONLY = -3, 25 | RELOAD_ALL_STATES = -2, 26 | RELOAD_GLOBAL_STATE = -1 27 | }; 28 | 29 | enum ElunaScriptCacheState 30 | { 31 | SCRIPT_CACHE_NONE = 0, 32 | SCRIPT_CACHE_REINIT = 1, 33 | SCRIPT_CACHE_LOADING = 2, 34 | SCRIPT_CACHE_READY = 3 35 | }; 36 | 37 | struct LuaScript; 38 | 39 | class ElunaLoader 40 | { 41 | private: 42 | ElunaLoader(); 43 | ~ElunaLoader(); 44 | 45 | public: 46 | ElunaLoader(ElunaLoader const&) = delete; 47 | ElunaLoader(ElunaLoader&&) = delete; 48 | 49 | ElunaLoader& operator= (ElunaLoader const&) = delete; 50 | ElunaLoader& operator= (ElunaLoader&&) = delete; 51 | static ElunaLoader* instance(); 52 | 53 | void LoadScripts(); 54 | void ReloadElunaForMap(int mapId); 55 | 56 | uint8 GetCacheState() const { return m_cacheState; } 57 | const std::vector& GetLuaScripts() const { return m_scriptCache; } 58 | const std::string& GetRequirePath() const { return m_requirePath; } 59 | const std::string& GetRequireCPath() const { return m_requirecPath; } 60 | 61 | #if defined ELUNA_TRINITY 62 | // efsw file watcher 63 | void InitializeFileWatcher(); 64 | efsw::FileWatcher lua_fileWatcher; 65 | efsw::WatchID lua_scriptWatcher; 66 | #endif 67 | 68 | private: 69 | void ReloadScriptCache(); 70 | void ReadFiles(lua_State* L, std::string path); 71 | void CombineLists(); 72 | void ProcessScript(lua_State* L, std::string filename, const size_t& filesize, const std::string& fullpath, int32 mapId); 73 | bool CompileScript(lua_State* L, LuaScript& script); 74 | static int LoadBytecodeChunk(lua_State* L, uint8* bytes, size_t len, BytecodeBuffer* buffer); 75 | 76 | std::atomic m_cacheState; 77 | std::vector m_scriptCache; 78 | std::string m_requirePath; 79 | std::string m_requirecPath; 80 | std::list m_scripts; 81 | std::list m_extensions; 82 | std::thread m_reloadThread; 83 | }; 84 | 85 | #if defined ELUNA_TRINITY 86 | /// File watcher responsible for watching lua scripts 87 | class ElunaUpdateListener : public efsw::FileWatchListener 88 | { 89 | public: 90 | ElunaUpdateListener() { } 91 | virtual ~ElunaUpdateListener() { } 92 | 93 | void handleFileAction(efsw::WatchID /*watchid*/, std::string const& dir, 94 | std::string const& filename, efsw::Action /*action*/, std::string oldFilename = "") final override; 95 | }; 96 | 97 | static ElunaUpdateListener elunaUpdateListener; 98 | #endif 99 | 100 | #define sElunaLoader ElunaLoader::instance() 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /hooks/InstanceHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | #include "ElunaInstanceAI.h" 14 | 15 | using namespace Hooks; 16 | 17 | #define START_HOOK(EVENT, AI) \ 18 | auto MapEventBindings = GetBinding>(REGTYPE_MAP);\ 19 | auto InstanceEventBindings = GetBinding>(REGTYPE_INSTANCE);\ 20 | auto mapKey = EntryKey(EVENT, AI->instance->GetId());\ 21 | auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ 22 | if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ 23 | return;\ 24 | PushInstanceData(AI);\ 25 | HookPush(AI->instance) 26 | 27 | #define START_HOOK_WITH_RETVAL(EVENT, AI, RETVAL) \ 28 | auto MapEventBindings = GetBinding>(REGTYPE_MAP);\ 29 | auto InstanceEventBindings = GetBinding>(REGTYPE_INSTANCE);\ 30 | auto mapKey = EntryKey(EVENT, AI->instance->GetId());\ 31 | auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ 32 | if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ 33 | return RETVAL;\ 34 | PushInstanceData(AI);\ 35 | HookPush(AI->instance) 36 | 37 | void Eluna::OnInitialize(ElunaInstanceAI* ai) 38 | { 39 | START_HOOK(INSTANCE_EVENT_ON_INITIALIZE, ai); 40 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 41 | } 42 | 43 | void Eluna::OnLoad(ElunaInstanceAI* ai) 44 | { 45 | START_HOOK(INSTANCE_EVENT_ON_LOAD, ai); 46 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 47 | } 48 | 49 | void Eluna::OnUpdateInstance(ElunaInstanceAI* ai, uint32 diff) 50 | { 51 | START_HOOK(INSTANCE_EVENT_ON_UPDATE, ai); 52 | HookPush(diff); 53 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 54 | } 55 | 56 | void Eluna::OnPlayerEnterInstance(ElunaInstanceAI* ai, Player* player) 57 | { 58 | START_HOOK(INSTANCE_EVENT_ON_PLAYER_ENTER, ai); 59 | HookPush(player); 60 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 61 | } 62 | 63 | void Eluna::OnCreatureCreate(ElunaInstanceAI* ai, Creature* creature) 64 | { 65 | START_HOOK(INSTANCE_EVENT_ON_CREATURE_CREATE, ai); 66 | HookPush(creature); 67 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 68 | } 69 | 70 | void Eluna::OnGameObjectCreate(ElunaInstanceAI* ai, GameObject* gameobject) 71 | { 72 | START_HOOK(INSTANCE_EVENT_ON_GAMEOBJECT_CREATE, ai); 73 | HookPush(gameobject); 74 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 75 | } 76 | 77 | bool Eluna::OnCheckEncounterInProgress(ElunaInstanceAI* ai) 78 | { 79 | START_HOOK_WITH_RETVAL(INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS, ai, false); 80 | return CallAllFunctionsBool(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 81 | } 82 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CUSTOM_METHODS_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/methods/Custom/CustomMethods.h") 2 | if(EXISTS "${CUSTOM_METHODS_HEADER}") 3 | if(NOT ${LUA_VERSION} MATCHES "luajit") 4 | target_compile_definitions(lualib PUBLIC ELUNA_USE_CUSTOM_METHODS) 5 | else() 6 | target_compile_definitions(lualib INTERFACE ELUNA_USE_CUSTOM_METHODS) 7 | endif() 8 | endif() 9 | 10 | # Define variables for paths 11 | set(MODULES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/modules") 12 | if(UNIX) 13 | set(MODULES_OUTPUT_DIR "bin/lua_scripts/modules") 14 | elseif(WIN32) 15 | set(MODULES_OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin/lua_scripts/modules") 16 | set(MODULES_OUTPUT_DIR_CONF "${CMAKE_BINARY_DIR}/bin/$/lua_scripts/modules") 17 | endif() 18 | 19 | # Add Lua compatibility definition 20 | if(NOT ${LUA_VERSION} MATCHES "luajit") 21 | target_compile_definitions(lualib PUBLIC LUA_COMPAT_MODULE) 22 | endif() 23 | 24 | # Collect module directories 25 | file(GLOB_RECURSE modules_list LIST_DIRECTORIES true ${MODULES_DIR}/*) 26 | foreach(dir ${modules_list}) 27 | if(IS_DIRECTORY ${dir}) 28 | get_filename_component(module_name ${dir} NAME) 29 | 30 | # Gather all module source files 31 | file(GLOB sources_module 32 | ${dir}/*.c 33 | ${dir}/*.cpp 34 | ${dir}/*.h 35 | ${dir}/*.hpp) 36 | 37 | # Add module target and properties 38 | if(sources_module) 39 | add_library(${module_name} MODULE ${sources_module}) 40 | target_include_directories(${module_name} INTERFACE ${PUBLIC_INCLUDES}) 41 | target_link_libraries(${module_name} PUBLIC lualib) 42 | set_target_properties(${module_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${MODULES_OUTPUT_DIR}) 43 | 44 | if(WIN32) 45 | set_target_properties(${module_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${MODULES_OUTPUT_DIR}) 46 | if(MSVC) 47 | foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) 48 | string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) 49 | set_target_properties(${module_name} 50 | PROPERTIES 51 | RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${MODULES_OUTPUT_DIR_CONF} 52 | LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${MODULES_OUTPUT_DIR_CONF}) 53 | endforeach() 54 | endif() 55 | endif() 56 | 57 | message(STATUS "Added Eluna custom module: ${dir}") 58 | endif() 59 | 60 | # Append to lists 61 | list(APPEND list_module_names ${module_name}) 62 | list(APPEND list_module_sources ${sources_module}) 63 | list(APPEND list_module_includes ${dir}) 64 | endif() 65 | endforeach() 66 | 67 | # Safeguard to remove module sources from all other build targets than the modules themselves 68 | macro(remove_module_sources target) 69 | get_target_property(_sources ${target} SOURCES) 70 | if(_sources) 71 | foreach(item ${list_module_sources}) 72 | list(REMOVE_ITEM _sources ${item}) 73 | endforeach() 74 | set_property(TARGET ${target} PROPERTY SOURCES ${_sources}) 75 | endif() 76 | 77 | get_target_property(_includes ${target} INCLUDE_DIRECTORIES) 78 | if(_includes) 79 | foreach(dir ${list_module_includes}) 80 | list(REMOVE_ITEM _includes ${dir}) 81 | endforeach() 82 | set_property(TARGET ${target} PROPERTY INCLUDE_DIRECTORIES ${_includes}) 83 | endif() 84 | endmacro() 85 | 86 | foreach(target ${all_targets}) 87 | if (NOT ${target} IN_LIST list_module_names) 88 | remove_module_sources(${target}) 89 | endif() 90 | endforeach() 91 | -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | 3 | 4 | {% block document_title -%} 5 | Eluna API Documentation 6 | {%- endblock %} 7 | 8 | 9 | {% block content %} 10 |
11 |

12 | The Eluna Lua Engine© API 13 |

14 |

15 | The Eluna Lua Engine© API allows you to add your own Lua code to be executed when certain events (called "hooks") occur. 16 |

17 |

18 | Add a new in-game command, give life to creatures with new AI, or even light players who try to duel on fire! 19 | If the hook exists, you can script it. 20 |

21 | 22 |

23 | About Eluna 24 |

25 |

26 | Eluna is a Lua engine for World of Warcraft emulators. 27 | Eluna supports CMaNGOS/MaNGOS 28 | and TrinityCore. 29 |

30 |

31 | To get Eluna, simply clone your favorite version of MaNGOS or Trinity from 32 | our Github account. 33 | Each fork there has Eluna already integrated, so you just need to compile and go! 34 |

35 |

36 | Join our community Discord server to keep up with Eluna development and user provided support. 37 |

38 | 39 |

40 | Tutorials & Guides 41 |

42 |

43 | We haven't written tutorials yet, but when we do, we'll put the links here. 44 |

45 | 46 |

47 | About this documentation 48 |

49 |

50 | The layout, CSS, and Javascript code for this documentation was borrowed from doc.rust-lang.org. 51 |

52 |

53 | The documentation generator was originally written by Patman64 and is maintained by the Eluna team. 54 |

55 |
56 | 57 |

Classes

58 | 59 | {%- for class in classes %} 60 | 61 | 71 | 74 | 75 | {%- endfor %} 76 |
62 | {%- if class.fully_documented %} 63 | 64 | {%- elif class.fully_undocumented %} 65 | 66 | {%- else %} 67 | 68 | {%- endif %} 69 | {{ class.name }} 70 | 72 |

{{ class.short_description|parse_links }}

73 |
77 | {% endblock %} 78 | -------------------------------------------------------------------------------- /ElunaEventMgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_EVENT_MGR_H 8 | #define _ELUNA_EVENT_MGR_H 9 | 10 | #include "ElunaUtility.h" 11 | #include "Common.h" 12 | #if defined ELUNA_TRINITY 13 | #include "Random.h" 14 | #elif defined ELUNA_CMANGOS 15 | #include "Util/Util.h" 16 | #else 17 | #include "Util.h" 18 | #endif 19 | #include 20 | 21 | #if defined ELUNA_TRINITY 22 | #include "Define.h" 23 | #else 24 | #include "Platform/Define.h" 25 | #endif 26 | 27 | class Eluna; 28 | class EventMgr; 29 | class ElunaEventProcessor; 30 | class WorldObject; 31 | 32 | enum LuaEventState 33 | { 34 | LUAEVENT_STATE_RUN, // On next call run the function normally 35 | LUAEVENT_STATE_ABORT, // On next call unregisters reffed function and erases the data 36 | LUAEVENT_STATE_ERASE, // On next call just erases the data 37 | }; 38 | 39 | struct LuaEvent 40 | { 41 | LuaEvent(int _funcRef, uint32 _min, uint32 _max, uint32 _repeats) : 42 | min(_min), max(_max), delay(0), repeats(_repeats), funcRef(_funcRef), state(LUAEVENT_STATE_RUN) 43 | { 44 | } 45 | 46 | void SetState(LuaEventState _state) 47 | { 48 | if (state != LUAEVENT_STATE_ERASE) 49 | state = _state; 50 | } 51 | 52 | void GenerateDelay() 53 | { 54 | delay = urand(min, max); 55 | } 56 | 57 | uint32 min; // Minimum delay between event calls 58 | uint32 max; // Maximum delay between event calls 59 | uint32 delay; // The currently used waiting time 60 | uint32 repeats; // Amount of repeats to make, 0 for infinite 61 | int funcRef; // Lua function reference ID, also used as event ID 62 | LuaEventState state; // State for next call 63 | }; 64 | 65 | class ElunaEventProcessor 66 | { 67 | friend class EventMgr; 68 | 69 | public: 70 | typedef std::multimap EventList; 71 | typedef std::unordered_map EventMap; 72 | 73 | ElunaEventProcessor(Eluna* _E, WorldObject* _obj); 74 | ~ElunaEventProcessor(); 75 | 76 | void Update(uint32 diff); 77 | // removes all timed events on next tick or at tick end 78 | void SetStates(LuaEventState state); 79 | // set the event to be removed when executing 80 | void SetState(int eventId, LuaEventState state); 81 | void AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats); 82 | EventMap eventMap; 83 | 84 | private: 85 | void RemoveEvents_internal(); 86 | void AddEvent(LuaEvent* luaEvent); 87 | void RemoveEvent(LuaEvent* luaEvent); 88 | EventList eventList; 89 | uint64 m_time; 90 | WorldObject* obj; 91 | Eluna* E; 92 | }; 93 | 94 | class EventMgr 95 | { 96 | public: 97 | typedef std::unordered_set ProcessorSet; 98 | ProcessorSet processors; 99 | std::unique_ptr globalProcessor; 100 | Eluna* E; 101 | 102 | EventMgr(Eluna* _E); 103 | ~EventMgr(); 104 | 105 | // Set the state of all timed events 106 | // Execute only in safe env 107 | void SetStates(LuaEventState state); 108 | 109 | // Sets the eventId's state in all processors 110 | // Execute only in safe env 111 | void SetState(int eventId, LuaEventState state); 112 | 113 | void UpdateProcessors(uint32 diff); 114 | }; 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### [![Eluna](docs/Eluna.png)](https://github.com/ElunaLuaEngine/Eluna) 2 | # Eluna Lua Engine 3 | 4 | __Eluna Lua Engine__ is an embedded Lua scripting engine designed for World of Warcraft emulators. It provides powerful scripting capabilities and supports several popular emulators, including MaNGOS, CMaNGOS and TrinityCore. 5 | 6 | We are continually working to improve Eluna's functionality and performance, and strive to deliver an extensive, intuitive and unified scripting experience across emulators. 7 | 8 | If you encounter any issues during installation or while working on scripts, please feel free to [open an issue](https://github.com/ElunaLuaEngine/Eluna/issues) or join our community Discord server. 9 | 10 | ## Community 11 | 12 | Join the official Eluna Discord server to connect with other community members, access resources and releases, and receive support. 13 | 14 | 15 | 16 | 17 | 18 | ## Documentation 19 | 20 | For comprehensive information on using Eluna, please refer to the resources below: 21 | 22 | * [Eluna API Documentation](http://elunaluaengine.github.io/) – Detailed API documentation. 23 | * [Lua Reference Manual](http://www.lua.org/manual/5.2/) – Official Lua 5.2 reference manual. 24 | 25 | ### Additional Resources 26 | 27 | * [Installation Guide](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/INSTALL.md) – Step-by-step installation instructions. 28 | * [Getting Started](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/USAGE.md) – Basic usage and examples. 29 | * [Eluna Features](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/IMPL_DETAILS.md) – Overview of key features and implementation details. 30 | * [Hook Documentation](https://github.com/ElunaLuaEngine/Eluna/blob/master/hooks/Hooks.h) – Documentation of available hooks. 31 | * [Example Scripts](https://github.com/ElunaLuaEngine/Scripts) – Sample scripts to get you started. 32 | * [Contributing Guide](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/CONTRIBUTING.md) – Instructions for contributing to Eluna. 33 | 34 | ## Source 35 | 36 | The Eluna source code is available on GitHub: 37 | 38 | - [Eluna Source](https://github.com/ElunaLuaEngine/Eluna) 39 | 40 | ### Emulator sources and forks 41 | 42 | Below are the emulator sources and specific forks that include the required modifications for Eluna compatibility: 43 | 44 | - **TrinityCore with Eluna** - Maintained by us! 45 | - [WotLK](https://github.com/ElunaLuaEngine/ElunaTrinityWotlk) [![automerge](https://github.com/ElunaLuaEngine/ElunaTrinityWotlk/actions/workflows/auto-merge.yml/badge.svg)](https://github.com/ElunaLuaEngine/ElunaTrinityWotlk/actions/workflows/auto-merge.yml) 46 | 47 | - **MaNGOS with Eluna** 48 | - [Vanilla](https://github.com/mangoszero/server) 49 | - [TBC](https://github.com/mangosone/server) 50 | - [WoTLK](https://github.com/mangostwo/server) 51 | 52 | - **cMaNGOS with Eluna** – Maintained by __[Niam5](https://github.com/Niam5)__ 53 | - [Vanilla](https://github.com/Niam5/Eluna-CMaNGOS-Classic) 54 | - [TBC](https://github.com/Niam5/Eluna-CMaNGOS-TBC) 55 | - [WoTLK](https://github.com/Niam5/Eluna-CMaNGOS-WotLK) 56 | 57 | - **AzerothCore Eluna Module** - Third party fork maintained by AzerothCore 58 | - [AzerothCore Eluna Module](https://github.com/azerothcore/mod-eluna) 59 | 60 | ## License 61 | 62 | This project is licensed under the terms described in the [LICENSE](https://github.com/ElunaLuaEngine/Eluna/blob/master/LICENSE) file. 63 | -------------------------------------------------------------------------------- /methods/VMangos/VehicleMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef VEHICLEMETHODS_H 8 | #define VEHICLEMETHODS_H 9 | #if ELUNA_EXPANSION >= EXP_WOTLK 10 | 11 | /*** 12 | * Inherits all methods from: none 13 | */ 14 | namespace LuaVehicle 15 | { 16 | /** 17 | * Returns true if the [Unit] passenger is on board 18 | * 19 | * @param [Unit] passenger 20 | * @return bool isOnBoard 21 | */ 22 | int IsOnBoard(lua_State* L, Vehicle* vehicle) 23 | { 24 | Unit* passenger = E->CHECKOBJ(L, 2); 25 | #if defined TRINITY || AZEROTHCORE 26 | Eluna::Push(L, passenger->IsOnVehicle(vehicle->GetBase())); 27 | #else 28 | Eluna::Push(L, vehicle->HasOnBoard(passenger)); 29 | #endif 30 | return 1; 31 | } 32 | 33 | /** 34 | * Returns the [Vehicle]'s owner 35 | * 36 | * @return [Unit] owner 37 | */ 38 | int GetOwner(lua_State* L, Vehicle* vehicle) 39 | { 40 | #if defined TRINITY || AZEROTHCORE 41 | Eluna::Push(L, vehicle->GetBase()); 42 | #else 43 | Eluna::Push(L, vehicle->GetOwner()); 44 | #endif 45 | return 1; 46 | } 47 | 48 | /** 49 | * Returns the [Vehicle]'s entry 50 | * 51 | * @return uint32 entry 52 | */ 53 | int GetEntry(lua_State* L, Vehicle* vehicle) 54 | { 55 | Eluna::Push(L, vehicle->GetVehicleEntry()->m_ID); 56 | return 1; 57 | } 58 | 59 | /** 60 | * Returns the [Vehicle]'s passenger in the specified seat 61 | * 62 | * @param int8 seat 63 | * @return [Unit] passenger 64 | */ 65 | int GetPassenger(lua_State* L, Vehicle* vehicle) 66 | { 67 | int8 seatId = E->CHECKVAL(L, 2); 68 | Eluna::Push(L, vehicle->GetPassenger(seatId)); 69 | return 1; 70 | } 71 | 72 | /** 73 | * Adds [Unit] passenger to a specified seat in the [Vehicle] 74 | * 75 | * @param [Unit] passenger 76 | * @param int8 seat 77 | */ 78 | int AddPassenger(lua_State* L, Vehicle* vehicle) 79 | { 80 | Unit* passenger = E->CHECKOBJ(L, 2); 81 | int8 seatId = E->CHECKVAL(L, 3); 82 | #if defined TRINITY || AZEROTHCORE 83 | vehicle->AddPassenger(passenger, seatId); 84 | #else 85 | if (vehicle->CanBoard(passenger)) 86 | vehicle->Board(passenger, seatId); 87 | #endif 88 | return 0; 89 | } 90 | 91 | /** 92 | * Removes [Unit] passenger from the [Vehicle] 93 | * 94 | * @param [Unit] passenger 95 | */ 96 | int RemovePassenger(lua_State* L, Vehicle* vehicle) 97 | { 98 | Unit* passenger = E->CHECKOBJ(L, 2); 99 | #if defined TRINITY || AZEROTHCORE 100 | vehicle->RemovePassenger(passenger); 101 | #else 102 | vehicle->UnBoard(passenger, false); 103 | #endif 104 | return 0; 105 | } 106 | 107 | ElunaRegister VehicleMethods[] = 108 | { 109 | // Getters 110 | { "GetOwner", &LuaVehicle::GetOwner }, 111 | { "GetEntry", &LuaVehicle::GetEntry }, 112 | { "GetPassenger", &LuaVehicle::GetPassenger }, 113 | 114 | // Boolean 115 | { "IsOnBoard", &LuaVehicle::IsOnBoard }, 116 | 117 | // Other 118 | { "AddPassenger", &LuaVehicle::AddPassenger }, 119 | { "RemovePassenger", &LuaVehicle::RemovePassenger } 120 | }; 121 | } 122 | 123 | #endif // Expansion WotLK or higher 124 | #endif // VEHICLEMETHODS_H 125 | -------------------------------------------------------------------------------- /extensions/ObjectVariables.ext: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | -- This program is free software licensed under GPL version 3 4 | -- Please see the included DOCS/LICENSE.md for more information 5 | -- 6 | 7 | -- filename.ext files are loaded before normal .lua files 8 | 9 | -- 10 | -- This extension allows saving data to specific object for it's lifetime in current runtime session 11 | -- Supports Map, Player, Creature, GameObject 12 | -- 13 | -- SetData sets a value 14 | -- obj:SetData(key, val) 15 | -- 16 | -- GetData gets the data table or a specific value by key from it 17 | -- local tbl = obj:GetData() 18 | -- local val = obj:GetData(key) 19 | -- 20 | 21 | local pairs = pairs 22 | 23 | local variableStores = { 24 | Map = {}, 25 | Player = {}, 26 | Creature = {}, 27 | GameObject = {}, 28 | } 29 | 30 | local function DestroyMapData(event, obj) 31 | local map = obj:GetMapId() 32 | local inst = obj:GetInstanceId() 33 | for k,v in pairs(variableStores) do 34 | local mapdata = v[map] 35 | if mapdata then 36 | mapdata[inst] = nil 37 | end 38 | end 39 | end 40 | 41 | local function DestroyObjData(event, obj) 42 | local otype = obj:GetObjectType() 43 | local guid = otype == "Map" and 1 or obj:GetGUIDLow() 44 | 45 | if otype == "Player" then 46 | variableStores[otype][guid] = nil 47 | return 48 | end 49 | 50 | local map = obj:GetMapId() 51 | local inst = obj:GetInstanceId() 52 | local mapdata = variableStores[otype][map] 53 | if mapdata then 54 | local instancedata = mapdata[inst] 55 | if instancedata then 56 | instancedata[guid] = nil 57 | end 58 | end 59 | end 60 | 61 | local function GetData(self, field) 62 | local otype = self:GetObjectType() 63 | local guid = otype == "Map" and 1 or self:GetGUIDLow() 64 | local varStore = variableStores[otype] 65 | 66 | if otype == "Player" then 67 | varStore[guid] = varStore[guid] or {} 68 | if field ~= nil then 69 | return varStore[guid][field] 70 | end 71 | return varStore[guid] 72 | end 73 | 74 | local map = self:GetMapId() 75 | local inst = self:GetInstanceId() 76 | varStore[map] = varStore[map] or {} 77 | varStore[map][inst] = varStore[map][inst] or {} 78 | varStore[map][inst][guid] = varStore[map][inst][guid] or {} 79 | 80 | if field ~= nil then 81 | return varStore[map][inst][guid][field] 82 | end 83 | return varStore[map][inst][guid] 84 | end 85 | 86 | local function SetData(self, field, val) 87 | local otype = self:GetObjectType() 88 | local guid = otype == "Map" and 1 or self:GetGUIDLow() 89 | local varStore = variableStores[otype] 90 | 91 | if otype == "Player" then 92 | varStore[guid] = varStore[guid] or {} 93 | varStore[guid][field] = val 94 | return 95 | end 96 | 97 | local map = self:GetMapId() 98 | local inst = self:GetInstanceId() 99 | varStore[map] = varStore[map] or {} 100 | varStore[map][inst] = varStore[map][inst] or {} 101 | varStore[map][inst][guid] = varStore[map][inst][guid] or {} 102 | 103 | varStore[map][inst][guid][field] = val 104 | end 105 | 106 | for k,v in pairs(variableStores) do 107 | _G[k].GetData = GetData 108 | _G[k].SetData = SetData 109 | end 110 | 111 | RegisterPlayerEvent(4, DestroyObjData) -- logout 112 | RegisterServerEvent(31, DestroyObjData) -- creature delete 113 | RegisterServerEvent(32, DestroyObjData) -- gameobject delete 114 | RegisterServerEvent(17, DestroyMapData) -- map create 115 | RegisterServerEvent(18, DestroyMapData) -- map destroy 116 | -------------------------------------------------------------------------------- /ElunaConfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #if defined ELUNA_TRINITY 8 | #include "Config.h" 9 | #else 10 | #include "Config/Config.h" 11 | #endif 12 | #include "ElunaConfig.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | ElunaConfig::ElunaConfig() 19 | { 20 | } 21 | 22 | ElunaConfig* ElunaConfig::instance() 23 | { 24 | static ElunaConfig instance; 25 | return &instance; 26 | } 27 | 28 | ElunaConfig::~ElunaConfig() 29 | { 30 | } 31 | 32 | void ElunaConfig::Initialize() 33 | { 34 | // Load bools 35 | SetConfig(CONFIG_ELUNA_ENABLED, "Eluna.Enabled", true); 36 | SetConfig(CONFIG_ELUNA_TRACEBACK, "Eluna.TraceBack", false); 37 | SetConfig(CONFIG_ELUNA_SCRIPT_RELOADER, "Eluna.ScriptReloader", false); 38 | SetConfig(CONFIG_ELUNA_ENABLE_UNSAFE, "Eluna.UseUnsafeMethods", true); 39 | SetConfig(CONFIG_ELUNA_ENABLE_DEPRECATED, "Eluna.UseDeprecatedMethods", true); 40 | SetConfig(CONFIG_ELUNA_ENABLE_RELOAD_COMMAND, "Eluna.ReloadCommand", true); 41 | 42 | // Load strings 43 | SetConfig(CONFIG_ELUNA_SCRIPT_PATH, "Eluna.ScriptPath", "lua_scripts"); 44 | SetConfig(CONFIG_ELUNA_ONLY_ON_MAPS, "Eluna.OnlyOnMaps", ""); 45 | SetConfig(CONFIG_ELUNA_REQUIRE_PATH_EXTRA, "Eluna.RequirePaths", ""); 46 | SetConfig(CONFIG_ELUNA_REQUIRE_CPATH_EXTRA, "Eluna.RequireCPaths", ""); 47 | 48 | // Load ints 49 | SetConfig(CONFIG_ELUNA_RELOAD_SECURITY_LEVEL, "Eluna.ReloadSecurityLevel", 3); 50 | 51 | // Call extra functions 52 | TokenizeAllowedMaps(); 53 | } 54 | 55 | void ElunaConfig::SetConfig(ElunaConfigBoolValues index, char const* fieldname, bool defvalue) 56 | { 57 | #if defined ELUNA_TRINITY 58 | SetConfig(index, sConfigMgr->GetBoolDefault(fieldname, defvalue)); 59 | #else 60 | SetConfig(index, sConfig.GetBoolDefault(fieldname, defvalue)); 61 | #endif 62 | } 63 | 64 | void ElunaConfig::SetConfig(ElunaConfigStringValues index, char const* fieldname, std::string defvalue) 65 | { 66 | #if defined ELUNA_TRINITY 67 | SetConfig(index, sConfigMgr->GetStringDefault(fieldname, defvalue)); 68 | #elif defined ELUNA_CMANGOS 69 | SetConfig(index, sConfig.GetStringDefault(fieldname, defvalue)); 70 | #else 71 | SetConfig(index, sConfig.GetStringDefault(fieldname, defvalue.c_str())); 72 | #endif 73 | } 74 | 75 | void ElunaConfig::SetConfig(ElunaConfigUInt32Values index, char const* fieldname, uint32 defvalue) 76 | { 77 | #if defined ELUNA_TRINITY 78 | SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue)); 79 | #else 80 | SetConfig(index, sConfig.GetIntDefault(fieldname, defvalue)); 81 | #endif 82 | } 83 | 84 | bool ElunaConfig::ShouldMapLoadEluna(uint32 id) 85 | { 86 | // if the set is empty (all maps), return true 87 | if (m_allowedMaps.empty()) 88 | return true; 89 | 90 | // Check if the map ID is in the set 91 | return (m_allowedMaps.find(id) != m_allowedMaps.end()); 92 | } 93 | 94 | void ElunaConfig::TokenizeAllowedMaps() 95 | { 96 | // clear allowed maps 97 | m_allowedMaps.clear(); 98 | 99 | // read the configuration value into stringstream 100 | std::istringstream maps(GetConfig(CONFIG_ELUNA_ONLY_ON_MAPS)); 101 | 102 | // tokenize maps and add to allowed maps 103 | std::string mapIdStr; 104 | while (std::getline(maps, mapIdStr, ',')) 105 | { 106 | // remove spaces 107 | mapIdStr.erase(std::remove_if(mapIdStr.begin(), mapIdStr.end(), [](char c) { 108 | return std::isspace(static_cast(c)); 109 | }), mapIdStr.end()); 110 | 111 | try { 112 | uint32 mapId = std::stoul(mapIdStr); 113 | m_allowedMaps.emplace(mapId); 114 | } 115 | catch (std::exception&) { 116 | ELUNA_LOG_ERROR("[Eluna]: Error tokenizing Eluna.OnlyOnMaps, invalid config value '%s'", mapIdStr.c_str()); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/method.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | 3 | 4 | {% block title -%} 5 | {{ current_class.name }}:{{ current_method.name }} - Eluna 6 | {%- endblock %} 7 | 8 | 9 | {% block description -%} 10 | API documentation for the {{ current_class.name }}:{{ current_method.name }} method in the Eluna engine. 11 | {%- endblock %} 12 | 13 | 14 | {% block document_title -%} 15 | Method 16 | 17 | {{- current_class.name -}} 18 | : 19 | {{- current_method.name -}} 20 | 21 | {%- endblock %} 22 | 23 | 24 | {% block sidebar %} 25 |

{{ current_class.name }} Methods

26 | 27 | 38 | {% endblock %} 39 | 40 | 41 | {% block content %} 42 | {%- if current_method.warning %} 43 |
44 | Warning: {{ current_method.warning }} 45 |
46 | {%- endif %} 47 |
48 | {%- if current_method.documented %} 49 | {{ current_method.description|parse_links }} 50 | {%- else %} 51 |

This method is undocumented. Use at your own risk.

52 |

For temporary documentation, please check the LuaFunctions source file.

53 | {%- endif %} 54 | 55 | {%- if current_method.tables %} 56 |
57 | {{ current_method.tables }} 58 |
59 | {%- endif %} 60 | 61 | 62 |

63 | Synopsis 64 |

65 | {%- for prototype in current_method.prototypes %} 66 |

67 | {{ prototype }} 68 |

69 | {%- endfor %} 70 | 71 |

72 | Arguments 73 |

74 |

75 | {%- if current_method.parameters|length > 0 %} 76 | {%- for param in current_method.parameters %} 77 |

78 |
{{ param.data_type|escape|parse_data_type }} {{ param.name if param.data_type != '...' }} {{- ' (' + param.default_value + ')' if param.default_value }}
79 |
{{ param.description|parse_links if param.description else 'See method description.' }}
80 |
81 | {%- endfor %} 82 | {%- elif not current_method.documented %} 83 | Unknown. 84 | {%- else %} 85 | None. 86 | {%- endif %} 87 |

88 | 89 |

90 | Returns 91 |

92 |

93 | {%- if current_method.returned|length > 0 %} 94 | {%- for returned in current_method.returned %} 95 |

96 |
{{ returned.data_type|escape|parse_data_type }} {{ returned.name }}
97 |
{{ returned.description|parse_links if returned.description else 'See method description.' }}
98 |
99 | {%- endfor %} 100 | {%- elif not current_method.documented %} 101 | Unknown. 102 | {%- else %} 103 | Nothing. 104 | {%- endif %} 105 |

106 |
107 | {% endblock %} 108 | -------------------------------------------------------------------------------- /hooks/HookHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _HOOK_HELPERS_H 8 | #define _HOOK_HELPERS_H 9 | 10 | #include "LuaEngine.h" 11 | #include "ElunaUtility.h" 12 | 13 | /* 14 | * Sets up the stack so that event handlers can be called. 15 | * 16 | * Returns the number of functions that were pushed onto the stack. 17 | */ 18 | template 19 | int Eluna::SetupStack(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, int number_of_arguments) 20 | { 21 | ASSERT(number_of_arguments == this->push_counter); 22 | ASSERT(key1.event_id == key2.event_id); 23 | // Stack: [arguments] 24 | 25 | HookPush(key1.event_id); 26 | this->push_counter = 0; 27 | ++number_of_arguments; 28 | // Stack: [arguments], event_id 29 | 30 | int arguments_top = lua_gettop(L); 31 | int first_argument_index = arguments_top - number_of_arguments + 1; 32 | ASSERT(arguments_top >= number_of_arguments); 33 | 34 | lua_insert(L, first_argument_index); 35 | // Stack: event_id, [arguments] 36 | 37 | bindings1->PushRefsFor(key1); 38 | if (bindings2) 39 | bindings2->PushRefsFor(key2); 40 | // Stack: event_id, [arguments], [functions] 41 | 42 | int number_of_functions = lua_gettop(L) - arguments_top; 43 | return number_of_functions; 44 | } 45 | 46 | /* 47 | * Replace one of the arguments pushed before `SetupStack` with a new value. 48 | */ 49 | template 50 | void Eluna::ReplaceArgument(T value, uint8 index) 51 | { 52 | ASSERT(index < lua_gettop(L) && index > 0); 53 | // Stack: event_id, [arguments], [functions], [results] 54 | 55 | Push(value); 56 | // Stack: event_id, [arguments], [functions], [results], value 57 | 58 | lua_replace(L, index + 1); 59 | // Stack: event_id, [arguments and value], [functions], [results] 60 | } 61 | 62 | /* 63 | * Call all event handlers registered to the event ID/entry combination and ignore any results. 64 | */ 65 | template 66 | void Eluna::CallAllFunctions(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2) 67 | { 68 | int number_of_arguments = this->push_counter; 69 | // Stack: [arguments] 70 | 71 | int number_of_functions = SetupStack(bindings1, bindings2, key1, key2, number_of_arguments); 72 | // Stack: event_id, [arguments], [functions] 73 | 74 | while (number_of_functions > 0) 75 | { 76 | CallOneFunction(number_of_functions, number_of_arguments, 0); 77 | --number_of_functions; 78 | // Stack: event_id, [arguments], [functions - 1] 79 | } 80 | // Stack: event_id, [arguments] 81 | 82 | CleanUpStack(number_of_arguments); 83 | // Stack: (empty) 84 | } 85 | 86 | /* 87 | * Call all event handlers registered to the event ID/entry combination, 88 | * and returns `default_value` if ALL event handlers returned `default_value`, 89 | * otherwise returns the opposite of `default_value`. 90 | */ 91 | template 92 | bool Eluna::CallAllFunctionsBool(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, bool default_value/* = false*/) 93 | { 94 | bool result = default_value; 95 | // Note: number_of_arguments here does not count in eventID, which is pushed in SetupStack 96 | int number_of_arguments = this->push_counter; 97 | // Stack: [arguments] 98 | 99 | int number_of_functions = SetupStack(bindings1, bindings2, key1, key2, number_of_arguments); 100 | // Stack: event_id, [arguments], [functions] 101 | 102 | while (number_of_functions > 0) 103 | { 104 | int r = CallOneFunction(number_of_functions, number_of_arguments, 1); 105 | --number_of_functions; 106 | // Stack: event_id, [arguments], [functions - 1], result 107 | 108 | if (lua_isboolean(L, r) && (lua_toboolean(L, r) == 1) != default_value) 109 | result = !default_value; 110 | 111 | lua_pop(L, 1); 112 | // Stack: event_id, [arguments], [functions - 1] 113 | } 114 | // Stack: event_id, [arguments] 115 | 116 | CleanUpStack(number_of_arguments); 117 | // Stack: (empty) 118 | return result; 119 | } 120 | 121 | #endif // _HOOK_HELPERS_H 122 | -------------------------------------------------------------------------------- /methods/CMangos/BigIntMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2025 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef BIGINTMETHODS_H 8 | #define BIGINTMETHODS_H 9 | 10 | namespace LuaBigInt 11 | { 12 | template 13 | constexpr int PerformOp(Eluna* E, Op op) 14 | { 15 | T val1 = E->CHECKVAL(1); 16 | T val2 = E->CHECKVAL(2); 17 | E->Push(op(val1, val2)); 18 | return 1; 19 | } 20 | 21 | template 22 | int Add(Eluna* E, T*) 23 | { 24 | return PerformOp(E, std::plus{}); 25 | } 26 | 27 | template 28 | int Subtract(Eluna* E, T*) 29 | { 30 | return PerformOp(E, std::minus{}); 31 | } 32 | 33 | template 34 | int Multiply(Eluna* E, T*) 35 | { 36 | return PerformOp(E, std::multiplies{}); 37 | } 38 | 39 | template 40 | int Divide(Eluna* E, T*) 41 | { 42 | return PerformOp(E, std::divides{}); 43 | } 44 | 45 | template 46 | int Mod(Eluna* E, T*) 47 | { 48 | return PerformOp(E, std::modulus{}); 49 | } 50 | 51 | template 52 | int UnaryMinus(Eluna* E, T*) 53 | { 54 | T val = E->CHECKVAL(1); 55 | E->Push(std::negate{}(val)); 56 | return 1; 57 | } 58 | 59 | template 60 | int Equal(Eluna* E, T*) 61 | { 62 | return PerformOp(E, std::equal_to{}); 63 | } 64 | 65 | template 66 | int Less(Eluna* E, T*) 67 | { 68 | return PerformOp(E, std::less{}); 69 | } 70 | 71 | template 72 | int LessOrEqual(Eluna* E, T*) 73 | { 74 | return PerformOp(E, std::less_equal{}); 75 | } 76 | 77 | template 78 | int ToString(Eluna* E, T*) 79 | { 80 | T val = E->CHECKVAL(1); 81 | std::ostringstream ss; 82 | ss << val; 83 | E->Push(ss.str()); 84 | return 1; 85 | } 86 | 87 | template 88 | int Pow(Eluna* E, T*) 89 | { 90 | T val1 = E->CHECKVAL(1); 91 | T val2 = E->CHECKVAL(2); 92 | E->Push(static_cast(powl(static_cast(val1), static_cast(val2)))); 93 | return 1; 94 | } 95 | 96 | int Equal(Eluna* E, ObjectGuid*) 97 | { 98 | E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); 99 | return 1; 100 | } 101 | 102 | int ToString(Eluna* E, ObjectGuid*) 103 | { 104 | E->Push(E->CHECKVAL(1).GetString()); 105 | return 1; 106 | } 107 | 108 | ElunaRegister LongLongMethods[] = 109 | { 110 | { "__add", &LuaBigInt::Add }, 111 | { "__sub", &LuaBigInt::Subtract }, 112 | { "__mul", &LuaBigInt::Multiply }, 113 | { "__div", &LuaBigInt::Divide }, 114 | { "__mod", &LuaBigInt::Mod }, 115 | { "__unm", &LuaBigInt::UnaryMinus }, 116 | { "__eq", &LuaBigInt::Equal }, 117 | { "__lt", &LuaBigInt::Less }, 118 | { "__le", &LuaBigInt::LessOrEqual }, 119 | { "__tostring", &LuaBigInt::ToString }, 120 | { "__pow", &LuaBigInt::Pow }, 121 | }; 122 | 123 | ElunaRegister ULongLongMethods[] = 124 | { 125 | { "__sub", &LuaBigInt::Subtract }, 126 | { "__mul", &LuaBigInt::Multiply }, 127 | { "__div", &LuaBigInt::Divide }, 128 | { "__mod", &LuaBigInt::Mod }, 129 | { "__eq", &LuaBigInt::Equal }, 130 | { "__lt", &LuaBigInt::Less }, 131 | { "__le", &LuaBigInt::LessOrEqual }, 132 | { "__tostring", &LuaBigInt::ToString }, 133 | { "__pow", &LuaBigInt::Pow }, 134 | }; 135 | 136 | ElunaRegister ObjectGuidMethods[] = 137 | { 138 | { "__tostring", &LuaBigInt::ToString }, 139 | { "__eq", &LuaBigInt::Equal }, 140 | }; 141 | }; 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /methods/Mangos/BigIntMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2025 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef BIGINTMETHODS_H 8 | #define BIGINTMETHODS_H 9 | 10 | namespace LuaBigInt 11 | { 12 | template 13 | constexpr int PerformOp(Eluna* E, Op op) 14 | { 15 | T val1 = E->CHECKVAL(1); 16 | T val2 = E->CHECKVAL(2); 17 | E->Push(op(val1, val2)); 18 | return 1; 19 | } 20 | 21 | template 22 | int Add(Eluna* E, T*) 23 | { 24 | return PerformOp(E, std::plus{}); 25 | } 26 | 27 | template 28 | int Subtract(Eluna* E, T*) 29 | { 30 | return PerformOp(E, std::minus{}); 31 | } 32 | 33 | template 34 | int Multiply(Eluna* E, T*) 35 | { 36 | return PerformOp(E, std::multiplies{}); 37 | } 38 | 39 | template 40 | int Divide(Eluna* E, T*) 41 | { 42 | return PerformOp(E, std::divides{}); 43 | } 44 | 45 | template 46 | int Mod(Eluna* E, T*) 47 | { 48 | return PerformOp(E, std::modulus{}); 49 | } 50 | 51 | template 52 | int UnaryMinus(Eluna* E, T*) 53 | { 54 | T val = E->CHECKVAL(1); 55 | E->Push(std::negate{}(val)); 56 | return 1; 57 | } 58 | 59 | template 60 | int Equal(Eluna* E, T*) 61 | { 62 | return PerformOp(E, std::equal_to{}); 63 | } 64 | 65 | template 66 | int Less(Eluna* E, T*) 67 | { 68 | return PerformOp(E, std::less{}); 69 | } 70 | 71 | template 72 | int LessOrEqual(Eluna* E, T*) 73 | { 74 | return PerformOp(E, std::less_equal{}); 75 | } 76 | 77 | template 78 | int ToString(Eluna* E, T*) 79 | { 80 | T val = E->CHECKVAL(1); 81 | std::ostringstream ss; 82 | ss << val; 83 | E->Push(ss.str()); 84 | return 1; 85 | } 86 | 87 | template 88 | int Pow(Eluna* E, T*) 89 | { 90 | T val1 = E->CHECKVAL(1); 91 | T val2 = E->CHECKVAL(2); 92 | E->Push(static_cast(powl(static_cast(val1), static_cast(val2)))); 93 | return 1; 94 | } 95 | 96 | int Equal(Eluna* E, ObjectGuid*) 97 | { 98 | E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); 99 | return 1; 100 | } 101 | 102 | int ToString(Eluna* E, ObjectGuid*) 103 | { 104 | E->Push(E->CHECKVAL(1).GetString()); 105 | return 1; 106 | } 107 | 108 | ElunaRegister LongLongMethods[] = 109 | { 110 | { "__add", &LuaBigInt::Add }, 111 | { "__sub", &LuaBigInt::Subtract }, 112 | { "__mul", &LuaBigInt::Multiply }, 113 | { "__div", &LuaBigInt::Divide }, 114 | { "__mod", &LuaBigInt::Mod }, 115 | { "__unm", &LuaBigInt::UnaryMinus }, 116 | { "__eq", &LuaBigInt::Equal }, 117 | { "__lt", &LuaBigInt::Less }, 118 | { "__le", &LuaBigInt::LessOrEqual }, 119 | { "__tostring", &LuaBigInt::ToString }, 120 | { "__pow", &LuaBigInt::Pow }, 121 | }; 122 | 123 | ElunaRegister ULongLongMethods[] = 124 | { 125 | { "__sub", &LuaBigInt::Subtract }, 126 | { "__mul", &LuaBigInt::Multiply }, 127 | { "__div", &LuaBigInt::Divide }, 128 | { "__mod", &LuaBigInt::Mod }, 129 | { "__eq", &LuaBigInt::Equal }, 130 | { "__lt", &LuaBigInt::Less }, 131 | { "__le", &LuaBigInt::LessOrEqual }, 132 | { "__tostring", &LuaBigInt::ToString }, 133 | { "__pow", &LuaBigInt::Pow }, 134 | }; 135 | 136 | ElunaRegister ObjectGuidMethods[] = 137 | { 138 | { "__tostring", &LuaBigInt::ToString }, 139 | { "__eq", &LuaBigInt::Equal }, 140 | }; 141 | }; 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /methods/VMangos/BigIntMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2025 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef BIGINTMETHODS_H 8 | #define BIGINTMETHODS_H 9 | 10 | namespace LuaBigInt 11 | { 12 | template 13 | constexpr int PerformOp(Eluna* E, Op op) 14 | { 15 | T val1 = E->CHECKVAL(1); 16 | T val2 = E->CHECKVAL(2); 17 | E->Push(op(val1, val2)); 18 | return 1; 19 | } 20 | 21 | template 22 | int Add(Eluna* E, T*) 23 | { 24 | return PerformOp(E, std::plus{}); 25 | } 26 | 27 | template 28 | int Subtract(Eluna* E, T*) 29 | { 30 | return PerformOp(E, std::minus{}); 31 | } 32 | 33 | template 34 | int Multiply(Eluna* E, T*) 35 | { 36 | return PerformOp(E, std::multiplies{}); 37 | } 38 | 39 | template 40 | int Divide(Eluna* E, T*) 41 | { 42 | return PerformOp(E, std::divides{}); 43 | } 44 | 45 | template 46 | int Mod(Eluna* E, T*) 47 | { 48 | return PerformOp(E, std::modulus{}); 49 | } 50 | 51 | template 52 | int UnaryMinus(Eluna* E, T*) 53 | { 54 | T val = E->CHECKVAL(1); 55 | E->Push(std::negate{}(val)); 56 | return 1; 57 | } 58 | 59 | template 60 | int Equal(Eluna* E, T*) 61 | { 62 | return PerformOp(E, std::equal_to{}); 63 | } 64 | 65 | template 66 | int Less(Eluna* E, T*) 67 | { 68 | return PerformOp(E, std::less{}); 69 | } 70 | 71 | template 72 | int LessOrEqual(Eluna* E, T*) 73 | { 74 | return PerformOp(E, std::less_equal{}); 75 | } 76 | 77 | template 78 | int ToString(Eluna* E, T*) 79 | { 80 | T val = E->CHECKVAL(1); 81 | std::ostringstream ss; 82 | ss << val; 83 | E->Push(ss.str()); 84 | return 1; 85 | } 86 | 87 | template 88 | int Pow(Eluna* E, T*) 89 | { 90 | T val1 = E->CHECKVAL(1); 91 | T val2 = E->CHECKVAL(2); 92 | E->Push(static_cast(powl(static_cast(val1), static_cast(val2)))); 93 | return 1; 94 | } 95 | 96 | int Equal(Eluna* E, ObjectGuid*) 97 | { 98 | E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); 99 | return 1; 100 | } 101 | 102 | int ToString(Eluna* E, ObjectGuid*) 103 | { 104 | E->Push(E->CHECKVAL(1).GetString()); 105 | return 1; 106 | } 107 | 108 | ElunaRegister LongLongMethods[] = 109 | { 110 | { "__add", &LuaBigInt::Add }, 111 | { "__sub", &LuaBigInt::Subtract }, 112 | { "__mul", &LuaBigInt::Multiply }, 113 | { "__div", &LuaBigInt::Divide }, 114 | { "__mod", &LuaBigInt::Mod }, 115 | { "__unm", &LuaBigInt::UnaryMinus }, 116 | { "__eq", &LuaBigInt::Equal }, 117 | { "__lt", &LuaBigInt::Less }, 118 | { "__le", &LuaBigInt::LessOrEqual }, 119 | { "__tostring", &LuaBigInt::ToString }, 120 | { "__pow", &LuaBigInt::Pow }, 121 | }; 122 | 123 | ElunaRegister ULongLongMethods[] = 124 | { 125 | { "__sub", &LuaBigInt::Subtract }, 126 | { "__mul", &LuaBigInt::Multiply }, 127 | { "__div", &LuaBigInt::Divide }, 128 | { "__mod", &LuaBigInt::Mod }, 129 | { "__eq", &LuaBigInt::Equal }, 130 | { "__lt", &LuaBigInt::Less }, 131 | { "__le", &LuaBigInt::LessOrEqual }, 132 | { "__tostring", &LuaBigInt::ToString }, 133 | { "__pow", &LuaBigInt::Pow }, 134 | }; 135 | 136 | ElunaRegister ObjectGuidMethods[] = 137 | { 138 | { "__tostring", &LuaBigInt::ToString }, 139 | { "__eq", &LuaBigInt::Equal }, 140 | }; 141 | }; 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /methods/TrinityCore/BigIntMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2025 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef BIGINTMETHODS_H 8 | #define BIGINTMETHODS_H 9 | 10 | namespace LuaBigInt 11 | { 12 | template 13 | constexpr int PerformOp(Eluna* E, Op op) 14 | { 15 | T val1 = E->CHECKVAL(1); 16 | T val2 = E->CHECKVAL(2); 17 | E->Push(op(val1, val2)); 18 | return 1; 19 | } 20 | 21 | template 22 | int Add(Eluna* E, T*) 23 | { 24 | return PerformOp(E, std::plus{}); 25 | } 26 | 27 | template 28 | int Subtract(Eluna* E, T*) 29 | { 30 | return PerformOp(E, std::minus{}); 31 | } 32 | 33 | template 34 | int Multiply(Eluna* E, T*) 35 | { 36 | return PerformOp(E, std::multiplies{}); 37 | } 38 | 39 | template 40 | int Divide(Eluna* E, T*) 41 | { 42 | return PerformOp(E, std::divides{}); 43 | } 44 | 45 | template 46 | int Mod(Eluna* E, T*) 47 | { 48 | return PerformOp(E, std::modulus{}); 49 | } 50 | 51 | template 52 | int UnaryMinus(Eluna* E, T*) 53 | { 54 | T val = E->CHECKVAL(1); 55 | E->Push(std::negate{}(val)); 56 | return 1; 57 | } 58 | 59 | template 60 | int Equal(Eluna* E, T*) 61 | { 62 | return PerformOp(E, std::equal_to{}); 63 | } 64 | 65 | template 66 | int Less(Eluna* E, T*) 67 | { 68 | return PerformOp(E, std::less{}); 69 | } 70 | 71 | template 72 | int LessOrEqual(Eluna* E, T*) 73 | { 74 | return PerformOp(E, std::less_equal{}); 75 | } 76 | 77 | template 78 | int ToString(Eluna* E, T*) 79 | { 80 | T val = E->CHECKVAL(1); 81 | std::ostringstream ss; 82 | ss << val; 83 | E->Push(ss.str()); 84 | return 1; 85 | } 86 | 87 | template 88 | int Pow(Eluna* E, T*) 89 | { 90 | T val1 = E->CHECKVAL(1); 91 | T val2 = E->CHECKVAL(2); 92 | E->Push(static_cast(powl(static_cast(val1), static_cast(val2)))); 93 | return 1; 94 | } 95 | 96 | int Equal(Eluna* E, ObjectGuid*) 97 | { 98 | E->Push(E->CHECKVAL(1) == E->CHECKVAL(2)); 99 | return 1; 100 | } 101 | 102 | int ToString(Eluna* E, ObjectGuid*) 103 | { 104 | E->Push(E->CHECKVAL(1).ToString()); 105 | return 1; 106 | } 107 | 108 | ElunaRegister LongLongMethods[] = 109 | { 110 | { "__add", &LuaBigInt::Add }, 111 | { "__sub", &LuaBigInt::Subtract }, 112 | { "__mul", &LuaBigInt::Multiply }, 113 | { "__div", &LuaBigInt::Divide }, 114 | { "__mod", &LuaBigInt::Mod }, 115 | { "__unm", &LuaBigInt::UnaryMinus }, 116 | { "__eq", &LuaBigInt::Equal }, 117 | { "__lt", &LuaBigInt::Less }, 118 | { "__le", &LuaBigInt::LessOrEqual }, 119 | { "__tostring", &LuaBigInt::ToString }, 120 | { "__pow", &LuaBigInt::Pow }, 121 | }; 122 | 123 | ElunaRegister ULongLongMethods[] = 124 | { 125 | { "__sub", &LuaBigInt::Subtract }, 126 | { "__mul", &LuaBigInt::Multiply }, 127 | { "__div", &LuaBigInt::Divide }, 128 | { "__mod", &LuaBigInt::Mod }, 129 | { "__eq", &LuaBigInt::Equal }, 130 | { "__lt", &LuaBigInt::Less }, 131 | { "__le", &LuaBigInt::LessOrEqual }, 132 | { "__tostring", &LuaBigInt::ToString }, 133 | { "__pow", &LuaBigInt::Pow }, 134 | }; 135 | 136 | ElunaRegister ObjectGuidMethods[] = 137 | { 138 | { "__tostring", &LuaBigInt::ToString }, 139 | { "__eq", &LuaBigInt::Equal }, 140 | }; 141 | }; 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /hooks/GameObjectHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaEventMgr.h" 13 | #include "ElunaTemplate.h" 14 | 15 | using namespace Hooks; 16 | 17 | #define START_HOOK(EVENT, ENTRY) \ 18 | auto binding = GetBinding>(REGTYPE_GAMEOBJECT);\ 19 | auto key = EntryKey(EVENT, ENTRY);\ 20 | if (!binding->HasBindingsFor(key))\ 21 | return; 22 | 23 | #define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ 24 | auto binding = GetBinding>(REGTYPE_GAMEOBJECT);\ 25 | auto key = EntryKey(EVENT, ENTRY);\ 26 | if (!binding->HasBindingsFor(key))\ 27 | return RETVAL; 28 | 29 | void Eluna::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget) 30 | { 31 | START_HOOK(GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); 32 | HookPush(pCaster); 33 | HookPush(spellId); 34 | HookPush(effIndex); 35 | HookPush(pTarget); 36 | CallAllFunctions(binding, key); 37 | } 38 | 39 | void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) 40 | { 41 | START_HOOK(GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry()); 42 | HookPush(pGameObject); 43 | HookPush(diff); 44 | CallAllFunctions(binding, key); 45 | } 46 | 47 | bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest) 48 | { 49 | START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry(), false); 50 | HookPush(pPlayer); 51 | HookPush(pGameObject); 52 | HookPush(pQuest); 53 | return CallAllFunctionsBool(binding, key); 54 | } 55 | 56 | bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt) 57 | { 58 | START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry(), false); 59 | HookPush(pPlayer); 60 | HookPush(pGameObject); 61 | HookPush(pQuest); 62 | HookPush(opt); 63 | return CallAllFunctionsBool(binding, key); 64 | } 65 | 66 | void Eluna::GetDialogStatus(const Player* pPlayer, const GameObject* pGameObject) 67 | { 68 | START_HOOK(GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry()); 69 | HookPush(pPlayer); 70 | HookPush(pGameObject); 71 | CallAllFunctions(binding, key); 72 | } 73 | 74 | #if ELUNA_EXPANSION >= EXP_WOTLK 75 | void Eluna::OnDestroyed(GameObject* pGameObject, WorldObject* attacker) 76 | { 77 | START_HOOK(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()); 78 | HookPush(pGameObject); 79 | HookPush(attacker); 80 | CallAllFunctions(binding, key); 81 | } 82 | 83 | void Eluna::OnDamaged(GameObject* pGameObject, WorldObject* attacker) 84 | { 85 | START_HOOK(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()); 86 | HookPush(pGameObject); 87 | HookPush(attacker); 88 | CallAllFunctions(binding, key); 89 | } 90 | #endif 91 | 92 | void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) 93 | { 94 | START_HOOK(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()); 95 | HookPush(pGameObject); 96 | HookPush(state); 97 | CallAllFunctions(binding, key); 98 | } 99 | 100 | void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) 101 | { 102 | START_HOOK(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()); 103 | HookPush(pGameObject); 104 | HookPush(state); 105 | CallAllFunctions(binding, key); 106 | } 107 | 108 | void Eluna::OnSpawn(GameObject* pGameObject) 109 | { 110 | START_HOOK(GAMEOBJECT_EVENT_ON_SPAWN, pGameObject->GetEntry()); 111 | HookPush(pGameObject); 112 | CallAllFunctions(binding, key); 113 | } 114 | 115 | void Eluna::OnAddToWorld(GameObject* pGameObject) 116 | { 117 | START_HOOK(GAMEOBJECT_EVENT_ON_ADD, pGameObject->GetEntry()); 118 | HookPush(pGameObject); 119 | CallAllFunctions(binding, key); 120 | } 121 | 122 | void Eluna::OnRemoveFromWorld(GameObject* pGameObject) 123 | { 124 | START_HOOK(GAMEOBJECT_EVENT_ON_REMOVE, pGameObject->GetEntry()); 125 | HookPush(pGameObject); 126 | CallAllFunctions(binding, key); 127 | } 128 | 129 | bool Eluna::OnGameObjectUse(Player* pPlayer, GameObject* pGameObject) 130 | { 131 | START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_USE, pGameObject->GetEntry(), false); 132 | HookPush(pGameObject); 133 | HookPush(pPlayer); 134 | return CallAllFunctionsBool(binding, key); 135 | } 136 | -------------------------------------------------------------------------------- /extensions/StackTracePlus/README.md: -------------------------------------------------------------------------------- 1 | # StackTracePlus # 2 | 3 | [![Build Status](https://travis-ci.org/ignacio/StackTracePlus.png?branch=master)](https://travis-ci.org/ignacio/StackTracePlus) 4 | 5 | [StackTracePlus](https://github.com/ignacio/StackTracePlus) provides enhanced stack traces for [Lua 5.1, Lua 5.2][1] and [LuaJIT][2]. 6 | 7 | StackTracePlus can be used as a replacement for debug.traceback. It gives detailed information about locals, tries to guess 8 | function names when they're not available, etc, so, instead of 9 | 10 | lua5.1.exe: D:\trunk_git\sources\stacktraceplus\test\test.lua:10: attempt to concatenate a nil value 11 | stack traceback: 12 | D:\trunk_git\sources\stacktraceplus\test\test.lua:10: in function 13 | (tail call): ? 14 | D:\trunk_git\sources\stacktraceplus\test\test.lua:15: in main chunk 15 | [C]: ? 16 | 17 | you'll get 18 | 19 | lua5.1.exe: D:\trunk_git\sources\stacktraceplus\test\test.lua:10: attempt to concatenate a nil value 20 | Stack Traceback 21 | =============== 22 | (2) C function 'function: 00A8F418' 23 | (3) Lua function 'g' at file 'D:\trunk_git\sources\stacktraceplus\test\test.lua:10' (best guess) 24 | Local variables: 25 | fun = table module 26 | str = string: "hey" 27 | tb = table: 027DCBE0 {dummy:1, blah:true, foo:bar} 28 | (*temporary) = nil 29 | (*temporary) = string: "text" 30 | (*temporary) = string: "attempt to concatenate a nil value" 31 | (4) tail call 32 | (5) main chunk of file 'D:\trunk_git\sources\stacktraceplus\test\test.lua' at line 15 33 | (6) C function 'function: 002CA480' 34 | 35 | ## Usage # 36 | 37 | StackTracePlus can be used as a replacement for `debug.traceback`, as an `xpcall` error handler or even from C code. Note that 38 | only the Lua 5.1 interpreter allows the traceback function to be replaced "on the fly". LuaJIT and Lua 5.2 always calls luaL_traceback internally so there is no easy way to override that. 39 | 40 | ```lua 41 | local STP = require "StackTracePlus" 42 | 43 | debug.traceback = STP.stacktrace 44 | function test() 45 | local s = "this is a string" 46 | local n = 42 47 | local t = { foo = "bar" } 48 | local co = coroutine 49 | local cr = coroutine.create 50 | 51 | error("an error") 52 | end 53 | test() 54 | ``` 55 | 56 | That script will output (only with Lua 5.1): 57 | 58 | lua5.1: example.lua:11: an error 59 | Stack Traceback 60 | =============== 61 | (2) C function 'function: 006B5758' 62 | (3) global C function 'error' 63 | (4) Lua global 'test' at file 'example.lua:11' 64 | Local variables: 65 | s = string: "this is a string" 66 | n = number: 42 67 | t = table: 006E5220 {foo:bar} 68 | co = coroutine table 69 | cr = C function: 003C7080 70 | (5) main chunk of file 'example.lua' at line 14 71 | (6) C function 'function: 00637B30' 72 | 73 | **StackTracePlus** is aware of the usual Lua libraries, like *coroutine*, *table*, *string*, *io*, etc and functions like 74 | *print*, *pcall*, *assert*, and so on. 75 | 76 | You can also make STP aware of your own tables and functions by calling *add_known_function* and *add_known_table*. 77 | 78 | ```lua 79 | local STP = require "StackTracePlus" 80 | 81 | debug.traceback = STP.stacktrace 82 | local my_table = { 83 | f = function() end 84 | } 85 | function my_function() 86 | end 87 | 88 | function test(data, func) 89 | local s = "this is a string" 90 | 91 | error("an error") 92 | end 93 | 94 | STP.add_known_table(my_table, "A description for my_table") 95 | STP.add_known_function(my_function, "A description for my_function") 96 | 97 | test( my_table, my_function ) 98 | ``` 99 | 100 | Will output: 101 | 102 | lua5.1: ..\test\example2.lua:13: an error 103 | Stack Traceback 104 | =============== 105 | (2) C function 'function: 0073AAA8' 106 | (3) global C function 'error' 107 | (4) Lua global 'test' at file '..\test\example2.lua:13' 108 | Local variables: 109 | data = A description for my_table 110 | func = Lua function 'A description for my_function' (defined at line 7 of chunk ..\test\example2.lua) 111 | s = string: "this is a string" 112 | (5) main chunk of file '..\test\example2.lua' at line 19 113 | (6) C function 'function: 00317B30' 114 | 115 | 116 | ## Installation # 117 | The easiest way to install is with [LuaRocks][3]. 118 | 119 | - luarocks install stacktraceplus 120 | 121 | If you don't want to use LuaRocks, just copy StackTracePlus.lua to Lua's path. 122 | 123 | ## License # 124 | **StackTracePlus** is available under the MIT license. 125 | 126 | [1]: http://www.lua.org/ 127 | [2]: http://luajit.org/ 128 | [3]: http://luarocks.org/ 129 | -------------------------------------------------------------------------------- /hooks/PacketHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK_SERVER(EVENT) \ 17 | auto binding = GetBinding>(REGTYPE_SERVER);\ 18 | auto key = EventKey(EVENT);\ 19 | if (!binding->HasBindingsFor(key))\ 20 | return; 21 | 22 | #define START_HOOK_PACKET(EVENT, OPCODE) \ 23 | auto binding = GetBinding>(REGTYPE_PACKET);\ 24 | auto key = EntryKey(EVENT, OPCODE);\ 25 | if (!binding->HasBindingsFor(key))\ 26 | return; 27 | 28 | bool Eluna::OnPacketSend(WorldSession* session, const WorldPacket& packet) 29 | { 30 | bool result = true; 31 | Player* player = NULL; 32 | if (session) 33 | player = session->GetPlayer(); 34 | OnPacketSendAny(player, packet, result); 35 | OnPacketSendOne(player, packet, result); 36 | return result; 37 | } 38 | void Eluna::OnPacketSendAny(Player* player, const WorldPacket& packet, bool& result) 39 | { 40 | START_HOOK_SERVER(SERVER_EVENT_ON_PACKET_SEND); 41 | HookPush(&packet); // pushing pointer to local is fine, a copy of value will be stored, not pointer itself 42 | HookPush(player); 43 | int n = SetupStack(binding, key, 2); 44 | 45 | while (n > 0) 46 | { 47 | int r = CallOneFunction(n--, 2, 1); 48 | 49 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 50 | result = false; 51 | 52 | lua_pop(L, 1); 53 | } 54 | 55 | CleanUpStack(2); 56 | } 57 | 58 | void Eluna::OnPacketSendOne(Player* player, const WorldPacket& packet, bool& result) 59 | { 60 | START_HOOK_PACKET(PACKET_EVENT_ON_PACKET_SEND, packet.GetOpcode()); 61 | HookPush(&packet); // pushing pointer to local is fine, a copy of value will be stored, not pointer itself 62 | HookPush(player); 63 | int n = SetupStack(binding, key, 2); 64 | 65 | while (n > 0) 66 | { 67 | int r = CallOneFunction(n--, 2, 1); 68 | 69 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 70 | result = false; 71 | 72 | lua_pop(L, 1); 73 | } 74 | 75 | CleanUpStack(2); 76 | } 77 | 78 | bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) 79 | { 80 | bool result = true; 81 | Player* player = NULL; 82 | if (session) 83 | player = session->GetPlayer(); 84 | OnPacketReceiveAny(player, packet, result); 85 | OnPacketReceiveOne(player, packet, result); 86 | return result; 87 | } 88 | 89 | void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result) 90 | { 91 | START_HOOK_SERVER(SERVER_EVENT_ON_PACKET_RECEIVE); 92 | HookPush(&packet); // pushing pointer to local is fine, a copy of value will be stored, not pointer itself 93 | HookPush(player); 94 | int n = SetupStack(binding, key, 2); 95 | 96 | while (n > 0) 97 | { 98 | int r = CallOneFunction(n--, 2, 2); 99 | 100 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 101 | result = false; 102 | 103 | if (lua_isuserdata(L, r + 1)) 104 | if (WorldPacket* data = CHECKOBJ(r + 1, false)) 105 | { 106 | #if defined ELUNA_TRINITY || defined ELUNA_VMANGOS 107 | packet = std::move(*data); 108 | #else 109 | packet = *data; 110 | #endif 111 | } 112 | 113 | lua_pop(L, 2); 114 | } 115 | 116 | CleanUpStack(2); 117 | } 118 | 119 | void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) 120 | { 121 | START_HOOK_PACKET(PACKET_EVENT_ON_PACKET_RECEIVE, packet.GetOpcode()); 122 | HookPush(&packet); // pushing pointer to local is fine, a copy of value will be stored, not pointer itself 123 | HookPush(player); 124 | int n = SetupStack(binding, key, 2); 125 | 126 | while (n > 0) 127 | { 128 | int r = CallOneFunction(n--, 2, 2); 129 | 130 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 131 | result = false; 132 | 133 | if (lua_isuserdata(L, r + 1)) 134 | if (WorldPacket* data = CHECKOBJ(r + 1, false)) 135 | { 136 | #if defined ELUNA_TRINITY || defined ELUNA_VMANGOS 137 | packet = std::move(*data); 138 | #else 139 | packet = *data; 140 | #endif 141 | } 142 | 143 | lua_pop(L, 2); 144 | } 145 | 146 | CleanUpStack(2); 147 | } 148 | -------------------------------------------------------------------------------- /hooks/ItemHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK(EVENT, ENTRY) \ 17 | auto binding = GetBinding>(REGTYPE_ITEM);\ 18 | auto key = EntryKey(EVENT, ENTRY);\ 19 | if (!binding->HasBindingsFor(key))\ 20 | return; 21 | 22 | #define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ 23 | auto binding = GetBinding>(REGTYPE_ITEM);\ 24 | auto key = EntryKey(EVENT, ENTRY);\ 25 | if (!binding->HasBindingsFor(key))\ 26 | return RETVAL; 27 | 28 | void Eluna::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget) 29 | { 30 | START_HOOK(ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); 31 | HookPush(pCaster); 32 | HookPush(spellId); 33 | HookPush(effIndex); 34 | HookPush(pTarget); 35 | CallAllFunctions(binding, key); 36 | } 37 | 38 | bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) 39 | { 40 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry(), false); 41 | HookPush(pPlayer); 42 | HookPush(pItem); 43 | HookPush(pQuest); 44 | return CallAllFunctionsBool(binding, key); 45 | } 46 | 47 | bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) 48 | { 49 | ObjectGuid guid = pItem->GET_GUID(); 50 | bool castSpell = true; 51 | 52 | if (!OnItemUse(pPlayer, pItem, targets)) 53 | castSpell = false; 54 | 55 | pItem = pPlayer->GetItemByGuid(guid); 56 | if (pItem) 57 | { 58 | if (!OnItemGossip(pPlayer, pItem, targets)) 59 | castSpell = false; 60 | pItem = pPlayer->GetItemByGuid(guid); 61 | } 62 | 63 | if (pItem && castSpell) 64 | return true; 65 | 66 | // Send equip error that shows no message 67 | // This is a hack fix to stop spell casting visual bug when a spell is not cast on use 68 | pPlayer->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr); 69 | return false; 70 | } 71 | 72 | bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) 73 | { 74 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_USE, pItem->GetEntry(), true); 75 | HookPush(pPlayer); 76 | HookPush(pItem); 77 | #if defined ELUNA_TRINITY 78 | if (GameObject* target = targets.GetGOTarget()) 79 | HookPush(target); 80 | else if (Item* target = targets.GetItemTarget()) 81 | HookPush(target); 82 | else if (Corpse* target = targets.GetCorpseTarget()) 83 | HookPush(target); 84 | else if (Unit* target = targets.GetUnitTarget()) 85 | HookPush(target); 86 | else if (WorldObject* target = targets.GetObjectTarget()) 87 | HookPush(target); 88 | else 89 | HookPush(); 90 | #else 91 | if (GameObject* target = targets.getGOTarget()) 92 | HookPush(target); 93 | else if (Item* target = targets.getItemTarget()) 94 | HookPush(target); 95 | else if (Corpse* target = pPlayer->GetMap()->GetCorpse(targets.getCorpseTargetGuid())) 96 | HookPush(target); 97 | else if (Unit* target = targets.getUnitTarget()) 98 | HookPush(target); 99 | else 100 | HookPush(); 101 | #endif 102 | 103 | return CallAllFunctionsBool(binding, key, true); 104 | } 105 | 106 | bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) 107 | { 108 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_EXPIRE, pProto->ItemId, false); 109 | HookPush(pPlayer); 110 | HookPush(pProto->ItemId); 111 | return CallAllFunctionsBool(binding, key); 112 | } 113 | 114 | bool Eluna::OnRemove(Player* pPlayer, Item* pItem) 115 | { 116 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_REMOVE, pItem->GetEntry(), false); 117 | HookPush(pPlayer); 118 | HookPush(pItem); 119 | return CallAllFunctionsBool(binding, key); 120 | } 121 | 122 | void Eluna::OnAdd(Player* pPlayer, Item* pItem) 123 | { 124 | START_HOOK(ITEM_EVENT_ON_ADD, pItem->GetEntry()); 125 | HookPush(pPlayer); 126 | HookPush(pItem); 127 | CallAllFunctions(binding, key); 128 | } 129 | 130 | void Eluna::OnItemEquip(Player* pPlayer, Item* pItem, uint8 slot) 131 | { 132 | START_HOOK(ITEM_EVENT_ON_EQUIP, pItem->GetEntry()); 133 | HookPush(pPlayer); 134 | HookPush(pItem); 135 | HookPush(slot); 136 | CallAllFunctions(binding, key); 137 | } 138 | 139 | void Eluna::OnItemUnEquip(Player* pPlayer, Item* pItem, uint8 slot) 140 | { 141 | START_HOOK(ITEM_EVENT_ON_UNEQUIP, pItem->GetEntry()); 142 | HookPush(pPlayer); 143 | HookPush(pItem); 144 | HookPush(slot); 145 | CallAllFunctions(binding, key); 146 | } 147 | -------------------------------------------------------------------------------- /ElunaEventMgr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "ElunaEventMgr.h" 8 | #include "LuaEngine.h" 9 | #if !defined ELUNA_CMANGOS 10 | #include "Object.h" 11 | #else 12 | #include "Entities/Object.h" 13 | #endif 14 | 15 | extern "C" 16 | { 17 | #include "lua.h" 18 | #include "lauxlib.h" 19 | }; 20 | 21 | ElunaEventProcessor::ElunaEventProcessor(Eluna* _E, WorldObject* _obj) : m_time(0), obj(_obj), E(_E) 22 | { 23 | if (obj) 24 | E->eventMgr->processors.insert(this); 25 | } 26 | 27 | ElunaEventProcessor::~ElunaEventProcessor() 28 | { 29 | { 30 | RemoveEvents_internal(); 31 | } 32 | 33 | if (obj) 34 | E->eventMgr->processors.erase(this); 35 | } 36 | 37 | void ElunaEventProcessor::Update(uint32 diff) 38 | { 39 | m_time += diff; 40 | for (EventList::iterator it = eventList.begin(); it != eventList.end() && it->first <= m_time; it = eventList.begin()) 41 | { 42 | LuaEvent* luaEvent = it->second; 43 | eventList.erase(it); 44 | 45 | if (luaEvent->state != LUAEVENT_STATE_ERASE) 46 | eventMap.erase(luaEvent->funcRef); 47 | 48 | if (luaEvent->state == LUAEVENT_STATE_RUN) 49 | { 50 | uint32 delay = luaEvent->delay; 51 | bool remove = luaEvent->repeats == 1; 52 | if (!remove) 53 | AddEvent(luaEvent); // Reschedule before calling incase RemoveEvents used 54 | 55 | // Call the timed event 56 | if(!obj || (obj && obj->IsInWorld())) 57 | E->OnTimedEvent(luaEvent->funcRef, delay, luaEvent->repeats ? luaEvent->repeats-- : luaEvent->repeats, obj); 58 | 59 | if (!remove) 60 | continue; 61 | } 62 | 63 | // Event should be deleted (executed last time or set to be aborted) 64 | RemoveEvent(luaEvent); 65 | } 66 | } 67 | 68 | void ElunaEventProcessor::SetStates(LuaEventState state) 69 | { 70 | for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) 71 | it->second->SetState(state); 72 | if (state == LUAEVENT_STATE_ERASE) 73 | eventMap.clear(); 74 | } 75 | 76 | void ElunaEventProcessor::RemoveEvents_internal() 77 | { 78 | for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) 79 | RemoveEvent(it->second); 80 | 81 | eventList.clear(); 82 | eventMap.clear(); 83 | } 84 | 85 | void ElunaEventProcessor::SetState(int eventId, LuaEventState state) 86 | { 87 | if (eventMap.find(eventId) != eventMap.end()) 88 | eventMap[eventId]->SetState(state); 89 | if (state == LUAEVENT_STATE_ERASE) 90 | eventMap.erase(eventId); 91 | } 92 | 93 | void ElunaEventProcessor::AddEvent(LuaEvent* luaEvent) 94 | { 95 | luaEvent->GenerateDelay(); 96 | eventList.insert(std::pair(m_time + luaEvent->delay, luaEvent)); 97 | eventMap[luaEvent->funcRef] = luaEvent; 98 | } 99 | 100 | void ElunaEventProcessor::AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats) 101 | { 102 | AddEvent(new LuaEvent(funcRef, min, max, repeats)); 103 | } 104 | 105 | void ElunaEventProcessor::RemoveEvent(LuaEvent* luaEvent) 106 | { 107 | // Unreference if should and if Eluna was not yet uninitialized and if the lua state still exists 108 | if (luaEvent->state != LUAEVENT_STATE_ERASE && E->HasLuaState()) 109 | { 110 | // Free lua function ref 111 | luaL_unref(E->L, LUA_REGISTRYINDEX, luaEvent->funcRef); 112 | } 113 | delete luaEvent; 114 | } 115 | 116 | EventMgr::EventMgr(Eluna* _E) : E(_E) 117 | { 118 | globalProcessor = std::make_unique(E, nullptr); 119 | } 120 | 121 | EventMgr::~EventMgr() 122 | { 123 | if (!processors.empty()) 124 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 125 | (*it)->RemoveEvents_internal(); 126 | globalProcessor->RemoveEvents_internal(); 127 | } 128 | 129 | void EventMgr::UpdateProcessors(uint32 diff) 130 | { 131 | if (!processors.empty()) 132 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 133 | (*it)->Update(diff); 134 | globalProcessor->Update(diff); 135 | } 136 | 137 | void EventMgr::SetStates(LuaEventState state) 138 | { 139 | if (!processors.empty()) 140 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 141 | (*it)->SetStates(state); 142 | globalProcessor->SetStates(state); 143 | } 144 | 145 | void EventMgr::SetState(int eventId, LuaEventState state) 146 | { 147 | if (!processors.empty()) 148 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 149 | (*it)->SetState(eventId, state); 150 | globalProcessor->SetState(eventId, state); 151 | } 152 | -------------------------------------------------------------------------------- /docs/ElunaDoc/templates/_base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% block title %}Eluna API{% endblock %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 | 28 | 29 | 40 | 41 | 66 | 67 |
68 |

69 | {% block document_title %}Title Missing{% endblock %} 70 | 71 | 72 | [-] 73 | [+] 74 | 75 | 76 |

77 | 78 | {% block content %}

Content missing.

{% endblock %} 79 |
80 | 81 | 82 | 83 | 84 | 85 | 115 | 116 | 119 | 120 | 121 | 122 | 123 |
Generated on
124 |
© 2010 - 2024 Eluna Lua Engine
125 | 126 | 127 | -------------------------------------------------------------------------------- /methods/Methods.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | // Eluna 8 | #include "LuaEngine.h" 9 | #include "ElunaEventMgr.h" 10 | #include "ElunaIncludes.h" 11 | #include "ElunaTemplate.h" 12 | #include "ElunaUtility.h" 13 | 14 | // Method includes 15 | #include "GlobalMethods.h" 16 | #include "ObjectMethods.h" 17 | #include "WorldObjectMethods.h" 18 | #include "UnitMethods.h" 19 | #include "PlayerMethods.h" 20 | #include "CreatureMethods.h" 21 | #include "GroupMethods.h" 22 | #include "GuildMethods.h" 23 | #include "GameObjectMethods.h" 24 | #include "ElunaQueryMethods.h" 25 | #include "AuraMethods.h" 26 | #include "ItemMethods.h" 27 | #include "WorldPacketMethods.h" 28 | #include "SpellMethods.h" 29 | #include "QuestMethods.h" 30 | #include "MapMethods.h" 31 | #include "CorpseMethods.h" 32 | #include "VehicleMethods.h" 33 | #include "BattleGroundMethods.h" 34 | #include "BigIntMethods.h" 35 | #include "CustomMethodsInterface.h" 36 | 37 | void RegisterMethods(Eluna* E) 38 | { 39 | ElunaTemplate<>::SetMethods(E, LuaGlobalFunctions::GlobalMethods); 40 | 41 | ElunaTemplate::Register(E, "Object"); 42 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 43 | 44 | ElunaTemplate::Register(E, "WorldObject"); 45 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 46 | ElunaTemplate::SetMethods(E, LuaWorldObject::WorldObjectMethods); 47 | 48 | ElunaTemplate::Register(E, "Unit"); 49 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 50 | ElunaTemplate::SetMethods(E, LuaWorldObject::WorldObjectMethods); 51 | ElunaTemplate::SetMethods(E, LuaUnit::UnitMethods); 52 | 53 | ElunaTemplate::Register(E, "Player"); 54 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 55 | ElunaTemplate::SetMethods(E, LuaWorldObject::WorldObjectMethods); 56 | ElunaTemplate::SetMethods(E, LuaUnit::UnitMethods); 57 | ElunaTemplate::SetMethods(E, LuaPlayer::PlayerMethods); 58 | 59 | ElunaTemplate::Register(E, "Creature"); 60 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 61 | ElunaTemplate::SetMethods(E, LuaWorldObject::WorldObjectMethods); 62 | ElunaTemplate::SetMethods(E, LuaUnit::UnitMethods); 63 | ElunaTemplate::SetMethods(E, LuaCreature::CreatureMethods); 64 | 65 | ElunaTemplate::Register(E, "GameObject"); 66 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 67 | ElunaTemplate::SetMethods(E, LuaWorldObject::WorldObjectMethods); 68 | ElunaTemplate::SetMethods(E, LuaGameObject::GameObjectMethods); 69 | 70 | ElunaTemplate::Register(E, "Corpse"); 71 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 72 | ElunaTemplate::SetMethods(E, LuaWorldObject::WorldObjectMethods); 73 | ElunaTemplate::SetMethods(E, LuaCorpse::CorpseMethods); 74 | 75 | ElunaTemplate::Register(E, "Item"); 76 | ElunaTemplate::SetMethods(E, LuaObject::ObjectMethods); 77 | ElunaTemplate::SetMethods(E, LuaItem::ItemMethods); 78 | 79 | #if ELUNA_EXPANSION >= EXP_WOTLK 80 | ElunaTemplate::Register(E, "Vehicle"); 81 | ElunaTemplate::SetMethods(E, LuaVehicle::VehicleMethods); 82 | #endif 83 | 84 | ElunaTemplate::Register(E, "Group"); 85 | ElunaTemplate::SetMethods(E, LuaGroup::GroupMethods); 86 | 87 | ElunaTemplate::Register(E, "Guild"); 88 | ElunaTemplate::SetMethods(E, LuaGuild::GuildMethods); 89 | 90 | ElunaTemplate::Register(E, "Aura"); 91 | ElunaTemplate::SetMethods(E, LuaAura::AuraMethods); 92 | 93 | ElunaTemplate::Register(E, "Spell"); 94 | ElunaTemplate::SetMethods(E, LuaSpell::SpellMethods); 95 | 96 | ElunaTemplate::Register(E, "Quest"); 97 | ElunaTemplate::SetMethods(E, LuaQuest::QuestMethods); 98 | 99 | ElunaTemplate::Register(E, "Map"); 100 | ElunaTemplate::SetMethods(E, LuaMap::MapMethods); 101 | 102 | ElunaTemplate::Register(E, "BattleGround"); 103 | ElunaTemplate::SetMethods(E, LuaBattleGround::BattleGroundMethods); 104 | 105 | ElunaTemplate::Register(E, "WorldPacket"); 106 | ElunaTemplate::SetMethods(E, LuaPacket::PacketMethods); 107 | 108 | ElunaTemplate::Register(E, "ElunaQuery"); 109 | ElunaTemplate::SetMethods(E, LuaQuery::QueryMethods); 110 | 111 | ElunaTemplate::Register(E, "long long"); 112 | ElunaTemplate::SetMethods(E, LuaBigInt::LongLongMethods); 113 | 114 | ElunaTemplate::Register(E, "unsigned long long"); 115 | ElunaTemplate::SetMethods(E, LuaBigInt::ULongLongMethods); 116 | 117 | ElunaTemplate::Register(E, "ObjectGuid"); 118 | ElunaTemplate::SetMethods(E, LuaBigInt::ObjectGuidMethods); 119 | 120 | LuaCustom::RegisterCustomMethods(E); 121 | 122 | LuaVal::Register(E->L); 123 | } 124 | -------------------------------------------------------------------------------- /ElunaInstanceAI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_INSTANCE_DATA_H 8 | #define _ELUNA_INSTANCE_DATA_H 9 | 10 | #include "LuaEngine.h" 11 | #if defined ELUNA_TRINITY 12 | #include "InstanceScript.h" 13 | #include "Map.h" 14 | #elif defined ELUNA_CMANGOS 15 | #include "Maps/InstanceData.h" 16 | #else 17 | #include "InstanceData.h" 18 | #endif 19 | 20 | /* 21 | * This class is a small wrapper around `InstanceData`, 22 | * allowing instances to be scripted with Eluna. 23 | * 24 | * 25 | * Note 1 26 | * ====== 27 | * 28 | * Instances of `ElunaInstanceAI` are owned by the core, so they 29 | * are not deleted when Eluna is reloaded. Thus `Load` is only called 30 | * by the core once, no matter how many times Eluna is reloaded. 31 | * 32 | * However, when Eluna reloads, all instance data in Eluna is lost. 33 | * So the solution is as follows: 34 | * 35 | * 1. Store the last save data in the member var `lastSaveData`. 36 | * 37 | * At first this is just the data given to us by the core when it calls `Load`, 38 | * but later on once we start saving new data this is from Eluna. 39 | * 40 | * 2. When retrieving instance data from Eluna, check if it's missing. 41 | * 42 | * The data will be missing if Eluna is reloaded, since a new Lua state is created. 43 | * 44 | * 3. If it *is* missing, call `Reload`. 45 | * 46 | * This reloads the last known instance save data into Eluna, and calls the appropriate hooks. 47 | * 48 | * 49 | * Note 2 50 | * ====== 51 | * 52 | * CMaNGOS expects some of these methods to be `const`. However, any of these 53 | * methods are free to call `Save`, resulting in mutation of `lastSaveData`. 54 | * 55 | * Therefore, none of the hooks are `const`-safe, and `const_cast` is used 56 | * to escape from these restrictions. 57 | */ 58 | class ElunaInstanceAI : public InstanceData 59 | { 60 | private: 61 | // The last save data to pass through this class, 62 | // either through `Load` or `Save`. 63 | std::string lastSaveData; 64 | 65 | public: 66 | #if defined ELUNA_TRINITY 67 | ElunaInstanceAI(Map* map) : InstanceData(map->ToInstanceMap()) 68 | { 69 | } 70 | #else 71 | ElunaInstanceAI(Map* map) : InstanceData(map) 72 | { 73 | } 74 | #endif 75 | 76 | #if !defined ELUNA_TRINITY 77 | void Initialize() override; 78 | #endif 79 | 80 | /* 81 | * These are responsible for serializing/deserializing the instance's 82 | * data table to/from the core. 83 | */ 84 | void Load(const char* data) override; 85 | #if defined ELUNA_TRINITY 86 | // Simply calls Save, since the functions are a bit different in name and data types on different cores 87 | std::string GetSaveData() override 88 | { 89 | return Save(); 90 | } 91 | const char* Save() const; 92 | #elif defined ELUNA_VMANGOS 93 | const char* Save() const; 94 | #else 95 | const char* Save() const override; 96 | #endif 97 | 98 | 99 | /* 100 | * Calls `Load` with the last save data that was passed to 101 | * or from Eluna. 102 | * 103 | * See: big documentation blurb at the top of this class. 104 | */ 105 | void Reload() 106 | { 107 | Load(NULL); 108 | } 109 | 110 | /* 111 | * These methods allow non-Lua scripts (e.g. DB, C++) to get/set instance data. 112 | */ 113 | #if !defined ELUNA_VMANGOS 114 | uint32 GetData(uint32 key) const override; 115 | #else 116 | uint32 GetData(uint32 key) const; 117 | #endif 118 | void SetData(uint32 key, uint32 value) override; 119 | 120 | #if !defined ELUNA_VMANGOS 121 | uint64 GetData64(uint32 key) const override; 122 | #else 123 | uint64 GetData64(uint32 key) const; 124 | #endif 125 | void SetData64(uint32 key, uint64 value) override; 126 | 127 | /* 128 | * These methods are just thin wrappers around Eluna. 129 | */ 130 | void Update(uint32 diff) override 131 | { 132 | // If Eluna is reloaded, it will be missing our instance data. 133 | // Reload here instead of waiting for the next hook call (possibly never). 134 | // This avoids having to have an empty Update hook handler just to trigger the reload. 135 | if (!instance->GetEluna()->HasInstanceData(instance)) 136 | Reload(); 137 | 138 | instance->GetEluna()->OnUpdateInstance(this, diff); 139 | } 140 | 141 | bool IsEncounterInProgress() const override 142 | { 143 | return instance->GetEluna()->OnCheckEncounterInProgress(const_cast(this)); 144 | } 145 | 146 | void OnPlayerEnter(Player* player) override 147 | { 148 | instance->GetEluna()->OnPlayerEnterInstance(this, player); 149 | } 150 | 151 | #if defined ELUNA_TRINITY 152 | void OnGameObjectCreate(GameObject* gameobject) override 153 | #else 154 | void OnObjectCreate(GameObject* gameobject) override 155 | #endif 156 | { 157 | instance->GetEluna()->OnGameObjectCreate(this, gameobject); 158 | } 159 | 160 | void OnCreatureCreate(Creature* creature) override 161 | { 162 | instance->GetEluna()->OnCreatureCreate(this, creature); 163 | } 164 | }; 165 | 166 | #endif // _ELUNA_INSTANCE_DATA_H 167 | -------------------------------------------------------------------------------- /docs/DOC_GEN.md: -------------------------------------------------------------------------------- 1 | # Documentation generation 2 | Eluna uses a custom made documentation generator to create it's [web documentation](http://elunaluaengine.github.io/). 3 | The generator is written in python by Patman. It works by parsing Eluna's source files for comments and then generates the HTML and javascript for the documentation based on them. 4 | 5 | This page guides you through generating the web documentation locally and explains the standards of the documentation comments for you to help us improve our documentation. To contribute with your documentation changes, create a [pull request](https://help.github.com/articles/using-pull-requests/) 6 | 7 | # Generating locally 8 | - install [python](https://www.python.org/)(2) 9 | - when installing, tick to install the path variable 10 | - you may need restart afterwards for the installation to properly take effect 11 | - install a package manager like [pip](https://pip.pypa.io/en/latest/) 12 | - if you installed pip and it does not work, restart or try easy_install command 13 | - install the dependencies with manager 14 | - [Jinja2](https://pypi.python.org/pypi/Jinja2) 15 | - [typedecorator](https://pypi.python.org/pypi/typedecorator) 16 | - [markdown](https://pypi.python.org/pypi/Markdown) 17 | - Run in cmd `python -m ElunaDoc` when at `\LuaEngine\docs\` 18 | 19 | # Documenting 20 | You can document functions in the Eluna source code. To find examples simply open a method header file like `PlayerMethods.h` and see the comments. 21 | 22 | ## Templates 23 | Here are some basic templates for a function documentation. When defining a parameter or a return value the type and value name are mandatory, unless the parameter type is `...`, which is used for variable arguments; do not include a name in this case. 24 | 25 | ```c++ 26 | /** 27 | * Short description (about 80 characters long). 28 | * 29 | * @param Type paramName 30 | * @return Type returnName 31 | */ 32 | ``` 33 | 34 | ```c++ 35 | /** 36 | * Short description (about 80 characters long). 37 | * 38 | * @param Type paramName = defaultValue : parameter description 39 | * @return Type returnName : return value description 40 | */ 41 | ``` 42 | 43 | This is a template for a function that takes in different parameters. When defining a parameter or a return value, the type and value name are mandatory. 44 | 45 | ```c++ 46 | /** 47 | * Short description (about 80 characters long). 48 | * 49 | * @proto returnValue = (object) 50 | * @proto returnValue = (x, y, z) 51 | * @param [WorldObject] object = defaultValue : parameter description 52 | * @param float x = defaultValue : parameter description 53 | * @param float y = defaultValue : parameter description 54 | * @param float z = defaultValue : parameter description 55 | * @return Type returnName : return value description 56 | */ 57 | ``` 58 | 59 | ## Standard 60 | A documentation comment block will always start with `/**` and end with `*/`. 61 | All lines start with `*` character followed by one space before any content. 62 | 63 | The first paragrph is used as a short description of the function/class, so it should be kept to about 80 characters. The other paragraphs can be as long as desired. 64 | 65 | All paragraphs in the description (including the first) should start with a capital letter and end with a period. 66 | **Paragraphs must be separated by an empty line**, e.g.: 67 | 68 | ```c++ 69 | /** 70 | * This is a short description (about 80 characters). 71 | * 72 | * Here's another paragraph with more info. NOTE THE EMPTY LINE BETWEEN THE PARAGRAPHS. 73 | * This does need to be short, and this line is still part of the same paragraph because 74 | * there is no empty line. 75 | */ 76 | ``` 77 | 78 | The parameter and return value descriptions should start with a lowercase letter and not end with a period. If more than one sentence is needed, start the *first* without a capital letter and end the *last* without a period. 79 | 80 | Any class, enum or function can be referenced (made a link to) with square brackets. 81 | `[Player]` will reference a player. `[WeatherType]` will reference an enum. `[Player:GetName]` will reference a function. 82 | 83 | Use correct indentation with documentation comments. 84 | 85 | ```c++ 86 | /** 87 | * Correct indentation. 88 | */ 89 | ``` 90 | 91 | ```c++ 92 | /** 93 | * Invalid indentation. 94 | */ 95 | ``` 96 | 97 | ## Markdown 98 | You can use [markdown](http://pythonhosted.org//Markdown/) in your descriptions. 99 | For syntax see http://daringfireball.net/projects/markdown/syntax and http://pythonhosted.org//Markdown/#differences 100 | 101 | ``` 102 | /** 103 | * Description. 104 | * 105 | * - list item 106 | * - list item 107 | * - list item 108 | * 109 | * 110 | * // Codeblock 111 | * // Code goes here. 112 | * // Note the 4-space indent. 113 | * 114 | * 115 | * `code line` 116 | * 117 | * *italic* 118 | * **bold** 119 | */ 120 | ``` 121 | 122 | **The above markdown code produces the output below:** 123 | 124 | Description. 125 | 126 | - list item 127 | - list item 128 | - list item 129 | 130 | ``` 131 | // Codeblock 132 | // Code goes here. 133 | // Note the 4-space indent. 134 | ``` 135 | 136 | `code line` 137 | 138 | *italic* 139 | **bold** 140 | 141 | ## Types 142 | Here are some examples of possible types and most commonly used ones: 143 | 144 | ``` 145 | string 146 | uint64 147 | uint32 148 | uint16 149 | uint8 150 | int64 151 | int32 152 | int16 153 | int8 154 | double 155 | float 156 | ... 157 | [EnumName] 158 | [Player] 159 | [Creature] 160 | [GameObject] 161 | [Item] 162 | [Unit] 163 | [WorldObject] 164 | [Object] 165 | ``` 166 | -------------------------------------------------------------------------------- /methods/CMangos/SpellMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef SPELLMETHODS_H 8 | #define SPELLMETHODS_H 9 | 10 | /*** 11 | * An instance of a spell, created when the spell is cast by a [Unit]. 12 | * 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaSpell 16 | { 17 | /** 18 | * Returns `true` if the [Spell] is automatically repeating, `false` otherwise. 19 | * 20 | * @return bool isAutoRepeating 21 | */ 22 | int IsAutoRepeat(Eluna* E, Spell* spell) 23 | { 24 | E->Push(spell->IsAutoRepeat()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the [Unit] that casted the [Spell]. 30 | * 31 | * @return [Unit] caster 32 | */ 33 | int GetCaster(Eluna* E, Spell* spell) 34 | { 35 | E->Push(spell->GetCaster()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the cast time of the [Spell]. 41 | * 42 | * @return int32 castTime 43 | */ 44 | int GetCastTime(Eluna* E, Spell* spell) 45 | { 46 | E->Push(spell->GetCastTime()); 47 | return 1; 48 | } 49 | 50 | /** 51 | * Returns the entry ID of the [Spell]. 52 | * 53 | * @return uint32 entryId 54 | */ 55 | int GetEntry(Eluna* E, Spell* spell) 56 | { 57 | E->Push(spell->m_spellInfo->Id); 58 | return 1; 59 | } 60 | 61 | /** 62 | * Returns the power cost of the [Spell]. 63 | * 64 | * @return uint32 powerCost 65 | */ 66 | int GetPowerCost(Eluna* E, Spell* spell) 67 | { 68 | E->Push(spell->GetPowerCost()); 69 | return 1; 70 | } 71 | 72 | /** 73 | * Returns the spell duration of the [Spell]. 74 | * 75 | * @return int32 duration 76 | */ 77 | int GetDuration(Eluna* E, Spell* spell) 78 | { 79 | E->Push(GetSpellDuration(spell->m_spellInfo)); 80 | return 1; 81 | } 82 | 83 | /** 84 | * Returns the target destination coordinates of the [Spell]. 85 | * 86 | * @return float x : x coordinate of the [Spell] 87 | * @return float y : y coordinate of the [Spell] 88 | * @return float z : z coordinate of the [Spell] 89 | */ 90 | int GetTargetDest(Eluna* E, Spell* spell) 91 | { 92 | if (!(spell->m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) 93 | return 3; 94 | float x, y, z; 95 | spell->m_targets.getDestination(x, y, z); 96 | E->Push(x); 97 | E->Push(y); 98 | E->Push(z); 99 | return 3; 100 | } 101 | 102 | /** 103 | * Returns the target [Object] of the [Spell]. 104 | * 105 | * The target can be any of the following [Object] types: 106 | * - [Player] 107 | * - [Creature] 108 | * - [GameObject] 109 | * - [Item] 110 | * - [Corpse] 111 | * 112 | * @return [Object] target 113 | */ 114 | int GetTarget(Eluna* E, Spell* spell) 115 | { 116 | if (GameObject* target = spell->m_targets.getGOTarget()) 117 | E->Push(target); 118 | else if (Item* target = spell->m_targets.getItemTarget()) 119 | E->Push(target); 120 | else if (Corpse* target = spell->GetCaster()->GetMap()->GetCorpse(spell->m_targets.getCorpseTargetGuid())) 121 | E->Push(target); 122 | else if (Unit* target = spell->m_targets.getUnitTarget()) 123 | E->Push(target); 124 | return 1; 125 | } 126 | 127 | /** 128 | * Sets the [Spell] to automatically repeat. 129 | * 130 | * @param bool repeat : set variable to 'true' for spell to automatically repeat 131 | */ 132 | int SetAutoRepeat(Eluna* E, Spell* spell) 133 | { 134 | bool repeat = E->CHECKVAL(2); 135 | spell->SetAutoRepeat(repeat); 136 | return 0; 137 | } 138 | 139 | /** 140 | * Casts the [Spell]. 141 | * 142 | * @param bool skipCheck = false : skips initial checks to see if the [Spell] can be casted or not, this is optional 143 | */ 144 | int Cast(Eluna* E, Spell* spell) 145 | { 146 | bool skipCheck = E->CHECKVAL(2, false); 147 | spell->cast(skipCheck); 148 | return 0; 149 | } 150 | 151 | /** 152 | * Cancels the [Spell]. 153 | */ 154 | int Cancel(Eluna* /*E*/, Spell* spell) 155 | { 156 | spell->cancel(); 157 | return 0; 158 | } 159 | 160 | /** 161 | * Finishes the [Spell]. 162 | */ 163 | int Finish(Eluna* /*E*/, Spell* spell) 164 | { 165 | spell->finish(); 166 | return 0; 167 | } 168 | 169 | ElunaRegister SpellMethods[] = 170 | { 171 | // Getters 172 | { "GetCaster", &LuaSpell::GetCaster }, 173 | { "GetCastTime", &LuaSpell::GetCastTime }, 174 | { "GetEntry", &LuaSpell::GetEntry }, 175 | { "GetDuration", &LuaSpell::GetDuration }, 176 | { "GetPowerCost", &LuaSpell::GetPowerCost }, 177 | { "GetTargetDest", &LuaSpell::GetTargetDest }, 178 | { "GetTarget", &LuaSpell::GetTarget }, 179 | 180 | // Setters 181 | { "SetAutoRepeat", &LuaSpell::SetAutoRepeat }, 182 | 183 | // Boolean 184 | { "IsAutoRepeat", &LuaSpell::IsAutoRepeat }, 185 | 186 | // Other 187 | { "Cancel", &LuaSpell::Cancel }, 188 | { "Cast", &LuaSpell::Cast }, 189 | { "Finish", &LuaSpell::Finish } 190 | }; 191 | }; 192 | #endif 193 | -------------------------------------------------------------------------------- /methods/VMangos/SpellMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef SPELLMETHODS_H 8 | #define SPELLMETHODS_H 9 | 10 | /*** 11 | * An instance of a spell, created when the spell is cast by a [Unit]. 12 | * 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaSpell 16 | { 17 | /** 18 | * Returns `true` if the [Spell] is automatically repeating, `false` otherwise. 19 | * 20 | * @return bool isAutoRepeating 21 | */ 22 | int IsAutoRepeat(Eluna* E, Spell* spell) 23 | { 24 | E->Push(spell->IsAutoRepeat()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the [Unit] that casted the [Spell]. 30 | * 31 | * @return [Unit] caster 32 | */ 33 | int GetCaster(Eluna* E, Spell* spell) 34 | { 35 | E->Push(spell->GetCaster()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the cast time of the [Spell]. 41 | * 42 | * @return int32 castTime 43 | */ 44 | int GetCastTime(Eluna* E, Spell* spell) 45 | { 46 | E->Push(spell->GetCastTime()); 47 | return 1; 48 | } 49 | 50 | /** 51 | * Returns the entry ID of the [Spell]. 52 | * 53 | * @return uint32 entryId 54 | */ 55 | int GetEntry(Eluna* E, Spell* spell) 56 | { 57 | E->Push(spell->m_spellInfo->Id); 58 | return 1; 59 | } 60 | 61 | /** 62 | * Returns the power cost of the [Spell]. 63 | * 64 | * @return uint32 powerCost 65 | */ 66 | int GetPowerCost(Eluna* E, Spell* spell) 67 | { 68 | E->Push(spell->GetPowerCost()); 69 | return 1; 70 | } 71 | 72 | /** 73 | * Returns the spell duration of the [Spell]. 74 | * 75 | * @return int32 duration 76 | */ 77 | int GetDuration(Eluna* E, Spell* spell) 78 | { 79 | E->Push(spell->GetSpellInfo()->GetDuration()); 80 | return 1; 81 | } 82 | 83 | /** 84 | * Returns the target destination coordinates of the [Spell]. 85 | * 86 | * @return float x : x coordinate of the [Spell] 87 | * @return float y : y coordinate of the [Spell] 88 | * @return float z : z coordinate of the [Spell] 89 | */ 90 | int GetTargetDest(Eluna* E, Spell* spell) 91 | { 92 | if (!(spell->m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) 93 | return 3; 94 | float x, y, z; 95 | spell->m_targets.getDestination(x, y, z); 96 | E->Push(x); 97 | E->Push(y); 98 | E->Push(z); 99 | return 3; 100 | } 101 | 102 | /** 103 | * Returns the target [Object] of the [Spell]. 104 | * 105 | * The target can be any of the following [Object] types: 106 | * - [Player] 107 | * - [Creature] 108 | * - [GameObject] 109 | * - [Item] 110 | * - [Corpse] 111 | * 112 | * @return [Object] target 113 | */ 114 | int GetTarget(Eluna* E, Spell* spell) 115 | { 116 | if (GameObject* target = spell->m_targets.getGOTarget()) 117 | E->Push(target); 118 | else if (Item* target = spell->m_targets.getItemTarget()) 119 | E->Push(target); 120 | else if (Corpse* target = spell->GetCaster()->GetMap()->GetCorpse(spell->m_targets.getCorpseTargetGuid())) 121 | E->Push(target); 122 | else if (Unit* target = spell->m_targets.getUnitTarget()) 123 | E->Push(target); 124 | return 1; 125 | } 126 | 127 | /** 128 | * Sets the [Spell] to automatically repeat. 129 | * 130 | * @param bool repeat : set variable to 'true' for spell to automatically repeat 131 | */ 132 | int SetAutoRepeat(Eluna* E, Spell* spell) 133 | { 134 | bool repeat = E->CHECKVAL(2); 135 | spell->SetAutoRepeat(repeat); 136 | return 0; 137 | } 138 | 139 | /** 140 | * Casts the [Spell]. 141 | * 142 | * @param bool skipCheck = false : skips initial checks to see if the [Spell] can be casted or not, this is optional 143 | */ 144 | int Cast(Eluna* E, Spell* spell) 145 | { 146 | bool skipCheck = E->CHECKVAL(2, false); 147 | spell->cast(skipCheck); 148 | return 0; 149 | } 150 | 151 | /** 152 | * Cancels the [Spell]. 153 | */ 154 | int Cancel(Eluna* /*E*/, Spell* spell) 155 | { 156 | spell->cancel(); 157 | return 0; 158 | } 159 | 160 | /** 161 | * Finishes the [Spell]. 162 | */ 163 | int Finish(Eluna* /*E*/, Spell* spell) 164 | { 165 | spell->finish(); 166 | return 0; 167 | } 168 | 169 | ElunaRegister SpellMethods[] = 170 | { 171 | // Getters 172 | { "GetCaster", &LuaSpell::GetCaster }, 173 | { "GetCastTime", &LuaSpell::GetCastTime }, 174 | { "GetEntry", &LuaSpell::GetEntry }, 175 | { "GetDuration", &LuaSpell::GetDuration }, 176 | { "GetPowerCost", &LuaSpell::GetPowerCost }, 177 | { "GetTargetDest", &LuaSpell::GetTargetDest }, 178 | { "GetTarget", &LuaSpell::GetTarget }, 179 | 180 | // Setters 181 | { "SetAutoRepeat", &LuaSpell::SetAutoRepeat }, 182 | 183 | // Boolean 184 | { "IsAutoRepeat", &LuaSpell::IsAutoRepeat }, 185 | 186 | // Other 187 | { "Cancel", &LuaSpell::Cancel }, 188 | { "Cast", &LuaSpell::Cast }, 189 | { "Finish", &LuaSpell::Finish } 190 | }; 191 | }; 192 | #endif 193 | -------------------------------------------------------------------------------- /methods/Mangos/SpellMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef SPELLMETHODS_H 8 | #define SPELLMETHODS_H 9 | 10 | /*** 11 | * An instance of a spell, created when the spell is cast by a [Unit]. 12 | * 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaSpell 16 | { 17 | /** 18 | * Returns `true` if the [Spell] is automatically repeating, `false` otherwise. 19 | * 20 | * @return bool isAutoRepeating 21 | */ 22 | int IsAutoRepeat(Eluna* E, Spell* spell) 23 | { 24 | E->Push(spell->IsAutoRepeat()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the [Unit] that casted the [Spell]. 30 | * 31 | * @return [Unit] caster 32 | */ 33 | int GetCaster(Eluna* E, Spell* spell) 34 | { 35 | E->Push(spell->GetCaster()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the cast time of the [Spell]. 41 | * 42 | * @return int32 castTime 43 | */ 44 | int GetCastTime(Eluna* E, Spell* spell) 45 | { 46 | E->Push(spell->GetCastTime()); 47 | return 1; 48 | } 49 | 50 | /** 51 | * Returns the entry ID of the [Spell]. 52 | * 53 | * @return uint32 entryId 54 | */ 55 | int GetEntry(Eluna* E, Spell* spell) 56 | { 57 | E->Push(spell->m_spellInfo->Id); 58 | return 1; 59 | } 60 | 61 | /** 62 | * Returns the power cost of the [Spell]. 63 | * 64 | * @return uint32 powerCost 65 | */ 66 | int GetPowerCost(Eluna* E, Spell* spell) 67 | { 68 | E->Push(spell->GetPowerCost()); 69 | return 1; 70 | } 71 | 72 | /** 73 | * Returns the spell duration of the [Spell]. 74 | * 75 | * @return int32 duration 76 | */ 77 | int GetDuration(Eluna* E, Spell* spell) 78 | { 79 | E->Push(GetSpellDuration(spell->m_spellInfo)); 80 | return 1; 81 | } 82 | 83 | /** 84 | * Returns the target destination coordinates of the [Spell]. 85 | * 86 | * @return float x : x coordinate of the [Spell] 87 | * @return float y : y coordinate of the [Spell] 88 | * @return float z : z coordinate of the [Spell] 89 | */ 90 | int GetTargetDest(Eluna* E, Spell* spell) 91 | { 92 | if (!(spell->m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) 93 | return 3; 94 | float x, y, z; 95 | spell->m_targets.getDestination(x, y, z); 96 | 97 | E->Push(x); 98 | E->Push(y); 99 | E->Push(z); 100 | return 3; 101 | } 102 | 103 | /** 104 | * Returns the target [Object] of the [Spell]. 105 | * 106 | * The target can be any of the following [Object] types: 107 | * - [Player] 108 | * - [Creature] 109 | * - [GameObject] 110 | * - [Item] 111 | * - [Corpse] 112 | * 113 | * @return [Object] target 114 | */ 115 | int GetTarget(Eluna* E, Spell* spell) 116 | { 117 | if (GameObject* target = spell->m_targets.getGOTarget()) 118 | E->Push(target); 119 | else if (Item* target = spell->m_targets.getItemTarget()) 120 | E->Push(target); 121 | else if (Corpse* target = spell->GetCaster()->GetMap()->GetCorpse(spell->m_targets.getCorpseTargetGuid())) 122 | E->Push(target); 123 | else if (Unit* target = spell->m_targets.getUnitTarget()) 124 | E->Push(target); 125 | 126 | return 1; 127 | } 128 | 129 | /** 130 | * Sets the [Spell] to automatically repeat. 131 | * 132 | * @param bool repeat : set variable to 'true' for spell to automatically repeat 133 | */ 134 | int SetAutoRepeat(Eluna* E, Spell* spell) 135 | { 136 | bool repeat = E->CHECKVAL(2); 137 | spell->SetAutoRepeat(repeat); 138 | return 0; 139 | } 140 | 141 | /** 142 | * Casts the [Spell]. 143 | * 144 | * @param bool skipCheck = false : skips initial checks to see if the [Spell] can be casted or not, this is optional 145 | */ 146 | int Cast(Eluna* E, Spell* spell) 147 | { 148 | bool skipCheck = E->CHECKVAL(2, false); 149 | spell->cast(skipCheck); 150 | return 0; 151 | } 152 | 153 | /** 154 | * Cancels the [Spell]. 155 | */ 156 | int Cancel(Eluna* /*E*/, Spell* spell) 157 | { 158 | spell->cancel(); 159 | return 0; 160 | } 161 | 162 | /** 163 | * Finishes the [Spell]. 164 | */ 165 | int Finish(Eluna* /*E*/, Spell* spell) 166 | { 167 | spell->finish(); 168 | return 0; 169 | } 170 | 171 | ElunaRegister SpellMethods[] = 172 | { 173 | // Getters 174 | { "GetCaster", &LuaSpell::GetCaster }, 175 | { "GetCastTime", &LuaSpell::GetCastTime }, 176 | { "GetEntry", &LuaSpell::GetEntry }, 177 | { "GetDuration", &LuaSpell::GetDuration }, 178 | { "GetPowerCost", &LuaSpell::GetPowerCost }, 179 | { "GetTargetDest", &LuaSpell::GetTargetDest }, 180 | { "GetTarget", &LuaSpell::GetTarget }, 181 | 182 | // Setters 183 | { "SetAutoRepeat", &LuaSpell::SetAutoRepeat }, 184 | 185 | // Boolean 186 | { "IsAutoRepeat", &LuaSpell::IsAutoRepeat }, 187 | 188 | // Other 189 | { "Cancel", &LuaSpell::Cancel }, 190 | { "Cast", &LuaSpell::Cast }, 191 | { "Finish", &LuaSpell::Finish } 192 | }; 193 | }; 194 | #endif 195 | -------------------------------------------------------------------------------- /methods/TrinityCore/SpellMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef SPELLMETHODS_H 8 | #define SPELLMETHODS_H 9 | 10 | /*** 11 | * An instance of a spell, created when the spell is cast by a [Unit]. 12 | * 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaSpell 16 | { 17 | /** 18 | * Returns `true` if the [Spell] is automatically repeating, `false` otherwise. 19 | * 20 | * @return bool isAutoRepeating 21 | */ 22 | int IsAutoRepeat(Eluna* E, Spell* spell) 23 | { 24 | E->Push(spell->IsAutoRepeat()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the [Unit] that casted the [Spell]. 30 | * 31 | * @return [Unit] caster 32 | */ 33 | int GetCaster(Eluna* E, Spell* spell) 34 | { 35 | E->Push(spell->GetCaster()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the cast time of the [Spell]. 41 | * 42 | * @return int32 castTime 43 | */ 44 | int GetCastTime(Eluna* E, Spell* spell) 45 | { 46 | E->Push(spell->GetCastTime()); 47 | return 1; 48 | } 49 | 50 | /** 51 | * Returns the entry ID of the [Spell]. 52 | * 53 | * @return uint32 entryId 54 | */ 55 | int GetEntry(Eluna* E, Spell* spell) 56 | { 57 | E->Push(spell->m_spellInfo->Id); 58 | return 1; 59 | } 60 | 61 | /** 62 | * Returns the power cost of the [Spell]. 63 | * 64 | * @return uint32 powerCost 65 | */ 66 | int GetPowerCost(Eluna* E, Spell* spell) 67 | { 68 | E->Push(spell->GetPowerCost()); 69 | return 1; 70 | } 71 | 72 | /** 73 | * Returns the spell duration of the [Spell]. 74 | * 75 | * @return int32 duration 76 | */ 77 | int GetDuration(Eluna* E, Spell* spell) 78 | { 79 | E->Push(spell->GetSpellInfo()->GetDuration()); 80 | return 1; 81 | } 82 | 83 | /** 84 | * Returns the target destination coordinates of the [Spell]. 85 | * 86 | * @return float x : x coordinate of the [Spell] 87 | * @return float y : y coordinate of the [Spell] 88 | * @return float z : z coordinate of the [Spell] 89 | */ 90 | int GetTargetDest(Eluna* E, Spell* spell) 91 | { 92 | if (!spell->m_targets.HasDst()) 93 | return 3; 94 | 95 | float x, y, z; 96 | spell->m_targets.GetDstPos()->GetPosition(x, y, z); 97 | 98 | E->Push(x); 99 | E->Push(y); 100 | E->Push(z); 101 | return 3; 102 | } 103 | 104 | /** 105 | * Returns the target [Object] of the [Spell]. 106 | * 107 | * The target can be any of the following [Object] types: 108 | * - [Player] 109 | * - [Creature] 110 | * - [GameObject] 111 | * - [Item] 112 | * - [Corpse] 113 | * 114 | * @return [Object] target 115 | */ 116 | int GetTarget(Eluna* E, Spell* spell) 117 | { 118 | if (GameObject* target = spell->m_targets.GetGOTarget()) 119 | E->Push(target); 120 | else if (Item* target = spell->m_targets.GetItemTarget()) 121 | E->Push(target); 122 | else if (Corpse* target = spell->m_targets.GetCorpseTarget()) 123 | E->Push(target); 124 | else if (Unit* target = spell->m_targets.GetUnitTarget()) 125 | E->Push(target); 126 | else if (WorldObject* target = spell->m_targets.GetObjectTarget()) 127 | E->Push(target); 128 | return 1; 129 | } 130 | 131 | /** 132 | * Sets the [Spell] to automatically repeat. 133 | * 134 | * @param bool repeat : set variable to 'true' for spell to automatically repeat 135 | */ 136 | int SetAutoRepeat(Eluna* E, Spell* spell) 137 | { 138 | bool repeat = E->CHECKVAL(2); 139 | spell->SetAutoRepeat(repeat); 140 | return 0; 141 | } 142 | 143 | /** 144 | * Casts the [Spell]. 145 | * 146 | * @param bool skipCheck = false : skips initial checks to see if the [Spell] can be casted or not, this is optional 147 | */ 148 | int Cast(Eluna* E, Spell* spell) 149 | { 150 | bool skipCheck = E->CHECKVAL(2, false); 151 | spell->cast(skipCheck); 152 | return 0; 153 | } 154 | 155 | /** 156 | * Cancels the [Spell]. 157 | */ 158 | int Cancel(Eluna* /*E*/, Spell* spell) 159 | { 160 | spell->cancel(); 161 | return 0; 162 | } 163 | 164 | /** 165 | * Finishes the [Spell]. 166 | */ 167 | int Finish(Eluna* /*E*/, Spell* spell) 168 | { 169 | spell->finish(); 170 | return 0; 171 | } 172 | 173 | ElunaRegister SpellMethods[] = 174 | { 175 | // Getters 176 | { "GetCaster", &LuaSpell::GetCaster }, 177 | { "GetCastTime", &LuaSpell::GetCastTime }, 178 | { "GetEntry", &LuaSpell::GetEntry }, 179 | { "GetDuration", &LuaSpell::GetDuration }, 180 | { "GetPowerCost", &LuaSpell::GetPowerCost }, 181 | { "GetTargetDest", &LuaSpell::GetTargetDest }, 182 | { "GetTarget", &LuaSpell::GetTarget }, 183 | 184 | // Setters 185 | { "SetAutoRepeat", &LuaSpell::SetAutoRepeat }, 186 | 187 | // Boolean 188 | { "IsAutoRepeat", &LuaSpell::IsAutoRepeat }, 189 | 190 | // Other 191 | { "Cancel", &LuaSpell::Cancel }, 192 | { "Cast", &LuaSpell::Cast }, 193 | { "Finish", &LuaSpell::Finish } 194 | }; 195 | }; 196 | #endif 197 | -------------------------------------------------------------------------------- /LuaValue.h: -------------------------------------------------------------------------------- 1 | // BSD-3-Clause 2 | // Copyright (c) 2022, Rochet2 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this 9 | // list of conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, 12 | // this list of conditions and the following disclaimer in the documentation 13 | // and/or other materials provided with the distribution. 14 | // 15 | // * Neither the name of the copyright holder nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #pragma once 31 | 32 | #include // std::unordered_map 33 | #include // std::to_string, std::string 34 | #include // std::monostate, std::variant, std::visit 35 | #include // std::unique_ptr, std::shared_ptr 36 | #include // std::decay_t, std::is_same_v, std::false_type 37 | #include // std::initializer_list 38 | #include // std::pair, std::make_pair, std::move 39 | 40 | constexpr const char* LUAVAL_MT_NAME = "LuaVal"; 41 | class LuaVal; 42 | struct lua_State; 43 | 44 | size_t LuaValHash(LuaVal const& k); 45 | 46 | namespace std { 47 | 48 | template <> 49 | struct hash 50 | { 51 | std::size_t operator()(const LuaVal& k) const 52 | { 53 | return LuaValHash(k); 54 | } 55 | }; 56 | } 57 | 58 | class LuaVal 59 | { 60 | public: 61 | typedef std::unordered_map MapType; 62 | typedef std::monostate NIL; 63 | template struct always_false : std::false_type {}; 64 | typedef std::shared_ptr WrappedMap; 65 | typedef std::variant LuaValVariant; 66 | 67 | static int lua_get(lua_State* L); 68 | static int lua_set(lua_State* L); 69 | 70 | static std::string to_string_map(MapType const* ptr); 71 | int asObject(lua_State* L) const; 72 | int asLua(lua_State* L, unsigned int depth) const; 73 | static LuaVal AsLuaVal(lua_State* L, int index); 74 | static LuaVal FromTable(lua_State* L, int index); 75 | static int lua_asLua(lua_State* L); 76 | static int lua_AsLuaVal(lua_State* L); 77 | static int lua_gc(lua_State* L); 78 | static int lua_to_string(lua_State* L); 79 | 80 | static LuaVal* GetLuaVal(lua_State* L, int index); 81 | static LuaVal* GetCheckLuaVal(lua_State* L, int index); 82 | static int PushLuaVal(lua_State* L, LuaVal const& lv); 83 | static void Register(lua_State* L); 84 | 85 | bool operator<(LuaVal const& b) const 86 | { 87 | return v < b.v; 88 | } 89 | 90 | bool operator==(LuaVal const& b) const 91 | { 92 | return v == b.v; 93 | } 94 | 95 | std::string to_string() const 96 | { 97 | return std::visit([](auto&& arg) -> std::string { 98 | using T = std::decay_t; 99 | if constexpr (std::is_same_v) 100 | return "nil"; 101 | else if constexpr (std::is_same_v) 102 | return arg; 103 | else if constexpr (std::is_same_v) 104 | return LuaVal::to_string_map(arg.get()); 105 | else if constexpr (std::is_same_v) 106 | return arg ? "true" : "false"; 107 | else if constexpr (std::is_same_v) 108 | return std::to_string(arg); 109 | else 110 | static_assert(always_false::value, "non-exhaustive visitor!"); 111 | }, v); 112 | } 113 | 114 | LuaVal() : v() {} 115 | LuaVal(std::string const& s) : v(s) {} 116 | LuaVal(bool b) : v(b) {} 117 | LuaVal(double d) : v(d) {} 118 | LuaVal(MapType const& t) : v(std::make_shared(t)) {} 119 | LuaVal(std::initializer_list /* MapType::value_type */> const& l) : v(std::make_shared(l)) {} 120 | 121 | LuaVal(LuaVal&& b) noexcept : v(std::move(b.v)) { 122 | } 123 | LuaVal(const LuaVal& b) : v(b.v) { 124 | } 125 | ~LuaVal() { 126 | } 127 | LuaVal& operator=(LuaVal&& b) noexcept 128 | { 129 | v = std::move(b.v); 130 | return *this; 131 | } 132 | LuaVal& operator=(const LuaVal& b) { 133 | v = b.v; 134 | return *this; 135 | } 136 | LuaVal clone() const { 137 | LuaVal lv; 138 | lv.v = std::visit([&](auto&& arg) -> LuaValVariant 139 | { 140 | using T = std::decay_t; 141 | if constexpr (std::is_same_v) 142 | return std::make_shared(*arg); 143 | else 144 | return arg; 145 | }, v); 146 | return lv; 147 | } 148 | LuaVal reference() const { 149 | return *this; 150 | } 151 | 152 | LuaValVariant v; 153 | }; 154 | -------------------------------------------------------------------------------- /methods/TrinityCore/AuraMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef AURAMETHODS_H 8 | #define AURAMETHODS_H 9 | 10 | /*** 11 | * The persistent effect of a [Spell] that remains on a [Unit] after the [Spell] 12 | * has been cast. 13 | * 14 | * As an example, if you cast a damage-over-time spell on a target, an [Aura] is 15 | * put on the target that deals damage continuously. 16 | * 17 | * [Aura]s on your player are displayed in-game as a series of icons to the left 18 | * of the mini-map. 19 | * 20 | * Inherits all methods from: none 21 | */ 22 | namespace LuaAura 23 | { 24 | /** 25 | * Returns the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 26 | * 27 | * @return [Unit] caster 28 | */ 29 | int GetCaster(Eluna* E, Aura* aura) 30 | { 31 | E->Push(aura->GetCaster()); 32 | return 1; 33 | } 34 | 35 | /** 36 | * Returns the GUID of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 37 | * 38 | * @return string caster_guid : the GUID of the Unit as a decimal string 39 | */ 40 | int GetCasterGUID(Eluna* E, Aura* aura) 41 | { 42 | E->Push(aura->GetCasterGUID()); 43 | return 1; 44 | } 45 | 46 | /** 47 | * Returns the level of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 48 | * 49 | * @return uint32 caster_level 50 | */ 51 | int GetCasterLevel(Eluna* E, Aura* aura) 52 | { 53 | E->Push(aura->GetCaster()->GetLevel()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Returns the amount of time left until the [Aura] expires. 59 | * 60 | * @return int32 duration : amount of time left in milliseconds 61 | */ 62 | int GetDuration(Eluna* E, Aura* aura) 63 | { 64 | E->Push(aura->GetDuration()); 65 | return 1; 66 | } 67 | 68 | /** 69 | * Returns the ID of the [Spell] that caused this [Aura] to be applied. 70 | * 71 | * @return uint32 aura_id 72 | */ 73 | int GetAuraId(Eluna* E, Aura* aura) 74 | { 75 | E->Push(aura->GetId()); 76 | return 1; 77 | } 78 | 79 | /** 80 | * Returns the amount of time this [Aura] lasts when applied. 81 | * 82 | * To determine how much time has passed since this Aura was applied, 83 | * subtract the result of [Aura]:GetDuration from the result of this method. 84 | * 85 | * @return int32 max_duration : the maximum duration of the Aura, in milliseconds 86 | */ 87 | int GetMaxDuration(Eluna* E, Aura* aura) 88 | { 89 | E->Push(aura->GetMaxDuration()); 90 | return 1; 91 | } 92 | 93 | /** 94 | * Returns the number of times the [Aura] has "stacked". 95 | * 96 | * This is the same as the number displayed on the [Aura]'s icon in-game. 97 | * 98 | * @return uint32 stack_amount 99 | */ 100 | int GetStackAmount(Eluna* E, Aura* aura) 101 | { 102 | E->Push(aura->GetStackAmount()); 103 | return 1; 104 | } 105 | 106 | /** 107 | * Returns the [Unit] that the [Aura] has been applied to. 108 | * 109 | * @return [Unit] owner 110 | */ 111 | int GetOwner(Eluna* E, Aura* aura) 112 | { 113 | E->Push(aura->GetOwner()); 114 | return 1; 115 | } 116 | 117 | /** 118 | * Change the amount of time before the [Aura] expires. 119 | * 120 | * @param int32 duration : the new duration of the Aura, in milliseconds 121 | */ 122 | int SetDuration(Eluna* E, Aura* aura) 123 | { 124 | int32 duration = E->CHECKVAL(2); 125 | 126 | aura->SetDuration(duration); 127 | return 0; 128 | } 129 | 130 | /** 131 | * Change the maximum amount of time before the [Aura] expires. 132 | * 133 | * This does not affect the current duration of the [Aura], but if the [Aura] 134 | * is reset to the maximum duration, it will instead change to `duration`. 135 | * 136 | * @param int32 duration : the new maximum duration of the Aura, in milliseconds 137 | */ 138 | int SetMaxDuration(Eluna* E, Aura* aura) 139 | { 140 | int32 duration = E->CHECKVAL(2); 141 | 142 | aura->SetMaxDuration(duration); 143 | return 0; 144 | } 145 | 146 | /** 147 | * Change the amount of times the [Aura] has "stacked" on the [Unit]. 148 | * 149 | * If `amount` is greater than or equal to the current number of stacks, 150 | * then the [Aura] has its duration reset to the maximum duration. 151 | * 152 | * @param uint8 amount 153 | */ 154 | int SetStackAmount(Eluna* E, Aura* aura) 155 | { 156 | uint8 amount = E->CHECKVAL(2); 157 | 158 | aura->SetStackAmount(amount); 159 | return 0; 160 | } 161 | 162 | /** 163 | * Remove this [Aura] from the [Unit] it is applied to. 164 | */ 165 | int Remove(Eluna* /*E*/, Aura* aura) 166 | { 167 | aura->Remove(); 168 | return 0; 169 | } 170 | 171 | ElunaRegister AuraMethods[] = 172 | { 173 | // Getters 174 | { "GetCaster", &LuaAura::GetCaster }, 175 | { "GetCasterGUID", &LuaAura::GetCasterGUID }, 176 | { "GetCasterLevel", &LuaAura::GetCasterLevel }, 177 | { "GetDuration", &LuaAura::GetDuration }, 178 | { "GetMaxDuration", &LuaAura::GetMaxDuration }, 179 | { "GetAuraId", &LuaAura::GetAuraId }, 180 | { "GetStackAmount", &LuaAura::GetStackAmount }, 181 | { "GetOwner", &LuaAura::GetOwner }, 182 | 183 | // Setters 184 | { "SetDuration", &LuaAura::SetDuration }, 185 | { "SetMaxDuration", &LuaAura::SetMaxDuration }, 186 | { "SetStackAmount", &LuaAura::SetStackAmount }, 187 | 188 | // Other 189 | { "Remove", &LuaAura::Remove } 190 | }; 191 | }; 192 | #endif 193 | -------------------------------------------------------------------------------- /methods/VMangos/AuraMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef AURAMETHODS_H 8 | #define AURAMETHODS_H 9 | 10 | /*** 11 | * The persistent effect of a [Spell] that remains on a [Unit] after the [Spell] 12 | * has been cast. 13 | * 14 | * As an example, if you cast a damage-over-time spell on a target, an [Aura] is 15 | * put on the target that deals damage continuously. 16 | * 17 | * [Aura]s on your player are displayed in-game as a series of icons to the left 18 | * of the mini-map. 19 | * 20 | * Inherits all methods from: none 21 | */ 22 | namespace LuaAura 23 | { 24 | /** 25 | * Returns the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 26 | * 27 | * @return [Unit] caster 28 | */ 29 | int GetCaster(Eluna* E, Aura* aura) 30 | { 31 | E->Push(aura->GetCaster()); 32 | return 1; 33 | } 34 | 35 | /** 36 | * Returns the GUID of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 37 | * 38 | * @return string caster_guid : the GUID of the Unit as a decimal string 39 | */ 40 | int GetCasterGUID(Eluna* E, Aura* aura) 41 | { 42 | E->Push(aura->GetCasterGuid()); 43 | return 1; 44 | } 45 | 46 | /** 47 | * Returns the level of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 48 | * 49 | * @return uint32 caster_level 50 | */ 51 | int GetCasterLevel(Eluna* E, Aura* aura) 52 | { 53 | E->Push(aura->GetCaster()->GetLevel()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Returns the amount of time left until the [Aura] expires. 59 | * 60 | * @return int32 duration : amount of time left in milliseconds 61 | */ 62 | int GetDuration(Eluna* E, Aura* aura) 63 | { 64 | E->Push(aura->GetAuraDuration()); 65 | return 1; 66 | } 67 | 68 | /** 69 | * Returns the ID of the [Spell] that caused this [Aura] to be applied. 70 | * 71 | * @return uint32 aura_id 72 | */ 73 | int GetAuraId(Eluna* E, Aura* aura) 74 | { 75 | E->Push(aura->GetId()); 76 | return 1; 77 | } 78 | 79 | /** 80 | * Returns the amount of time this [Aura] lasts when applied. 81 | * 82 | * To determine how much time has passed since this Aura was applied, 83 | * subtract the result of [Aura]:GetDuration from the result of this method. 84 | * 85 | * @return int32 max_duration : the maximum duration of the Aura, in milliseconds 86 | */ 87 | int GetMaxDuration(Eluna* E, Aura* aura) 88 | { 89 | E->Push(aura->GetAuraMaxDuration()); 90 | return 1; 91 | } 92 | 93 | /** 94 | * Returns the number of times the [Aura] has "stacked". 95 | * 96 | * This is the same as the number displayed on the [Aura]'s icon in-game. 97 | * 98 | * @return uint32 stack_amount 99 | */ 100 | int GetStackAmount(Eluna* E, Aura* aura) 101 | { 102 | E->Push(aura->GetStackAmount()); 103 | return 1; 104 | } 105 | 106 | /** 107 | * Returns the [Unit] that the [Aura] has been applied to. 108 | * 109 | * @return [Unit] owner 110 | */ 111 | int GetOwner(Eluna* E, Aura* aura) 112 | { 113 | E->Push(aura->GetTarget()); 114 | return 1; 115 | } 116 | 117 | /** 118 | * Change the amount of time before the [Aura] expires. 119 | * 120 | * @param int32 duration : the new duration of the Aura, in milliseconds 121 | */ 122 | int SetDuration(Eluna* E, Aura* aura) 123 | { 124 | int32 duration = E->CHECKVAL(2); 125 | aura->GetHolder()->SetAuraDuration(duration); 126 | aura->GetHolder()->UpdateAuraDuration(); 127 | return 0; 128 | } 129 | 130 | /** 131 | * Change the maximum amount of time before the [Aura] expires. 132 | * 133 | * This does not affect the current duration of the [Aura], but if the [Aura] 134 | * is reset to the maximum duration, it will instead change to `duration`. 135 | * 136 | * @param int32 duration : the new maximum duration of the Aura, in milliseconds 137 | */ 138 | int SetMaxDuration(Eluna* E, Aura* aura) 139 | { 140 | int32 duration = E->CHECKVAL(2); 141 | aura->GetHolder()->SetAuraMaxDuration(duration); 142 | aura->GetHolder()->UpdateAuraDuration(); 143 | return 0; 144 | } 145 | 146 | /** 147 | * Change the amount of times the [Aura] has "stacked" on the [Unit]. 148 | * 149 | * If `amount` is greater than or equal to the current number of stacks, 150 | * then the [Aura] has its duration reset to the maximum duration. 151 | * 152 | * @param uint32 amount 153 | */ 154 | int SetStackAmount(Eluna* E, Aura* aura) 155 | { 156 | uint8 amount = E->CHECKVAL(2); 157 | aura->GetHolder()->SetStackAmount(amount); 158 | return 0; 159 | } 160 | 161 | /** 162 | * Remove this [Aura] from the [Unit] it is applied to. 163 | */ 164 | int Remove(Eluna* E, Aura* aura) 165 | { 166 | aura->GetTarget()->RemoveSpellAuraHolder(aura->GetHolder(), AURA_REMOVE_BY_CANCEL); 167 | E->CHECKOBJ(1)->Invalidate(); 168 | return 0; 169 | } 170 | 171 | ElunaRegister AuraMethods[] = 172 | { 173 | // Getters 174 | { "GetCaster", &LuaAura::GetCaster }, 175 | { "GetCasterGUID", &LuaAura::GetCasterGUID }, 176 | { "GetCasterLevel", &LuaAura::GetCasterLevel }, 177 | { "GetDuration", &LuaAura::GetDuration }, 178 | { "GetMaxDuration", &LuaAura::GetMaxDuration }, 179 | { "GetAuraId", &LuaAura::GetAuraId }, 180 | { "GetStackAmount", &LuaAura::GetStackAmount }, 181 | { "GetOwner", &LuaAura::GetOwner }, 182 | 183 | // Setters 184 | { "SetDuration", &LuaAura::SetDuration }, 185 | { "SetMaxDuration", &LuaAura::SetMaxDuration }, 186 | { "SetStackAmount", &LuaAura::SetStackAmount }, 187 | 188 | // Other 189 | { "Remove", &LuaAura::Remove } 190 | }; 191 | }; 192 | #endif 193 | -------------------------------------------------------------------------------- /ElunaIncludes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_INCLUDES_H 8 | #define _ELUNA_INCLUDES_H 9 | 10 | // Required 11 | #if !defined ELUNA_CMANGOS 12 | #include "AccountMgr.h" 13 | #include "AuctionHouseMgr.h" 14 | #include "Bag.h" 15 | #include "Cell.h" 16 | #include "CellImpl.h" 17 | #include "Channel.h" 18 | #include "Chat.h" 19 | #include "DBCStores.h" 20 | #include "GameEventMgr.h" 21 | #include "GossipDef.h" 22 | #include "GridNotifiers.h" 23 | #include "GridNotifiersImpl.h" 24 | #include "Group.h" 25 | #include "Guild.h" 26 | #include "GuildMgr.h" 27 | #include "Language.h" 28 | #include "Mail.h" 29 | #include "MapManager.h" 30 | #include "ObjectAccessor.h" 31 | #include "ObjectMgr.h" 32 | #include "Opcodes.h" 33 | #include "Pet.h" 34 | #include "Player.h" 35 | #include "ReputationMgr.h" 36 | #include "ScriptMgr.h" 37 | #include "Spell.h" 38 | #include "SpellAuras.h" 39 | #include "SpellMgr.h" 40 | #include "TemporarySummon.h" 41 | #include "WorldPacket.h" 42 | #include "WorldSession.h" 43 | #if defined ELUNA_TRINITY 44 | #include "Battleground.h" 45 | #include "Config.h" 46 | #include "DatabaseEnv.h" 47 | #include "GitRevision.h" 48 | #include "GroupMgr.h" 49 | #include "MiscPackets.h" 50 | #include "MotionMaster.h" 51 | #include "ScriptedCreature.h" 52 | #include "SpellHistory.h" 53 | #include "SpellInfo.h" 54 | #include "WeatherMgr.h" 55 | #elif defined ELUNA_VMANGOS 56 | #include "BasicAI.h" 57 | #include "SQLStorages.h" 58 | #elif defined ELUNA_MANGOS 59 | #include "SQLStorages.h" 60 | #endif // ELUNA_TRINITY 61 | #if ELUNA_EXPANSION > EXP_CLASSIC 62 | #include "ArenaTeam.h" 63 | #endif 64 | #if ELUNA_EXPANSION >= EXP_WOTLK 65 | #include "Vehicle.h" 66 | #endif 67 | #else 68 | #include "Accounts/AccountMgr.h" 69 | #include "AuctionHouse/AuctionHouseMgr.h" 70 | #include "Chat/Channel.h" 71 | #include "Chat/Chat.h" 72 | #include "DBScripts/ScriptMgr.h" 73 | #include "Entities/GossipDef.h" 74 | #include "Entities/Pet.h" 75 | #include "Entities/Player.h" 76 | #include "Entities/TemporarySpawn.h" 77 | #include "GameEvents/GameEventMgr.h" 78 | #include "Globals/ObjectAccessor.h" 79 | #include "Globals/ObjectMgr.h" 80 | #include "Grids/Cell.h" 81 | #include "Grids/CellImpl.h" 82 | #include "Grids/GridNotifiers.h" 83 | #include "Grids/GridNotifiersImpl.h" 84 | #include "Groups/Group.h" 85 | #include "Guilds/Guild.h" 86 | #include "Guilds/GuildMgr.h" 87 | #include "Mails/Mail.h" 88 | #include "Maps/MapManager.h" 89 | #include "Reputation/ReputationMgr.h" 90 | #include "Server/DBCStores.h" 91 | #include "Server/Opcodes.h" 92 | #include "Server/WorldPacket.h" 93 | #include "Server/WorldSession.h" 94 | #include "Spells/Spell.h" 95 | #include "Spells/SpellAuras.h" 96 | #include "Spells/SpellMgr.h" 97 | #include "Tools/Language.h" 98 | #include "Server/SQLStorages.h" 99 | #if ELUNA_EXPANSION > EXP_CLASSIC 100 | #include "Arena/ArenaTeam.h" 101 | #endif 102 | #if ELUNA_EXPANSION >= EXP_WOTLK 103 | #include "Entities/Vehicle.h" 104 | #endif 105 | #if ELUNA_EXPANSION >= EXP_CATA 106 | #include "AI/BaseAI/AggressorAI.h" 107 | #else 108 | #include "AI/BaseAI/UnitAI.h" 109 | #endif 110 | #endif 111 | 112 | #if !defined ELUNA_TRINITY 113 | #include "Config/Config.h" 114 | #include "BattleGroundMgr.h" 115 | #if !defined ELUNA_MANGOS 116 | #include "revision.h" 117 | #else 118 | #include "GitRevision.h" 119 | #include "revision_data.h" 120 | #endif 121 | #endif 122 | 123 | #if !defined ELUNA_MANGOS 124 | #if ELUNA_EXPANSION > EXP_CLASSIC 125 | typedef Opcodes OpcodesList; 126 | #endif 127 | #endif 128 | 129 | /* 130 | * Note: if you add or change a CORE_NAME or CORE_VERSION #define, 131 | * please update LuaGlobalFunctions::GetCoreName or LuaGlobalFunctions::GetCoreVersion documentation example string. 132 | */ 133 | #if defined ELUNA_CMANGOS 134 | #define CORE_NAME "cMaNGOS" 135 | #define CORE_VERSION REVISION_DATE " " REVISION_ID 136 | #if ELUNA_EXPANSION == EXP_CATA 137 | #define NUM_MSG_TYPES MAX_OPCODE_TABLE_SIZE 138 | #endif 139 | #endif 140 | 141 | #if defined ELUNA_VMANGOS 142 | #define CORE_NAME "vMaNGOS" 143 | #define CORE_VERSION REVISION_HASH 144 | #define DEFAULT_LOCALE LOCALE_enUS 145 | #endif 146 | 147 | #if defined ELUNA_MANGOS 148 | #define CORE_NAME "MaNGOS" 149 | #define CORE_VERSION PROJECT_REVISION_NR 150 | #endif 151 | 152 | #if defined ELUNA_TRINITY 153 | #define CORE_NAME "TrinityCore" 154 | #define REGEN_TIME_FULL 155 | #endif 156 | 157 | #if defined ELUNA_TRINITY 158 | #define CORE_VERSION (GitRevision::GetFullVersion()) 159 | #define eWorld (sWorld) 160 | #define eMapMgr (sMapMgr) 161 | #define eGuildMgr (sGuildMgr) 162 | #define eObjectMgr (sObjectMgr) 163 | #define eAccountMgr (sAccountMgr) 164 | #define eAuctionMgr (sAuctionMgr) 165 | #define eGameEventMgr (sGameEventMgr) 166 | #define eObjectAccessor() ObjectAccessor:: 167 | #else 168 | #define eWorld (&sWorld) 169 | #define eMapMgr (&sMapMgr) 170 | #define eConfigMgr (&sConfig) 171 | #define eGuildMgr (&sGuildMgr) 172 | #define eObjectMgr (&sObjectMgr) 173 | #define eAccountMgr (&sAccountMgr) 174 | #define eAuctionMgr (&sAuctionMgr) 175 | #define eGameEventMgr (&sGameEventMgr) 176 | #define eObjectAccessor() sObjectAccessor. 177 | #define SERVER_MSG_STRING SERVER_MSG_CUSTOM 178 | #define TOTAL_LOCALES MAX_LOCALE 179 | #define TARGETICONCOUNT TARGET_ICON_COUNT 180 | #define MAX_TALENT_SPECS MAX_TALENT_SPEC_COUNT 181 | #if !defined ELUNA_VMANGOS 182 | #define TEAM_NEUTRAL TEAM_INDEX_NEUTRAL 183 | #endif 184 | 185 | 186 | #if defined ELUNA_VMANGOS 187 | #define PLAYER_FIELD_LIFETIME_HONORABLE_KILLS PLAYER_FIELD_LIFETIME_HONORBALE_KILLS 188 | #endif 189 | 190 | #if ELUNA_EXPANSION == EXP_TBC 191 | #define SPELL_AURA_MOD_KILL_XP_PCT SPELL_AURA_MOD_XP_PCT 192 | #endif 193 | 194 | #if !defined ELUNA_MANGOS 195 | #if ELUNA_EXPANSION >= EXP_WOTLK 196 | #define UNIT_BYTE2_FLAG_SANCTUARY UNIT_BYTE2_FLAG_SUPPORTABLE 197 | #endif 198 | #endif 199 | 200 | #if !defined ELUNA_CMANGOS 201 | typedef TemporarySummon TempSummon; 202 | #else 203 | typedef TemporarySpawn TempSummon; 204 | #endif 205 | typedef SpellEntry SpellInfo; 206 | #endif // ELUNA_TRINITY 207 | 208 | #endif // _ELUNA_INCLUDES_H 209 | -------------------------------------------------------------------------------- /ElunaUtility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_UTIL_H 8 | #define _ELUNA_UTIL_H 9 | 10 | #include "Common.h" 11 | 12 | #define EXP_CLASSIC 0 13 | #define EXP_TBC 1 14 | #define EXP_WOTLK 2 15 | #define EXP_CATA 3 16 | 17 | #if !defined ELUNA_CMANGOS 18 | #include "SharedDefines.h" 19 | #include "ObjectGuid.h" 20 | #include "Log.h" 21 | #if defined ELUNA_TRINITY 22 | #include "QueryResult.h" 23 | #else 24 | #include "Database/QueryResult.h" 25 | #endif 26 | #else 27 | #include "Globals/SharedDefines.h" 28 | #include "Entities/ObjectGuid.h" 29 | #include "Database/QueryResult.h" 30 | #include "Log/Log.h" 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #if defined ELUNA_TRINITY || ELUNA_CMANGOS 39 | #define USING_BOOST 40 | #endif 41 | 42 | #if defined TRINITY_PLATFORM && defined TRINITY_PLATFORM_WINDOWS 43 | #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS 44 | #define ELUNA_WINDOWS 45 | #endif 46 | #elif defined PLATFORM && defined PLATFORM_WINDOWS 47 | #if PLATFORM == PLATFORM_WINDOWS 48 | #define ELUNA_WINDOWS 49 | #endif 50 | #else 51 | #error Eluna could not determine platform 52 | #endif 53 | 54 | #if defined ELUNA_TRINITY 55 | typedef QueryResult ElunaQuery; 56 | #define GET_GUID GetGUID 57 | #define HIGHGUID_PLAYER HighGuid::Player 58 | #define HIGHGUID_UNIT HighGuid::Unit 59 | #define HIGHGUID_ITEM HighGuid::Item 60 | #define HIGHGUID_GAMEOBJECT HighGuid::GameObject 61 | #define HIGHGUID_PET HighGuid::Pet 62 | #define HIGHGUID_TRANSPORT HighGuid::Transport 63 | #define HIGHGUID_VEHICLE HighGuid::Vehicle 64 | #define HIGHGUID_CONTAINER HighGuid::Container 65 | #define HIGHGUID_DYNAMICOBJECT HighGuid::DynamicObject 66 | #define HIGHGUID_CORPSE HighGuid::Corpse 67 | #define HIGHGUID_MO_TRANSPORT HighGuid::Mo_Transport 68 | #define HIGHGUID_INSTANCE HighGuid::Instance 69 | #define HIGHGUID_GROUP HighGuid::Group 70 | #endif 71 | 72 | #if defined ELUNA_TRINITY 73 | #include "fmt/printf.h" 74 | #define ELUNA_LOG_TC_FMT(TC_LOG_MACRO, ...) \ 75 | try { \ 76 | std::string message = fmt::sprintf(__VA_ARGS__); \ 77 | TC_LOG_MACRO("eluna", "{}", message); \ 78 | } catch (const std::exception& e) { \ 79 | TC_LOG_MACRO("eluna", "Failed to format log message: {}", e.what()); \ 80 | } 81 | #define ELUNA_LOG_INFO(...) ELUNA_LOG_TC_FMT(TC_LOG_INFO, __VA_ARGS__); 82 | #define ELUNA_LOG_ERROR(...) ELUNA_LOG_TC_FMT(TC_LOG_ERROR, __VA_ARGS__); 83 | #define ELUNA_LOG_DEBUG(...) ELUNA_LOG_TC_FMT(TC_LOG_DEBUG, __VA_ARGS__); 84 | #elif defined ELUNA_VMANGOS 85 | typedef std::shared_ptr ElunaQuery; 86 | #define ASSERT MANGOS_ASSERT 87 | #define ELUNA_LOG_INFO(...) sLog.Out(LOG_ELUNA, LOG_LVL_BASIC,__VA_ARGS__); 88 | #define ELUNA_LOG_ERROR(...) sLog.Out(LOG_ELUNA, LOG_LVL_ERROR,__VA_ARGS__); 89 | #define ELUNA_LOG_DEBUG(...) sLog.Out(LOG_ELUNA, LOG_LVL_DEBUG,__VA_ARGS__); 90 | #define GET_GUID GetObjectGuid 91 | #define GetGameObjectTemplate GetGameObjectInfo 92 | #define GetItemTemplate GetItemPrototype 93 | #define GetTemplate GetProto 94 | #else 95 | typedef std::shared_ptr ElunaQuery; 96 | #define ASSERT MANGOS_ASSERT 97 | #define ELUNA_LOG_INFO(...) sLog.outString(__VA_ARGS__); 98 | #define ELUNA_LOG_ERROR(...) sLog.outErrorEluna(__VA_ARGS__); 99 | #define ELUNA_LOG_DEBUG(...) sLog.outDebug(__VA_ARGS__); 100 | #define GET_GUID GetObjectGuid 101 | #define GetGameObjectTemplate GetGameObjectInfo 102 | #define GetItemTemplate GetItemPrototype 103 | #define GetTemplate GetProto 104 | #endif 105 | 106 | #if !defined MAKE_NEW_GUID 107 | #define MAKE_NEW_GUID(l, e, h) ObjectGuid(h, e, l) 108 | #endif 109 | #if !defined GUID_ENPART 110 | #define GUID_ENPART(guid) ObjectGuid(guid).GetEntry() 111 | #endif 112 | #if !defined GUID_LOPART 113 | #define GUID_LOPART(guid) ObjectGuid(guid).GetCounter() 114 | #endif 115 | #if !defined GUID_HIPART 116 | #define GUID_HIPART(guid) ObjectGuid(guid).GetHigh() 117 | #endif 118 | 119 | typedef std::vector BytecodeBuffer; 120 | 121 | class Unit; 122 | class WorldObject; 123 | struct FactionTemplateEntry; 124 | 125 | namespace ElunaUtil 126 | { 127 | uint32 GetCurrTime(); 128 | 129 | uint32 GetTimeDiff(uint32 oldMSTime); 130 | 131 | class ObjectGUIDCheck 132 | { 133 | public: 134 | ObjectGUIDCheck(ObjectGuid guid); 135 | bool operator()(WorldObject* object); 136 | 137 | ObjectGuid _guid; 138 | }; 139 | 140 | // Binary predicate to sort WorldObjects based on the distance to a reference WorldObject 141 | class ObjectDistanceOrderPred 142 | { 143 | public: 144 | ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending = true); 145 | bool operator()(WorldObject const* pLeft, WorldObject const* pRight) const; 146 | 147 | WorldObject const* m_refObj; 148 | const bool m_ascending; 149 | }; 150 | 151 | // Doesn't get self 152 | class WorldObjectInRangeCheck 153 | { 154 | public: 155 | WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, 156 | uint16 typeMask = 0, uint32 entry = 0, uint32 hostile = 0, uint32 dead = 0); 157 | WorldObject const& GetFocusObject() const; 158 | bool operator()(WorldObject* u); 159 | 160 | WorldObject const* const i_obj; 161 | Unit const* i_obj_unit; 162 | FactionTemplateEntry const* i_obj_fact; 163 | uint32 const i_hostile; // 0 both, 1 hostile, 2 friendly 164 | uint32 const i_entry; 165 | float i_range; 166 | uint16 const i_typeMask; 167 | uint32 const i_dead; // 0 both, 1 alive, 2 dead 168 | bool const i_nearest; 169 | }; 170 | 171 | /* 172 | * Encodes `data` in Base-64 and store the result in `output`. 173 | */ 174 | void EncodeData(const unsigned char* data, size_t input_length, std::string& output); 175 | 176 | /* 177 | * Decodes `data` from Base-64 and returns a pointer to the result, or `NULL` on error. 178 | * 179 | * The returned result buffer must be `delete[]`ed by the caller. 180 | */ 181 | unsigned char* DecodeData(const char* data, size_t *output_length); 182 | }; 183 | 184 | #endif 185 | --------------------------------------------------------------------------------