cmake: Fix SDL2 header version detection
authorsheepluva
Sat, 29 Apr 2017 23:45:14 +0200
changeset 12383 e3d9abcc427a
parent 12326 0a6d232b4c49
child 12384 1adc078355d1
cmake: Fix SDL2 header version detection
cmake_modules/FindSDL2_image.cmake
cmake_modules/FindSDL2_mixer.cmake
cmake_modules/FindSDL2_net.cmake
cmake_modules/FindSDL2_ttf.cmake
hedgewars/CMakeLists.txt
hedgewars/uScript.pas.temp
--- a/cmake_modules/FindSDL2_image.cmake	Tue Apr 25 21:00:44 2017 +0200
+++ b/cmake_modules/FindSDL2_image.cmake	Sat Apr 29 23:45:14 2017 +0200
@@ -55,13 +55,13 @@
   PATH_SUFFIXES lib
 )
 
-if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h")
-  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_IMAGE_MINOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL2_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_IMAGE_PATCHLEVEL[ \t]+[0-9]+$")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}")
+if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h")
+  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}")
   set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH})
   unset(SDL2_IMAGE_VERSION_MAJOR_LINE)
   unset(SDL2_IMAGE_VERSION_MINOR_LINE)
@@ -87,8 +87,8 @@
                                   VERSION_VAR SDL2_IMAGE_VERSION_STRING)
 
 # for backward compatiblity
-set(SDL2IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARIES})
-set(SDL2IMAGE_INCLUDE_DIR ${SDL2_IMAGE_INCLUDE_DIRS})
-set(SDL2IMAGE_FOUND ${SDL2_IMAGE_FOUND})
+set(SDLIMAGE_LIBRARY ${SDL2_IMAGE_LIBRARIES})
+set(SDLIMAGE_INCLUDE_DIR ${SDL2_IMAGE_INCLUDE_DIRS})
+set(SDLIMAGE_FOUND ${SDL2_IMAGE_FOUND})
 
 mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)
--- a/cmake_modules/FindSDL2_mixer.cmake	Tue Apr 25 21:00:44 2017 +0200
+++ b/cmake_modules/FindSDL2_mixer.cmake	Sat Apr 29 23:45:14 2017 +0200
@@ -33,8 +33,7 @@
 #  License text for the above reference.)
 
 if(NOT SDL2_MIXER_INCLUDE_DIR AND SDL2MIXER_INCLUDE_DIR)
-  set(SDL2_MIXER_INCLUDE_DIR ${SDL2MIXER_INCLUDE_DIR} CACHE PATH "directory cache
-entry initialized from old variable name")
+  set(SDL2_MIXER_INCLUDE_DIR ${SDL2MIXER_INCLUDE_DIR} CACHE PATH "directory cache entry initialized from old variable name")
 endif()
 find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h
   HINTS
@@ -55,13 +54,13 @@
   PATH_SUFFIXES lib
 )
 
-if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h")
-  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL2_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
+if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h")
+  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
   set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH})
   unset(SDL2_MIXER_VERSION_MAJOR_LINE)
   unset(SDL2_MIXER_VERSION_MINOR_LINE)
@@ -87,8 +86,8 @@
                                   VERSION_VAR SDL2_MIXER_VERSION_STRING)
 
 # for backward compatiblity
-set(SDL2MIXER_LIBRARY ${SDL2_MIXER_LIBRARIES})
-set(SDL2MIXER_INCLUDE_DIR ${SDL2_MIXER_INCLUDE_DIRS})
-set(SDL2MIXER_FOUND ${SDL2_MIXER_FOUND})
+set(SDLMIXER_LIBRARY ${SDL2_MIXER_LIBRARIES})
+set(SDLMIXER_INCLUDE_DIR ${SDL2_MIXER_INCLUDE_DIRS})
+set(SDLMIXER_FOUND ${SDL2_MIXER_FOUND})
 
 mark_as_advanced(SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR)
--- a/cmake_modules/FindSDL2_net.cmake	Tue Apr 25 21:00:44 2017 +0200
+++ b/cmake_modules/FindSDL2_net.cmake	Sat Apr 29 23:45:14 2017 +0200
@@ -55,13 +55,13 @@
   PATH_SUFFIXES lib
 )
 
-if(SDL2_NET_INCLUDE_DIR AND EXISTS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h")
-  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h" SDL2_NET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_NET_MAJOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h" SDL2_NET_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_NET_MINOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL2_net.h" SDL2_NET_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_NET_PATCHLEVEL[ \t]+[0-9]+$")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MAJOR "${SDL2_NET_VERSION_MAJOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MINOR "${SDL2_NET_VERSION_MINOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_PATCH "${SDL2_NET_VERSION_PATCH_LINE}")
+if(SDL2_NET_INCLUDE_DIR AND EXISTS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h")
+  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MAJOR "${SDL2_NET_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MINOR "${SDL2_NET_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_PATCH "${SDL2_NET_VERSION_PATCH_LINE}")
   set(SDL2_NET_VERSION_STRING ${SDL2_NET_VERSION_MAJOR}.${SDL2_NET_VERSION_MINOR}.${SDL2_NET_VERSION_PATCH})
   unset(SDL2_NET_VERSION_MAJOR_LINE)
   unset(SDL2_NET_VERSION_MINOR_LINE)
@@ -87,8 +87,8 @@
                                   VERSION_VAR SDL2_NET_VERSION_STRING)
 
 # for backward compatiblity
-set(SDL2NET_LIBRARY ${SDL2_NET_LIBRARIES})
-set(SDL2NET_INCLUDE_DIR ${SDL2_NET_INCLUDE_DIRS})
-set(SDL2NET_FOUND ${SDL2_NET_FOUND})
+set(SDLNET_LIBRARY ${SDL2_NET_LIBRARIES})
+set(SDLNET_INCLUDE_DIR ${SDL2_NET_INCLUDE_DIRS})
+set(SDLNET_FOUND ${SDL2_NET_FOUND})
 
 mark_as_advanced(SDL2_NET_LIBRARY SDL2_NET_INCLUDE_DIR)
--- a/cmake_modules/FindSDL2_ttf.cmake	Tue Apr 25 21:00:44 2017 +0200
+++ b/cmake_modules/FindSDL2_ttf.cmake	Sat Apr 29 23:45:14 2017 +0200
@@ -55,13 +55,13 @@
   PATH_SUFFIXES lib
 )
 
-if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h")
-  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_TTF_MINOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL2_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_TTF_PATCHLEVEL[ \t]+[0-9]+$")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
+if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h")
+  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+[0-9]+$")
+  file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
+  string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
   set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH})
   unset(SDL2_TTF_VERSION_MAJOR_LINE)
   unset(SDL2_TTF_VERSION_MINOR_LINE)
@@ -87,8 +87,8 @@
                                   VERSION_VAR SDL2_TTF_VERSION_STRING)
 
 # for backward compatiblity
-set(SDL2TTF_LIBRARY ${SDL2_TTF_LIBRARIES})
-set(SDL2TTF_INCLUDE_DIR ${SDL2_TTF_INCLUDE_DIRS})
-set(SDL2TTF_FOUND ${SDL2_TTF_FOUND})
+set(SDLTTF_LIBRARY ${SDL2_TTF_LIBRARIES})
+set(SDLTTF_INCLUDE_DIR ${SDL2_TTF_INCLUDE_DIRS})
+set(SDLTTF_FOUND ${SDL2_TTF_FOUND})
 
 mark_as_advanced(SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR)
--- a/hedgewars/CMakeLists.txt	Tue Apr 25 21:00:44 2017 +0200
+++ b/hedgewars/CMakeLists.txt	Sat Apr 29 23:45:14 2017 +0200
@@ -1,10 +1,10 @@
 enable_language(Pascal)
 
 find_package(SDL2 REQUIRED)
-find_package(SDL2_image REQUIRED)
-find_package(SDL2_net REQUIRED)
-find_package(SDL2_ttf REQUIRED)
-find_package(SDL2_mixer REQUIRED)
+find_package(SDL2_image 2 REQUIRED)
+find_package(SDL2_net 2 REQUIRED)
+find_package(SDL2_ttf 2 REQUIRED)
+find_package(SDL2_mixer 2 REQUIRED)
 
 include(CheckLibraryExists)
 include(${CMAKE_MODULE_PATH}/utils.cmake)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uScript.pas.temp	Sat Apr 29 23:45:14 2017 +0200
@@ -0,0 +1,3640 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uScript;
+(*
+ * This unit defines, implements and registers functions and
+ * variables/constants bindings for usage in Lua scripts.
+ *
+ * Please keep https://hedgewars.org/kb/LuaAPI up to date!
+ *
+ * Note: If you add a new function, make sure to test if _all_ parameters
+ *       work as intended! (Especially conversions errors can sneak in
+ *       unnoticed and render the parameter useless!)
+ *)
+interface
+
+procedure ScriptPrintStack;
+procedure ScriptClearStack;
+
+procedure ScriptLoad(name : shortstring);
+procedure ScriptOnPreviewInit;
+procedure ScriptOnGameInit;
+procedure ScriptOnScreenResize;
+procedure ScriptSetInteger(name : shortstring; value : LongInt);
+procedure ScriptSetString(name : shortstring; value : shortstring);
+
+procedure ScriptCall(fname : shortstring);
+function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
+function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
+function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
+function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
+function ScriptExists(fname : shortstring) : boolean;
+
+procedure LuaParseString(s: shortString);
+
+//function ParseCommandOverride(key, value : shortstring) : shortstring;  This did not work out well
+
+procedure initModule;
+procedure freeModule;
+
+implementation
+
+uses LuaPas,
+    uConsole,
+    uConsts,
+    uGears,
+    uGearsList,
+    uGearsUtils,
+    uFloat,
+    uWorld,
+    uAmmos,
+    uTeams,
+    uSound,
+    uChat,
+    uStats,
+    uStore,
+    uRandom,
+    uTypes,
+    uVariables,
+    uCommands,
+    uCaptions,
+    uDebug,
+    uCollisions,
+    uRenderUtils,
+    uTextures,
+    uLandGraphics,
+    uUtils,
+    uIO,
+    uVisualGearsList,
+    uGearsHandlersMess,
+    uPhysFSLayer,
+    SDLh
+{$IFNDEF PAS2C}
+    , typinfo
+{$ENDIF}
+    ;
+
+var luaState : Plua_State;
+    ScriptAmmoLoadout : shortstring;
+    ScriptAmmoProbability : shortstring;
+    ScriptAmmoDelay : shortstring;
+    ScriptAmmoReinforcement : shortstring;
+    ScriptLoaded : boolean;
+    mapDims : boolean;
+    PointsBuffer: shortstring;
+    prevCursorPoint: TPoint;  // why is tpoint still in sdlh...
+
+{$IFDEF USE_LUA_SCRIPT}
+procedure ScriptPrepareAmmoStore; forward;
+procedure ScriptApplyAmmoStore; forward;
+procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); forward;
+procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte); forward;
+
+var LuaDebugInfo: lua_Debug;
+
+procedure SetGlobals; forward;
+procedure LuaParseString(s: shortString);
+begin
+    SetGlobals;
+    AddFileLog('[Lua] input string: ' + s);
+    AddChatString(#3 + '[Lua] > ' + s);
+    if luaL_dostring(luaState, Str2PChar(s)) <> 0 then
+        begin
+        AddFileLog('[Lua] input string parsing error!');
+        AddChatString(#5 + '[Lua] Error while parsing!');
+        end;
+end;
+
+function LuaUpdateDebugInfo(): Boolean;
+begin
+    FillChar(LuaDebugInfo, sizeof(LuaDebugInfo), 0);
+
+    if lua_getstack(luaState, 1, @LuaDebugInfo) = 0 then
+        exit(false); // stack not deep enough
+
+    // get source name and line count
+    lua_getinfo(luaState, PChar('Sl'), @LuaDebugInfo);
+    exit(true);
+end;
+
+procedure LuaError(s: shortstring);
+var src: shortstring;
+const
+    maxsrclen = 20;
+begin
+    if LuaUpdateDebugInfo() then
+        begin
+        src:= StrPas(LuaDebugInfo.source);
+        s:= 'LUA ERROR [ ... '
+            + copy(src, Length(src) - maxsrclen, maxsrclen - 3) + ':'
+            + inttostr(LuaDebugInfo.currentLine) + ']: ' + s;
+        end
+    else
+        s:= 'LUA ERROR: ' + s;
+    WriteLnToConsole(s);
+    AddChatString(#5 + s);
+    if cTestLua then
+        halt(HaltTestLuaError);
+end;
+
+procedure LuaCallError(error, call, paramsyntax: shortstring);
+begin
+    LuaError(call + ': ' + error);
+    LuaError('-- SYNTAX: ' + call + ' ( ' + paramsyntax + ' )');
+end;
+
+procedure LuaParameterCountError(expected, call, paramsyntax: shortstring; wrongcount: LongInt); inline;
+begin
+    // TODO: i18n?
+    LuaCallError('Wrong number of parameters! (is: ' + inttostr(wrongcount) + ', should be: '+ expected + ')', call, paramsyntax);
+end;
+
+// compare with allowed count
+function CheckLuaParamCount(L : Plua_State; count: LongInt; call, paramsyntax: shortstring): boolean; inline;
+var c: LongInt;
+begin
+    c:= lua_gettop(L);
+    if c <> count then
+        begin
+        LuaParameterCountError('exactly ' + inttostr(count), call, paramsyntax, c);
+        exit(false);
+        end;
+
+    CheckLuaParamCount:= true;
+end;
+
+// check if is either count1 or count2
+function CheckAndFetchParamCount(L : Plua_State; count1, count2: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline;
+begin
+    actual:= lua_gettop(L);
+    if (actual <> count1) and (actual <> count2) then
+        begin
+        LuaParameterCountError('either ' + inttostr(count1) + ' or ' + inttostr(count2), call, paramsyntax, actual);
+        exit(false);
+        end;
+
+    CheckAndFetchParamCount:= true;
+end;
+
+// check if is in range of count1 and count2
+function CheckAndFetchParamCountRange(L : Plua_State; count1, count2: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline;
+begin
+    actual:= lua_gettop(L);
+    if (actual < count1) or (actual > count2) then
+        begin
+        LuaParameterCountError('at least ' + inttostr(count1) + ', but at most ' + inttostr(count2), call, paramsyntax, actual);
+        exit(false);
+        end;
+
+    CheckAndFetchParamCountRange:= true;
+end;
+
+// check if is same or higher as minCount
+function CheckAndFetchLuaParamMinCount(L : Plua_State; minCount: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline;
+begin
+    actual:= lua_gettop(L);
+    if (actual < minCount) then
+        begin
+        LuaParameterCountError(inttostr(minCount) + ' or more', call, paramsyntax, actual);
+        exit(false);
+        end;
+
+    CheckAndFetchLuaParamMinCount:= true;
+end;
+
+function LuaToGearTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TGearType))) or (i > ord(High(TGearType))) then
+        begin
+        LuaCallError('Invalid gearType!', call, paramsyntax);
+        LuaToGearTypeOrd:= -1;
+        end
+    else
+        LuaToGearTypeOrd:= i;
+end;
+
+function LuaToVisualGearTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TVisualGearType))) or (i > ord(High(TVisualGearType))) then
+        begin
+        LuaCallError('Invalid visualGearType!', call, paramsyntax);
+        LuaToVisualGearTypeOrd:= -1;
+        end
+    else
+        LuaToVisualGearTypeOrd:= i;
+end;
+
+function LuaToAmmoTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TAmmoType))) or (i > ord(High(TAmmoType))) then
+        begin
+        LuaCallError('Invalid ammoType!', call, paramsyntax);
+        LuaToAmmoTypeOrd:= -1;
+        end
+    else
+        LuaToAmmoTypeOrd:= i;
+end;
+
+function LuaToStatInfoTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TStatInfoType))) or (i > ord(High(TStatInfoType))) then
+        begin
+        LuaCallError('Invalid statInfoType!', call, paramsyntax);
+        LuaToStatInfoTypeOrd:= -1;
+        end
+    else
+        LuaToStatInfoTypeOrd:= i;
+end;
+
+function LuaToSoundOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TSound))) or (i > ord(High(TSound))) then
+        begin
+        LuaCallError('Invalid soundId!', call, paramsyntax);
+        LuaToSoundOrd:= -1;
+        end
+    else
+        LuaToSoundOrd:= i;
+end;
+
+function LuaToHogEffectOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(THogEffect))) or (i > ord(High(THogEffect))) then
+        begin
+        LuaCallError('Invalid effect type!', call, paramsyntax);
+        LuaToHogEffectOrd:= -1;
+        end
+    else
+        LuaToHogEffectOrd:= i;
+end;
+
+function LuaToCapGroupOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TCapGroup))) or (i > ord(High(TCapGroup))) then
+        begin
+        LuaCallError('Invalid capgroup type!', call, paramsyntax);
+        LuaToCapGroupOrd:= -1;
+        end
+    else
+        LuaToCapGroupOrd:= i;
+end;
+
+function LuaToSpriteOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TSprite))) or (i > ord(High(TSprite))) then
+        begin
+        LuaCallError('Invalid sprite id!', call, paramsyntax);
+        LuaToSpriteOrd:= -1;
+        end
+    else
+        LuaToSpriteOrd:= i;
+end;
+
+function LuaToMapGenOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
+begin
+    if lua_isnoneornil(L, i) then i:= -1
+    else i:= lua_tointeger(L, i);
+    if (i < ord(Low(TMapGen))) or (i > ord(High(TMapGen))) then
+        begin
+        LuaCallError('Invalid mapgen id!', call, paramsyntax);
+        LuaToMapGenOrd:= -1;
+        end
+    else
+        LuaToMapGenOrd:= i;
+end;
+
+// wrapped calls
+
+// functions called from Lua:
+// function(L : Plua_State) : LongInt; Cdecl;
+// where L contains the state, returns the number of return values on the stack
+// call CheckLuaParamCount or CheckAndFetchParamCount
+// to validate/get the number of passed arguments (see their call definitions)
+//
+// use as return value the number of variables pushed back to the lua script
+
+function lc_band(L: PLua_State): LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 2, 'band', 'value1, value2') then
+        lua_pushinteger(L, lua_tointeger(L, 2) and lua_tointeger(L, 1))
+    else
+        lua_pushnil(L);
+    lc_band := 1;
+end;
+
+function lc_bor(L: PLua_State): LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 2, 'bor', 'value1, value2') then
+        lua_pushinteger(L, lua_tointeger(L, 2) or lua_tointeger(L, 1))
+    else
+        lua_pushnil(L);
+    lc_bor := 1;
+end;
+
+function lc_bnot(L: PLua_State): LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'bnot', 'value') then
+        lua_pushinteger(L, (not lua_tointeger(L, 1)))
+    else
+        lua_pushnil(L);
+    lc_bnot := 1;
+end;
+
+function lc_div(L: PLua_State): LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 2, 'div', 'dividend, divisor') then
+        lua_pushinteger(L, lua_tointeger(L, 1) div lua_tointeger(L, 2))
+    else
+        lua_pushnil(L);
+    lc_div := 1;
+end;
+
+function lc_getinputmask(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'GetInputMask', '') then
+        lua_pushinteger(L, InputMask);
+    lc_getinputmask:= 1
+end;
+
+function lc_setinputmask(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'SetInputMask', 'mask') then
+        InputMask:= lua_tointeger(L, 1);
+    lc_setinputmask:= 0
+end;
+
+function lc_writelntoconsole(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'WriteLnToConsole', 'string') then
+        WriteLnToConsole('Lua: ' + lua_tostring(L ,1));
+    lc_writelntoconsole:= 0;
+end;
+
+function lc_parsecommand(L : Plua_State) : LongInt; Cdecl;
+var t: PChar;
+    i,c: LongWord;
+    s: shortstring;
+begin
+    if CheckLuaParamCount(L, 1, 'ParseCommand', 'string') then
+        begin
+        t:= lua_tolstring(L, 1, Psize_t(@c));
+
+        for i:= 1 to c do s[i]:= t[i-1];
+        s[0]:= char(c);
+
+        ParseCommand(s, true, true);
+
+        end;
+    lc_parsecommand:= 0;
+end;
+
+// sets weapon to the desired ammo type
+function lc_setweapon(L : Plua_State) : LongInt; Cdecl;
+var at: LongInt;
+const
+    call = 'SetWeapon';
+    params = 'ammoType';
+begin
+    // no point to run this without any CurrentHedgehog
+    if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 1, call, params)) then
+        begin
+        at:= LuaToAmmoTypeOrd(L, 1, call, params);
+        if at >= 0 then
+            ParseCommand('setweap ' + char(at), true, true);
+        end;
+    lc_setweapon:= 0;
+end;
+
+// enable/disable cinematic effects
+function lc_setcinematicmode(L : Plua_State) : LongInt; Cdecl;
+const
+    call = 'SetCinematicMode';
+    params = 'enable';
+begin
+    if (CheckLuaParamCount(L, 1, call, params)) then
+        begin
+        CinematicScript:= lua_toboolean(L, 1);
+        end;
+    lc_setcinematicmode:= 0;
+end;
+
+// no parameter means reset to default (and 0 means unlimited)
+function lc_setmaxbuilddistance(L : Plua_State) : LongInt; Cdecl;
+var np: LongInt;
+const
+    call = 'SetMaxBuildDistance';
+    params = '[ distInPx ]';
+begin
+    if CheckAndFetchParamCountRange(L, 0, 1, call, params, np) then
+        begin
+        if np = 0 then
+            begin
+            // no args? reset
+            cBuildMaxDist:= cDefaultBuildMaxDist;
+            end
+        else
+            CBuildMaxDist:= lua_tointeger(L, 1);
+        end;
+    lc_setmaxbuilddistance:= 0;
+end;
+
+// sets weapon to whatever weapons is next (wraps around, amSkip is skipped)
+function lc_setnextweapon(L : Plua_State) : LongInt; Cdecl;
+var at          : LongInt;
+    nextAmmo    : TAmmo;
+    s, a, cs, fa: LongInt;
+const
+    call = 'SetNextWeapon';
+    params = '';
+begin
+    if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 0, call, params)) then
+        begin
+        at:= -1;
+        with CurrentHedgehog^ do
+            begin
+            cs:= 0; // current slot
+            fa:= 0; // first ammo item to check
+
+            // if something is selected, find it is successor
+            if curAmmoType <> amNothing then
+                begin
+                // get current slot index
+                cs:= Ammoz[CurAmmoType].Slot;
+                // find current ammo index
+                while (fa < cMaxSlotAmmoIndex)
+                    and (Ammo^[cs, fa].AmmoType <> CurAmmoType) do
+                        inc(fa);
+                // increase once more because we will not successor
+                inc(fa);
+                end;
+
+            // find first available ammo
+            // revisit current slot too (current item might not be first)
+            for s:= cs to cs + cMaxSlotIndex + 1 do
+                begin
+                for a:= fa to cMaxSlotAmmoIndex do
+                    begin
+                    // check if we went full circle
+                    if (a = fa) and (s = cs + cMaxSlotIndex + 1)  then
+                        exit(0);
+
+                    // get ammo
+                    nextAmmo:= Ammo^[s mod (cMaxSlotIndex + 1), a];
+                    // only switch to ammos the hog actually has
+                    if (nextAmmo.AmmoType <> amNothing)
+                        and (nextAmmo.AmmoType <> amSkip) and (nextAmmo.Count > 0) then
+                            begin
+                            at:= ord(nextAmmo.AmmoType);
+                            break;
+                            end;
+                    end;
+                // stop slot loop if something was found
+                if at >= 0 then
+                    break;
+                // check following slots starting with first item
+                fa:= 0;
+                end;
+            end;
+
+        if at >= 0 then
+            ParseCommand('setweap ' + char(at), true, true);
+        end;
+    lc_setnextweapon:= 0;
+end;
+
+function lc_showmission(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 5, 'ShowMission', 'caption, subcaption, text, icon, time') then
+        ShowMission(lua_tostringA(L, 1), lua_tostringA(L, 2), lua_tostringA(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5));
+    lc_showmission:= 0;
+end;
+
+function lc_hidemission(L : Plua_State) : LongInt; Cdecl;
+begin
+    L:= L; // avoid compiler hint
+    HideMission;
+    lc_hidemission:= 0;
+end;
+
+function lc_setammotexts(L : Plua_State) : LongInt; Cdecl;
+const
+    call = 'SetAmmoTexts';
+    params = 'ammoType, name, caption, description';
+begin
+    if CheckLuaParamCount(L, 4, call, params) then
+        SetAmmoTexts(TAmmoType(LuaToAmmoTypeOrd(L, 1, call, params)), lua_tostringA(L, 2), lua_tostringA(L, 3), lua_tostringA(L, 4));
+    lc_setammotexts:= 0;
+end;
+
+function lc_setammodescriptionappendix(L : Plua_State) : LongInt; Cdecl;
+const
+    call = 'SetAmmoDescriptionAppendix';
+    params = 'ammoType, descAppend';
+var
+    ammoType: TAmmoType;
+    descAppend: ansistring;
+begin
+    if CheckLuaParamCount(L, 2, call, params) then
+        begin
+        ammoType := TAmmoType(LuaToAmmoTypeOrd(L, 1, call, params));
+        descAppend := lua_tostringA(L, 2);
+        trluaammoa[Ammoz[ammoType].NameId] := descAppend;
+        end;
+    lc_setammodescriptionappendix := 0;
+end;
+
+function lc_enablegameflags(L : Plua_State) : LongInt; Cdecl;
+var i, n : integer;
+begin
+    // can have 1 or more arguments
+    if CheckAndFetchLuaParamMinCount(L, 1, 'EnableGameFlags', 'gameFlag, ... ', n) then
+        begin
+        for i:= 1 to n do
+            GameFlags := GameFlags or LongWord(lua_tointeger(L, i));
+        ScriptSetInteger('GameFlags', GameFlags);
+        end;
+    lc_enablegameflags:= 0;
+end;
+
+function lc_disablegameflags(L : Plua_State) : LongInt; Cdecl;
+var i , n: integer;
+begin
+    // can have 1 or more arguments
+    if CheckAndFetchLuaParamMinCount(L, 1, 'DisableGameFlags', 'gameFlag, ... ', n) then
+        begin
+        for i:= 1 to n do
+            GameFlags := GameFlags and (not LongWord(lua_tointeger(L, i)));
+        ScriptSetInteger('GameFlags', GameFlags);
+        end;
+    lc_disablegameflags:= 0;
+end;
+
+function lc_cleargameflags(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'ClearGameFlags', '') then
+        begin
+        GameFlags:= 0;
+        ScriptSetInteger('GameFlags', GameFlags);
+        end;
+    lc_cleargameflags:= 0;
+end;
+
+function lc_getgameflag(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGameFlag', 'gameflag') then
+        lua_pushboolean(L, (GameFlags and LongWord(lua_tointeger(L, 1)) <> 0))
+    else
+        lua_pushnil(L);
+    lc_getgameflag:= 1;
+end;
+
+function lc_addcaption(L : Plua_State) : LongInt; Cdecl;
+var cg: LongInt;
+const
+    call = 'AddCaption';
+    params = 'text [, color, captiongroup]';
+begin
+    if CheckAndFetchParamCount(L, 1, 3, call, params, cg) then
+        begin
+        if cg = 1 then
+            AddCaption(lua_tostringA(L, 1), cWhiteColor, capgrpMessage)
+        else
+            begin
+            cg:= LuaToCapGroupOrd(L, 3, call, params);
+            if cg >= 0 then
+                AddCaption(lua_tostringA(L, 1), lua_tointeger(L, 2) shr 8, TCapGroup(cg));
+            end
+        end;
+    lc_addcaption:= 0;
+end;
+
+function lc_campaignlock(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'CampaignLock', 'TODO') then
+        begin
+        // TODO
+        end;
+    lc_campaignlock:= 0;
+end;
+
+function lc_campaignunlock(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'CampaignUnlock', 'TODO') then
+        begin
+        // TODO
+        end;
+    lc_campaignunlock:= 0;
+end;
+
+function lc_spawnfakehealthcrate(L: Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 4,'SpawnFakeHealthCrate', 'x, y, explode, poison') then
+        begin
+        gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
+        HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L)
+        end
+    else
+        lua_pushnil(L);
+    lc_spawnfakehealthcrate := 1;
+end;
+
+function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 4,'SpawnFakeAmmoCrate', 'x, y, explode, poison') then
+        begin
+        gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
+        AmmoCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L)
+        end
+    else
+        lua_pushnil(L);
+    lc_spawnfakeammocrate := 1;
+end;
+
+function lc_spawnfakeutilitycrate(L: PLua_State): LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 4,'SpawnFakeUtilityCrate', 'x, y, explode, poison') then
+        begin
+        gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
+        UtilityCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L)
+        end
+    else
+        lua_pushnil(L);
+    lc_spawnfakeutilitycrate := 1;
+end;
+
+function lc_spawnhealthcrate(L: Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+var health, n: LongInt;
+begin
+    if CheckAndFetchParamCount(L, 2, 3, 'SpawnHealthCrate', 'x, y [, health]', n) then
+        begin
+        if n = 3 then
+            health:= lua_tointeger(L, 3)
+        else
+            health:= cHealthCaseAmount;
+        gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), HealthCrate, health, 0);
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L);
+    lc_spawnhealthcrate := 1;
+end;
+
+function lc_spawnammocrate(L: PLua_State): LongInt; Cdecl;
+var gear: PGear;
+    n   : LongInt;
+begin
+    if CheckAndFetchParamCount(L, 3, 4, 'SpawnAmmoCrate', 'x, y, content [, amount]', n) then
+        begin
+        if n = 3 then
+             gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), 0)
+        else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), lua_tointeger(L, 4));
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L);
+    lc_spawnammocrate := 1;
+end;
+
+function lc_spawnutilitycrate(L: PLua_State): LongInt; Cdecl;
+var gear: PGear;
+    n   : LongInt;
+begin
+    if CheckAndFetchParamCount(L, 3, 4, 'SpawnUtilityCrate', 'x, y, content [, amount]', n) then
+        begin
+        if n = 3 then
+             gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), 0)
+        else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), lua_tointeger(L, 4));
+        if gear <> nil then
+             lua_pushinteger(L, gear^.uid)
+        else lua_pushnil(L);
+       end
+    else
+        lua_pushnil(L);
+    lc_spawnutilitycrate := 1;
+end;
+
+function lc_addgear(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+    x, y, s, t: LongInt;
+    dx, dy: hwFloat;
+    gt: TGearType;
+const
+    call = 'AddGear';
+    params = 'x, y, gearType, state, dx, dy, timer';
+begin
+    if CheckLuaParamCount(L, 7, call, params) then
+        begin
+        t:= LuaToGearTypeOrd(L, 3, call, params);
+        if t >= 0 then
+            begin
+            gt:= TGearType(t);
+            x:= lua_tointeger(L, 1);
+            y:= lua_tointeger(L, 2);
+            s:= lua_tointeger(L, 4);
+            dx:= int2hwFloat(lua_tointeger(L, 5)) / 1000000;
+            dy:= int2hwFloat(lua_tointeger(L, 6)) / 1000000;
+            t:= lua_tointeger(L, 7);
+
+            gear:= AddGear(x, y, gt, s, dx, dy, t);
+            lastGearByUID:= gear;
+            lua_pushinteger(L, gear^.uid)
+            end
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L);
+    lc_addgear:= 1; // 1 return value
+end;
+
+function lc_deletegear(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'DeleteGear', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.Message:= gear^.Message or gmDelete;
+        end;
+    lc_deletegear:= 0
+end;
+
+function lc_addvisualgear(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+    x, y, s, n, layer: LongInt;
+    c: Boolean;
+    vgt: TVisualGearType;
+    uid: Longword;
+const
+    call = 'AddVisualGear';
+    params = 'x, y, visualGearType, state, critical [, layer]';
+begin
+    uid:= 0;
+    if CheckAndFetchParamCount(L, 5, 6, call, params, n) then
+        begin
+        s:= LuaToVisualGearTypeOrd(L, 3, call, params);
+        if s >= 0 then
+            begin
+            vgt:= TVisualGearType(s);
+            x:= lua_tointeger(L, 1);
+            y:= lua_tointeger(L, 2);
+            s:= lua_tointeger(L, 4);
+            c:= lua_toboolean(L, 5);
+
+            if n = 6 then
+                begin
+                layer:= lua_tointeger(L, 6);
+                vg:= AddVisualGear(x, y, vgt, s, c, layer);
+                end
+            else
+                vg:= AddVisualGear(x, y, vgt, s, c);
+
+            if vg <> nil then
+                begin
+                lastVisualGearByUID:= vg;
+                uid:= vg^.uid;
+                lua_pushinteger(L, uid);
+                end;
+            end
+            else
+                lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_addvisualgear:= 1; // 1 return value
+end;
+
+function lc_deletevisualgear(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+begin
+    vg:= nil;
+    if CheckLuaParamCount(L, 1, 'DeleteVisualGear', 'vgUid') then
+        begin
+        vg:= VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then
+            DeleteVisualGear(vg);
+        end;
+    // allow caller to know whether there was something to delete
+    lua_pushboolean(L, vg <> nil);
+    lc_deletevisualgear:= 1
+end;
+
+function lc_getvisualgeartype(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetVisualGearType', 'vgUid') then
+        begin
+        vg := VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then
+            lua_pushinteger(L, ord(vg^.Kind))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getvisualgeartype:= 1
+end;
+
+
+function lc_getvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
+var vg: PVisualGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetVisualGearValues', 'vgUid') then
+        begin
+        vg:= VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then
+            begin
+            lua_pushinteger(L, round(vg^.X));
+            lua_pushinteger(L, round(vg^.Y));
+            lua_pushnumber(L, vg^.dX);
+            lua_pushnumber(L, vg^.dY);
+            lua_pushnumber(L, vg^.Angle);
+            lua_pushinteger(L, vg^.Frame);
+            lua_pushinteger(L, vg^.FrameTicks);
+            lua_pushinteger(L, vg^.State);
+            lua_pushinteger(L, vg^.Timer);
+            lua_pushinteger(L, vg^.Tint);
+            end
+        else
+            begin
+            lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+            lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+            end
+        end
+    else
+        begin
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+        end;
+    lc_getvisualgearvalues:= 10
+end;
+
+function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+begin
+// Param count can be 1-11 at present
+//    if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint') then
+//        begin
+        vg:= VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then
+            begin
+            if not lua_isnoneornil(L, 2) then
+                vg^.X:= lua_tointeger(L, 2);
+            if not lua_isnoneornil(L, 3) then
+                vg^.Y:= lua_tointeger(L, 3);
+            if not lua_isnoneornil(L, 4) then
+                vg^.dX:= lua_tonumber(L, 4);
+            if not lua_isnoneornil(L, 5) then
+                vg^.dY:= lua_tonumber(L, 5);
+            if not lua_isnoneornil(L, 6) then
+                vg^.Angle:= lua_tonumber(L, 6);
+            if not lua_isnoneornil(L, 7) then
+                vg^.Frame:= lua_tointeger(L, 7);
+            if not lua_isnoneornil(L, 8) then
+                vg^.FrameTicks:= lua_tointeger(L, 8);
+            if not lua_isnoneornil(L, 9) then
+                vg^.State:= lua_tointeger(L, 9);
+            if not lua_isnoneornil(L, 10) then
+                vg^.Timer:= lua_tointeger(L, 10);
+            if not lua_isnoneornil(L, 11) then
+                vg^.Tint:= lua_tointeger(L, 11)
+            end;
+//        end
+//    else
+//        lua_pushnil(L); // return value on stack (nil)
+    lc_setvisualgearvalues:= 0
+end;
+
+// so. going to use this to get/set some of the more obscure gear values which were not already exposed elsewhere
+// can keep adding things in the future. isnoneornil makes it safe
+function lc_getgearvalues(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearValues', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            lua_pushinteger(L, gear^.Angle);
+            lua_pushinteger(L, gear^.Power);
+            lua_pushinteger(L, gear^.WDTimer);
+            lua_pushinteger(L, gear^.Radius);
+            lua_pushinteger(L, hwRound(gear^.Density * _10000));
+            lua_pushinteger(L, gear^.Karma);
+            lua_pushnumber(L,  gear^.DirAngle);
+            lua_pushinteger(L, gear^.AdvBounce);
+            lua_pushinteger(L, Integer(gear^.ImpactSound));
+            lua_pushinteger(L, gear^.nImpactSounds);
+            lua_pushinteger(L, gear^.Tint);
+            lua_pushinteger(L, gear^.Damage);
+            lua_pushinteger(L, gear^.Boom)
+            end
+        else
+            begin
+            lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+            lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+            lua_pushnil(L); lua_pushnil(L); lua_pushnil(L)
+            end
+        end
+    else
+        begin
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L)
+        end;
+    lc_getgearvalues:= 13
+end;
+
+function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+// Currently allows 1-14 params
+//    if CheckLuaParamCount(L, 14, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage, Boom') then
+//        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            if not lua_isnoneornil(L, 2) then
+                gear^.Angle := lua_tointeger(L, 2);
+            if not lua_isnoneornil(L, 3) then
+                gear^.Power := lua_tointeger(L, 3);
+            if not lua_isnoneornil(L, 4) then
+                gear^.WDTimer := lua_tointeger(L, 4);
+            if not lua_isnoneornil(L, 5) then
+                gear^.Radius := lua_tointeger(L, 5);
+            if not lua_isnoneornil(L, 6) then
+                gear^.Density:= int2hwFloat(lua_tointeger(L, 6)) / 10000;
+            if not lua_isnoneornil(L, 7) then
+                gear^.Karma := lua_tointeger(L, 7);
+            if not lua_isnoneornil(L, 8) then
+                gear^.DirAngle:= lua_tonumber(L, 8);
+            if not lua_isnoneornil(L, 9) then
+                gear^.AdvBounce := lua_tointeger(L, 9);
+            if not lua_isnoneornil(L, 10) then
+                gear^.ImpactSound := TSound(lua_tointeger(L, 10));
+            if not lua_isnoneornil(L, 11) then
+                gear^.nImpactSounds := lua_tointeger(L, 11);
+            if not lua_isnoneornil(L, 12) then
+                gear^.Tint := lua_tointeger(L, 12);
+            if not lua_isnoneornil(L, 13) then
+                gear^.Damage := lua_tointeger(L, 13);
+            if not lua_isnoneornil(L, 14) then
+                gear^.Boom := lua_tointeger(L, 14);
+            end;
+//        end
+//    else
+//        lua_pushnil(L); // return value on stack (nil)
+    lc_setgearvalues:= 0
+end;
+
+function lc_getfollowgear(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'GetFollowGear', '') then
+        begin
+        if FollowGear = nil then
+            lua_pushnil(L)
+        else
+            lua_pushinteger(L, FollowGear^.uid);
+        end
+    else
+        lua_pushnil(L);
+    lc_getfollowgear:= 1; // 1 return value
+end;
+
+function lc_getgeartype(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearType', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, ord(gear^.Kind))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgeartype:= 1
+end;
+
+function lc_getgearmessage(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearMessage', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.message)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgearmessage:= 1
+end;
+
+function lc_getgearelasticity(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearElasticity', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, hwRound(gear^.elasticity * _10000))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgearelasticity:= 1
+end;
+
+function lc_setgearelasticity(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetGearElasticity', 'gearUid, Elasticity') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.Elasticity:= int2hwFloat(lua_tointeger(L, 2)) / 10000
+        end;
+    lc_setgearelasticity:= 0
+end;
+
+function lc_getgearfriction(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearFriction', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, hwRound(gear^.friction * _10000))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgearfriction:= 1
+end;
+
+function lc_setgearfriction(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetGearFriction', 'gearUid, Friction') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.Friction:= int2hwFloat(lua_tointeger(L, 2)) / 10000
+        end;
+    lc_setgearfriction:= 0
+end;
+
+function lc_setgearmessage(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetGearMessage', 'gearUid, message') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.message:= lua_tointeger(L, 2);
+        end;
+    lc_setgearmessage:= 0
+end;
+
+function lc_getgearpos(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearPos', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.Pos)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgearpos:= 1
+end;
+
+function lc_setgearpos(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetGearPos', 'gearUid, value') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.Pos:= lua_tointeger(L, 2);
+        end;
+    lc_setgearpos:= 0
+end;
+
+function lc_getgearcollisionmask(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearCollisionMask', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.CollisionMask)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgearcollisionmask:= 1
+end;
+
+function lc_setgearcollisionmask(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetGearCollisionMask', 'gearUid, mask') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.CollisionMask:= lua_tointeger(L, 2);
+        end;
+    lc_setgearcollisionmask:= 0
+end;
+
+function lc_gethoglevel(L : Plua_State): LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogLevel', 'gearUid') then
+        begin
+        gear := GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            lua_pushinteger(L, gear^.Hedgehog^.BotLevel)
+        else
+            lua_pushnil(L);
+    end;
+    lc_gethoglevel := 1;
+end;
+
+function lc_sethoglevel(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetHogLevel', 'gearUid, level') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            gear^.Hedgehog^.BotLevel:= lua_tointeger(L, 2);
+        end;
+    lc_sethoglevel:= 0
+end;
+
+function lc_gethogclan(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogClan', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            begin
+            lua_pushinteger(L, gear^.Hedgehog^.Team^.Clan^.ClanIndex)
+            end
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethogclan:= 1
+end;
+
+function lc_getclancolor(L : Plua_State) : LongInt; Cdecl;
+var idx: integer;
+begin
+    if CheckLuaParamCount(L, 1, 'GetClanColor', 'clanIdx') then
+        begin
+        idx:= lua_tointeger(L, 1);
+        if (not lua_isnumber(L, 1)) then
+            begin
+            LuaError('Argument ''clanIdx'' must be a number!');
+            lua_pushnil(L);
+            end
+        else if (idx < 0) or (idx >= ClansCount) then
+            begin
+            LuaError('Argument ''clanIdx'' out of range! (There are currently ' + IntToStr(ClansCount) + ' clans, so valid range is: 0-' + IntToStr(ClansCount-1) + ')');
+            lua_pushnil(L);
+            end
+        else
+            lua_pushinteger(L, ClansArray[idx]^.Color shl 8 or $FF);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getclancolor:= 1
+end;
+
+function lc_setclancolor(L : Plua_State) : LongInt; Cdecl;
+var clan : PClan;
+    team : PTeam;
+    hh   : THedgehog;
+    i, j : LongInt;
+begin
+    if CheckLuaParamCount(L, 2, 'SetClanColor', 'clan, color') then
+        begin
+        i:= lua_tointeger(L,1);
+        if i >= ClansCount then exit(0);
+        clan := ClansArray[i];
+        clan^.Color:= lua_tointeger(L, 2) shr 8;
+
+        for i:= 0 to Pred(clan^.TeamsNumber) do
+            begin
+            team:= clan^.Teams[i];
+            for j:= 0 to 7 do
+                begin
+                hh:= team^.Hedgehogs[j];
+                if (hh.Gear <> nil) or (hh.GearHidden <> nil) then
+                    begin
+                    FreeAndNilTexture(hh.NameTagTex);
+                    hh.NameTagTex:= RenderStringTex(ansistring(hh.Name), clan^.Color, fnt16);
+                    RenderHealth(hh);
+                    end;
+                end;
+            FreeAndNilTexture(team^.NameTagTex);
+            team^.NameTagTex:= RenderStringTex(ansistring(clan^.Teams[i]^.TeamName), clan^.Color, fnt16);
+            end;
+
+        FreeAndNilTexture(clan^.HealthTex);
+        clan^.HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, clan^.Teams[0]^.NameTagTex^.h, clan^.Color);
+        end;
+
+    lc_setclancolor:= 0
+end;
+
+function lc_gethogvoicepack(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogVoicepack', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.Voicepack^.name))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethogvoicepack:= 1
+end;
+
+function lc_gethoggrave(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogGrave', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.GraveName))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethoggrave:= 1
+end;
+
+function lc_gethogflag(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogFlag', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        // TODO error messages
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.Flag))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethogflag:= 1
+end;
+
+function lc_gethogfort(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogFort', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        // TODO error messages
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.FortName))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethogfort:= 1
+end;
+
+function lc_ishoglocal(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'IsHogLocal', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        // TODO error messages
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            lua_pushboolean(L, IsHogLocal(gear^.Hedgehog))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_ishoglocal:= 1
+end;
+
+function lc_gethogteamname(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogTeamName', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        // TODO error messages
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.TeamName))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethogteamname:= 1
+end;
+
+function lc_sethogteamname(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetHogTeamName', 'gearUid, name') then
+        begin
+        gear := GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            begin
+            gear^.Hedgehog^.Team^.TeamName := lua_tostring(L, 2);
+
+            FreeAndNilTexture(gear^.Hedgehog^.Team^.NameTagTex);
+            gear^.Hedgehog^.Team^.NameTagTex:= RenderStringTex(ansistring(gear^.Hedgehog^.Team^.TeamName), gear^.Hedgehog^.Team^.Clan^.Color, fnt16);
+            end
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_sethogteamname:= 1
+end;
+
+function lc_gethogname(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogName', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            begin
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Name))
+            end
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethogname:= 1
+end;
+
+function lc_sethogname(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetHogName', 'gearUid, name') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            begin
+            gear^.Hedgehog^.Name:= lua_tostring(L, 2);
+
+            FreeAndNilTexture(gear^.Hedgehog^.NameTagTex);
+            gear^.Hedgehog^.NameTagTex:= RenderStringTex(ansistring(gear^.Hedgehog^.Name), gear^.Hedgehog^.Team^.Clan^.Color, fnt16)
+            end
+        end;
+    lc_sethogname:= 0;
+end;
+
+function lc_gettimer(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetTimer', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.Timer)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gettimer:= 1
+end;
+
+function lc_getflighttime(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetFlightTime', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.FlightTime)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getflighttime:= 1
+end;
+
+function lc_gethealth(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHealth', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.Health)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gethealth:= 1
+end;
+
+function lc_getx(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetX', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, hwRound(gear^.X))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getx:= 1
+end;
+
+function lc_gety(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetY', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, hwRound(gear^.Y))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gety:= 1
+end;
+
+function lc_copypv(L : Plua_State) : LongInt; Cdecl;
+var gears, geard : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'CopyPV', 'fromGearUid, toGearUid') then
+        begin
+        gears:= GearByUID(lua_tointeger(L, 1));
+        geard:= GearByUID(lua_tointeger(L, 2));
+        if (gears <> nil) and (geard <> nil) then
+            begin
+            geard^.X:= gears^.X;
+            geard^.Y:= gears^.Y;
+            geard^.dX:= gears^.dX;
+            geard^.dY:= gears^.dY;
+            end
+        end;
+    lc_copypv:= 0
+end;
+
+function lc_followgear(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'FollowGear', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then FollowGear:= gear
+        end;
+    lc_followgear:= 0
+end;
+
+function lc_hogsay(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+   vgear : PVisualGear;
+       s : LongWord;
+       n : LongInt;
+begin
+    if CheckAndFetchParamCount(L, 3, 4, 'HogSay', 'gearUid, text, manner [, vgState]', n) then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            // state defaults to 0 if state param is given
+            if n = 4 then
+                s:= lua_tointeger(L, 4)
+            else
+                s:= 0;
+            vgear:= AddVisualGear(0, 0, vgtSpeechBubble, s, true);
+            if vgear <> nil then
+               begin
+               vgear^.Text:= lua_tostring(L, 2);
+               if Gear^.Kind = gtHedgehog then
+                   begin
+                   AddChatString(#9+'[' + gear^.Hedgehog^.Name + '] '+vgear^.text);
+                   vgear^.Hedgehog:= gear^.Hedgehog
+                   end
+               else vgear^.Frame:= gear^.uid;
+
+               vgear^.FrameTicks:= lua_tointeger(L, 3);
+               if (vgear^.FrameTicks < 1) or (vgear^.FrameTicks > 3) then
+                   vgear^.FrameTicks:= 1;
+               lua_pushinteger(L, vgear^.Uid);
+               end
+            end
+        else
+            lua_pushnil(L)
+        end
+    else
+        lua_pushnil(L);
+    lc_hogsay:= 1
+end;
+
+function lc_switchhog(L : Plua_State) : LongInt; Cdecl;
+var gear, prevgear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'SwitchHog', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+// should we allow this when there is no current hedgehog? might do some odd(er) things to turn sequence.
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (CurrentHedgehog <> nil) then
+            begin
+            prevgear := CurrentHedgehog^.Gear;
+            if prevgear <> nil then
+                begin
+                prevgear^.Active := false;
+                prevgear^.State:= prevgear^.State and (not gstHHDriven);
+                prevgear^.Z := cHHZ;
+                prevgear^.Message:= prevgear^.Message or gmRemoveFromList or gmAddToList;
+                end;
+
+            SwitchCurrentHedgehog(gear^.Hedgehog);
+            CurrentTeam:= CurrentHedgehog^.Team;
+
+            gear^.State:= gear^.State or gstHHDriven;
+            gear^.Active := true;
+            gear^.Z := cCurrHHZ;
+            gear^.Message:= gear^.Message or gmRemoveFromList or gmAddToList;
+            end
+        end;
+    lc_switchhog:= 0
+end;
+
+function lc_addammo(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+    at, n: LongInt;
+const
+    call = 'AddAmmo';
+    params = 'gearUid, ammoType [, ammoCount]';
+begin
+    if CheckAndFetchParamCount(L, 2, 3, call, params, n) then
+        begin
+        at:= LuaToAmmoTypeOrd(L, 2, call, params);
+        if at >= 0 then
+            begin
+            gear:= GearByUID(lua_tointeger(L, 1));
+            if (gear <> nil) and (gear^.Hedgehog <> nil) then
+                if n = 2 then
+                    AddAmmo(gear^.Hedgehog^, TAmmoType(at))
+                else
+                    SetAmmo(gear^.Hedgehog^, TAmmoType(at), lua_tointeger(L, 3))
+            end;
+        end;
+    lc_addammo:= 0
+end;
+
+function lc_getammocount(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+    ammo : PAmmo;
+    at   : LongInt;
+const
+    call = 'GetAmmoCount';
+    params = 'gearUid, ammoType';
+begin
+    if CheckLuaParamCount(L, 2, call, params) then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and (gear^.Hedgehog <> nil) then
+            begin
+            at:= LuaToAmmoTypeOrd(L, 2, call, params);
+            if at >= 0 then
+                begin
+                ammo:= GetAmmoEntry(gear^.Hedgehog^, TAmmoType(at));
+                if ammo^.AmmoType = amNothing then
+                    lua_pushinteger(L, 0)
+                else
+                    lua_pushinteger(L, ammo^.Count);
+                end;
+            end
+        else lua_pushinteger(L, 0);
+        end
+    else
+        lua_pushnil(L);
+    lc_getammocount:= 1
+end;
+
+function lc_sethealth(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetHealth', 'gearUid, health') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            gear^.Health:= lua_tointeger(L, 2);
+
+            if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+                begin
+                RenderHealth(gear^.Hedgehog^);
+                RecountTeamHealth(gear^.Hedgehog^.Team)
+                end;
+            // Why did this do a "setalltoactive" ?
+            //SetAllToActive;
+            Gear^.Active:= true;
+            AllInactive:= false
+            end
+        end;
+    lc_sethealth:= 0
+end;
+
+function lc_settimer(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetTimer', 'gearUid, timer') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then gear^.Timer:= lua_tointeger(L, 2)
+        end;
+    lc_settimer:= 0
+end;
+
+function lc_setflighttime(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetFlightTime', 'gearUid, flighttime') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then gear^.FlightTime:= lua_tointeger(L, 2)
+        end;
+    lc_setflighttime:= 0
+end;
+
+function lc_seteffect(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+    t   : LongInt;
+const
+    call = 'SetEffect';
+    params = 'gearUid, effect, effectState';
+begin
+    if CheckLuaParamCount(L, 3, call, params) then
+        begin
+        t:= LuaToHogEffectOrd(L, 2, call, params);
+        if t >= 0 then
+            begin
+            gear := GearByUID(lua_tointeger(L, 1));
+            if (gear <> nil) and (gear^.Hedgehog <> nil) then
+                gear^.Hedgehog^.Effects[THogEffect(t)]:= lua_tointeger(L, 3);
+            end;
+        end;
+    lc_seteffect := 0;
+end;
+
+function lc_geteffect(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+    t    : LongInt;
+const
+    call = 'GetEffect';
+    params = 'gearUid, effect';
+begin
+    if CheckLuaParamCount(L, 2, call, params) then
+        begin
+        t:= LuaToHogEffectOrd(L, 2, call, params);
+        if t >= 0 then
+            begin
+            gear:= GearByUID(lua_tointeger(L, 1));
+            if (gear <> nil) and (gear^.Hedgehog <> nil) then
+                lua_pushinteger(L, gear^.Hedgehog^.Effects[THogEffect(t)])
+            else
+                lua_pushinteger(L, 0)
+            end;
+        end
+    else
+        lua_pushinteger(L, 0);
+    lc_geteffect:= 1
+end;
+
+function lc_setstate(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetState', 'gearUid, state') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            gear^.State:= lua_tointeger(L, 2);
+            SetAllToActive;
+            end
+        end;
+    lc_setstate:= 0
+end;
+
+function lc_getstate(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetState', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.State)
+        else
+            lua_pushnil(L)
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getstate:= 1
+end;
+
+function lc_gettag(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetTag', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.Tag)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_gettag:= 1
+end;
+
+function lc_settag(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetTag', 'gearUid, tag') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            gear^.Tag:= lua_tointeger(L, 2);
+            SetAllToActive;
+            end
+        end;
+    lc_settag:= 0
+end;
+
+function lc_endgame(L : Plua_State) : LongInt; Cdecl;
+begin
+    L:= L; // avoid compiler hint
+    AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000);
+    lc_endgame:= 0
+end;
+
+function lc_sendstat(L : Plua_State) : LongInt; Cdecl;
+var statInfo : TStatInfoType;
+    i, n     : LongInt;
+    color, tn: shortstring;
+    needsTn  : boolean;
+const
+    call = 'SendStat';
+    params = 'statInfoType, color [, teamname]';
+begin
+    if CheckAndFetchParamCount(L, 2, 3, call, params, n) then
+        begin
+        i:= LuaToStatInfoTypeOrd(L, 1, call, params);
+        if i >= 0 then
+            begin
+            statInfo:= TStatInfoType(i);
+            needsTn:= ((statInfo = siPlayerKills) or (statInfo = siClanHealth));
+            // check if param count is correct for the used statInfo
+            if (n = 3) <> needsTn then
+                begin
+                if n = 3 then
+                    LuaCallError(EnumToStr(statInfo) + ' does not support the teamname parameter', call, params)
+                else
+                    LuaCallError(EnumToStr(statInfo) + ' requires the teamname parameter', call, params);
+                end
+            else // count is correct!
+                begin
+                if needsTn then
+                    begin
+                    // 3: team name
+                    for i:= 0 to Pred(TeamsCount) do
+                        begin
+                        color:= _S'0';
+                        tn:= lua_tostring(L, 3);
+                        with TeamsArray[i]^ do
+                            begin
+                                if TeamName = tn then
+                                    begin
+                                    color := uUtils.IntToStr(Clan^.Color);
+                                    Break;
+                                    end
+                            end
+                        end;
+                    if (statInfo = siPlayerKills) then
+                        begin
+                            SendStat(siPlayerKills, color + ' ' +
+                                lua_tostring(L, 2) + ' ' + tn);
+                        end
+                    else if (statInfo = siClanHealth) then
+                        begin
+                            SendStat(siClanHealth, color + ' ' +
+                                lua_tostring(L, 2));
+                        end
+                    end
+                else
+                    begin
+                    SendStat(statInfo,lua_tostring(L, 2));
+                    end;
+                end;
+            end;
+        end;
+    lc_sendstat:= 0
+end;
+
+function lc_sendhealthstatsoff(L : Plua_State) : LongInt; Cdecl;
+begin
+    L:= L; // avoid compiler hint
+    uStats.SendHealthStatsOn := false;
+    lc_sendhealthstatsoff:= 0
+end;
+
+function lc_findplace(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+    fall: boolean;
+    tryhard: boolean;
+    left, right, n: LongInt;
+begin
+    if CheckAndFetchParamCount(L, 4, 5, 'FindPlace', 'gearUid, fall, left, right [, tryHarder]', n) then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        fall:= lua_toboolean(L, 2);
+        left:= lua_tointeger(L, 3);
+        right:= lua_tointeger(L, 4);
+        if n = 5 then
+            tryhard:= lua_toboolean(L, 5)
+        else
+            tryhard:= false;
+        if gear <> nil then
+            FindPlace(gear, fall, left, right, tryhard);
+        if gear <> nil then
+            lua_pushinteger(L, gear^.uid)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_findplace:= 1
+end;
+
+function lc_playsound(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+    n, s: LongInt;
+const
+    call = 'PlaySound';
+    params = 'soundId [, hhGearUid]';
+begin
+    if CheckAndFetchParamCount(L, 1, 2, call, params, n) then
+        begin
+        s:= LuaToSoundOrd(L, 1, call, params);
+        if s >= 0 then
+            begin
+            // no gear specified
+            if n = 1 then
+                PlaySound(TSound(s))
+            else
+                begin
+                gear:= GearByUID(lua_tointeger(L, 2));
+                if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+                    AddVoice(TSound(s),gear^.Hedgehog^.Team^.Voicepack)
+                end;
+            end;
+        end;
+    lc_playsound:= 0;
+end;
+
+function lc_addteam(L : Plua_State) : LongInt; Cdecl;
+var np: LongInt;
+begin
+    if CheckAndFetchParamCount(L, 5, 6, 'AddTeam', 'teamname, color, grave, fort, voicepack [, flag]', np) then
+        begin
+        ParseCommand('addteam x ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 1), true, true);
+        ParseCommand('grave ' + lua_tostring(L, 3), true, true);
+        ParseCommand('fort ' + lua_tostring(L, 4), true, true);
+        ParseCommand('voicepack ' + lua_tostring(L, 5), true, true);
+        if (np = 6) then ParseCommand('flag ' + lua_tostring(L, 6), true, true);
+        CurrentTeam^.Binds:= DefaultBinds
+        // fails on x64
+        //lua_pushinteger(L, LongInt(CurrentTeam));
+        end;
+    //else
+        //lua_pushnil(L)
+    lc_addteam:= 0;//1;
+end;
+
+function lc_dismissteam(L : Plua_State) : LongInt; Cdecl;
+var HHGear: PGear;
+    i, h  : LongInt;
+    hidden: boolean;
+begin
+    if CheckLuaParamCount(L, 1, 'DismissTeam', 'teamname') then
+        begin
+        if TeamsCount > 0 then
+            for i:= 0 to Pred(TeamsCount) do
+                begin
+                // skip teams that don't have matching name
+                if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then
+                    continue;
+
+                // destroy all hogs of matching team, including the hidden ones
+                for h:= 0 to cMaxHHIndex do
+                    begin
+                    hidden:= (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil);
+                    if hidden then
+                        RestoreHog(@TeamsArray[i]^.Hedgehogs[h]);
+                    // destroy hedgehog gear, if any
+                    HHGear:= TeamsArray[i]^.Hedgehogs[h].Gear;
+                    if HHGear <> nil then
+                        begin
+                        // smoke effect
+                        if (not hidden) then
+                            begin
+                            AddVisualGear(hwRound(HHGear^.X), hwRound(HHGear^.Y), vgtSmokeWhite);
+                            AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
+                            AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
+                            AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
+                            AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
+                            end;
+                        HHGear^.Message:= HHGear^.Message or gmDestroy;
+                        end;
+                    end;
+                // can't dismiss more than one team
+                break;
+                end;
+        end;
+    lc_dismissteam:= 0;
+end;
+
+function lc_addhog(L : Plua_State) : LongInt; Cdecl;
+var temp: ShortString;
+begin
+    if CheckLuaParamCount(L, 4, 'AddHog', 'hogname, botlevel, health, hat') then
+        begin
+        temp:= lua_tostring(L, 4);
+        ParseCommand('addhh ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 3) + ' ' + lua_tostring(L, 1), true, true);
+        ParseCommand('hat ' + temp, true, true);
+        lua_pushinteger(L, CurrentHedgehog^.Gear^.uid);
+        end
+    else
+        lua_pushnil(L);
+    lc_addhog:= 1;
+end;
+
+function lc_hogturnleft(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'HogTurnLeft', 'gearUid, boolean') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.dX.isNegative:= lua_toboolean(L, 2);
+        end;
+    lc_hogturnleft:= 0;
+end;
+
+function lc_getgearposition(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearPosition', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            lua_pushinteger(L, hwRound(gear^.X));
+            lua_pushinteger(L, hwRound(gear^.Y))
+            end
+        else
+            begin
+            lua_pushnil(L);
+            lua_pushnil(L)
+            end;
+        end
+    else
+        begin
+        lua_pushnil(L);
+        lua_pushnil(L)
+        end;
+    lc_getgearposition:= 2;
+end;
+
+function lc_setgearposition(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+    col: boolean;
+    x, y: LongInt;
+begin
+    if CheckLuaParamCount(L, 3, 'SetGearPosition', 'gearUid, x, y') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            col:= gear^.CollisionIndex >= 0;
+            x:= lua_tointeger(L, 2);
+            y:= lua_tointeger(L, 3);
+            if col then
+                DeleteCI(gear);
+            gear^.X:= int2hwfloat(x);
+            gear^.Y:= int2hwfloat(y);
+            if col then
+                AddCI(gear);
+            SetAllToActive
+            end
+        end;
+    lc_setgearposition:= 0
+end;
+
+function lc_getgeartarget(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearTarget', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            lua_pushinteger(L, gear^.Target.X);
+            lua_pushinteger(L, gear^.Target.Y)
+            end
+        else
+            begin
+            lua_pushnil(L);
+            lua_pushnil(L)
+            end
+        end
+    else
+        begin
+        lua_pushnil(L);
+        lua_pushnil(L)
+        end;
+    lc_getgeartarget:= 2;
+end;
+
+function lc_setgeartarget(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 3, 'SetGearTarget', 'gearUid, x, y') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            gear^.Target.X:= lua_tointeger(L, 2);
+            gear^.Target.Y:= lua_tointeger(L, 3)
+            end
+        end;
+    lc_setgeartarget:= 0
+end;
+
+function lc_getgearvelocity(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+var t: LongInt;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearVelocity', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            t:= hwRound(gear^.dX * 1000000);
+            // gear dX determines hog orientation
+            if (gear^.dX.isNegative) and (t = 0) then t:= -1;
+            lua_pushinteger(L, t);
+            lua_pushinteger(L, hwRound(gear^.dY * 1000000))
+            end
+        end
+    else
+        begin
+        lua_pushnil(L);
+        lua_pushnil(L);
+        end;
+    lc_getgearvelocity:= 2;
+end;
+
+function lc_setgearvelocity(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 3, 'SetGearVelocity', 'gearUid, dx, dy') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            begin
+            gear^.dX:= int2hwFloat(lua_tointeger(L, 2)) / 1000000;
+            gear^.dY:= int2hwFloat(lua_tointeger(L, 3)) / 1000000;
+            SetAllToActive;
+            end
+        end;
+    lc_setgearvelocity:= 0
+end;
+
+function lc_setzoom(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'SetZoom', 'zoomLevel') then
+        begin
+        ZoomValue:= lua_tonumber(L, 1);
+        if ZoomValue < cMaxZoomLevel then
+            ZoomValue:= cMaxZoomLevel;
+        if ZoomValue > cMinZoomLevel then
+            ZoomValue:= cMinZoomLevel;
+        end;
+    lc_setzoom:= 0
+end;
+
+function lc_getzoom(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'GetZoom', '') then
+        lua_pushnumber(L, ZoomValue)
+    else
+        lua_pushnil(L);
+    lc_getzoom:= 1
+end;
+
+function lc_setammo(L : Plua_State) : LongInt; Cdecl;
+var np, at: LongInt;
+const
+    call = 'SetAmmo';
+    params = 'ammoType, count, probability, delay [, numberInCrate]';
+begin
+    if CheckAndFetchParamCount(L, 4, 5, call, params, np) then
+        begin
+        at:= LuaToAmmoTypeOrd(L, 1, call, params);
+        if at >= 0 then
+            begin
+            if np = 4 then
+                ScriptSetAmmo(TAmmoType(at), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), 1)
+            else
+                ScriptSetAmmo(TAmmoType(at), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5));
+            end;
+        end;
+    lc_setammo:= 0
+end;
+
+function lc_setammodelay(L : Plua_State) : LongInt; Cdecl;
+var at: LongInt;
+const
+    call = 'SetAmmoDelay';
+    params = 'ammoType, delay';
+begin
+    if CheckLuaParamCount(L, 2, call, params) then
+        begin
+        at:= LuaToAmmoTypeOrd(L, 1, call, params);
+        if at >= 0 then
+            ScriptSetAmmoDelay(TAmmoType(at), lua_tointeger(L, 2));
+        end;
+    lc_setammodelay:= 0
+end;
+
+function lc_setammostore(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 4, 'SetAmmoStore', 'loadouts, probabilities, delays, reinforments') then
+        begin
+        ScriptAmmoLoadout:= lua_tostring(L, 1);
+        ScriptAmmoProbability:= lua_tostring(L, 2);
+        ScriptAmmoDelay:= lua_tostring(L, 3);
+        ScriptAmmoReinforcement:= lua_tostring(L, 4);
+        end;
+    lc_setammostore:= 0
+end;
+
+function lc_getrandom(L : Plua_State) : LongInt; Cdecl;
+var m : LongInt;
+begin
+    if CheckLuaParamCount(L, 1, 'GetRandom', 'number') then
+        begin
+        m:= lua_tointeger(L, 1);
+        if (m > 0) then
+            lua_pushinteger(L, GetRandom(m))
+        else
+            begin
+            LuaError('Lua: Tried to pass 0 to GetRandom!');
+            lua_pushnil(L);
+            end
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getrandom:= 1
+end;
+
+function lc_setwind(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'SetWind', 'windSpeed') then
+        begin
+        cWindSpeed:= int2hwfloat(lua_tointeger(L, 1)) / 100 * cMaxWindSpeed;
+        cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue;
+        if cWindSpeed.isNegative then
+            CWindSpeedf := -cWindSpeedf;
+        AddVisualGear(0, 0, vgtSmoothWindBar);
+        end;
+    lc_setwind:= 0
+end;
+
+function lc_maphasborder(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'MapHasBorder', '') then
+        lua_pushboolean(L, hasBorder)
+    else
+        lua_pushnil(L);
+    lc_maphasborder:= 1
+end;
+
+function lc_getgearradius(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetGearRadius', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            lua_pushinteger(L, gear^.Radius)
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_getgearradius:= 1
+end;
+
+function lc_gethoghat(L : Plua_State): LongInt; Cdecl;
+var gear : PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'GetHogHat', 'gearUid') then
+        begin
+        gear := GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
+            lua_pushstring(L, str2pchar(gear^.Hedgehog^.Hat))
+        else
+            lua_pushnil(L);
+        end
+    else
+        lua_pushnil(L);
+    lc_gethoghat := 1;
+end;
+
+function lc_sethoghat(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+    hat: ShortString;
+begin
+    if CheckLuaParamCount(L, 2, 'SetHogHat', 'gearUid, hat') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+            begin
+            hat:= lua_tostring(L, 2);
+            gear^.Hedgehog^.Hat:= hat;
+            AddFileLog('Changed hat to: '+hat);
+            if (Length(hat) > 39) and (Copy(hat,1,8) = 'Reserved') and (Copy(hat,9,32) = gear^.Hedgehog^.Team^.PlayerHash) then
+                LoadHedgehogHat(gear^.Hedgehog^, 'Reserved/' + Copy(hat,9,Length(hat)-8))
+            else
+                LoadHedgehogHat(gear^.Hedgehog^, hat)
+            end
+        end;
+    lc_sethoghat:= 0;
+end;
+
+function lc_placesprite(L : Plua_State) : LongInt; Cdecl;
+var spr   : TSprite;
+    lf    : Word;
+    tint  : LongWord;
+    i, n : LongInt;
+    placed, behind, flipHoriz, flipVert : boolean;
+const
+    call = 'PlaceSprite';
+    params = 'x, y, sprite, frameIdx, tint, behind, flipHoriz, flipVert, [, landFlag, ... ]';
+begin
+    placed:= false;
+    if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
+        begin
+        if not lua_isnoneornil(L, 5) then
+            tint := lua_tointeger(L, 5)
+        else tint := $FFFFFFFF;
+        if not lua_isnoneornil(L, 6) then
+            behind := lua_toboolean(L, 6)
+        else behind := false;
+        if not lua_isnoneornil(L, 7) then
+            flipHoriz := lua_toboolean(L, 7)
+        else flipHoriz := false;
+        if not lua_isnoneornil(L, 8) then
+            flipVert := lua_toboolean(L, 8)
+        else flipVert := false;
+        lf:= 0;
+
+        // accept any amount of landflags, loop is never executed if n<9
+        for i:= 9 to n do
+            lf:= lf or lua_tointeger(L, i);
+
+        n:= LuaToSpriteOrd(L, 3, call, params);
+        if n >= 0 then
+            begin
+            spr:= TSprite(n);
+            if SpritesData[spr].Surface = nil then
+                LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' )
+            else
+                placed:= ForcePlaceOnLand(
+                    lua_tointeger(L, 1) - SpritesData[spr].Width div 2,
+                    lua_tointeger(L, 2) - SpritesData[spr].Height div 2,
+                    spr, lua_tointeger(L, 4), lf, tint, behind, flipHoriz, flipVert);
+            end;
+        end;
+
+    lua_pushboolean(L, placed);
+    lc_placesprite:= 1
+end;
+
+function lc_erasesprite(L : Plua_State) : LongInt; Cdecl;
+var spr   : TSprite;
+    lf    : Word;
+    i, n : LongInt;
+    eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert : boolean;
+const
+    call = 'EraseSprite';
+    params = 'x, y, sprite, frameIdx, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert, [, landFlag, ... ]';
+begin
+    if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
+        begin
+        if not lua_isnoneornil(L, 5) then
+            eraseOnLFMatch := lua_toboolean(L, 5)
+        else eraseOnLFMatch := false;
+        if not lua_isnoneornil(L, 6) then
+            onlyEraseLF := lua_toboolean(L, 6)
+        else onlyEraseLF := false;
+        if not lua_isnoneornil(L, 7) then
+            flipHoriz := lua_toboolean(L, 7)
+        else flipHoriz := false;
+        if not lua_isnoneornil(L, 8) then
+            flipVert := lua_toboolean(L, 8)
+        else flipVert := false;
+        lf:= 0;
+
+        // accept any amount of landflags, loop is never executed if n<9
+        for i:= 9 to n do
+            lf:= lf or lua_tointeger(L, i);
+
+        n:= LuaToSpriteOrd(L, 3, call, params);
+        if n >= 0 then
+            begin
+            spr:= TSprite(n);
+            if SpritesData[spr].Surface = nil then
+                LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' )
+            else
+                EraseLand(
+                    lua_tointeger(L, 1) - SpritesData[spr].Width div 2,
+                    lua_tointeger(L, 2) - SpritesData[spr].Height div 2,
+                    spr, lua_tointeger(L, 4), lf, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert);
+            end;
+        end;
+    lc_erasesprite:= 0
+end;
+
+function lc_placegirder(L : Plua_State) : LongInt; Cdecl;
+var placed: boolean;
+begin
+    placed:= false;
+    if CheckLuaParamCount(L, 3, 'PlaceGirder', 'x, y, frameIdx') then
+        placed:= TryPlaceOnLandSimple(
+            lua_tointeger(L, 1) - SpritesData[sprAmGirder].Width div 2,
+            lua_tointeger(L, 2) - SpritesData[sprAmGirder].Height div 2,
+            sprAmGirder, lua_tointeger(L, 3), true, false);
+
+    lua_pushboolean(L, placed);
+    lc_placegirder:= 1
+end;
+
+function lc_placerubber(L : Plua_State) : LongInt; Cdecl;
+var placed: boolean;
+begin
+    placed:= false;
+    if CheckLuaParamCount(L, 3, 'PlaceRubber', 'x, y, frameIdx') then
+        placed:= TryPlaceOnLand(
+            lua_tointeger(L, 1) - SpritesData[sprAmRubber].Width div 2,
+            lua_tointeger(L, 2) - SpritesData[sprAmRubber].Height div 2,
+            sprAmRubber, lua_tointeger(L, 3), true, lfBouncy);
+
+    lua_pushboolean(L, placed);
+    lc_placerubber:= 1
+end;
+
+function lc_getcurammotype(L : Plua_State): LongInt; Cdecl;
+begin
+    if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 0, 'GetCurAmmoType', '')) then
+        lua_pushinteger(L, ord(CurrentHedgehog^.CurAmmoType))
+    else
+        lua_pushinteger(L, ord(amNothing));
+    lc_getcurammotype := 1;
+end;
+
+function lc_savecampaignvar(L : Plua_State): LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 2, 'SaveCampaignVar', 'varname, value') then
+        SendIPC('V!' + lua_tostring(L, 1) + ' ' + lua_tostring(L, 2) + #0);
+    lc_savecampaignvar := 0;
+end;
+
+function lc_getcampaignvar(L : Plua_State): LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'GetCampaignVar', 'varname') then
+        SendIPCAndWaitReply('V?' + lua_tostring(L, 1) + #0);
+    lua_pushstring(L, str2pchar(CampaignVariable));
+    lc_getcampaignvar := 1;
+end;
+
+function lc_hidehog(L: Plua_State): LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'HideHog', 'gearUid') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        HideHog(gear^.hedgehog)
+        end;
+    lc_hidehog := 0;
+end;
+
+function lc_restorehog(L: Plua_State): LongInt; Cdecl;
+var i, h: LongInt;
+    uid: LongWord;
+begin
+    if CheckLuaParamCount(L, 1, 'RestoreHog', 'gearUid') then
+        begin
+        uid:= LongWord(lua_tointeger(L, 1));
+        if TeamsCount > 0 then
+            for i:= 0 to Pred(TeamsCount) do
+                for h:= 0 to cMaxHHIndex do
+                    if (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil) and (TeamsArray[i]^.Hedgehogs[h].GearHidden^.uid = uid) then
+                        begin
+                        RestoreHog(@TeamsArray[i]^.Hedgehogs[h]);
+                        exit(0)
+                        end
+        end;
+    lc_restorehog := 0;
+end;
+
+// boolean TestRectForObstacle(x1, y1, x2, y2, landOnly)
+function lc_testrectforobstacle(L : Plua_State) : LongInt; Cdecl;
+var rtn: Boolean;
+begin
+    if CheckLuaParamCount(L, 5, 'TestRectForObstacle', 'x1, y1, x2, y2, landOnly') then
+        begin
+        rtn:= TestRectangleForObstacle(
+                    lua_tointeger(L, 1),
+                    lua_tointeger(L, 2),
+                    lua_tointeger(L, 3),
+                    lua_tointeger(L, 4),
+                    lua_toboolean(L, 5)
+                    );
+        lua_pushboolean(L, rtn);
+        end
+    else
+        lua_pushnil(L); // return value on stack (nil)
+    lc_testrectforobstacle:= 1
+end;
+
+
+function lc_getgravity(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'GetGravity', '') then
+        lua_pushinteger(L, hwRound(SignAs(_0_5, cGravity) + (cGravity * 50 / cMaxWindSpeed)));
+    lc_getgravity:= 1
+end;
+
+function lc_setgravity(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'SetGravity', 'percent') then
+        begin
+        cGravity:= _0_02 * lua_tointeger(L, 1) * cMaxWindSpeed;
+        cGravityf:= 0.00025 * lua_tointeger(L, 1) * 0.02
+        end;
+    lc_setgravity:= 0
+end;
+
+function lc_setwaterline(L : Plua_State) : LongInt; Cdecl;
+var iterator: PGear;
+begin
+    if CheckLuaParamCount(L, 1, 'SetWaterLine', 'waterline') then
+        begin
+        cWaterLine:= lua_tointeger(L,1);
+        AllInactive:= false;
+        iterator:= GearsList;
+        while iterator <> nil do
+            begin
+            if not (iterator^.Kind in [gtPortal, gtAirAttack]) and (iterator^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) then
+                begin
+                iterator^.Active:= true;
+                if iterator^.dY.QWordValue = 0 then iterator^.dY.isNegative:= false;
+                iterator^.State:= iterator^.State or gstMoving;
+                DeleteCI(iterator)
+                end;
+            iterator:= iterator^.NextGear
+            end
+        end;
+    lc_setwaterline:= 0
+end;
+
+function lc_setgearaihints(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+    if CheckLuaParamCount(L, 2, 'SetAIHintOnGear', 'gearUid, aiHints') then
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then
+            gear^.aihints:= lua_tointeger(L, 2);
+        end;
+    lc_setgearaihints:= 0
+end;
+
+
+function lc_hedgewarsscriptload(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'HedgewarsScriptLoad', 'scriptPath') then
+        ScriptLoad(lua_tostring(L, 1))
+    else
+        lua_pushnil(L);
+    lc_hedgewarsscriptload:= 0;
+end;
+
+
+function lc_declareachievement(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 4, 'DeclareAchievement', 'achievementId, teamname, location, value') then
+        declareAchievement(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), lua_tointeger(L, 4));
+    lc_declareachievement:= 0
+end;
+
+function lc_getammoname(L : Plua_state) : LongInt; Cdecl;
+var np, at: LongInt;
+    ignoreOverwrite: Boolean;
+const call = 'GetAmmoName';
+      params = 'ammoType [, ignoreOverwrite ]';
+begin
+    if CheckAndFetchParamCountRange(L, 1, 2, call, params, np) then
+        begin
+        at:= LuaToAmmoTypeOrd(L, 1, call, params);                                                                                                   
+        ignoreOverwrite := false;
+        if np > 1 then
+            ignoreOverwrite := lua_toboolean(L, 2);
+        if at >= 0 then   
+            if (not ignoreOverwrite) and (length(trluaammo[Ammoz[TAmmoType(at)].NameId]) > 0) then
+                lua_pushstring(L, PChar(trluaammo[Ammoz[TAmmoType(at)].NameId]))
+            else
+                lua_pushstring(L, PChar(trammo[Ammoz[TAmmoType(at)].NameId]));
+        end
+    else
+        lua_pushnil(L);
+    lc_getammoname:= 1;
+end;
+
+function lc_startghostpoints(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 1, 'StartGhostPoints', 'count') then
+        startGhostPoints(lua_tointeger(L, 1));
+    lc_startghostpoints:= 0
+end;
+
+function lc_dumppoint(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 2, 'DumpPoint', 'x, y') then
+        dumpPoint(lua_tointeger(L, 1), lua_tointeger(L, 2));
+    lc_dumppoint:= 0
+end;
+
+
+procedure ScriptFlushPoints();
+begin
+    ParseCommand('draw ' + PointsBuffer, true, true);
+    PointsBuffer:= '';
+end;
+
+
+function lc_addPoint(L : Plua_State) : LongInt; Cdecl;
+var np, param: LongInt;
+begin
+    if CheckAndFetchParamCountRange(L, 2, 4, 'AddPoint', 'x, y [, width [, erase] ]', np) then
+        begin
+        // x
+        param:= LongInt(lua_tointeger(L,1));
+        PointsBuffer:= PointsBuffer + char((param shr 8) and $FF);
+        PointsBuffer:= PointsBuffer + char((param and $FF));
+        // y
+        param:= LongInt(lua_tointeger(L,2));
+        PointsBuffer:= PointsBuffer + char((param shr 8) and $FF);
+        PointsBuffer:= PointsBuffer + char((param and $FF));
+        // width
+        if np > 2 then
+            begin
+            param:= lua_tointeger(L,3);
+            param:= (param or $80);
+            // erase
+            if (np > 3) and lua_toboolean(L, 4) then
+                param:= (param or $40);
+            PointsBuffer:= PointsBuffer + char(param);
+            end
+        // no width defined
+        else
+            PointsBuffer:= PointsBuffer + char(0);
+
+        // flush before shortstring limit length is reached
+        if length(PointsBuffer) > 245 then
+            ScriptFlushPoints();
+        end;
+    lc_addPoint:= 0
+end;
+
+
+function lc_flushPoints(L : Plua_State) : LongInt; Cdecl;
+begin
+    if CheckLuaParamCount(L, 0, 'FlushPoints', '') then
+        if length(PointsBuffer) > 0 then
+            ScriptFlushPoints();
+    lc_flushPoints:= 0
+end;
+
+// stuff for lua tests
+function lc_endluatest(L : Plua_State) : LongInt; Cdecl;
+var rstring: shortstring;
+const
+    call = 'EndLuaTest';
+    params = 'TEST_SUCCESSFUL or TEST_FAILED';
+begin
+    if CheckLuaParamCount(L, 1, call, params) then
+        begin
+
+        case lua_tointeger(L, 1) of
+            HaltTestSuccess : rstring:= 'Success';
+            HaltTestFailed: rstring:= 'FAILED';
+        else
+            begin
+            LuaCallError('Parameter must be either ' + params, call, params);
+            exit(0);
+            end;
+        end;
+
+        if cTestLua then
+            begin
+            WriteLnToConsole('Lua test finished, result: ' + rstring);
+            halt(lua_tointeger(L, 1));
+            end
+        else LuaError('Not in lua test mode, engine will keep running. Reported test result: ' + rstring);
+
+        end;
+
+    lc_endluatest:= 0;
+end;
+///////////////////
+
+procedure ScriptPrintStack;
+var n, i : LongInt;
+begin
+    n:= lua_gettop(luaState);
+    WriteLnToConsole('Lua: Stack (' + inttostr(n) + ' elements):');
+    for i:= 1 to n do
+        if not lua_isboolean(luaState, i) then
+            WriteLnToConsole('Lua:  ' + inttostr(i) + ': ' + lua_tostring(luaState, i))
+        else if lua_toboolean(luaState, i) then
+            WriteLnToConsole('Lua:  ' + inttostr(i) + ': true')
+        else
+            WriteLnToConsole('Lua:  ' + inttostr(i) + ': false');
+end;
+
+procedure ScriptClearStack;
+begin
+    lua_settop(luaState, 0)
+end;
+
+procedure ScriptSetNil(name : shortstring);
+begin
+    lua_pushnil(luaState);
+    lua_setglobal(luaState, Str2PChar(name));
+end;
+
+procedure ScriptSetInteger(name : shortstring; value : LongInt);
+begin
+    lua_pushinteger(luaState, value);
+    lua_setglobal(luaState, Str2PChar(name));
+end;
+
+procedure ScriptSetString(name : shortstring; value : shortstring);
+begin
+    lua_pushstring(luaState, Str2PChar(value));
+    lua_setglobal(luaState, Str2PChar(name));
+end;
+
+function ScriptGetInteger(name : shortstring) : LongInt;
+begin
+    lua_getglobal(luaState, Str2PChar(name));
+    ScriptGetInteger:= lua_tointeger(luaState, -1);
+    lua_pop(luaState, 1);
+end;
+
+function ScriptGetString(name : shortstring) : shortstring;
+begin
+    lua_getglobal(luaState, Str2PChar(name));
+    ScriptGetString:= lua_tostring(luaState, -1);
+    lua_pop(luaState, 1);
+end;
+
+procedure ScriptOnPreviewInit;
+begin
+// not required if there is no script to run
+if not ScriptLoaded then
+    exit;
+
+ScriptSetString('Seed', cSeed);
+ScriptSetInteger('TemplateFilter', cTemplateFilter);
+ScriptSetInteger('TemplateNumber', LuaTemplateNumber);
+ScriptSetInteger('MapGen', ord(cMapGen));
+ScriptSetInteger('MapFeatureSize', cFeatureSize);
+
+ScriptCall('onPreviewInit');
+
+// pop game variables
+ParseCommand('seed ' + ScriptGetString('Seed'), true, true);
+cTemplateFilter  := ScriptGetInteger('TemplateFilter');
+LuaTemplateNumber:= ScriptGetInteger('TemplateNumber');
+cMapGen          := TMapGen(ScriptGetInteger('MapGen'));
+cFeatureSize     := ScriptGetInteger('MapFeatureSize');
+end;
+
+procedure ScriptOnGameInit;
+var i, j, k: LongInt;
+begin
+// not required if there is no script to run
+if not ScriptLoaded then
+    exit;
+
+// push game variables so they may be modified by the script
+ScriptSetInteger('CursorX', CursorPoint.X);
+ScriptSetInteger('CursorY', CursorPoint.Y);
+ScriptSetInteger('BorderColor', ExplosionBorderColor);
+ScriptSetInteger('GameFlags', GameFlags);
+ScriptSetInteger('WorldEdge', ord(WorldEdge));
+ScriptSetString('Seed', cSeed);
+ScriptSetInteger('TemplateFilter', cTemplateFilter);
+ScriptSetInteger('TemplateNumber', LuaTemplateNumber);
+ScriptSetInteger('MapGen', ord(cMapGen));
+ScriptSetInteger('MapFeatureSize', cFeatureSize);
+ScriptSetInteger('ScreenHeight', cScreenHeight);
+ScriptSetInteger('ScreenWidth', cScreenWidth);
+ScriptSetInteger('TurnTime', cHedgehogTurnTime);
+ScriptSetInteger('CaseFreq', cCaseFactor);
+ScriptSetInteger('HealthCaseProb', cHealthCaseProb);
+ScriptSetInteger('HealthCaseAmount', cHealthCaseAmount);
+ScriptSetInteger('DamagePercent', cDamagePercent);
+ScriptSetInteger('RopePercent', cRopePercent);
+ScriptSetInteger('MinesNum', cLandMines);
+ScriptSetInteger('MinesTime', cMinesTime);
+ScriptSetInteger('MineDudPercent', cMineDudPercent);
+ScriptSetInteger('AirMinesNum', cAirMines);
+ScriptSetInteger('Explosives', cExplosives);
+ScriptSetInteger('Delay', cInactDelay);
+ScriptSetInteger('Ready', cReadyDelay);
+ScriptSetInteger('SuddenDeathTurns', cSuddenDTurns);
+ScriptSetInteger('WaterRise', cWaterRise);
+ScriptSetInteger('HealthDecrease', cHealthDecrease);
+ScriptSetInteger('GetAwayTime', cGetAwayTime);
+ScriptSetString('Map', cMapName);
+ScriptSetString('Theme', Theme);
+ScriptSetString('Goals', '');
+
+ScriptCall('onGameInit');
+
+// pop game variables
+ParseCommand('seed ' + ScriptGetString('Seed'), true, true);
+cTemplateFilter  := ScriptGetInteger('TemplateFilter');
+LuaTemplateNumber:= ScriptGetInteger('TemplateNumber');
+cMapGen          := TMapGen(ScriptGetInteger('MapGen'));
+cFeatureSize     := ScriptGetInteger('MapFeatureSize');
+GameFlags        := ScriptGetInteger('GameFlags');
+WorldEdge        := TWorldEdge(ScriptGetInteger('WorldEdge'));
+cHedgehogTurnTime:= ScriptGetInteger('TurnTime');
+cCaseFactor      := ScriptGetInteger('CaseFreq');
+cHealthCaseProb  := ScriptGetInteger('HealthCaseProb');
+cHealthCaseAmount:= ScriptGetInteger('HealthCaseAmount');
+cDamagePercent   := ScriptGetInteger('DamagePercent');
+cRopePercent     := ScriptGetInteger('RopePercent');
+cLandMines       := ScriptGetInteger('MinesNum');
+cMinesTime       := ScriptGetInteger('MinesTime');
+cMineDudPercent  := ScriptGetInteger('MineDudPercent');
+cAirMines        := ScriptGetInteger('AirMinesNum');
+cExplosives      := ScriptGetInteger('Explosives');
+cInactDelay      := ScriptGetInteger('Delay');
+cReadyDelay      := ScriptGetInteger('Ready');
+cSuddenDTurns    := ScriptGetInteger('SuddenDeathTurns');
+cWaterRise       := ScriptGetInteger('WaterRise');
+cHealthDecrease  := ScriptGetInteger('HealthDecrease');
+cGetAwayTime     := ScriptGetInteger('GetAwayTime');
+
+if cMapName <> ScriptGetString('Map') then
+    ParseCommand('map ' + ScriptGetString('Map'), true, true);
+if ScriptGetString('Theme') <> '' then
+    ParseCommand('theme ' + ScriptGetString('Theme'), true, true);
+LuaGoals:= ScriptGetString('Goals');
+
+// Support lua changing the ammo layout - assume all hogs have same ammo, note this might leave a few ammo stores lying around.
+k:= 0;
+if (GameFlags and gfSharedAmmo) <> 0 then
+    for i:= 0 to Pred(ClansCount) do
+        for j:= 0 to Pred(ClansArray[i]^.TeamsNumber) do
+            for k:= 0 to Pred(ClansArray[i]^.Teams[j]^.HedgehogsNumber) do
+                ClansArray[i]^.Teams[j]^.Hedgehogs[k].AmmoStore:= i
+else if (GameFlags and gfPerHogAmmo) <> 0 then
+    for i:= 0 to Pred(TeamsCount) do
+        for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
+            begin
+            TeamsArray[i]^.Hedgehogs[j].AmmoStore:= k;
+            if StoreCnt-1 < k then AddAmmoStore;
+            inc(k)
+            end
+else
+    for i:= 0 to Pred(TeamsCount) do
+        begin
+        for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
+            TeamsArray[i]^.Hedgehogs[j].AmmoStore:= k;
+        if StoreCnt-1 < k then AddAmmoStore;
+        inc(k)
+        end;
+if ScriptExists('onAmmoStoreInit') or ScriptExists('onNewAmmoStore') then
+    begin
+    // reset ammostore (quite unclean, but works?)
+    uAmmos.freeModule;
+    uAmmos.initModule;
+    if ScriptExists('onAmmoStoreInit') then
+        begin
+        ScriptPrepareAmmoStore;
+        ScriptCall('onAmmoStoreInit');
+        SetAmmoLoadout(ScriptAmmoLoadout);
+        SetAmmoProbability(ScriptAmmoProbability);
+        SetAmmoDelay(ScriptAmmoDelay);
+        SetAmmoReinforcement(ScriptAmmoReinforcement)
+        end;
+    ScriptApplyAmmoStore
+    end;
+
+ScriptSetInteger('ClansCount', ClansCount);
+ScriptSetInteger('TeamsCount', TeamsCount);
+mapDims:= false
+end;
+
+
+// Update values of screen dimensions and allow script to react to resolution change
+procedure ScriptOnScreenResize();
+begin
+ScriptSetInteger('ScreenHeight', cScreenHeight);
+ScriptSetInteger('ScreenWidth', cScreenWidth);
+ScriptCall('onScreenResize');
+end;
+
+// custom script loader via physfs, passed to lua_load
+const BUFSIZE = 1024;
+
+procedure ScriptLoad(name : shortstring);
+var ret : LongInt;
+      s : shortstring;
+      f : PFSFile;
+    buf : array[0..Pred(BUFSIZE)] of byte;
+//lua_buf : luaL_Buffer;
+begin
+s:= cPathz[ptData] + name;
+if not pfsExists(s) then
+    begin
+    AddFileLog('[LUA] Script not found: ' + name);
+    exit;
+    end;
+
+f:= pfsOpenRead(s);
+if f = nil then
+    exit;
+
+physfsReaderSetBuffer(@buf);
+ret:= lua_load(luaState, @physfsReader, f, Str2PChar(s));
+pfsClose(f);
+
+if ret <> 0 then
+    begin
+    LuaError('Failed to load ' + name + '(error ' + IntToStr(ret) + ')');
+    LuaError(lua_tostring(luaState, -1));
+    end
+else
+    begin
+    WriteLnToConsole('Lua: ' + name + ' loaded');
+    // dump and hash all functions currently known by lua
+    // use hash to salt map hash
+// init buffer
+//luaL_buffinit(luaState, @lua_buf);
+//lua_dump(luaState, @lua_dump_digester, @lua_buf);
+// cleanup buffer
+//luaL_pushresult(@lua_buf);
+    // --
+    // could first read the file, then hash it, then use load_string
+    // call the script file
+    lua_pcall(luaState, 0, 0, 0);
+    ScriptLoaded:= true
+    end;
+hedgewarsMountPackage(Str2PChar(copy(s, 1, length(s)-4)+'.hwp'));
+end;
+
+procedure SetGlobals;
+begin
+ScriptSetInteger('TurnTimeLeft', TurnTimeLeft);
+ScriptSetInteger('GameTime', GameTicks);
+ScriptSetInteger('TotalRounds', TotalRounds);
+ScriptSetInteger('WaterLine', cWaterLine);
+if isCursorVisible and (not bShowAmmoMenu) then
+    begin
+    if (prevCursorPoint.X <> CursorPoint.X) or
+       (prevCursorPoint.Y <> CursorPoint.Y) then
+        begin
+        ScriptSetInteger('CursorX', CursorPoint.X - WorldDx);
+        ScriptSetInteger('CursorY', cScreenHeight - CursorPoint.Y- WorldDy);
+        prevCursorPoint.X:= CursorPoint.X;
+        prevCursorPoint.Y:= CursorPoint.Y;
+        end
+    end
+else
+    begin
+    ScriptSetInteger('CursorX', NoPointX);
+    ScriptSetInteger('CursorY', NoPointX);
+    prevCursorPoint.X:= NoPointX;
+    prevCursorPoint.Y:= NoPointX
+    end;
+
+if not mapDims then
+    begin
+    mapDims:= true;
+    ScriptSetInteger('LAND_WIDTH', LAND_WIDTH);
+    ScriptSetInteger('LAND_HEIGHT', LAND_HEIGHT);
+    ScriptSetInteger('LeftX', leftX);
+    ScriptSetInteger('RightX', rightX);
+    ScriptSetInteger('TopY', topY)
+    end;
+if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
+    ScriptSetInteger('CurrentHedgehog', CurrentHedgehog^.Gear^.UID)
+else
+    ScriptSetNil('CurrentHedgehog');
+end;
+
+procedure GetGlobals;
+begin
+// TODO
+// Use setters instead, because globals should be read-only!
+// Otherwise globals might be changed by Lua, but then unexpectatly overwritten by engine when a ScriptCall is triggered by whatever Lua is doing!
+// Sure, one could work around that in engine (e.g. by setting writable globals in SetGlobals only when their engine-side value has actually changed since SetGlobals was called the last time...), but things just get messier and messier then.
+// It is inconsistent anyway to have some globals be read-only and others not with no indication whatsoever.
+// -- sheepluva
+TurnTimeLeft:= ScriptGetInteger('TurnTimeLeft');
+end;
+
+procedure ScriptCall(fname : shortstring);
+begin
+if (not ScriptLoaded) or (not ScriptExists(fname)) then
+    exit;
+SetGlobals;
+lua_getglobal(luaState, Str2PChar(fname));
+if lua_pcall(luaState, 0, 0, 0) <> 0 then
+    begin
+    LuaError('Error while calling ' + fname + ': ' + lua_tostring(luaState, -1));
+    lua_pop(luaState, 1)
+    end;
+GetGlobals;
+end;
+
+(*
+function ParseCommandOverride(key, value : shortstring) : shortstring;
+begin
+ParseCommandOverride:= value;
+if not ScriptExists('ParseCommandOverride') then
+    exit;
+lua_getglobal(luaState, Str2PChar('ParseCommandOverride'));
+lua_pushstring(luaState, Str2PChar(key));
+lua_pushstring(luaState, Str2PChar(value));
+if lua_pcall(luaState, 2, 1, 0) <> 0 then
+    begin
+    LuaError('Lua: Error while calling ParseCommandOverride: ' + lua_tostring(luaState, -1));
+    lua_pop(luaState, 1)
+    end
+else
+    begin
+    ParseCommandOverride:= lua_tostring(luaState, -1);
+    lua_pop(luaState, 1)
+    end;
+end;
+*)
+
+function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
+begin
+ScriptCall:= ScriptCall(fname, par1, 0, 0, 0)
+end;
+
+function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
+begin
+ScriptCall:= ScriptCall(fname, par1, par2, 0, 0)
+end;
+
+function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
+begin
+ScriptCall:= ScriptCall(fname, par1, par2, par3, 0)
+end;
+
+function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
+begin
+if (not ScriptLoaded) or (not ScriptExists(fname)) then
+    exit(0);
+SetGlobals;
+lua_getglobal(luaState, Str2PChar(fname));
+lua_pushinteger(luaState, par1);
+lua_pushinteger(luaState, par2);
+lua_pushinteger(luaState, par3);
+lua_pushinteger(luaState, par4);
+ScriptCall:= 0;
+if lua_pcall(luaState, 4, 1, 0) <> 0 then
+    begin
+    LuaError('Error while calling ' + fname + ': ' + lua_tostring(luaState, -1));
+    lua_pop(luaState, 1)
+    end
+else
+    begin
+    ScriptCall:= lua_tointeger(luaState, -1);
+    lua_pop(luaState, 1)
+    end;
+GetGlobals;
+end;
+
+function ScriptExists(fname : shortstring) : boolean;
+begin
+if not ScriptLoaded then
+    begin
+    ScriptExists:= false;
+    exit
+    end;
+lua_getglobal(luaState, Str2PChar(fname));
+ScriptExists:= not lua_isnoneornil(luaState, -1);
+lua_pop(luaState, 1)
+end;
+
+procedure ScriptPrepareAmmoStore;
+var i: ShortInt;
+begin
+ScriptAmmoLoadout:= '';
+ScriptAmmoDelay:= '';
+ScriptAmmoProbability:= '';
+ScriptAmmoReinforcement:= '';
+for i:=1 to ord(High(TAmmoType)) do
+    begin
+    ScriptAmmoLoadout:= ScriptAmmoLoadout + '0';
+    ScriptAmmoProbability:= ScriptAmmoProbability + '0';
+    ScriptAmmoDelay:= ScriptAmmoDelay + '0';
+    ScriptAmmoReinforcement:= ScriptAmmoReinforcement + '0';
+    end;
+end;
+
+procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte);
+begin
+//if (ord(ammo) < 1) or (count > 9) or (count < 0) or (probability < 0) or (probability > 8) or (delay < 0) or (delay > 9) or (reinforcement < 0) or (reinforcement > 8) then
+if (ord(ammo) < 1) or (count > 9) or (probability > 8) or (delay > 9) or (reinforcement > 8) then
+    exit;
+ScriptAmmoLoadout[ord(ammo)]:= inttostr(count)[1];
+ScriptAmmoProbability[ord(ammo)]:= inttostr(probability)[1];
+ScriptSetAmmoDelay(ammo, delay);
+ScriptAmmoReinforcement[ord(ammo)]:= inttostr(reinforcement)[1];
+end;
+
+procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte);
+begin
+// change loadout string if ammo store has not been initialized yet
+if (StoreCnt = 0) then
+begin
+    if (delay <= 9) then
+        ScriptAmmoDelay[ord(ammo)]:= inttostr(delay)[1];
+end
+// change 'live' delay values
+else if (CurrentTeam <> nil) then
+        ammoz[ammo].SkipTurns:= CurrentTeam^.Clan^.TurnNumber + delay;
+end;
+
+procedure ScriptApplyAmmoStore;
+var i, j, k : LongInt;
+begin
+if (GameFlags and gfSharedAmmo) <> 0 then
+    for i:= 0 to Pred(ClansCount) do
+        begin
+        if ScriptExists('onNewAmmoStore') then
+            begin
+            ScriptPrepareAmmoStore;
+            ScriptCall('onNewAmmoStore',i,-1);
+            SetAmmoLoadout(ScriptAmmoLoadout);
+            SetAmmoProbability(ScriptAmmoProbability);
+            SetAmmoDelay(ScriptAmmoDelay);
+            SetAmmoReinforcement(ScriptAmmoReinforcement)
+            end;
+        AddAmmoStore;
+        for j:= 0 to Pred(ClansArray[i]^.TeamsNumber) do
+            for k:= 0 to Pred(ClansArray[i]^.Teams[j]^.HedgehogsNumber) do
+                ClansArray[i]^.Teams[j]^.Hedgehogs[k].AmmoStore:= StoreCnt - 1
+        end
+else if (GameFlags and gfPerHogAmmo) <> 0 then
+    for i:= 0 to Pred(TeamsCount) do
+        for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
+            begin
+            if ScriptExists('onNewAmmoStore') then
+                begin
+                ScriptPrepareAmmoStore;
+                ScriptCall('onNewAmmoStore',i,j);
+                SetAmmoLoadout(ScriptAmmoLoadout);
+                SetAmmoProbability(ScriptAmmoProbability);
+                SetAmmoDelay(ScriptAmmoDelay);
+                SetAmmoReinforcement(ScriptAmmoReinforcement)
+                end;
+            AddAmmoStore;
+            TeamsArray[i]^.Hedgehogs[j].AmmoStore:= StoreCnt - 1
+            end
+else
+    for i:= 0 to Pred(TeamsCount) do
+        begin
+        if ScriptExists('onNewAmmoStore') then
+            begin
+            ScriptPrepareAmmoStore;
+            ScriptCall('onNewAmmoStore',i,-1);
+            SetAmmoLoadout(ScriptAmmoLoadout);
+            SetAmmoProbability(ScriptAmmoProbability);
+            SetAmmoDelay(ScriptAmmoDelay);
+            SetAmmoReinforcement(ScriptAmmoReinforcement)
+            end;
+        AddAmmoStore;
+        for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
+            TeamsArray[i]^.Hedgehogs[j].AmmoStore:= StoreCnt - 1
+        end
+end;
+
+procedure initModule;
+var at : TGearType;
+    vgt: TVisualGearType;
+    am : TAmmoType;
+    si : TStatInfoType;
+    st : TSound;
+    he : THogEffect;
+    cg : TCapGroup;
+    spr: TSprite;
+    mg : TMapGen;
+    we : TWorldEdge;
+begin
+// initialize lua
+luaState:= lua_open;
+if checkFails(luaState <> nil, 'lua_open failed', true) then exit;
+
+// open internal libraries
+luaopen_base(luaState);
+luaopen_string(luaState);
+luaopen_math(luaState);
+luaopen_table(luaState);
+
+// import some variables
+ScriptSetString(_S'L', cLocale);
+
+// import game flags
+ScriptSetInteger('gfForts', gfForts);
+ScriptSetInteger('gfMultiWeapon', gfMultiWeapon);
+ScriptSetInteger('gfSolidLand', gfSolidLand);
+ScriptSetInteger('gfBorder', gfBorder);
+ScriptSetInteger('gfBottomBorder', gfBottomBorder);
+ScriptSetInteger('gfDivideTeams', gfDivideTeams);
+ScriptSetInteger('gfLowGravity', gfLowGravity);
+ScriptSetInteger('gfLaserSight', gfLaserSight);
+ScriptSetInteger('gfInvulnerable', gfInvulnerable);
+ScriptSetInteger('gfResetHealth', gfResetHealth);
+ScriptSetInteger('gfVampiric', gfVampiric);
+ScriptSetInteger('gfKarma', gfKarma);
+ScriptSetInteger('gfArtillery', gfArtillery);
+ScriptSetInteger('gfOneClanMode', gfOneClanMode);
+ScriptSetInteger('gfRandomOrder', gfRandomOrder);
+ScriptSetInteger('gfKing', gfKing);
+ScriptSetInteger('gfPlaceHog', gfPlaceHog);
+ScriptSetInteger('gfSharedAmmo', gfSharedAmmo);
+ScriptSetInteger('gfDisableGirders', gfDisableGirders);
+ScriptSetInteger('gfDisableLandObjects', gfDisableLandObjects);
+ScriptSetInteger('gfAISurvival', gfAISurvival);
+ScriptSetInteger('gfInfAttack', gfInfAttack);
+ScriptSetInteger('gfResetWeps', gfResetWeps);
+ScriptSetInteger('gfPerHogAmmo', gfPerHogAmmo);
+ScriptSetInteger('gfDisableWind', gfDisableWind);
+ScriptSetInteger('gfMoreWind', gfMoreWind);
+ScriptSetInteger('gfTagTeam', gfTagTeam);
+ScriptSetInteger('gfShoppaBorder', gfShoppaBorder);
+
+ScriptSetInteger('gmLeft', gmLeft);
+ScriptSetInteger('gmRight', gmRight);
+ScriptSetInteger('gmUp', gmUp);
+ScriptSetInteger('gmDown', gmDown);
+ScriptSetInteger('gmSwitch', gmSwitch);
+ScriptSetInteger('gmAttack', gmAttack);
+ScriptSetInteger('gmLJump', gmLJump);
+ScriptSetInteger('gmHJump', gmHJump);
+ScriptSetInteger('gmDestroy', gmDestroy);
+ScriptSetInteger('gmSlot', gmSlot);
+ScriptSetInteger('gmWeapon', gmWeapon);
+ScriptSetInteger('gmTimer', gmTimer);
+ScriptSetInteger('gmAnimate', gmAnimate);
+ScriptSetInteger('gmPrecise', gmPrecise);
+ScriptSetInteger('gmAllStoppable', gmAllStoppable);
+
+// speech bubbles
+ScriptSetInteger('SAY_SAY', 1);
+ScriptSetInteger('SAY_THINK', 2);
+ScriptSetInteger('SAY_SHOUT', 3);
+
+// register gear types
+for at:= Low(TGearType) to High(TGearType) do
+    ScriptSetInteger(EnumToStr(at), ord(at));
+
+for vgt:= Low(TVisualGearType) to High(TVisualGearType) do
+    ScriptSetInteger(EnumToStr(vgt), ord(vgt));
+
+// register sounds
+for st:= Low(TSound) to High(TSound) do
+    ScriptSetInteger(EnumToStr(st), ord(st));
+
+// register ammo types
+for am:= Low(TAmmoType) to High(TAmmoType) do
+    ScriptSetInteger(EnumToStr(am), ord(am));
+
+for si:= Low(TStatInfoType) to High(TStatInfoType) do
+    ScriptSetInteger(EnumToStr(si), ord(si));
+
+for he:= Low(THogEffect) to High(THogEffect) do
+    ScriptSetInteger(EnumToStr(he), ord(he));
+
+for cg:= Low(TCapGroup) to High(TCapGroup) do
+    ScriptSetInteger(EnumToStr(cg), ord(cg));
+
+for spr:= Low(TSprite) to High(TSprite) do
+    ScriptSetInteger(EnumToStr(spr), ord(spr));
+
+for mg:= Low(TMapGen) to High(TMapGen) do
+    ScriptSetInteger(EnumToStr(mg), ord(mg));
+
+for we:= Low(TWorldEdge) to High(TWorldEdge) do
+    ScriptSetInteger(EnumToStr(we), ord(we));
+
+ScriptSetInteger('gstDrowning'      , gstDrowning);
+ScriptSetInteger('gstHHDriven'      , gstHHDriven);
+ScriptSetInteger('gstMoving'        , gstMoving);
+ScriptSetInteger('gstAttacked'      , gstAttacked);
+ScriptSetInteger('gstAttacking'     , gstAttacking);
+ScriptSetInteger('gstCollision'     , gstCollision);
+ScriptSetInteger('gstChooseTarget'  , gstChooseTarget);
+ScriptSetInteger('gstHHJumping'     , gstHHJumping);
+ScriptSetInteger('gsttmpFlag'       , gsttmpFlag);
+ScriptSetInteger('gstHHThinking'    , gstHHThinking);
+ScriptSetInteger('gstNoDamage'      , gstNoDamage);
+ScriptSetInteger('gstHHHJump'       , gstHHHJump);
+ScriptSetInteger('gstAnimation'     , gstAnimation);
+ScriptSetInteger('gstHHDeath'       , gstHHDeath);
+ScriptSetInteger('gstWinner'        , gstWinner);
+ScriptSetInteger('gstWait'          , gstWait);
+ScriptSetInteger('gstNotKickable'   , gstNotKickable);
+ScriptSetInteger('gstLoser'         , gstLoser);
+ScriptSetInteger('gstHHGone'        , gstHHGone);
+ScriptSetInteger('gstInvisible'     , gstInvisible);
+ScriptSetInteger('gstSubmersible'   , gstSubmersible);
+ScriptSetInteger('gstFrozen'        , gstFrozen);
+ScriptSetInteger('gstNoGravity'     , gstNoGravity);
+
+// ai hints
+ScriptSetInteger('aihUsualProcessing', aihUsualProcessing);
+ScriptSetInteger('aihDoesntMatter'   , aihDoesntMatter);
+
+// land flags
+ScriptSetInteger('lfIndestructible', lfIndestructible);
+ScriptSetInteger('lfIce'           , lfIce);
+ScriptSetInteger('lfBouncy'        , lfBouncy);
+
+// register functions
+lua_register(luaState, _P'HideHog', @lc_hidehog);
+lua_register(luaState, _P'RestoreHog', @lc_restorehog);
+lua_register(luaState, _P'SaveCampaignVar', @lc_savecampaignvar);
+lua_register(luaState, _P'GetCampaignVar', @lc_getcampaignvar);
+lua_register(luaState, _P'band', @lc_band);
+lua_register(luaState, _P'bor', @lc_bor);
+lua_register(luaState, _P'bnot', @lc_bnot);
+lua_register(luaState, _P'div', @lc_div);
+lua_register(luaState, _P'GetInputMask', @lc_getinputmask);
+lua_register(luaState, _P'SetInputMask', @lc_setinputmask);
+lua_register(luaState, _P'AddGear', @lc_addgear);
+lua_register(luaState, _P'DismissTeam', @lc_dismissteam);
+lua_register(luaState, _P'EnableGameFlags', @lc_enablegameflags);
+lua_register(luaState, _P'DisableGameFlags', @lc_disablegameflags);
+lua_register(luaState, _P'ClearGameFlags', @lc_cleargameflags);
+lua_register(luaState, _P'GetGameFlag', @lc_getgameflag);
+lua_register(luaState, _P'DeleteGear', @lc_deletegear);
+lua_register(luaState, _P'AddVisualGear', @lc_addvisualgear);
+lua_register(luaState, _P'DeleteVisualGear', @lc_deletevisualgear);
+lua_register(luaState, _P'GetVisualGearType', @lc_getvisualgeartype);
+lua_register(luaState, _P'GetVisualGearValues', @lc_getvisualgearvalues);
+lua_register(luaState, _P'SetVisualGearValues', @lc_setvisualgearvalues);
+lua_register(luaState, _P'GetGearValues', @lc_getgearvalues);
+lua_register(luaState, _P'SetGearValues', @lc_setgearvalues);
+lua_register(luaState, _P'SpawnHealthCrate', @lc_spawnhealthcrate);
+lua_register(luaState, _P'SpawnAmmoCrate', @lc_spawnammocrate);
+lua_register(luaState, _P'SpawnUtilityCrate', @lc_spawnutilitycrate);
+lua_register(luaState, _P'SpawnFakeHealthCrate', @lc_spawnfakehealthcrate);
+lua_register(luaState, _P'SpawnFakeAmmoCrate', @lc_spawnfakeammocrate);
+lua_register(luaState, _P'SpawnFakeUtilityCrate', @lc_spawnfakeutilitycrate);
+lua_register(luaState, _P'WriteLnToConsole', @lc_writelntoconsole);
+lua_register(luaState, _P'GetGearType', @lc_getgeartype);
+lua_register(luaState, _P'EndGame', @lc_endgame);
+lua_register(luaState, _P'SendStat', @lc_sendstat);
+lua_register(luaState, _P'SendHealthStatsOff', @lc_sendhealthstatsoff);
+lua_register(luaState, _P'FindPlace', @lc_findplace);
+lua_register(luaState, _P'SetGearPosition', @lc_setgearposition);
+lua_register(luaState, _P'GetGearPosition', @lc_getgearposition);
+lua_register(luaState, _P'SetGearTarget', @lc_setgeartarget);
+lua_register(luaState, _P'GetGearTarget', @lc_getgeartarget);
+lua_register(luaState, _P'SetGearVelocity', @lc_setgearvelocity);
+lua_register(luaState, _P'GetGearVelocity', @lc_getgearvelocity);
+lua_register(luaState, _P'ParseCommand', @lc_parsecommand);
+lua_register(luaState, _P'ShowMission', @lc_showmission);
+lua_register(luaState, _P'HideMission', @lc_hidemission);
+lua_register(luaState, _P'SetAmmoTexts', @lc_setammotexts);
+lua_register(luaState, _P'SetAmmoDescriptionAppendix', @lc_setammodescriptionappendix);
+lua_register(luaState, _P'AddCaption', @lc_addcaption);
+lua_register(luaState, _P'SetAmmo', @lc_setammo);
+lua_register(luaState, _P'SetAmmoDelay', @lc_setammodelay);
+lua_register(luaState, _P'SetAmmoStore', @lc_setammostore);
+lua_register(luaState, _P'PlaySound', @lc_playsound);
+lua_register(luaState, _P'AddTeam', @lc_addteam);
+lua_register(luaState, _P'AddHog', @lc_addhog);
+lua_register(luaState, _P'AddAmmo', @lc_addammo);
+lua_register(luaState, _P'GetAmmoCount', @lc_getammocount);
+lua_register(luaState, _P'SetHealth', @lc_sethealth);
+lua_register(luaState, _P'GetHealth', @lc_gethealth);
+lua_register(luaState, _P'SetEffect', @lc_seteffect);
+lua_register(luaState, _P'GetEffect', @lc_geteffect);
+lua_register(luaState, _P'GetHogClan', @lc_gethogclan);
+lua_register(luaState, _P'GetClanColor', @lc_getclancolor);
+lua_register(luaState, _P'SetClanColor', @lc_setclancolor);
+lua_register(luaState, _P'GetHogVoicepack', @lc_gethogvoicepack);
+lua_register(luaState, _P'GetHogFlag', @lc_gethogflag);
+lua_register(luaState, _P'GetHogFort', @lc_gethogfort);
+lua_register(luaState, _P'GetHogGrave', @lc_gethoggrave);
+lua_register(luaState, _P'IsHogLocal', @lc_ishoglocal);
+lua_register(luaState, _P'GetHogTeamName', @lc_gethogteamname);
+lua_register(luaState, _P'SetHogTeamName', @lc_sethogteamname);
+lua_register(luaState, _P'GetHogName', @lc_gethogname);
+lua_register(luaState, _P'SetHogName', @lc_sethogname);
+lua_register(luaState, _P'GetHogLevel', @lc_gethoglevel);
+lua_register(luaState, _P'SetHogLevel', @lc_sethoglevel);
+lua_register(luaState, _P'GetX', @lc_getx);
+lua_register(luaState, _P'GetY', @lc_gety);
+lua_register(luaState, _P'CopyPV', @lc_copypv);
+lua_register(luaState, _P'FollowGear', @lc_followgear);
+lua_register(luaState, _P'GetFollowGear', @lc_getfollowgear);
+lua_register(luaState, _P'SetState', @lc_setstate);
+lua_register(luaState, _P'GetState', @lc_getstate);
+lua_register(luaState, _P'GetTag', @lc_gettag);
+lua_register(luaState, _P'SetTag', @lc_settag);
+lua_register(luaState, _P'SetTimer', @lc_settimer);
+lua_register(luaState, _P'GetTimer', @lc_gettimer);
+lua_register(luaState, _P'SetFlightTime', @lc_setflighttime);
+lua_register(luaState, _P'GetFlightTime', @lc_getflighttime);
+lua_register(luaState, _P'SetZoom', @lc_setzoom);
+lua_register(luaState, _P'GetZoom', @lc_getzoom);
+lua_register(luaState, _P'HogSay', @lc_hogsay);
+lua_register(luaState, _P'SwitchHog', @lc_switchhog);
+lua_register(luaState, _P'HogTurnLeft', @lc_hogturnleft);
+lua_register(luaState, _P'CampaignLock', @lc_campaignlock);
+lua_register(luaState, _P'CampaignUnlock', @lc_campaignunlock);
+lua_register(luaState, _P'GetGearElasticity', @lc_getgearelasticity);
+lua_register(luaState, _P'SetGearElasticity', @lc_setgearelasticity);
+lua_register(luaState, _P'GetGearFriction', @lc_getgearfriction);
+lua_register(luaState, _P'SetGearFriction', @lc_setgearfriction);
+lua_register(luaState, _P'GetGearRadius', @lc_getgearradius);
+lua_register(luaState, _P'GetGearMessage', @lc_getgearmessage);
+lua_register(luaState, _P'SetGearMessage', @lc_setgearmessage);
+lua_register(luaState, _P'GetGearPos', @lc_getgearpos);
+lua_register(luaState, _P'SetGearPos', @lc_setgearpos);
+lua_register(luaState, _P'GetGearCollisionMask', @lc_getgearcollisionmask);
+lua_register(luaState, _P'SetGearCollisionMask', @lc_setgearcollisionmask);
+lua_register(luaState, _P'GetRandom', @lc_getrandom);
+lua_register(luaState, _P'SetWind', @lc_setwind);
+lua_register(luaState, _P'MapHasBorder', @lc_maphasborder);
+lua_register(luaState, _P'GetHogHat', @lc_gethoghat);
+lua_register(luaState, _P'SetHogHat', @lc_sethoghat);
+lua_register(luaState, _P'EraseSprite', @lc_erasesprite);
+lua_register(luaState, _P'PlaceSprite', @lc_placesprite);
+lua_register(luaState, _P'PlaceGirder', @lc_placegirder);
+lua_register(luaState, _P'PlaceRubber', @lc_placerubber);
+lua_register(luaState, _P'GetCurAmmoType', @lc_getcurammotype);
+lua_register(luaState, _P'TestRectForObstacle', @lc_testrectforobstacle);
+lua_register(luaState, _P'GetGravity', @lc_getgravity);
+lua_register(luaState, _P'SetGravity', @lc_setgravity);
+lua_register(luaState, _P'SetWaterLine', @lc_setwaterline);
+lua_register(luaState, _P'SetNextWeapon', @lc_setnextweapon);
+lua_register(luaState, _P'SetWeapon', @lc_setweapon);
+lua_register(luaState, _P'SetCinematicMode', @lc_setcinematicmode);
+lua_register(luaState, _P'SetMaxBuildDistance', @lc_setmaxbuilddistance);
+lua_register(luaState, _P'GetAmmoName', @lc_getammoname);
+// drawn map functions
+lua_register(luaState, _P'AddPoint', @lc_addPoint);
+lua_register(luaState, _P'FlushPoints', @lc_flushPoints);
+
+lua_register(luaState, _P'SetGearAIHints', @lc_setgearaihints);
+lua_register(luaState, _P'HedgewarsScriptLoad', @lc_hedgewarsscriptload);
+lua_register(luaState, _P'DeclareAchievement', @lc_declareachievement);
+lua_register(luaState, _P'StartGhostPoints', @lc_startghostpoints);
+lua_register(luaState, _P'DumpPoint', @lc_dumppoint);
+
+ScriptSetInteger('TEST_SUCCESSFUL'   , HaltTestSuccess);
+ScriptSetInteger('TEST_FAILED'       , HaltTestFailed);
+lua_register(luaState, _P'EndLuaTest', @lc_endluatest);
+
+ScriptClearStack; // just to be sure stack is empty
+ScriptLoaded:= false;
+end;
+
+procedure freeModule;
+begin
+lua_close(luaState);
+end;
+
+{$ELSE}
+procedure ScriptPrintStack;
+begin
+end;
+
+procedure ScriptClearStack;
+begin
+end;
+
+procedure ScriptLoad(name : shortstring);
+begin
+    name:= name; // avoid hint
+end;
+
+procedure ScriptOnGameInit;
+begin
+end;
+
+procedure ScriptCall(fname : shortstring);
+begin
+    fname:= fname; // avoid hint
+end;
+
+function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
+begin
+    // avoid hints
+    fname:= fname;
+    par1:= par1;
+    par2:= par2;
+    par3:= par3;
+    par4:= par4;
+    ScriptCall:= 0
+end;
+
+function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
+begin
+    // avoid hints
+    fname:= fname;
+    par1:= par1;
+    ScriptCall:= 0
+end;
+
+function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
+begin
+    // avoid hints
+    fname:= fname;
+    par1:= par1;
+    par2:= par2;
+    ScriptCall:= 0
+end;
+
+function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
+begin
+    // avoid hints
+    fname:= fname;
+    par1:= par1;
+    par2:= par2;
+    par3:= par3;
+    ScriptCall:= 0
+end;
+
+function ScriptExists(fname : shortstring) : boolean;
+begin
+    fname:= fname; // avoid hint
+    ScriptExists:= false
+end;
+(*
+function ParseCommandOverride(key, value : shortstring) : shortstring;
+begin
+    // avoid hints
+    key:= key;
+    value:= value;
+    ParseCommandOverride:= ''
+end;
+*)
+
+procedure ScriptOnScreenResize;
+begin
+end;
+
+procedure ScriptOnPreviewInit;
+begin
+end;
+
+procedure ScriptSetInteger(name : shortstring; value : LongInt);
+begin
+end;
+
+procedure ScriptSetString(name : shortstring; value : shortstring);
+begin
+end;
+
+procedure LuaParseString(s : ShortString);
+begin
+end;
+
+procedure initModule;
+begin
+mapDims:= false;
+PointsBuffer:= '';
+prevCursorPoint.X:= NoPointX;
+prevCursorPoint.Y:= 0;
+end;
+
+procedure freeModule;
+begin
+end;
+
+{$ENDIF}
+end.