Engine:
authorsmxx
Wed, 10 Feb 2010 00:55:40 +0000
changeset 2786 85f6425a4d74
parent 2785 de6406cd6b25
child 2787 cf5fc37b4508
Engine: * Added LUA scripting support for trainings (and maybe soon) scenarios/missions * Converted Shotgun and Bazooka Training to LUA * New dependency: LUA 5.1 * New Mission Objectives window * Extended default keybinds for non-iPhone builds * NOTE: Script function names etc. might change soon so don't work too hard on your own missions (for now)! This is experimental! Frontend: * Added support for new training maps/LUA scripts
QTfrontend/game.cpp
QTfrontend/pages.cpp
cmake_modules/FindLua51.cmake
hedgewars/CCHandlers.inc
hedgewars/CMakeLists.txt
hedgewars/LuaPas.pas
hedgewars/hwengine.pas
hedgewars/uConsole.pas
hedgewars/uGame.pas
hedgewars/uGears.pas
hedgewars/uKeys.pas
hedgewars/uScript.pas
hedgewars/uStore.pas
hedgewars/uWorld.pas
share/hedgewars/Data/CMakeLists.txt
share/hedgewars/Data/Graphics/missions.png
share/hedgewars/Data/Locale/de.txt
share/hedgewars/Data/Missions/Bazooka Training.hwt
share/hedgewars/Data/Missions/CMakeLists.txt
share/hedgewars/Data/Missions/Shotgun Training.hwt
share/hedgewars/Data/Trainings/001_Shotgun.txt
share/hedgewars/Data/Trainings/002_Bazooka.txt
share/hedgewars/Data/Trainings/003_RCPlane.txt
share/hedgewars/Data/Trainings/CMakeLists.txt
--- a/QTfrontend/game.cpp	Tue Feb 09 21:51:52 2010 +0000
+++ b/QTfrontend/game.cpp	Wed Feb 10 00:55:40 2010 +0000
@@ -136,25 +136,7 @@
 	QByteArray traincfg;
 	HWProto::addStringToBuffer(traincfg, "TL");
 
-	QFile file(datadir->absolutePath() + "/Trainings/" + training + ".txt");
-	if(!file.open(QFile::ReadOnly))
-	{
-		emit ErrorMessage(tr("Error reading training config file"));
-		return;
-	}
-
-	QTextStream stream(&file);
-	while(!stream.atEnd())
-	{
-		QString line = stream.readLine();
-		if(!line.isEmpty() && !line.startsWith("#"))
-			if(line != "<binds>")
-				HWProto::addStringToBuffer(traincfg, "e" + line);
-			else
-				for(int i = 0; i < BINDS_NUMBER; i++)
-					if(!cbinds[i].strbind.isEmpty())
-						HWProto::addStringToBuffer(traincfg, "ebind " + cbinds[i].strbind + " " + cbinds[i].action);
-	}
+	HWProto::addStringToBuffer(traincfg, "escript " + datadir->absolutePath() + "/Missions/" + training + ".hwt");
 
 	RawSendIPC(traincfg);
 }
--- a/QTfrontend/pages.cpp	Tue Feb 09 21:51:52 2010 +0000
+++ b/QTfrontend/pages.cpp	Wed Feb 10 00:55:40 2010 +0000
@@ -766,9 +766,9 @@
 
 	QDir tmpdir;
 	tmpdir.cd(datadir->absolutePath());
-	tmpdir.cd("Trainings");
+	tmpdir.cd("Missions");
 	tmpdir.setFilter(QDir::Files);
-	CBSelect->addItems(tmpdir.entryList(QStringList("*_*.txt")).replaceInStrings(QRegExp("^(.*)\\.txt"), "\\1"));
+	CBSelect->addItems(tmpdir.entryList(QStringList("*.hwt")).replaceInStrings(QRegExp("^(.*)\\.hwt"), "\\1"));
 
 	pageLayout->addWidget(CBSelect, 1, 1);
 	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake_modules/FindLua51.cmake	Wed Feb 10 00:55:40 2010 +0000
@@ -0,0 +1,40 @@
+# Find the Lua 5.1 includes and library
+#
+# LUA51_INCLUDE_DIR - where to find lua.h
+# LUA51_LIBRARIES - List of fully qualified libraries to link against
+# LUA51_FOUND - Set to TRUE if found
+
+# Copyright (c) 2007, Pau Garcia i Quiles, <pgquiles@elpauer.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+IF(LUA51_INCLUDE_DIR AND LUA51_LIBRARIES)
+    SET(LUA51_FIND_QUIETLY TRUE)
+ENDIF(LUA51_INCLUDE_DIR AND LUA51_LIBRARIES)
+
+FIND_PATH(LUA51_INCLUDE_DIR lua5.1/lua.h)
+
+FIND_LIBRARY(LUA51_LIBRARIES NAMES lua5.1)
+
+IF(LUA51_INCLUDE_DIR AND LUA51_LIBRARIES)
+   SET(LUA51_FOUND TRUE)
+   INCLUDE(CheckLibraryExists)
+   CHECK_LIBRARY_EXISTS(${LUA51_LIBRARIES} lua_close "" LUA51_NEED_PREFIX)
+ELSE(LUA51_INCLUDE_DIR AND LUA51_LIBRARIES)
+   SET(LUA51_FOUND FALSE)
+   MESSAGE("D'oh")
+ENDIF (LUA51_INCLUDE_DIR AND LUA51_LIBRARIES)
+
+IF(LUA51_FOUND)
+  IF (NOT LUA51_FIND_QUIETLY)
+    MESSAGE(STATUS "Found Lua 5.1 library: ${LUA51_LIBRARIES}")
+    MESSAGE(STATUS "Found Lua 5.1 headers: ${LUA51_INCLUDE_DIR}")
+  ENDIF (NOT LUA51_FIND_QUIETLY)
+ELSE(LUA51_FOUND)
+  IF(LUA51_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could NOT find Lua 5.1")
+  ENDIF(LUA51_FIND_REQUIRED)
+ENDIF(LUA51_FOUND)
+
+MARK_AS_ADVANCED(LUA51_INCLUDE_DIR LUA51_LIBRARIES)
--- a/hedgewars/CCHandlers.inc	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/CCHandlers.inc	Wed Feb 10 00:55:40 2010 +0000
@@ -131,6 +131,13 @@
 CurrentTeam^.flag:= s
 end;
 
+procedure chScript(var s: shortstring);
+begin
+if s[1]='"' then Delete(s, 1, 1);
+if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
+ScriptLoad(s)
+end;
+
 procedure chAddHH(var id: shortstring);
 var s: shortstring;
     Gear: PGear;
--- a/hedgewars/CMakeLists.txt	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/CMakeLists.txt	Wed Feb 10 00:55:40 2010 +0000
@@ -5,6 +5,7 @@
 find_package(SDL_net)
 find_package(SDL_ttf)
 find_package(SDL_mixer)
+find_package(LUA51 REQUIRED)
 
 #find which version of SDL_image and SDL_mixer we have (for IMG_Init and Mix_Init)
 #if the headers are not installed, the newer apis won't be activated
@@ -34,7 +35,7 @@
 set(fpc_tryexe fpc)
 set(hwengine_project ${hedgewars_SOURCE_DIR}/hedgewars/hwengine.pas)
 
-set(	engine_sources
+set(engine_sources
 	${hwengine_project}
 	SDLh.pas
 	uAI.pas
@@ -59,6 +60,7 @@
 	uLocale.pas
 	uMisc.pas
 	uRandom.pas
+	uScript.pas
 	uSHA.pas
 	uSound.pas
 	uStats.pas
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/LuaPas.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -0,0 +1,1051 @@
+unit LuaPas;
+
+(*
+ * A complete Pascal wrapper for Lua 5.1 DLL module.
+ *
+ * Created by Geo Massar, 2006
+ * Distributed as free/open source.
+ *)
+
+interface
+
+{.$DEFINE LUA_GETHOOK}
+
+type
+  size_t   = type Cardinal;
+  Psize_t  = ^size_t;
+  PPointer = ^Pointer;
+
+  lua_State = record end;
+  Plua_State = ^lua_State;
+
+const
+{$IFDEF UNIX}
+  LuaDLL = 'lua5.1.so';
+//  LuaDLL = 'lua5.1.a';
+{$ELSE}
+  LuaDLL = 'lua5.1.dll';
+{$ENDIF}
+
+
+(*****************************************************************************)
+(*                               luaconfig.h                                 *)
+(*****************************************************************************)
+
+(*
+** $Id: luaconf.h,v 1.81 2006/02/10 17:44:06 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*)
+
+(*
+** {==================================================================
+@@ LUA_NUMBER is the type of numbers in Lua.
+** CHANGE the following definitions only if you want to build Lua
+** with a number type different from double. You may also need to
+** change lua_number2int & lua_number2integer.
+** ===================================================================
+*)
+type
+  LUA_NUMBER_  = type Double;            // ending underscore is needed in Pascal
+  LUA_INTEGER_ = type LongInt;
+
+(*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@* of a function in debug information.
+** CHANGE it if you want a different size.
+*)
+const
+  LUA_IDSIZE = 60;
+
+(*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+*)
+const
+  LUAL_BUFFERSIZE = 1024;
+
+(*
+@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
+@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
+** CHANGE them if you want different prompts. (You can also change the
+** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
+*)
+const
+  LUA_PROMPT  = '> ';
+  LUA_PROMPT2 = '>> ';
+
+(*
+@@ lua_readline defines how to show a prompt and then read a line from
+@* the standard input.
+@@ lua_saveline defines how to "save" a read line in a "history".
+@@ lua_freeline defines how to free a line read by lua_readline.
+** CHANGE them if you want to improve this functionality (e.g., by using
+** GNU readline and history facilities).
+*)
+function  lua_readline(L : Plua_State; var b : PChar; p : PChar): Boolean;
+procedure lua_saveline(L : Plua_State; idx : LongInt);
+procedure lua_freeline(L : Plua_State; b : PChar);
+
+(*
+@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
+@* is, whether we're running lua interactively).
+** CHANGE it if you have a better definition for non-POSIX/non-Windows
+** systems.
+*/
+#include <io.h>
+#include <stdio.h>
+#define lua_stdin_is_tty()	_isatty(_fileno(stdin))
+*)
+const
+  lua_stdin_is_tty = TRUE;
+
+(*****************************************************************************)
+(*                                  lua.h                                    *)
+(*****************************************************************************)
+
+(*
+** $Id: lua.h,v 1.216 2006/01/10 12:50:13 roberto Exp $
+** Lua - An Extensible Extension Language
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** See Copyright Notice at the end of this file
+*)
+
+const
+  LUA_VERSION     = 'Lua 5.1';
+  LUA_VERSION_NUM = 501;
+  LUA_COPYRIGHT   = 'Copyright (C) 1994-2006 Tecgraf, PUC-Rio';
+  LUA_AUTHORS     = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes';
+
+  (* mark for precompiled code (`<esc>Lua') *)
+  LUA_SIGNATURE = #27'Lua';
+
+  (* option for multiple returns in `lua_pcall' and `lua_call' *)
+  LUA_MULTRET = -1;
+
+  (*
+  ** pseudo-indices
+  *)
+  LUA_REGISTRYINDEX = -10000;
+  LUA_ENVIRONINDEX  = -10001;
+  LUA_GLOBALSINDEX  = -10002;
+
+function lua_upvalueindex(idx : LongInt) : LongInt;   // a marco
+
+const
+  (* thread status; 0 is OK *)
+  LUA_YIELD_    = 1;     // Note: the ending underscore is needed in Pascal
+  LUA_ERRRUN    = 2;
+  LUA_ERRSYNTAX = 3;
+  LUA_ERRMEM    = 4;
+  LUA_ERRERR    = 5;
+
+type
+  lua_CFunction = function(L : Plua_State) : LongInt; cdecl;
+
+  (*
+  ** functions that read/write blocks when loading/dumping Lua chunks
+  *)
+  lua_Reader = function (L : Plua_State; ud : Pointer;
+                         sz : Psize_t) : PChar; cdecl;
+  lua_Writer = function (L : Plua_State; const p : Pointer; sz : size_t;
+                         ud : Pointer) : LongInt; cdecl;
+
+  (*
+  ** prototype for memory-allocation functions
+  *)
+  lua_Alloc = function (ud, ptr : Pointer;
+                        osize, nsize : size_t) : Pointer; cdecl;
+
+const
+  (*
+  ** basic types
+  *)
+  LUA_TNONE          = -1;
+
+  LUA_TNIL           = 0;
+  LUA_TBOOLEAN       = 1;
+  LUA_TLIGHTUSERDATA = 2;
+  LUA_TNUMBER        = 3;
+  LUA_TSTRING        = 4;
+  LUA_TTABLE         = 5;
+  LUA_TFUNCTION      = 6;
+  LUA_TUSERDATA	     = 7;
+  LUA_TTHREAD        = 8;
+
+  (* minimum Lua stack available to a C function *)
+  LUA_MINSTACK = 20;
+
+type
+  (* type of numbers in Lua *)
+  lua_Number = LUA_NUMBER_;
+
+  (* type for integer functions *)
+  lua_Integer = LUA_INTEGER_;
+
+(*
+** state manipulation
+*)
+function  lua_newstate(f : lua_Alloc; ud : Pointer) : Plua_State;
+  cdecl; external LuaDLL;
+procedure lua_close(L: Plua_State);
+  cdecl; external LuaDLL;
+function  lua_newthread(L : Plua_State) : Plua_State;
+  cdecl; external LuaDLL;
+
+function  lua_atpanic(L : Plua_State; panicf : lua_CFunction) : lua_CFunction;
+  cdecl; external LuaDLL;
+
+
+(*
+** basic stack manipulation
+*)
+function  lua_gettop(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+procedure lua_settop(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_pushvalue(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_remove(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_insert(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_replace(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+function  lua_checkstack(L : Plua_State; sz : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+
+procedure lua_xmove(src, dest : Plua_State; n : LongInt);
+  cdecl; external LuaDLL;
+
+
+(*
+** access functions (stack -> C)
+*)
+function lua_isnumber(L : Plua_State; idx : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_isstring(L : Plua_State; idx : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_iscfunction(L : Plua_State; idx : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_isuserdata(L : Plua_State; idx : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_type(L : Plua_State; idx : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+function lua_typename(L : Plua_State; tp : LongInt) : PChar;
+  cdecl; external LuaDLL;
+
+function lua_equal(L : Plua_State; idx1, idx2 : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_rawequal(L : Plua_State; idx1, idx2 : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_lessthan(L : Plua_State; idx1, idx2 : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+
+function lua_tonumber(L : Plua_State; idx : LongInt) : lua_Number;
+  cdecl; external LuaDLL;
+function lua_tointeger(L : Plua_State; idx : LongInt) : lua_Integer;
+  cdecl; external LuaDLL;
+function lua_toboolean(L : Plua_State; idx : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+function lua_tolstring(L : Plua_State; idx : LongInt;
+                       len : Psize_t) : PChar;
+  cdecl; external LuaDLL;
+function lua_objlen(L : Plua_State; idx : LongInt) : size_t;
+  cdecl; external LuaDLL;
+function lua_tocfunction(L : Plua_State; idx : LongInt) : lua_CFunction;
+  cdecl; external LuaDLL;
+function lua_touserdata(L : Plua_State; idx : LongInt) : Pointer;
+  cdecl; external LuaDLL;
+function lua_tothread(L : Plua_State; idx : LongInt) : Plua_State;
+  cdecl; external LuaDLL;
+function lua_topointer(L : Plua_State; idx : LongInt) : Pointer;
+  cdecl; external LuaDLL;
+
+
+(*
+** push functions (C -> stack)
+*)
+procedure lua_pushnil(L : Plua_State);
+  cdecl; external LuaDLL;
+procedure lua_pushnumber(L : Plua_State; n : lua_Number);
+  cdecl; external LuaDLL;
+procedure lua_pushinteger(L : Plua_State; n : lua_Integer);
+  cdecl; external LuaDLL;
+procedure lua_pushlstring(L : Plua_State; const s : PChar; ls : size_t);
+  cdecl; external LuaDLL;
+procedure lua_pushstring(L : Plua_State; const s : PChar);
+  cdecl; external LuaDLL;
+function  lua_pushvfstring(L : Plua_State;
+                           const fmt : PChar; argp : Pointer) : PChar;
+  cdecl; external LuaDLL;
+function  lua_pushfstring(L : Plua_State; const fmt : PChar) : PChar; varargs;
+  cdecl; external LuaDLL;
+procedure lua_pushcclosure(L : Plua_State; fn : lua_CFunction; n : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_pushboolean(L : Plua_State; b : LongBool);
+  cdecl; external LuaDLL;
+procedure lua_pushlightuserdata(L : Plua_State; p : Pointer);
+  cdecl; external LuaDLL;
+function  lua_pushthread(L : Plua_state) : Cardinal;
+  cdecl; external LuaDLL;
+
+
+(*
+** get functions (Lua -> stack)
+*)
+procedure lua_gettable(L : Plua_State ; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_getfield(L : Plua_State; idx : LongInt; k : PChar);
+  cdecl; external LuaDLL;
+procedure lua_rawget(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_rawgeti(L : Plua_State; idx, n : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_createtable(L : Plua_State; narr, nrec : LongInt);
+  cdecl; external LuaDLL;
+function  lua_newuserdata(L : Plua_State; sz : size_t) : Pointer;
+  cdecl; external LuaDLL;
+function  lua_getmetatable(L : Plua_State; objindex : LongInt) : LongBool;
+  cdecl; external LuaDLL;
+procedure lua_getfenv(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+
+
+(*
+** set functions (stack -> Lua)
+*)
+procedure lua_settable(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_setfield(L : Plua_State; idx : LongInt; const k : PChar);
+  cdecl; external LuaDLL;
+procedure lua_rawset(L : Plua_State; idx : LongInt);
+  cdecl; external LuaDLL;
+procedure lua_rawseti(L : Plua_State; idx , n: LongInt);
+  cdecl; external LuaDLL;
+function lua_setmetatable(L : Plua_State; objindex : LongInt): LongBool;
+  cdecl; external LuaDLL;
+function lua_setfenv(L : Plua_State; idx : LongInt): LongBool;
+  cdecl; external LuaDLL;
+
+(*
+** `load' and `call' functions (load and run Lua code)
+*)
+procedure lua_call(L : Plua_State; nargs, nresults : LongInt);
+  cdecl; external LuaDLL;
+function  lua_pcall(L : Plua_State;
+                    nargs, nresults, errfunc : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+function  lua_cpcall(L : Plua_State;
+                     func : lua_CFunction; ud : Pointer) : LongInt;
+  cdecl; external LuaDLL;
+function  lua_load(L : Plua_State; reader : lua_Reader;
+                   dt : Pointer; const chunkname : PChar) : LongInt;
+  cdecl; external LuaDLL;
+
+function lua_dump(L : Plua_State; writer : lua_Writer; data: Pointer) : LongInt;
+  cdecl; external LuaDLL;
+
+
+(*
+** coroutine functions
+*)
+function lua_yield(L : Plua_State; nresults : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+function lua_resume(L : Plua_State; narg : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+function lua_status(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+(*
+** garbage-collection functions and options
+*)
+const
+  LUA_GCSTOP       = 0;
+  LUA_GCRESTART    = 1;
+  LUA_GCCOLLECT    = 2;
+  LUA_GCCOUNT      = 3;
+  LUA_GCCOUNTB	   = 4;
+  LUA_GCSTEP       = 5;
+  LUA_GCSETPAUSE   = 6;
+  LUA_GCSETSTEPMUL = 7;
+
+function lua_gc(L : Plua_State; what, data : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+
+(*
+** miscellaneous functions
+*)
+function lua_error(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function lua_next(L : Plua_State; idx : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+
+procedure lua_concat(L : Plua_State; n : LongInt);
+  cdecl; external LuaDLL;
+
+function  lua_getallocf(L : Plua_State; ud : PPointer) : lua_Alloc;
+  cdecl; external LuaDLL;
+procedure lua_setallocf(L : Plua_State; f : lua_Alloc; ud : Pointer);
+  cdecl; external LuaDLL;
+
+(*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*)
+procedure lua_pop(L : Plua_State; n : LongInt);
+
+procedure lua_newtable(L : Plua_State);
+
+procedure lua_register(L : Plua_State; n : PChar; f : lua_CFunction);
+
+procedure lua_pushcfunction(L : Plua_State; f : lua_CFunction);
+
+function  lua_strlen(L : Plua_State; idx : LongInt) : LongInt;
+
+function lua_isfunction(L : Plua_State; n : LongInt) : Boolean;
+function lua_istable(L : Plua_State; n : LongInt) : Boolean;
+function lua_islightuserdata(L : Plua_State; n : LongInt) : Boolean;
+function lua_isnil(L : Plua_State; n : LongInt) : Boolean;
+function lua_isboolean(L : Plua_State; n : LongInt) : Boolean;
+function lua_isthread(L : Plua_State; n : LongInt) : Boolean;
+function lua_isnone(L : Plua_State; n : LongInt) : Boolean;
+function lua_isnoneornil(L : Plua_State; n : LongInt) : Boolean;
+
+procedure lua_pushliteral(L : Plua_State; s : PChar);
+
+procedure lua_setglobal(L : Plua_State; s : PChar);
+procedure lua_getglobal(L : Plua_State; s : PChar);
+
+function lua_tostring(L : Plua_State; idx : LongInt) : PChar;
+
+
+(*
+** compatibility macros and functions
+*)
+function lua_open : Plua_State;
+
+procedure lua_getregistry(L : Plua_State);
+
+function lua_getgccount(L : Plua_State) : LongInt;
+
+type
+  lua_Chuckreader = type lua_Reader;
+  lua_Chuckwriter = type lua_Writer;
+
+(* ====================================================================== *)
+
+(*
+** {======================================================================
+** Debug API
+** =======================================================================
+*)
+
+(*
+** Event codes
+*)
+const
+  LUA_HOOKCALL    = 0;
+  LUA_HOOKRET     = 1;
+  LUA_HOOKLINE    = 2;
+  LUA_HOOKCOUNT   = 3;
+  LUA_HOOKTAILRET = 4;
+
+
+(*
+** Event masks
+*)
+  LUA_MASKCALL  = 1 shl LUA_HOOKCALL;
+  LUA_MASKRET   = 1 shl LUA_HOOKRET;
+  LUA_MASKLINE  = 1 shl LUA_HOOKLINE;
+  LUA_MASKCOUNT = 1 shl LUA_HOOKCOUNT;
+
+type
+  lua_Debug = packed record
+    event : LongInt;
+    name : PChar;          (* (n) *)
+    namewhat : PChar;      (* (n) `global', `local', `field', `method' *)
+    what : PChar;          (* (S) `Lua', `C', `main', `tail' *)
+    source : PChar;        (* (S) *)
+    currentline : LongInt; (* (l) *)
+    nups : LongInt;        (* (u) number of upvalues *)
+    linedefined : LongInt; (* (S) *)
+    short_src : array [0..LUA_IDSIZE-1] of Char; (* (S) *)
+    (* private part *)
+    i_ci : LongInt;        (* active function *)
+  end;
+  Plua_Debug = ^lua_Debug;
+
+  (* Functions to be called by the debuger in specific events *)
+  lua_Hook = procedure (L : Plua_State; ar : Plua_Debug); cdecl;
+
+
+function lua_getstack(L : Plua_State; level : LongInt;
+                      ar : Plua_Debug) : LongInt;
+  cdecl; external LuaDLL;
+function lua_getinfo(L : Plua_State; const what : PChar;
+                     ar: Plua_Debug): LongInt;
+  cdecl; external LuaDLL;
+function lua_getlocal(L : Plua_State;
+                      ar : Plua_Debug; n : LongInt) : PChar;
+  cdecl; external LuaDLL;
+function lua_setlocal(L : Plua_State;
+                      ar : Plua_Debug; n : LongInt) : PChar;
+  cdecl; external LuaDLL;
+function lua_getupvalue(L : Plua_State; funcindex, n : LongInt) : PChar;
+  cdecl; external LuaDLL;
+function lua_setupvalue(L : Plua_State; funcindex, n : LongInt) : PChar;
+  cdecl; external LuaDLL;
+
+function lua_sethook(L : Plua_State; func : lua_Hook;
+                     mask, count: LongInt): LongInt;
+  cdecl; external LuaDLL;
+{$IFDEF LUA_GETHOOK}
+function lua_gethook(L : Plua_State) : lua_Hook;
+  cdecl; external LuaDLL;
+{$ENDIF}
+
+function lua_gethookmask(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+function lua_gethookcount(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+
+(*****************************************************************************)
+(*                                  lualib.h                                 *)
+(*****************************************************************************)
+
+(*
+** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $
+** Lua standard libraries
+** See Copyright Notice at the end of this file
+*)
+
+const
+  (* Key to file-handle type *)
+  LUA_FILEHANDLE  = 'FILE*';
+
+  LUA_COLIBNAME   = 'coroutine';
+  LUA_TABLIBNAME  = 'table';
+  LUA_IOLIBNAME   = 'io';
+  LUA_OSLIBNAME   = 'os';
+  LUA_STRLIBNAME  = 'string';
+  LUA_MATHLIBNAME = 'math';
+  LUA_DBLIBNAME   = 'debug';
+  LUA_LOADLIBNAME = 'package';
+
+function luaopen_base(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_table(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_io(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_os(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_string(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_math(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_debug(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaopen_package(L : Plua_State) : LongInt;
+  cdecl; external LuaDLL;
+
+procedure luaL_openlibs(L : Plua_State);
+  cdecl; external LuaDLL;
+
+procedure lua_assert(x : Boolean);    // a macro
+
+
+(*****************************************************************************)
+(*                                  lauxlib.h                                *)
+(*****************************************************************************)
+
+(*
+** $Id: lauxlib.h,v 1.87 2005/12/29 15:32:11 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice at the end of this file.
+*)
+
+// not compatibility with the behavior of setn/getn in Lua 5.0
+function  luaL_getn(L : Plua_State; idx : LongInt) : LongInt;
+procedure luaL_setn(L : Plua_State; i, j : LongInt);
+
+const
+  LUA_ERRFILE = LUA_ERRERR + 1;
+
+type
+  luaL_Reg = packed record
+    name : PChar;
+    func : lua_CFunction;
+  end;
+  PluaL_Reg = ^luaL_Reg;
+
+
+procedure luaL_openlib(L : Plua_State; const libname : PChar;
+                       const lr : PluaL_Reg; nup : LongInt);
+  cdecl; external LuaDLL;
+procedure luaL_register(L : Plua_State; const libname : PChar;
+                       const lr : PluaL_Reg);
+  cdecl; external LuaDLL;
+function luaL_getmetafield(L : Plua_State; obj : LongInt;
+                           const e : PChar) : LongInt;
+  cdecl; external LuaDLL;
+function luaL_callmeta(L : Plua_State; obj : LongInt;
+                       const e : PChar) : LongInt;
+  cdecl; external LuaDLL;
+function luaL_typerror(L : Plua_State; narg : LongInt;
+                       const tname : PChar) : LongInt;
+  cdecl; external LuaDLL;
+function luaL_argerror(L : Plua_State; numarg : LongInt;
+                       const extramsg : PChar) : LongInt;
+  cdecl; external LuaDLL;
+function luaL_checklstring(L : Plua_State; numArg : LongInt;
+                           ls : Psize_t) : PChar;
+  cdecl; external LuaDLL;
+function luaL_optlstring(L : Plua_State; numArg : LongInt;
+                         const def: PChar; ls: Psize_t) : PChar;
+  cdecl; external LuaDLL;
+function luaL_checknumber(L : Plua_State; numArg : LongInt) : lua_Number;
+  cdecl; external LuaDLL;
+function luaL_optnumber(L : Plua_State; nArg : LongInt;
+                        def : lua_Number) : lua_Number;
+  cdecl; external LuaDLL;
+
+function luaL_checkinteger(L : Plua_State; numArg : LongInt) : lua_Integer;
+  cdecl; external LuaDLL;
+function luaL_optinteger(L : Plua_State; nArg : LongInt;
+                        def : lua_Integer) : lua_Integer;
+  cdecl; external LuaDLL;
+
+procedure luaL_checkstack(L : Plua_State; sz : LongInt; const msg : PChar);
+  cdecl; external LuaDLL;
+procedure luaL_checktype(L : Plua_State; narg, t : LongInt);
+  cdecl; external LuaDLL;
+procedure luaL_checkany(L : Plua_State; narg : LongInt);
+  cdecl; external LuaDLL;
+
+function luaL_newmetatable(L : Plua_State; const tname : PChar) : LongInt;
+  cdecl; external LuaDLL;
+function luaL_checkudata(L : Plua_State; ud : LongInt;
+                         const tname : PChar) : Pointer;
+  cdecl; external LuaDLL;
+
+procedure luaL_where(L : Plua_State; lvl : LongInt);
+  cdecl; external LuaDLL;
+function  luaL_error(L : Plua_State; const fmt : PChar) : LongInt; varargs;
+  cdecl; external LuaDLL;
+
+function luaL_checkoption(L : Plua_State; narg : LongInt; const def : PChar;
+                          const lst : array of PChar) : LongInt;
+  cdecl; external LuaDLL;
+
+function  luaL_ref(L : Plua_State; t : LongInt) : LongInt;
+  cdecl; external LuaDLL;
+procedure luaL_unref(L : Plua_State; t, ref : LongInt);
+  cdecl; external LuaDLL;
+
+function luaL_loadfile(L : Plua_State; const filename : PChar) : LongInt;
+  cdecl; external LuaDLL;
+function luaL_loadbuffer(L : Plua_State; const buff : PChar;
+                         sz : size_t; const name: PChar) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaL_loadstring(L : Plua_State; const s : Pchar) : LongInt;
+  cdecl; external LuaDLL;
+
+function luaL_newstate : Plua_State;
+  cdecl; external LuaDLL;
+
+function luaL_gsub(L : Plua_State; const s, p, r : PChar) : PChar;
+  cdecl; external LuaDLL;
+
+function luaL_findtable(L : Plua_State; idx : LongInt;
+                        const fname : PChar; szhint : LongInt) : PChar;
+  cdecl; external LuaDLL;
+
+
+(*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*)
+
+function luaL_argcheck(L : Plua_State; cond : Boolean; numarg : LongInt;
+                       extramsg : PChar): LongInt;
+function luaL_checkstring(L : Plua_State; n : LongInt) : PChar;
+function luaL_optstring(L : Plua_State; n : LongInt; d : PChar) : PChar;
+function luaL_checkint(L : Plua_State; n : LongInt) : LongInt;
+function luaL_optint(L : Plua_State; n, d : LongInt): LongInt;
+function luaL_checklong(L : Plua_State; n : LongInt) : LongInt;
+function luaL_optlong(L : Plua_State; n : LongInt; d : LongInt) : LongInt;
+
+function luaL_typename(L : Plua_State; idx : LongInt) : PChar;
+
+function luaL_dofile(L : Plua_State; fn : PChar) : LongInt;
+
+function luaL_dostring(L : Plua_State; s : PChar) : LongInt;
+
+procedure luaL_getmetatable(L : Plua_State; n : PChar);
+
+(* not implemented yet
+#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+*)
+
+(*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*)
+
+type
+  luaL_Buffer = packed record
+    p : PChar;       (* current position in buffer *)
+    lvl : LongInt;   (* number of strings in the stack (level) *)
+    L : Plua_State;
+    buffer : array [0..LUAL_BUFFERSIZE-1] of Char;
+  end;
+  PluaL_Buffer = ^luaL_Buffer;
+
+procedure luaL_addchar(B : PluaL_Buffer; c : Char);
+
+(* compatibility only *)
+procedure luaL_putchar(B : PluaL_Buffer; c : Char);
+
+procedure luaL_addsize(B : PluaL_Buffer; n : LongInt);
+
+procedure luaL_buffinit(L : Plua_State; B : PluaL_Buffer);
+  cdecl; external LuaDLL;
+function  luaL_prepbuffer(B : PluaL_Buffer) : PChar;
+  cdecl; external LuaDLL;
+procedure luaL_addlstring(B : PluaL_Buffer; const s : PChar; ls : size_t);
+  cdecl; external LuaDLL;
+procedure luaL_addstring(B : PluaL_Buffer; const s : PChar);
+  cdecl; external LuaDLL;
+procedure luaL_addvalue(B : PluaL_Buffer);
+  cdecl; external LuaDLL;
+procedure luaL_pushresult(B : PluaL_Buffer);
+  cdecl; external LuaDLL;
+
+(* ====================================================== *)
+
+
+(* compatibility with ref system *)
+
+(* pre-defined references *)
+const
+  LUA_NOREF  = -2;
+  LUA_REFNIL = -1;
+
+function lua_ref(L : Plua_State; lock : Boolean) : LongInt;
+
+procedure lua_unref(L : Plua_State; ref : LongInt);
+
+procedure lua_getref(L : Plua_State; ref : LongInt);
+
+
+(******************************************************************************)
+(******************************************************************************)
+(******************************************************************************)
+
+implementation
+
+uses
+  SysUtils;
+
+(*****************************************************************************)
+(*                            luaconfig.h                                    *)
+(*****************************************************************************)
+
+function  lua_readline(L : Plua_State; var b : PChar; p : PChar): Boolean;
+var
+  s : AnsiString;
+begin
+  Write(p);                        // show prompt
+  ReadLn(s);                       // get line
+  b := PChar(s);                   //   and return it
+  lua_readline := (b[0] <> #4);          // test for ctrl-D
+end;
+
+procedure lua_saveline(L : Plua_State; idx : LongInt);
+begin
+end;
+
+procedure lua_freeline(L : Plua_State; b : PChar);
+begin
+end;
+
+
+(*****************************************************************************)
+(*                                  lua.h                                    *)
+(*****************************************************************************)
+
+function lua_upvalueindex(idx : LongInt) : LongInt;
+begin
+  lua_upvalueindex := LUA_GLOBALSINDEX - idx;
+end;
+
+procedure lua_pop(L : Plua_State; n : LongInt);
+begin
+  lua_settop(L, -n - 1);
+end;
+
+procedure lua_newtable(L : Plua_State);
+begin
+  lua_createtable(L, 0, 0);
+end;
+
+procedure lua_register(L : Plua_State; n : PChar; f : lua_CFunction);
+begin
+  lua_pushcfunction(L, f);
+  lua_setglobal(L, n);
+end;
+
+procedure lua_pushcfunction(L : Plua_State; f : lua_CFunction);
+begin
+  lua_pushcclosure(L, f, 0);
+end;
+
+function  lua_strlen(L : Plua_State; idx : LongInt) : LongInt;
+begin
+  lua_strlen := lua_objlen(L, idx);
+end;
+
+function lua_isfunction(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_isfunction := lua_type(L, n) = LUA_TFUNCTION;
+end;
+
+function lua_istable(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_istable := lua_type(L, n) = LUA_TTABLE;
+end;
+
+function lua_islightuserdata(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_islightuserdata := lua_type(L, n) = LUA_TLIGHTUSERDATA;
+end;
+
+function lua_isnil(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_isnil := lua_type(L, n) = LUA_TNIL;
+end;
+
+function lua_isboolean(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_isboolean := lua_type(L, n) = LUA_TBOOLEAN;
+end;
+
+function lua_isthread(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_isthread := lua_type(L, n) = LUA_TTHREAD;
+end;
+
+function lua_isnone(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_isnone := lua_type(L, n) = LUA_TNONE;
+end;
+
+function lua_isnoneornil(L : Plua_State; n : LongInt) : Boolean;
+begin
+  lua_isnoneornil := lua_type(L, n) <= 0;
+end;
+
+procedure lua_pushliteral(L : Plua_State; s : PChar);
+begin
+  lua_pushlstring(L, s, StrLen(s));
+end;
+
+procedure lua_setglobal(L : Plua_State; s : PChar);
+begin
+  lua_setfield(L, LUA_GLOBALSINDEX, s);
+end;
+
+procedure lua_getglobal(L: Plua_State; s: PChar);
+begin
+  lua_getfield(L, LUA_GLOBALSINDEX, s);
+end;
+
+function lua_tostring(L : Plua_State; idx : LongInt) : PChar;
+begin
+  lua_tostring := lua_tolstring(L, idx, nil);
+end;
+
+function lua_open : Plua_State;
+begin
+  lua_open := luaL_newstate;
+end;
+
+procedure lua_getregistry(L : Plua_State);
+begin
+  lua_pushvalue(L, LUA_REGISTRYINDEX);
+end;
+
+function lua_getgccount(L : Plua_State) : LongInt;
+begin
+  lua_getgccount := lua_gc(L, LUA_GCCOUNT, 0);
+end;
+
+
+(*****************************************************************************)
+(*                                  lualib.h                                 *)
+(*****************************************************************************)
+
+procedure lua_assert(x : Boolean);
+begin
+end;
+
+
+(*****************************************************************************)
+(*                                  lauxlib.h    n                           *)
+(*****************************************************************************)
+
+function luaL_getn(L : Plua_State; idx : LongInt) : LongInt;
+begin
+  luaL_getn := lua_objlen(L, idx);
+end;
+
+procedure luaL_setn(L : plua_State; i, j : LongInt);
+begin
+  (* no op *)
+end;
+
+function luaL_argcheck(L : Plua_State; cond : Boolean; numarg : LongInt;
+                       extramsg : PChar): LongInt;
+begin
+  if not cond then
+    luaL_argcheck := luaL_argerror(L, numarg, extramsg)
+  else
+    luaL_argcheck := 0;
+end;
+
+function luaL_checkstring(L : Plua_State; n : LongInt) : PChar;
+begin
+  luaL_checkstring := luaL_checklstring(L, n, nil);
+end;
+
+function luaL_optstring(L : Plua_State; n : LongInt; d : PChar) : PChar;
+begin
+  luaL_optstring := luaL_optlstring(L, n, d, nil);
+end;
+
+function luaL_checkint(L : Plua_State; n : LongInt) : LongInt;
+begin
+  luaL_checkint := luaL_checkinteger(L, n);
+end;
+
+function luaL_optint(L : Plua_State; n, d : LongInt): LongInt;
+begin
+  luaL_optint := luaL_optinteger(L, n, d);
+end;
+
+function luaL_checklong(L : Plua_State; n : LongInt) : LongInt;
+begin
+  luaL_checklong := luaL_checkinteger(L, n);
+end;
+
+function luaL_optlong(L : Plua_State; n : LongInt; d : LongInt) : LongInt;
+begin
+  luaL_optlong := luaL_optinteger(L, n, d);
+end;
+
+function luaL_typename(L : Plua_State; idx : LongInt) : PChar;
+begin
+  luaL_typename := lua_typename( L, lua_type(L, idx) );
+end;
+
+function luaL_dofile(L : Plua_State; fn : PChar) : LongInt;
+begin
+  luaL_dofile := luaL_loadfile(L, fn);
+  if luaL_dofile = 0 then
+    luaL_dofile := lua_pcall(L, 0, 0, 0);
+end;
+
+function luaL_dostring(L : Plua_State; s : PChar) : LongInt;
+begin
+  luaL_dostring := luaL_loadstring(L, s);
+  if luaL_dostring = 0 then
+    luaL_dostring := lua_pcall(L, 0, 0, 0);
+end;
+
+procedure luaL_getmetatable(L : Plua_State; n : PChar);
+begin
+  lua_getfield(L, LUA_REGISTRYINDEX, n);
+end;
+
+procedure luaL_addchar(B : PluaL_Buffer; c : Char);
+begin
+  if not(B^.p < B^.buffer + LUAL_BUFFERSIZE) then
+    luaL_prepbuffer(B);
+  B^.p^ := c;
+  Inc(B^.p);
+end;
+
+procedure luaL_putchar(B : PluaL_Buffer; c : Char);
+begin
+  luaL_addchar(B, c);
+end;
+
+procedure luaL_addsize(B : PluaL_Buffer; n : LongInt);
+begin
+  Inc(B^.p, n);
+end;
+
+function lua_ref(L : Plua_State; lock : Boolean) : LongInt;
+begin
+  if lock then
+    lua_ref := luaL_ref(L, LUA_REGISTRYINDEX)
+  else begin
+    lua_pushstring(L, 'unlocked references are obsolete');
+    lua_error(L);
+    lua_ref := 0;
+  end;
+end;
+
+procedure lua_unref(L : Plua_State; ref : LongInt);
+begin
+  luaL_unref(L, LUA_REGISTRYINDEX, ref);
+end;
+
+procedure lua_getref(L : Plua_State; ref : LongInt);
+begin
+  lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
+end;
+
+
+(******************************************************************************
+* Original copyright for the lua source and headers:
+*  1994-2004 Tecgraf, PUC-Rio.
+*  www.lua.org.
+*
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************)
+
+end.
+
--- a/hedgewars/hwengine.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/hwengine.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -54,11 +54,12 @@
 	uStats in 'uStats.pas',
 	uChat in 'uChat.pas',
 	uTriggers in 'uTriggers.pas',
-	uLandTexture in 'uLandTexture.pas'
+	uLandTexture in 'uLandTexture.pas',
+	uScript in 'uScript.pas',
 	{$IFDEF IPHONEOS}
-	, PascalExports in 'PascalExports.pas'
+	PascalExports in 'PascalExports.pas',
 	{$ELSE}
-	, sysutils
+	sysutils
 	{$ENDIF}
 	;
 
@@ -115,6 +116,7 @@
 				FinishProgress;
 				PlayMusic;
 				SetScale(zoom);
+				ScriptCall('onGameStart');
 				GameState:= gsGame;
 				end;
 		gsConfirm,
@@ -286,11 +288,15 @@
 	    LoadLocale(Pathz[ptLocale] + '/' + cLocaleFName);
         end;
 
+	ScriptCall('onTeamSetup');
+		
 	if recordFileName = '' then
 		SendIPCAndWaitReply('C')        // ask for game config
 	else
 		LoadRecordFromFile(recordFileName);
 
+	ScriptOnGameInit;
+
 	s:= 'eproto ' + inttostr(cNetProtoVersion);
 	SendIPCRaw(@s[0], Length(s) + 1); // send proto version
 
@@ -342,6 +348,7 @@
 	init_uTriggers();
 	init_uVisualGears();
 	init_uWorld();
+	init_uScript();
 end;
 
 procedure freeEverything;
@@ -377,7 +384,7 @@
 	free_uConsole();
 	free_uMisc();
 	free_uConsts();		//stub
-
+	free_uScript();
 end;
 {$IFNDEF IPHONEOS}
 /////////////////////////
--- a/hedgewars/uConsole.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/uConsole.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -38,7 +38,7 @@
 
 implementation
 uses uMisc, uStore, Types, uConsts, uGears, uTeams, uIO, uKeys, uWorld, uLand,
-     uRandom, uAmmos, uTriggers, uStats, uGame, uChat, SDLh, uSound, uVisualGears;
+     uRandom, uAmmos, uTriggers, uStats, uGame, uChat, SDLh, uSound, uVisualGears, uScript;
 
 const cLineWidth: LongInt = 0;
       cLinesCount = 256;
@@ -305,6 +305,7 @@
 	RegisterVariable('+cur_r'  , vtCommand, @chCurR_p       , true );
 	RegisterVariable('-cur_r'  , vtCommand, @chCurR_m       , true );
 	RegisterVariable('flag'    , vtCommand, @chFlag         , false);
+	RegisterVariable('script'  , vtCommand, @chScript       , false);
 end;
 
 procedure free_uConsole;
--- a/hedgewars/uGame.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/uGame.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -27,7 +27,7 @@
 ////////////////////
    implementation
 ////////////////////
-uses uMisc, uConsts, uWorld, uKeys, uTeams, uIO, uAI, uGears, uConsole;
+uses uMisc, uConsts, uWorld, uKeys, uTeams, uIO, uAI, uGears, uConsole, uScript;
 
 procedure DoGameTick(Lag: LongInt);
 var i: LongInt;
@@ -46,6 +46,7 @@
 i:= 1;
 while (GameState <> gsExit) and (i <= Lag) do
     begin
+	ScriptCall('onGameTick');
     if not CurrentTeam^.ExtDriven then
        begin
        if CurrentHedgehog^.BotLevel <> 0 then ProcessBot;
--- a/hedgewars/uGears.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/uGears.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -91,7 +91,7 @@
 
 implementation
 uses uWorld, uMisc, uStore, uConsole, uSound, uTeams, uRandom, uCollisions, uLand, uIO, uLandGraphics,
-	uAIMisc, uLocale, uAI, uAmmos, uTriggers, uStats, uVisualGears,
+	uAIMisc, uLocale, uAI, uAmmos, uTriggers, uStats, uVisualGears, uScript, 
 {$IFDEF GLES11}
 	gles11;
 {$ELSE}
@@ -423,6 +423,8 @@
      end;
 InsertGearToList(gear);
 AddGear:= gear;
+
+ScriptCall('onGearAdd', LongInt(gear));
 end;
 
 procedure DeleteGear(Gear: PGear);
@@ -430,6 +432,9 @@
 	t,i: Longword;
     k: boolean;
 begin
+
+ScriptCall('onGearDelete', LongInt(gear));
+
 DeleteCI(Gear);
 
 if Gear^.Tex <> nil then
--- a/hedgewars/uKeys.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/uKeys.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -57,7 +57,9 @@
 	//ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer;
 	ControllerHats: array[0..5] of array[0..19] of Byte;
 	ControllerButtons: array[0..5] of array[0..19] of Byte;
-	
+
+	DefaultBinds, CurrentBinds: TBinds;
+
 {$IFDEF IPHONEOS}
 	leftClick: boolean;
 	middleClick: boolean;
@@ -86,7 +88,6 @@
 
 var tkbd, tkbdn: TKeyboardState;
     KeyNames: array [0..cKeyMaxIndex] of string[15];
-    DefaultBinds, CurrentBinds: TBinds;
 	
 function KeyNameToCode(name: string): word;
 var code: Word;
@@ -321,18 +322,26 @@
 
 DefaultBinds[KeyNameToCode('f12')]:= 'fullscr';
 
-{$IFDEF IPHONEOS}
+
+
 DefaultBinds[ 1]:= '/put';
 DefaultBinds[ 3]:= 'ammomenu';
 DefaultBinds[ 8]:= 'hjump';
 DefaultBinds[ 9]:= 'switch';
 DefaultBinds[13]:= 'ljump';
+DefaultBinds[32]:= '+attack';
+{$IFDEF IPHONEOS}
 DefaultBinds[23]:= '+up';
 DefaultBinds[24]:= '+down';
 DefaultBinds[25]:= '+left';
 DefaultBinds[26]:= '+right';
-DefaultBinds[32]:= '+attack';
 DefaultBinds[44]:= 'chat';
+{$ELSE}
+DefaultBinds[KeyNameToCode('up')]:= '+up';
+DefaultBinds[KeyNameToCode('down')]:= '+down';
+DefaultBinds[KeyNameToCode('left')]:= '+left';
+DefaultBinds[KeyNameToCode('right')]:= '+right';
+DefaultBinds[KeyNameToCode('left_shift')]:= '+precise';
 {$ENDIF}
 
 SetDefaultBinds();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uScript.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -0,0 +1,501 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2008 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uScript;
+interface
+
+procedure ScriptPrintStack;
+procedure ScriptClearStack;
+
+procedure ScriptLoad(name : string);
+procedure ScriptOnGameInit;
+
+procedure ScriptCall(fname : string);
+function ScriptCall(fname : string; par1: LongInt) : LongInt;
+function ScriptCall(fname : string; par1, par2: LongInt) : LongInt;
+function ScriptCall(fname : string; par1, par2, par3: LongInt) : LongInt;
+function ScriptCall(fname : string; par1, par2, par3, par4 : LongInt) : LongInt;
+
+procedure init_uScript;
+procedure free_uScript;
+
+implementation
+uses LuaPas in 'LuaPas.pas',
+	uConsole,
+	uMisc,
+	uConsts,
+	uGears,
+	uFloat,
+	uWorld,
+	uAmmos,
+	uSound,
+	uTeams,
+	uKeys,
+	typinfo;
+
+var luaState : Plua_State;
+	ScriptAmmoStore : string;
+	
+procedure ScriptPrepareAmmoStore; forward;
+procedure ScriptApplyAmmoStore; forward;
+procedure ScriptSetAmmo(ammo : TAmmoType; count, propability: Byte); forward;
+
+// 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 lua_gettop(L) to receive number of parameters passed
+
+function lc_writelntoconsole(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) = 1 then
+		begin
+		WriteLnToConsole('LUA: ' + lua_tostring(L ,1));
+		end
+	else
+		AddFileLog('LUA: Wrong number of parameters passed to WriteLnToConsole!');
+	lc_writelntoconsole:= 0;
+end;
+
+function lc_parsecommand(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) = 1 then
+		begin
+		ParseCommand(lua_tostring(L ,1), true);
+		end
+	else
+		AddFileLog('LUA: Wrong number of parameters passed to ParseCommand!');
+	lc_parsecommand:= 0;
+end;
+
+function lc_showmission(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) = 5 then
+		begin
+		ShowMission(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5));
+		end
+	else
+		AddFileLog('LUA: Wrong number of parameters passed to ShowMission!');
+	lc_showmission:= 0;
+end;
+
+function lc_hidemission(L : Plua_State) : LongInt; Cdecl;
+begin
+	HideMission;
+	lc_hidemission:= 0;
+end;
+
+function lc_addgear(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+	x, y, s, t: LongInt;
+	dx, dy: hwFloat;
+	gt: TGearType;
+begin
+	if lua_gettop(L) <> 7 then
+		begin
+		AddFileLog('LUA: Wrong number of parameters passed to AddGear!');
+		lua_pushnil(L); // return value on stack (nil)
+		end
+	else
+		begin
+		x:= lua_tointeger(L, 1);
+		y:= lua_tointeger(L, 2);
+		gt:= TGearType(lua_tointeger(L, 3));
+		s:= lua_tointeger(L, 4);
+		dx:= int2hwFloat(round(lua_tonumber(L, 5) * 1000)) / 1000;
+		dy:= int2hwFloat(round(lua_tonumber(L, 6) * 1000)) / 1000;
+		t:= lua_tointeger(L, 7);
+
+		gear:= AddGear(x, y, gt, s, dx, dy, t);
+		lua_pushnumber(L, LongInt(gear))
+		end;
+	lc_addgear:= 1; // 1 return value
+end;
+
+function lc_getgeartype(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) <> 1 then
+		begin
+		AddFileLog('LUA: Wrong number of parameters passed to GetGearType!');
+		lua_pushnil(L); // return value on stack (nil)
+		end
+	else
+		lua_pushinteger(L, ord(PGear(lua_tointeger(L, 1))^.Kind));
+	lc_getgeartype:= 1
+end;
+
+function lc_endgame(L : Plua_State) : LongInt; Cdecl;
+begin
+	GameState:= gsExit;
+	lc_endgame:= 0
+end;
+
+function lc_findplace(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+	fall: boolean;
+	left, right: LongInt;
+begin
+	if lua_gettop(L) <> 4 then
+		AddFileLog('LUA: Wrong number of parameters passed to FindPlace!')
+	else
+		begin
+		gear:= PGear(lua_tointeger(L, 1));
+		fall:= lua_toboolean(L, 2);
+		left:= lua_tointeger(L, 3);
+		right:= lua_tointeger(L, 4);
+		FindPlace(gear, fall, left, right)
+		end;
+	lc_findplace:= 0
+end;
+
+function lc_playsound(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) <> 1 then
+		AddFileLog('LUA: Wrong number of parameters passed to PlaySound!')
+	else
+		PlaySound(TSound(lua_tointeger(L, 1)));
+	lc_playsound:= 0;
+end;
+
+function lc_addteam(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) <> 5 then
+		AddFileLog('LUA: Wrong number of parameters passed to AddTeam!')
+	else
+		begin
+		ParseCommand('addteam ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 1), true);
+		ParseCommand('grave ' + lua_tostring(L, 3), true);
+		ParseCommand('fort ' + lua_tostring(L, 4), true);
+		ParseCommand('voicepack ' + lua_tostring(L, 5), true);
+		CurrentTeam^.Binds:= DefaultBinds;
+		lua_pushinteger(L, LongInt(CurrentTeam));
+		end;
+	lc_addteam:= 1;
+end;
+
+function lc_addhog(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) <> 4 then
+		begin
+		AddFileLog('LUA: Wrong number of parameters passed to AddHog!');
+		lua_pushnil(L)
+		end
+	else
+		begin
+		ParseCommand('addhh ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 3) + ' ' + lua_tostring(L, 1), true);
+		ParseCommand('hat ' + lua_tostring(L, 4), true);
+		WriteLnToConsole('last hog: ' + inttostr(LongInt(CurrentHedgehog)));
+		lua_pushinteger(L, LongInt(CurrentHedgehog^.Gear));
+		end;
+	lc_addhog:= 1;
+end;
+
+function lc_getgearposition(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+	if lua_gettop(L) <> 1 then
+		begin
+		AddFileLog('LUA: Wrong number of parameters passed to GetGearPosition!');
+		lua_pushnil(L);
+		lua_pushnil(L)
+		end
+	else
+		begin
+		gear:= PGear(lua_tointeger(L, 1));
+		lua_pushinteger(L, hwRound(gear^.X));
+		lua_pushinteger(L, hwRound(gear^.Y))
+		end;
+	lc_getgearposition:= 2;
+end;
+
+function lc_setgearposition(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+	x, y: LongInt;
+begin
+	if lua_gettop(L) <> 3 then
+		AddFileLog('LUA: Wrong number of parameters passed to SetGearPosition!')
+	else
+		begin
+		gear:= PGear(lua_tointeger(L, 1));
+		x:= lua_tointeger(L, 2);
+		y:= lua_tointeger(L, 3);
+		gear^.X:= int2hwfloat(x);
+		gear^.Y:= int2hwfloat(y);
+		end;
+	lc_setgearposition:= 0
+end;
+
+function lc_setammo(L : Plua_State) : LongInt; Cdecl;
+begin
+	if lua_gettop(L) <> 3 then
+		AddFileLog('LUA: Wrong number of parameters passed to SetAmmo!')
+	else
+		begin
+		ScriptSetAmmo(TAmmoType(lua_tointeger(L, 1)), lua_tointeger(L, 2), lua_tointeger(L, 3));
+		end;
+	lc_setammo:= 0
+end;
+///////////////////
+
+procedure ScriptPrintStack;
+var n, i : LongInt;
+begin
+	n:= lua_gettop(luaState);
+	AddFileLog('LUA: Stack (' + inttostr(n) + ' elements):');
+	for i:= 1 to n do
+		if not lua_isboolean(luaState, i) then
+			AddFileLog('LUA:  ' + inttostr(i) + ': ' + lua_tostring(luaState, i))
+		else if lua_toboolean(luaState, i) then
+			AddFileLog('LUA:  ' + inttostr(i) + ': true')
+		else
+			AddFileLog('LUA:  ' + inttostr(i) + ': false');
+end;
+
+procedure ScriptClearStack;
+begin
+lua_settop(luaState, 0)
+end;
+
+procedure ScriptSetInteger(name : string; value : LongInt);
+begin
+lua_pushinteger(luaState, value);
+lua_setglobal(luaState, Str2PChar(name));
+end;
+
+procedure ScriptSetString(name : string; value : string);
+begin
+lua_pushstring(luaState, Str2PChar(value));
+lua_setglobal(luaState, Str2PChar(name));
+end;
+
+function ScriptGetInteger(name : string) : LongInt;
+begin
+lua_getglobal(luaState, Str2PChar(name));
+ScriptGetInteger:= lua_tointeger(luaState, -1);
+lua_pop(luaState, 1);
+end;
+
+function ScriptGetString(name : string) : string;
+begin
+lua_getglobal(luaState, Str2PChar(name));
+ScriptGetString:= lua_tostring(luaState, -1);
+lua_pop(luaState, 1);
+end;
+
+procedure ScriptOnGameInit;
+begin
+		// push game variables so they may be modified by the script
+		ScriptSetInteger('GameFlags', GameFlags);
+		ScriptSetString('Seed', cSeed);
+		ScriptSetInteger('TurnTime', cHedgehogTurnTime);
+		ScriptSetInteger('CaseFreq', cCaseFactor);
+		ScriptSetInteger('LandAdds', cLandAdditions);
+		ScriptSetInteger('Delay', cInactDelay);
+		ScriptSetString('Map', '');
+		ScriptSetString('Theme', '');
+
+		ScriptCall('onGameInit');
+		
+		// pop game variables
+		ParseCommand('seed ' + ScriptGetString('Seed'), true);
+		ParseCommand('$gmflags ' + ScriptGetString('GameFlags'), true);
+		ParseCommand('$turntime ' + ScriptGetString('TurnTime'), true);
+		ParseCommand('$casefreq ' + ScriptGetString('CaseFreq'), true);
+		ParseCommand('$landadds ' + ScriptGetString('LandAdds'), true);
+		ParseCommand('$delay ' + ScriptGetString('Delay'), true);
+		if ScriptGetString('Map') <> '' then
+			ParseCommand('map ' + ScriptGetString('Map'), true);
+		if ScriptGetString('Theme') <> '' then
+			ParseCommand('theme ' + ScriptGetString('Theme'), true);	
+
+	ScriptPrepareAmmoStore;
+	ScriptCall('onAmmoStoreInit');
+	ScriptApplyAmmoStore;
+end;
+
+procedure ScriptLoad(name : string);
+var ret : LongInt;
+begin
+	ret:= luaL_loadfile(luaState, Str2PChar(name));
+	if ret <> 0 then
+		AddFileLog('LUA: Failed to load ' + name + '(error ' + IntToStr(ret) + ')')
+	else
+		begin
+		AddFileLog('LUA: ' + name + ' loaded');
+		// call the script file
+		lua_pcall(luaState, 0, 0, 0);	
+		end
+end;
+
+procedure ScriptCall(fname : string);
+begin
+	lua_getglobal(luaState, Str2PChar(fname));
+	if lua_pcall(luaState, 0, 0, 0) <> 0 then
+		begin
+		AddFileLog('LUA: Error while calling ' + fname + ': ' + lua_tostring(luaState, -1));
+		lua_pop(luaState, 1)
+		end;
+end;
+
+function ScriptCall(fname : string; par1: LongInt) : LongInt;
+begin
+ScriptCall:= ScriptCall(fname, par1, 0, 0, 0)
+end;
+
+function ScriptCall(fname : string; par1, par2: LongInt) : LongInt;
+begin
+ScriptCall:= ScriptCall(fname, par1, par2, 0, 0)
+end;
+
+function ScriptCall(fname : string; par1, par2, par3: LongInt) : LongInt;
+begin
+ScriptCall:= ScriptCall(fname, par1, par2, par3, 0)
+end;
+
+function ScriptCall(fname : string; par1, par2, par3, par4 : LongInt) : LongInt;
+begin
+	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
+		AddFileLog('LUA: 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;
+end;
+
+procedure ScriptPrepareAmmoStore;
+var i: ShortInt;
+begin
+ScriptAmmoStore:= '';
+for i:=1 to ord(High(TAmmoType)) do
+	ScriptAmmoStore:= ScriptAmmoStore + '00';
+end;
+
+procedure ScriptSetAmmo(ammo : TAmmoType; count, propability: Byte);
+begin
+if (ord(ammo) < 1) or (count > 9) or (count < 0) or (propability < 0) or (propability > 8) then
+	exit;
+ScriptAmmoStore[ord(ammo)]:= inttostr(count)[1];
+ScriptAmmoStore[ord(ammo) + ord(high(TAmmoType))]:= inttostr(propability)[1];
+end;
+
+procedure ScriptApplyAmmoStore;
+begin
+	AddAmmoStore(ScriptAmmoStore);
+end;
+
+// small helper functions making registering enums a lot easier
+function str(const en : TGearType) : string; overload;
+begin
+str:= GetEnumName(TypeInfo(TGearType), ord(en))
+end;
+
+function str(const en : TSound) : string; overload;
+begin
+str:= GetEnumName(TypeInfo(TSound), ord(en))
+end;
+
+function str(const en : TAmmoType) : string; overload;
+begin
+str:= GetEnumName(TypeInfo(TAmmoType), ord(en))
+end;
+///////////////////
+
+procedure init_uScript;
+var at : TGearType;
+	am : TAmmoType;
+	st : TSound;
+begin
+// initialize lua
+luaState:= lua_open;
+
+// open internal libraries
+luaopen_base(luaState);
+luaopen_string(luaState);
+luaopen_math(luaState);
+
+// import some variables
+ScriptSetInteger('LAND_WIDTH', LAND_WIDTH);
+ScriptSetInteger('LAND_HEIGHT', LAND_HEIGHT);
+
+// import game flags
+ScriptSetInteger('gfForts',gfForts);
+ScriptSetInteger('gfMultiWeapon',gfMultiWeapon);
+ScriptSetInteger('gfSolidLand',gfSolidLand);
+ScriptSetInteger('gfBorder',gfBorder);
+ScriptSetInteger('gfDivideTeams',gfDivideTeams);
+ScriptSetInteger('gfLowGravity',gfLowGravity);
+ScriptSetInteger('gfLaserSight',gfLaserSight);
+ScriptSetInteger('gfInvulnerable',gfInvulnerable);
+ScriptSetInteger('gfMines',gfMines);
+ScriptSetInteger('gfVampiric',gfVampiric);
+ScriptSetInteger('gfKarma',gfKarma);
+ScriptSetInteger('gfArtillery',gfArtillery);
+ScriptSetInteger('gfOneClanMode',gfOneClanMode);
+ScriptSetInteger('gfRandomOrder',gfRandomOrder);
+ScriptSetInteger('gfKing',gfKing);
+
+// register gear types
+for at:= Low(TGearType) to High(TGearType) do
+	ScriptSetInteger(str(at), ord(at));
+
+// register sounds
+for st:= Low(TSound) to High(TSound) do
+	ScriptSetInteger(str(st), ord(st));
+
+// register ammo types
+for am:= Low(TAmmoType) to High(TAmmoType) do
+	ScriptSetInteger(str(am), ord(am));
+	
+// register functions
+lua_register(luaState, 'AddGear', @lc_addgear);
+lua_register(luaState, 'WriteLnToConsole', @lc_writelntoconsole);
+lua_register(luaState, 'GetGearType', @lc_getgeartype);
+lua_register(luaState, 'EndGame', @lc_endgame);
+lua_register(luaState, 'FindPlace', @lc_findplace);
+lua_register(luaState, 'SetGearPosition', @lc_setgearposition);
+lua_register(luaState, 'GetGearPosition', @lc_getgearposition);
+lua_register(luaState, 'ParseCommand', @lc_parsecommand);
+lua_register(luaState, 'ShowMission', @lc_showmission);
+lua_register(luaState, 'HideMission', @lc_hidemission);
+lua_register(luaState, 'SetAmmo', @lc_setammo);
+lua_register(luaState, 'PlaySound', @lc_playsound);
+lua_register(luaState, 'AddTeam', @lc_addteam);
+lua_register(luaState, 'AddHog', @lc_addhog);
+
+ScriptClearStack; // just to be sure stack is empty
+end;
+
+procedure free_uScript;
+begin
+lua_close(luaState);
+end;
+
+end.
--- a/hedgewars/uStore.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/uStore.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -39,6 +39,7 @@
     squaresize : LongInt;
     numsquares : LongInt;
     ProgrTex: PTexture;
+	MissionIcons: PSDL_Surface;
 
 procedure init_uStore;
 procedure free_uStore;
@@ -73,6 +74,7 @@
 function  LoadImage(const filename: string; imageFlags: LongInt): PSDL_Surface;
 procedure SetupOpenGL;
 procedure SetScale(f: GLfloat);
+function RenderHelpWindow(caption, subcaption, description, extra: shortstring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture;
 procedure RenderWeaponTooltip(atype: TAmmoType);
 procedure ShowWeaponTooltip(x, y: LongInt);
 procedure FreeWeaponTooltip;
@@ -253,6 +255,7 @@
 						end
 					end;
 		end;
+		MissionIcons:= LoadImage(Pathz[ptGraphics] + '/missions', ifCritical);
 	end;
 
 	procedure MakeCrossHairs;
@@ -819,6 +822,7 @@
     FreeTexture(SpritesData[ii].Texture);
     if SpritesData[ii].Surface <> nil then SDL_FreeSurface(SpritesData[ii].Surface)
     end;
+SDL_FreeSurface(MissionIcons);
 
 FreeTexture(HHTexture)
 end;
--- a/hedgewars/uWorld.pas	Tue Feb 09 21:51:52 2010 +0000
+++ b/hedgewars/uWorld.pas	Wed Feb 10 00:55:40 2010 +0000
@@ -42,6 +42,8 @@
 procedure InitWorld;
 procedure DrawWorld(Lag: LongInt);
 procedure AddCaption(s: string; Color: Longword; Group: TCapGroup);
+procedure ShowMission(caption, subcaption, text: string; icon, time : LongInt);
+procedure HideMission;
 
 implementation
 uses	uStore, uMisc, uTeams, uIO, uConsole, uKeys, uLocale, uSound, uAmmos, uVisualGears, uChat, uLandTexture, uLand,
@@ -66,11 +68,15 @@
     SoundTimerTicks: Longword;
     prevPoint: TPoint;
 	amSel: TAmmoType = amNothing;
+	missionTex: PTexture;
+	missionTimer: LongInt;
 
 procedure InitWorld;
 var i, t: LongInt;
     cp: PClan;
 begin
+missionTimer:= 0;
+
 if (GameFlags and gfRandomOrder) <> 0 then  // shuffle them up a bit
    begin
    for i:= 0 to ClansCount * 4 do
@@ -610,6 +616,14 @@
 if fastUntilLag then DrawCentered(0, (cScreenHeight shr 1), SyncTexture);
 if isPaused then DrawCentered(0, (cScreenHeight shr 1), PauseTexture);
 
+if missionTimer <> 0 then
+	begin
+	if missionTimer > 0 then dec(missionTimer, Lag);
+	if missionTimer < 0 then missionTimer:= 0; // avoid subtracting below 0
+	if missionTex <> nil then
+		DrawCentered(0, (cScreenHeight shr 1) + 100, missionTex);
+	end;
+
 // fps
 {$IFDEF IPHONEOS}
 offset:= 40;
@@ -778,6 +792,35 @@
 if WorldDx > 1024 then WorldDx:= 1024;
 end;
 
+procedure ShowMission(caption, subcaption, text: string; icon, time : LongInt);
+var r: TSDL_Rect;
+begin
+r.w:= 32;
+r.h:= 32;
+
+if time = 0 then time:= 5000;
+missionTimer:= time;
+if missionTex <> nil then FreeTexture(missionTex);
+
+if icon > -1 then
+	begin
+	r.x:= 0;
+	r.y:= icon * 32;
+	missionTex:= RenderHelpWindow(caption, subcaption, text, '', 0, MissionIcons, @r)
+	end
+else
+	begin
+	r.x:= ((-icon - 1) shr 5) * 32;
+	r.y:= ((-icon - 1) mod 32) * 32;
+	missionTex:= RenderHelpWindow(caption, subcaption, text, '', 0, SpritesData[sprAMAmmos].Surface, @r)
+	end;
+end;
+
+procedure HideMission;
+begin
+missionTimer:= 0
+end;
+
 procedure init_uWorld;
 begin
 	fpsTexture:= nil;
@@ -795,13 +838,14 @@
 	SoundTimerTicks:= 0;
 	prevPoint.X:= 0;
 	prevPoint.Y:= 0;
+	missionTimer:= 0;
 	
 	FillChar(Captions, sizeof(Captions), 0)
 end;
 
 procedure free_uWorld;
 begin
-
+if missionTex <> nil then FreeTexture(missionTex);
 end;
 
 end.
--- a/share/hedgewars/Data/CMakeLists.txt	Tue Feb 09 21:51:52 2010 +0000
+++ b/share/hedgewars/Data/CMakeLists.txt	Wed Feb 10 00:55:40 2010 +0000
@@ -1,3 +1,3 @@
-foreach(dir "Fonts" "Forts" "Graphics" "Locale" "Maps" "Music" "Sounds" "Themes" "Trainings" "Names")
+foreach(dir "Fonts" "Forts" "Graphics" "Locale" "Maps" "Music" "Sounds" "Themes" "Missions" "Names")
   add_subdirectory(${dir})
 endforeach(dir)
Binary file share/hedgewars/Data/Graphics/missions.png has changed
--- a/share/hedgewars/Data/Locale/de.txt	Tue Feb 09 21:51:52 2010 +0000
+++ b/share/hedgewars/Data/Locale/de.txt	Wed Feb 10 00:55:40 2010 +0000
@@ -1,4 +1,4 @@
-; German locale
+; German locale
 
 00:00=Granate
 00:01=Splittergranate
@@ -52,6 +52,10 @@
 01:07=%1 verbleibend
 01:08=Treibstoff
 01:09=Synchronisiere ...
+01:10=Benutzung beendet nicht die eigene Runde!
+01:11=Waffe oder Werkzeug noch nicht verfügbar!
+01:10=Benutzung beendet nicht die eigene Runde!
+01:11=Waffe oder Werkzeug noch nicht verfügbar!
 
 ; Event messages
 ; Hog (%1) died
@@ -153,4 +157,90 @@
 ; Hog (%1) shot an home run (using the bat and another hog)
 02:10=Home Run!
 02:10=Ein Vogel, ein Flugzeug, ...
-02:10=Der verleiht Flügel!
\ No newline at end of file
+02:10=Der verleiht Flügel!
+
+; Weapon Categories
+03:00=Zeitzünder-Granate
+03:01=Zeitzünder-Granate
+03:02=Ballistische Waffe
+03:03=Zielsuchende Waffe
+03:04=Gewehr (mehrere Schüsse)
+03:05=Grabwerkzeug
+03:06=Aktion
+03:07=Fortbewegungsmittel
+03:08=Annäherungsbombe
+03:09=Pistole (mehrere Schüsse)
+03:10=BOOM!
+03:11=Bonk!
+03:12=Kampfkunst
+03:13=UNUSED
+03:14=Fortbewegungsmittel
+03:15=Luftschlag
+03:16=Luftschlag
+03:17=Grabwerkzeug
+03:18=Werkzeug
+03:19=Fortbewegungsmittel
+03:20=Aktion
+03:21=Ballistische Waffe
+03:22=Nenn' mich Indiana!
+03:23=Kampfkunst
+03:24=Der Kuchen ist keine Lüge!
+03:25=Verkleidung
+03:26=Saftige Granate
+03:27=Feurige Granate
+03:28=Ballistische Waffe
+03:29=Ballistische Waffe
+03:30=Luftschlag
+03:31=Ferngesteuerte Bombe
+03:32=Temporärer Effekt
+03:33=Temporärer Effekt
+03:34=Temporärer Effekt
+03:35=Temporärer Effekt
+03:36=Temporärer Effekt
+03:37=Temporärer Effekt
+03:38=Gewehr (ein Schuss)
+03:39=Fortbewegungsmittel
+03:40=Brandbombe
+
+; Weapon Descriptions (use | as line breaks)
+04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power
+04:01=Attack your enemies using a cluster bomb.|It will split into smaller bombs once its timer|reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power
+04:02=Attack your enemies using a ballistic projectile|that might be influenced by wind.|Attack: Hold to shoot with more power
+04:03=Launch a guided bomb that while home into|the selected target. Don't shoot with full power|to improve its precision.|Cursor: Pick target|Attack: Hold to shoot with more power
+04:04=Attack your enemy using a shotgun with two shots.|Thanks to its spread you don't need direct hits|to harm your opponents.|Attack: Shoot (multiple times)
+04:05=Move underground! Use the pickhammer to drill|a hole into the ground and reach other areas.|Attack: Start or stop digging
+04:06=Bored? No way to attack? Save your ammo?|No problem! Just skip your turn, coward!|Attack: Skip your turn without fighting
+04:07=Bridge huge distances using timed shots with the|rope. Use your momentum to slide into other hogs|or drop grenades and other weapons on them.|Attack: Shoot or release the rope|Long Jump: Drop grenades or similar weapons
+04:08=Keep your enemies away by dropping a mine in|narrow passages or right below their feet. Be|sure to retreat before you trigger it yourself!|Attack: Drop mine next to your feet
+04:09=Not sure about your aiming? Use the Desert|Eagle to attack using up to five shots.|Attack: Shoot (multiple times)
+04:10=Brute force is always an option. Drop this classic|explosive next to your enemies and retreat.|Attack: Drop dynamite next to your feet
+04:11=Get rid of enemy hogs by batting them over|the map borders or into water. Or how about|knocking some mines to your friends?|Attack: Bat everything in front of you
+04:12=Get close and personal to unleash the power of|this almost deadly martial arts technique.|Attack: Perform the Fire Punch
+04:13=UNUSED
+04:14=Fear of heights? Better grab a parachute.|It will unfold once|you fall too far and|save your hog from taking fall damage.|Attack: Unfold the parachute
+04:15=Call in an airplane to attack your enemies|using a bombing run.|Left/Right: Determine attack direction|Cursor: Select target region
+04:16=Call in an airplane to drop several mines|in the target area.|Left/Right: Determine attack direction|Cursor: Select target region
+04:17=Need shelter? Use the blow torch to dig|a tunnel into solid ground granting you|cover.|Attack: Start or stop digging
+04:18=Need additional protection or want to pass|unpassable ground? Place some girders as you|like.|Left/Right: Select girder to place|Cursor: Place girder in a valid position
+04:19=Used at the right moment teleportation can|be more powerful than almost all weapons as|it allows you to save hogs from dangerous|situations within seconds.|Cursor: Select target region
+04:20=Allows you to play the current turn with|a different hog.|Attack: Enable switching hogs
+04:21=Shoot a grenade-like projectile that will|release multiple bombs upon impact.|Attack: Shoot at full power
+04:22=Not just for Indiana Jones! The whip is an|useful weapon in many situations. Especially|when you'd like to shove someone off a cliff.|Attack: Strike everything in front of you
+04:23=If you have nothing to lose, this might be|quite handy. Sacrifice your hog by launching|it into a specific direction hurting everything|on his way and exploding at the end.|Attack: Launch the devastating and deadly attack
+04:24=Happy Birthday! Launch this cake, let it walk right|next to your enemies and let them have an explosive|party. The cake is able to pass almost all terrain|but he might detonate earlier this way.|Attack: Start the cake or let it stop and explode
+04:25=Use this disguise kit to get your enemies to jump|towards your hog (and into some gap or hole).|Attack: Use the kit and try to seduce another hog
+04:26=Throw this juicy water melon at your enemies. Once|the timer expires, it will split into several|explosive pieces.|Attack: Hold to shoot with more power
+04:27=Let hellfire rain onto your opponents by using|this fiendish explosive. Don't get too close to|the explosion as smaller fires might last longer.|Attack: Hold to shoot with more power
+04:28=Short time after launching this rocket, it will|start drilling through solid ground and explode|once its fuse is triggered or it resurfaces again.|Attack: Hold to shoot with more power
+04:29=This is nothing for small kids! The ball gun fires|tons of small colored balls filled with explosives.|Attack: Shoot at full power|Up/Down: Continue aiming
+04:30=Call in an airplane to launch a powerful napalm|strike. With proper aiming this attack can eradicate|huge parts of landscape including unlucky hogs|sitting there.|Left/Right: Determine attack direction|Cursor: Select target region
+04:31=The RC plane is the ideal weapon to collect crates or|attack far away hogs. Either steer it into enemies or|drop some bombs first.|Attack: Launch the plane or drop bombs|Long Jump: Let the valkyries ride into battle|Up/Down: Steer the plane
+04:32=Low gravity is more effective than any diet! Jump|higher and over greater distances or let your enemies|fly even further.|Attack: Activate
+04:33=Sometimes you just need that little extra boost to|deal some more damage.|Attack: Activate
+04:34=Can't touch me!|Attack: Activate
+04:35=Sometimes time's running too fast. Grab some extra|seconds to finish your attack.|Attack: Activate
+04:36=Well, sometimes you're just too bad in aiming. Get|some assistance using modern day technology.|Attack: Activate
+04:37=Don't fear the daylight. It will just last one turn|but will enable you to absorb the damage you do to|other hogs.|Attack: Activate
+04:38=The sniper rifle can be the most devastating weapon|in your whole arsenal, however it's very ineffective|at close quarters. The damage dealt increases with|the distance to its target.|Attack: Shoot (once)
+04:39=Fly to other parts of the map using the flying|saucer. This hard to master utility is able to|bring you to almost any position on the battlefield.|Attack: Activate|Up/Left/Right: Apply force into one direction
+04:40=Set some ground on fire using this bottle filled|with (soon to be) burning liquid.|Attack: Hold to shoot with more power
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Bazooka Training.hwt	Wed Feb 10 00:55:40 2010 +0000
@@ -0,0 +1,141 @@
+-- Hedgewars Bazooka Training
+-- Scripting Example
+
+-- Lines such as this one are comments - they are ignored
+-- by the game, no matter what kind of text is in there.
+-- It's also possible to place a comment after some real
+-- instruction as you see below. In short, everything
+-- following "--" is ignored.
+
+---------------------------------------------------------------
+
+-- This variable will hold the number of destroyed targets.
+score = 0
+-- This variable represents the number of targets to destroy.
+score_goal = 5
+-- This variable controls how many milliseconds/ticks we'd
+-- like to wait before we end the round once all targets
+-- have been destroyed.
+end_timer = 5000 -- 5000 ms = 5 s
+
+-- This is a custom function to make it easier to
+-- spawn more targets with just one line of code
+-- You may define as many custom functions as you
+-- like.
+function spawnTarget()
+	-- add a new target gear
+	gear = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
+	
+	-- move it to a random position within 0 and
+	-- LAND_WIDTH - the width of the map
+	FindPlace(gear, true, 0, LAND_WIDTH)
+	
+	-- move the target to a higher vertical position
+	-- to ensure it's not somewhere down below
+	x, y = GetGearPosition(gear)
+	SetGearPosition(gear, x, 500)
+end
+
+-- This function is called before the game loads its
+-- resources.
+-- It's one of the predefined function names that will
+-- be called by the game. They give you entry points
+-- where you're able to call your own code using either
+-- provided instructions or custom functions.
+function onGameInit()
+	-- At first we have to overwrite/set some global variables
+	-- that define the map, the game has to load, as well as
+	-- other things such as the game rules to use, etc.
+	-- Things we don't modify here will use their default values.
+
+	-- The base number for the random number generator
+	Seed = 1337
+	-- Game settings and rules
+	GameFlags = gfMultiWeapon + gfOneClanMode + gfSolidLand
+	-- The time the player has to move each round (in ms)
+	TurnTime = 25000
+	-- The frequency of crate drops
+	CaseFreq = 0
+	-- The number of land objects being placed
+	LandAdds = 0
+	-- The delay between each round
+	Delay = 0
+	-- The map to be played
+	Map = "Bamboo"
+	-- The theme to be used
+	Theme = "Bamboo"
+
+	-- Create the player team
+	AddTeam("'Zooka Team", 14483456, "Simple", "Island", "Default")
+	-- And add a hog to it
+	hog = AddHog("Hunter", 0, 1, "NoHat")
+	SetGearPosition(hog, 1960, 1160);
+end
+
+-- This function is called when the round starts
+-- it spawns the first target that has to be destroyed.
+-- In addition it shows the scenario goal(s).
+function onGameStart()
+	-- Spawn the first target.
+	spawnTarget()
+	
+	-- Show some nice mission goals.
+	-- Parameters are: caption, sub caption, description,
+	-- extra text, icon and time to show.
+	-- A negative icon parameter (-n) represents the n-th weapon icon
+	-- A positive icon paramter (n) represents the (n+1)-th mission icon
+	-- A timeframe of 0 is replaced with the default time to show.
+	ShowMission("Bazooka Training", "Aiming Practice", "Eliminate all targets before your time runs out.|You have unlimited ammo for this mission.", -amBazooka, 0);
+end
+
+-- This function is called every game tick.
+-- Note that there are 1000 ticks within one second.
+-- You shouldn't try to calculate too complicated
+-- code here as this might slow down your game.
+function onGameTick()
+	-- If the goal is reached ...
+	if score == score_goal then
+		-- ... check to see if the time we'd like to
+		-- wait has passed and then ...
+		if end_timer == 0 then
+			-- ... end the game ...
+			EndGame()
+		else
+			-- ... or just lower the timer by 1.
+			end_timer = end_timer - 1
+		end
+	end
+end
+
+-- This function is called when the game is initialized
+-- to request the available ammo and probabilities
+function onAmmoStoreInit()
+	-- add an unlimited supply of bazooka ammo
+	SetAmmo(amBazooka, 9, 0)
+end
+
+-- This function is called when a new gear is added.
+-- We don't need it for this training, so we can
+-- keep it empty.
+function onGearAdd(gear)
+end
+
+-- This function is called before a gear is destroyed.
+-- We use it to count the number of targets destroyed.
+function onGearDelete(gear)
+	-- We're only interested in target gears.
+	if GetGearType(gear) == gtTarget then
+		-- Add one point to our score/counter
+		score = score + 1
+		-- If we haven't reached the goal ...
+		if score < score_goal then
+			-- ... spawn another target.
+			spawnTarget()
+		else
+			-- Otherwise show that the goal was accomplished
+			ShowMission("Bazooka Training", "Aiming Practice", "Congratulations! You've eliminated all targets|within the allowed time frame.", 0, 0);
+			-- Also let the hogs shout "victory!"
+			PlaySound(sndVictory)
+		end
+	end
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/CMakeLists.txt	Wed Feb 10 00:55:40 2010 +0000
@@ -0,0 +1,9 @@
+file(GLOB Trainings t*.txt t*.lua)
+file(GLOB Singleplayer s*.txt s*.lua)
+file(GLOB Cooperative c*.txt c*.lua)
+
+install(FILES
+	${Trainings}
+	${Singleplayer}
+	${Cooperative}
+	DESTINATION ${SHAREPATH}Data/Trainings)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Shotgun Training.hwt	Wed Feb 10 00:55:40 2010 +0000
@@ -0,0 +1,143 @@
+-- Hedgewars Shotgun Training
+-- Scripting Example
+
+-- Lines such as this one are comments - they are ignored
+-- by the game, no matter what kind of text is in there.
+-- It's also possible to place a comment after some real
+-- instruction as you see below. In short, everything
+-- following "--" is ignored.
+
+---------------------------------------------------------------
+
+-- This variable will hold the number of destroyed targets.
+score = 0
+-- This variable represents the number of targets to destroy.
+score_goal = 5
+-- This variable controls how many milliseconds/ticks we'd
+-- like to wait before we end the round once all targets
+-- have been destroyed.
+end_timer = 5000 -- 5000 ms = 5 s
+
+-- This is a custom function to make it easier to
+-- spawn more targets with just one line of code
+-- You may define as many custom functions as you
+-- like.
+function spawnTarget()
+	-- add a new target gear
+	gear = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
+	
+	-- move it to a random position within 0 and
+	-- LAND_WIDTH - the width of the map
+	FindPlace(gear, true, 0, LAND_WIDTH)
+	
+	-- move the target to a higher vertical position
+	-- to ensure it's not somewhere down below
+	x, y = GetGearPosition(gear)
+	SetGearPosition(gear, x, 500)
+end
+
+-- This function is called before the game loads its
+-- resources.
+-- It's one of the predefined function names that will
+-- be called by the game. They give you entry points
+-- where you're able to call your own code using either
+-- provided instructions or custom functions.
+function onGameInit()
+	-- At first we have to overwrite/set some global variables
+	-- that define the map, the game has to load, as well as
+	-- other things such as the game rules to use, etc.
+	-- Things we don't modify here will use their default values.
+
+	-- The base number for the random number generator
+	Seed = 0
+	-- Game settings and rules
+	GameFlags = gfMultiWeapon + gfOneClanMode
+	-- The time the player has to move each round (in ms)
+	TurnTime = 90000
+	-- The frequency of crate drops
+	CaseFreq = 0
+	-- The number of land objects being placed
+	LandAdds = 0
+	-- The delay between each round
+	Delay = 0
+	-- The map to be played
+	Map = "Bamboo"
+	-- The theme to be used
+	Theme = "Bamboo"
+
+	-- Create the player team
+	AddTeam("Shotgun Team", 14483456, "Simple", "Island", "Default")
+	-- And add a hog to it
+	hog = AddHog("Hunter", 0, 1, "NoHat")
+	SetGearPosition(hog, 1960, 1160);
+end
+
+-- This function is called when the round starts
+-- it spawns the first target that has to be destroyed.
+-- In addition it shows the scenario goal(s).
+function onGameStart()
+	-- Spawn the first target.
+	spawnTarget()
+	
+	-- Show some nice mission goals.
+	-- Parameters are: caption, sub caption, description,
+	-- extra text, icon and time to show.
+	-- A negative icon parameter (-n) represents the n-th weapon icon
+	-- A positive icon paramter (n) represents the (n+1)-th mission icon
+	-- A timeframe of 0 is replaced with the default time to show.
+	ShowMission("Shotgun Training", "Aiming Practice", "Eliminate all targets before your time runs out.|You have unlimited ammo for this mission.", -5, 0);
+end
+
+-- This function is called every game tick.
+-- Note that there are 1000 ticks within one second.
+-- You shouldn't try to calculate too complicated
+-- code here as this might slow down your game.
+function onGameTick()
+	-- If the goal is reached ...
+	if score == score_goal then
+		-- ... check to see if the time we'd like to
+		-- wait has passed and then ...
+		if end_timer == 0 then
+			-- ... end the game ...
+			EndGame()
+		else
+			-- ... or just lower the timer by 1.
+			end_timer = end_timer - 1
+		end
+	end
+end
+
+-- This function is called when the game is initialized
+-- to request the available ammo and probabilities
+function onAmmoStoreInit()
+	-- add an unlimited supply of shotgun ammo
+	SetAmmo(amShotgun, 9, 0)
+	-- add one optional laser sight
+	SetAmmo(amLaserSight, 1, 0)
+end
+
+-- This function is called when a new gear is added.
+-- We don't need it for this training, so we can
+-- keep it empty.
+function onGearAdd(gear)
+end
+
+-- This function is called before a gear is destroyed.
+-- We use it to count the number of targets destroyed.
+function onGearDelete(gear)
+	-- We're only interested in target gears.
+	if GetGearType(gear) == gtTarget then
+		-- Add one point to our score/counter
+		score = score + 1
+		-- If we haven't reached the goal ...
+		if score < score_goal then
+			-- ... spawn another target.
+			spawnTarget()
+		else
+			-- Otherwise show that the goal was accomplished
+			ShowMission("Shotgun Training", "Aiming Practice", "Congratulations! You've eliminated all targets|within the allowed time frame.", 0, 0);
+			-- Also let the hogs shout "victory!"
+			PlaySound(sndVictory)
+		end
+	end
+end
\ No newline at end of file
--- a/share/hedgewars/Data/Trainings/001_Shotgun.txt	Tue Feb 09 21:51:52 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-seed 0
-$gmflags 4098
-$turntime 90000
-$casefreq 0
-$landadds 0
-$delay 0
-map mushrooms
-theme nature
-ammstore 00009000000000000000000000000000000000000000000000000000000000000000000000000000
-
-addteam 14483456 Shotgun Team
-<binds>
-grave Simple
-fort Island
-voicepack Default
-addhh 0 1 Hunter
-hat NoHat
-hhcoords 2334 1254
-
-addtrig s2147483649 1 1 30 2154 1274 1
-addtrig s1 1 1 30 2334 1914 2
-addtrig s2 1 1 30 2774 1484 3
-addtrig s3 1 1 30 1659 1024 4
-addtrig s4 1 1 30 2474 1269 5
-addtrig s5 1 1 30 1244 1259 6
-addtrig s6 1 1 30 2534 1629 7
-addtrig C7 1 1
-addtrig F2147483649 2 1
--- a/share/hedgewars/Data/Trainings/002_Bazooka.txt	Tue Feb 09 21:51:52 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-seed 0
-$gmflags 268435462
-$turntime 25000
-$casefreq 0
-$landadds 0
-$delay 0
-map Bamboo
-theme Bamboo
-ammstore 00900000000000000000000000000000000000000000000000000000000000000000000000000000
-hhcoords 1960 1190
-addtrig s2147483649 1 1 30 1150 1500 1
-addtrig s1 1 1 30 2735 1000 3
-addtrig s1 1 1 30 1770 1500 3
-addtrig s1 1 1 30 2350 1500 3
-addtrig s3 3 1 30 2870 1500 7
-addtrig C7 1 1
-addtrig F2147483649 2 1
--- a/share/hedgewars/Data/Trainings/003_RCPlane.txt	Tue Feb 09 21:51:52 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-seed 1
-$gmflags 268435458
-$trflags 31
-$turntime 30000
-$casefreq 0
-$landadds 0
-$delay 0
-map EarthRise
-theme nature
-ammstore 00000000000000000000000000000010000000000000000000000000000000000000000000000000
-addtrig C7 1 1
-addtrig F2147483649 2 1
--- a/share/hedgewars/Data/Trainings/CMakeLists.txt	Tue Feb 09 21:51:52 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-file(GLOB Trainings 0*.txt)
-
-install(FILES
-	${Trainings}
-	DESTINATION ${SHAREPATH}Data/Trainings)