stratagus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Stratagus-CVS] stratagus/src/unit ccl_unit.c


From: Jimmy Salmon
Subject: [Stratagus-CVS] stratagus/src/unit ccl_unit.c
Date: Tue, 02 Dec 2003 19:27:23 -0500

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Jimmy Salmon <address@hidden>   03/12/02 19:27:23

Modified files:
        src/unit       : ccl_unit.c 

Log message:
        Added lua functions

Patches:
Index: stratagus/src/unit/ccl_unit.c
diff -u stratagus/src/unit/ccl_unit.c:1.82 stratagus/src/unit/ccl_unit.c:1.83
--- stratagus/src/unit/ccl_unit.c:1.82  Sun Nov 30 15:03:34 2003
+++ stratagus/src/unit/ccl_unit.c       Tue Dec  2 19:27:23 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_unit.c,v 1.82 2003/11/30 20:03:34 jsalmon3 Exp $
+//     $Id: ccl_unit.c,v 1.83 2003/12/03 00:27:23 jsalmon3 Exp $
 
 //@{
 
@@ -62,6 +62,7 @@
     /// Get resource by name
 extern unsigned CclGetResourceByName(SCM ptr);
 #elif defined(USE_LUA)
+extern UnitType* CclGetUnitType(lua_State* l);
     /// Get resource by name
 extern unsigned CclGetResourceByName(lua_State* l);
 #endif
@@ -214,6 +215,12 @@
 {
     return UnitSlots[gh_scm2int(value)];
 }
+#elif defined(USE_LUA)
+local Unit* CclGetUnit(lua_State* l)
+{
+    return UnitSlots[(int)LuaToNumber(l, -1)];
+}
+#endif
 
 /**
 **     Parse order
@@ -221,7 +228,8 @@
 **     @param list     All options of the order.
 **     @param order    OUT: resulting order.
 */
-local void CclParseOrder(SCM list,Order* order)
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local void CclParseOrder(SCM list, Order* order)
 {
     SCM value;
     SCM sublist;
@@ -296,7 +304,7 @@
 
            value = gh_car(list);
            list = gh_cdr(list);
-           str = gh_scm2newstr(value,NULL);
+           str = gh_scm2newstr(value, NULL);
 
            slot = strtol(str + 1, NULL, 16);
            order->Goal = UnitSlots[slot];
@@ -317,7 +325,7 @@
 
            value = gh_car(list);
            list = gh_cdr(list);
-           str = gh_scm2newstr(value,NULL);
+           str = gh_scm2newstr(value, NULL);
            order->Type = UnitTypeByIdent(str);
            free(str);
 
@@ -362,6 +370,187 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseOrder(lua_State* l, Order* order)
+{
+    const char* value;
+    int args;
+    int j;
+
+    //
+    // Parse the list: (still everything could be changed!)
+    //
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       if (!strcmp(value, "action-none")) {
+           order->Action = UnitActionNone;
+       } else if (!strcmp(value, "action-still")) {
+           order->Action = UnitActionStill;
+       } else if (!strcmp(value, "action-stand-ground")) {
+           order->Action = UnitActionStandGround;
+       } else if (!strcmp(value, "action-follow")) {
+           order->Action = UnitActionFollow;
+       } else if (!strcmp(value, "action-move")) {
+           order->Action = UnitActionMove;
+       } else if (!strcmp(value, "action-attack")) {
+           order->Action = UnitActionAttack;
+       } else if (!strcmp(value, "action-attack-ground")) {
+           order->Action = UnitActionAttackGround;
+       } else if (!strcmp(value, "action-die")) {
+           order->Action = UnitActionDie;
+       } else if (!strcmp(value, "action-spell-cast")) {
+           order->Action = UnitActionSpellCast;
+       } else if (!strcmp(value, "action-train")) {
+           order->Action = UnitActionTrain;
+       } else if (!strcmp(value, "action-upgrade-to")) {
+           order->Action = UnitActionUpgradeTo;
+       } else if (!strcmp(value, "action-research")) {
+           order->Action = UnitActionResearch;
+       } else if (!strcmp(value, "action-builded")) {
+           order->Action = UnitActionBuilded;
+       } else if (!strcmp(value, "action-board")) {
+           order->Action = UnitActionBoard;
+       } else if (!strcmp(value, "action-unload")) {
+           order->Action = UnitActionUnload;
+       } else if (!strcmp(value, "action-patrol")) {
+           order->Action = UnitActionPatrol;
+       } else if (!strcmp(value, "action-build")) {
+           order->Action = UnitActionBuild;
+       } else if (!strcmp(value, "action-repair")) {
+           order->Action = UnitActionRepair;
+       } else if (!strcmp(value, "action-resource")) {
+           order->Action = UnitActionResource;
+       } else if (!strcmp(value, "action-return-goods")) {
+           order->Action = UnitActionReturnGoods;
+
+       } else if (!strcmp(value, "flags")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Flags = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+
+       } else if (!strcmp(value, "range")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Range = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "min-range")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->MinRange = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "width")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Width = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "height")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Height = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "goal")) {
+           int slot;
+
+           ++j;
+           lua_rawgeti(l, -1, 1);
+           value = LuaToString(l, -1);
+           lua_pop(l, 1);
+
+           slot = strtol(value + 1, NULL, 16);
+           order->Goal = UnitSlots[slot];
+           if (!UnitSlots[slot]) {
+               DebugLevel0Fn("FIXME: Forward reference not supported\n");
+           }
+           ++UnitSlots[slot]->Refs;
+
+       } else if (!strcmp(value, "tile")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, -1, 1);
+           order->X = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, -1, 2);
+           order->Y = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_pop(l, 1);
+
+       } else if (!strcmp(value, "type")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Type = UnitTypeByIdent(LuaToString(l, -1));
+
+       } else if (!strcmp(value, "patrol")) {
+           int x1;
+           int x2;
+
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, -1, 1);
+           x1 = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, -1, 2);
+           x2 = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           order->Arg1 = (void*)((x1 << 16) | x2);
+           lua_pop(l, 1);
+
+       } else if (!strcmp(value, "spell")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Arg1 = SpellTypeByIdent(LuaToString(l, -1));
+           lua_pop(l, 1);
+
+       } else if (!strcmp(value, "upgrade")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Arg1 = UpgradeByIdent(LuaToString(l, -1));
+           lua_pop(l, 1);
+
+       } else if (!strcmp(value, "mine")) {
+           int x1;
+           int x2;
+
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, -1, 1);
+           x1 = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, -1, 2);
+           x2 = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           order->Arg1 = (void*)((x1 << 16) | x2);
+           lua_pop(l, 1);
+
+       } else if (!strcmp(value, "arg1")) {
+           ++j;
+           lua_rawgeti(l, -1, j + 1);
+           order->Arg1 = (void*)(int)LuaToNumber(l, -1);
+           lua_pop(l, 1);
+
+       } else {
+          // FIXME: this leaves a half initialized unit
+          lua_pushfstring(l, "Unsupported tag: %s", value);
+          lua_error(l);
+       }
+    }
+}
+#endif
 
 /**
 **     Parse orders.
@@ -369,17 +558,33 @@
 **     @param unit     Unit pointer which should get the orders.
 **     @param vector   All options of the order.
 */
-local void CclParseOrders(Unit* unit, SCM vector)
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local void CclParseOrders(SCM vector, Unit* unit)
 {
     int i;
     int n;
 
-    n=gh_vector_length(vector);
+    n = gh_vector_length(vector);
     DebugCheck(n != MAX_ORDERS);
     for (i = 0; i < n; ++i) {
        CclParseOrder(gh_vector_ref(vector, gh_int2scm(i)), &unit->Orders[i]);
     }
 }
+#elif defined(USE_LUA)
+local void CclParseOrders(lua_State* l, Unit* unit)
+{
+    int args;
+    int j;
+
+    args = luaL_getn(l, -1);
+    DebugCheck(args != MAX_ORDERS);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       CclParseOrder(l, &unit->Orders[j]);
+       lua_pop(l, 1);
+    }
+}
+#endif
 
 /**
 **     Parse builded
@@ -387,6 +592,7 @@
 **     @param unit     Unit pointer which should be filled with the data.
 **     @param list     All options of the builded data.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local void CclParseBuilded(Unit* unit, SCM list)
 {
     SCM value;
@@ -426,6 +632,56 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseBuilded(lua_State* l, Unit* unit)
+{
+    const char* value;
+    int args;
+    int j;
+
+    if (!lua_istable(l, -1)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       ++j;
+       if (!strcmp(value, "worker")) {
+           int slot;
+
+           lua_rawgeti(l, -1, j + 1);
+           value = LuaToString(l, -1);
+           lua_pop(l, 1);
+           slot = strtol(value + 1, NULL, 16);
+           DebugCheck(!UnitSlots[slot]);
+           unit->Data.Builded.Worker = UnitSlots[slot];
+           ++UnitSlots[slot]->Refs;
+       } else if (!strcmp(value, "progress")) {
+           lua_rawgeti(l, -1, j + 1);
+           unit->Data.Builded.Progress = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "cancel")) {
+           unit->Data.Builded.Cancel = 1;
+           --j;
+       } else if (!strcmp(value, "frame")) {
+           int frame;
+           ConstructionFrame* cframe;
+
+           lua_rawgeti(l, -1, j + 1);
+           frame = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           cframe = unit->Type->Construction->Frames;
+           while (frame--) {
+               cframe = cframe->Next;
+           }
+           unit->Data.Builded.Frame = cframe;
+       }
+    }
+}
+#endif
 
 /**
 **     Parse res worker data
@@ -433,6 +689,7 @@
 **     @param unit     Unit pointer which should be filled with the data.
 **     @param list     All options of the resource worker data.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local void CclParseResWorker(Unit* unit, SCM list)
 {
     SCM value;
@@ -449,6 +706,34 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseResWorker(lua_State* l, Unit* unit)
+{
+    const char* value;
+    int args;
+    int j;
+
+    if (!lua_istable(l, -1)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       ++j;
+       if (!strcmp(value, "time-to-harvest")) {
+           lua_rawgeti(l, -1, j + 1);
+           unit->Data.ResWorker.TimeToHarvest = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "done-harvesting")) {
+           unit->Data.ResWorker.DoneHarvesting = 1;
+           --j;
+       }
+    }
+}
+#endif
 
 /**
 **     Parse research
@@ -456,6 +741,7 @@
 **     @param unit     Unit pointer which should be filled with the data.
 **     @param list     All options of the research data.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local void CclParseResearch(Unit* unit, SCM list)
 {
     SCM value;
@@ -473,6 +759,32 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseResearch(lua_State* l, Unit* unit)
+{
+    const char* value;
+    int args;
+    int j;
+
+    if (!lua_istable(l, -1)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       ++j;
+       if (!strcmp(value, "ident")) {
+           lua_rawgeti(l, -1, j + 1);
+           value = LuaToString(l, -1);
+           lua_pop(l, 1);
+           unit->Data.Research.Upgrade = UpgradeByIdent(value);
+       }
+    }
+}
+#endif
 
 /**
 **     Parse upgrade to
@@ -480,6 +792,7 @@
 **     @param unit     Unit pointer which should be filled with the data.
 **     @param list     All options of the upgrade to data.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local void CclParseUpgradeTo(Unit* unit, SCM list)
 {
     SCM value;
@@ -493,6 +806,31 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseUpgradeTo(lua_State* l, Unit* unit)
+{
+    const char* value;
+    int args;
+    int j;
+
+    if (!lua_istable(l, -1)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       ++j;
+       if (!strcmp(value, "ticks")) {
+           lua_rawgeti(l, -1, j + 1);
+           unit->Data.UpgradeTo.Ticks = LuaToNumber(l, 1);
+           lua_pop(l, 1);
+       }
+    }
+}
+#endif
 
 /**
 **     Parse stored data for train order
@@ -500,7 +838,8 @@
 **     @param unit     Unit pointer which should be filled with the data.
 **     @param list     All options of the trained order
 */
-local void CclParseTrain(Unit *unit, SCM list)
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local void CclParseTrain(Unit* unit, SCM list)
 {
     SCM value;
     SCM sublist;
@@ -534,6 +873,56 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseTrain(lua_State* l, Unit* unit)
+{
+    const char* value;
+    int i;
+    int args;
+    int j;
+
+    if (!lua_istable(l, -1)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       ++j;
+       if (!strcmp(value, "ticks")) {
+           lua_rawgeti(l, -1, j + 1);
+           unit->Data.Train.Ticks = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "count")) {
+           lua_rawgeti(l, -1, j + 1);
+           unit->Data.Train.Count = LuaToNumber(l, 1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "queue")) {
+           int subargs;
+           int k;
+
+           lua_rawgeti(l, -1, j + 1);
+           if (!lua_istable(l, -1)) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           subargs = luaL_getn(l, -1);
+           for (i = 0, k = 0; i < MAX_UNIT_TRAIN && k < subargs; ++i, ++k) {
+               lua_rawgeti(l, -1, k + 1);
+               value = LuaToString(l, -1);
+               if (!strcmp(value, "unit-none")) {
+                   unit->Data.Train.What[i] = NULL;
+               } else {
+                   unit->Data.Train.What[i] = UnitTypeByIdent(value);
+               }
+           }
+           lua_pop(l, 1);
+       }
+    }
+}
+#endif
 
 /**
 **     Parse stored data for move order
@@ -541,7 +930,8 @@
 **     @param unit     Unit pointer which should be filled with the data.
 **     @param list     All options of the move order
 */
-local void CclParseMove(Unit *unit, SCM list)
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local void CclParseMove(Unit* unit, SCM list)
 {
     SCM value;
     SCM sublist;
@@ -565,12 +955,54 @@
        }
     }
 }
+#elif defined(USE_LUA)
+local void CclParseMove(lua_State* l, Unit* unit)
+{
+    const char* value;
+    int args;
+    int j;
+
+    if (!lua_istable(l, -1)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    args = luaL_getn(l, -1);
+    for (j = 0; j < args; ++j) {
+       lua_rawgeti(l, -1, j + 1);
+       value = LuaToString(l, -1);
+       lua_pop(l, 1);
+       ++j;
+       if (!strcmp(value, "fast")) {
+           unit->Data.Move.Fast = 1;
+           --j;
+       } else if (!strcmp(value, "path")) {
+           int subargs;
+           int k;
+
+           lua_rawgeti(l, -1, j + 1);
+           if (!lua_istable(l, -1)) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           subargs = luaL_getn(l, -1);
+           for (k = 0; k < subargs; ++k) {
+               lua_rawgeti(l, -1, k + 1);
+               unit->Data.Move.Path[k] = LuaToNumber(l, -1);
+               lua_pop(l, 1);
+           }
+           unit->Data.Move.Length = subargs;
+           lua_pop(l, 1);
+       }
+    }
+}
+#endif
 
 /**
 **     Parse unit
 **
 **     @param list     List describing unit
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclUnit(SCM list)
 {
     SCM value;
@@ -605,7 +1037,7 @@
        list = gh_cdr(list);
 
        if (gh_eq_p(value, gh_symbol2scm("type"))) {
-           type=UnitTypeByIdent(str = gh_scm2newstr(gh_car(list),NULL));
+           type = UnitTypeByIdent(str = gh_scm2newstr(gh_car(list), NULL));
            free(str);
            list = gh_cdr(list);
        } else if (gh_eq_p(value, gh_symbol2scm("seen-type"))) {
@@ -815,9 +1247,10 @@
            list = gh_cdr(list);
        } else if (gh_eq_p(value, gh_symbol2scm("orders"))) {
            int hp;
+
            sublist = gh_car(list);
            list = gh_cdr(list);
-           CclParseOrders(unit,sublist);
+           CclParseOrders(sublist, unit);
            // now we know unit's action so we can assign it to a player
            hp = unit->HP;
            AssignUnitToPlayer (unit, player);
@@ -872,7 +1305,7 @@
            list = gh_cdr(list);
            CclParseMove(unit, sublist);
        } else if (gh_eq_p(value, gh_symbol2scm("goal"))) {
-           unit->Goal=UnitSlots[gh_scm2int(gh_car(list))];
+           unit->Goal = UnitSlots[gh_scm2int(gh_car(list))];
            list = gh_cdr(list);
        } else if (gh_eq_p(value, gh_symbol2scm("auto-cast"))) {
            str = gh_scm2newstr(gh_car(list),NULL);
@@ -914,91 +1347,533 @@
 
     return SCM_UNSPECIFIED;
 }
-
-/**
-**     Make a unit.
-**
-**     @param type     Unit-type of the unit,
-**     @param player   Owning player number of the unit.
-**
-**     @return         Returns the slot number of the made unit.
-*/
-local SCM CclMakeUnit(SCM type, SCM player)
+#elif defined(USE_LUA)
+local int CclUnit(lua_State* l)
 {
-    UnitType* unittype;
+    const char* value;
     Unit* unit;
+    UnitType* type;
+    UnitType* seentype;
+    Player* player;
+    int slot;
+    int i;
+    int insidecount;
+    const char* s;
+    int args;
+    int j;
 
-    unittype = CclGetUnitType(type);
-    unit = MakeUnit(unittype, &Players[gh_scm2int(player)]);
-
-    return gh_int2scm(unit->Slot);
-}
-
-/**
-**     Place a unit on map.
-**
-**     @param unit     Unit (slot number) to be placed.
-**     @param x        X map tile position.
-**     @param y        Y map tile position.
-**
-**     @return         Returns the slot number of the made placed.
-*/
-local SCM CclPlaceUnit(SCM unit, SCM x, SCM y)
-{
-    PlaceUnit(CclGetUnit(unit), gh_scm2int(x), gh_scm2int(y));
-    return unit;
-}
-
-/**
-**     Create a unit and place it on the map
-**
-**     @param type     Unit-type of the unit,
-**     @param player   Owning player number of the unit.
-**     @param x        X map tile position.
-**     @param y        Y map tile position.
-**
-**     @return         Returns the slot number of the made unit.
-*/
-local SCM CclCreateUnit(SCM type, SCM player, SCM x, SCM y)
-{
-    UnitType* unittype;
-    Unit* unit;
-    int heading;
-    int playerno;
-    int mask;
-    int ix;
-    int iy;
+    args = lua_gettop(l);
+    j = 0;
 
-    unittype = CclGetUnitType(type);
-    ix = gh_scm2int(x);
-    iy = gh_scm2int(y);
+    insidecount = -1;
+    slot = LuaToNumber(l, j + 1);
+    ++j;
+    DebugLevel3Fn("parsing unit #%d\n" _C_ slot);
 
-    heading = SyncRand() % 256;
-    playerno = TriggerGetPlayer(player);
-    if (playerno == -1) {
-       printf("CreateUnit: You cannot use 'any in create-unit, specify a 
player\n");
-       errl("bad player", player);
-       return SCM_UNSPECIFIED;
-    }
-    unit = MakeUnit(unittype, &Players[playerno]);
-    mask = UnitMovementMask(unit);
-    if (CheckedCanMoveToMask(ix, iy, mask)) {
-       unit->Wait = 1;
-       PlaceUnit(unit, ix, iy);
-    } else {
-       unit->X = ix;
-       unit->Y = iy;
-       DropOutOnSide(unit, heading, unittype->TileWidth, unittype->TileHeight);
-    }
+    unit = NULL;
+    type = NULL;
+    seentype = NULL;
+    player = NULL;
+    i = 0;
 
-    return gh_int2scm(unit->Slot);
-}
+    //
+    // Parse the list: (still everything could be changed!)
+    //
+    for (; j < args; ++j) {
+       value = LuaToString(l, j + 1);
+       ++j;
+
+       if (!strcmp(value, "type")) {
+           type = UnitTypeByIdent(LuaToString(l, j + 1));
+       } else if (!strcmp(value, "seen-type")) {
+           seentype = UnitTypeByIdent(LuaToString(l, j + 1));
+       } else if (!strcmp(value, "name")) {
+           unit->Name = strdup(LuaToString(l, j + 1));
+       } else if (!strcmp(value, "player")) {
+           player = &Players[(int)LuaToNumber(l, j + 1)];
 
-/**
-**     Order a unit
-**
-**     (order-unit player unit-type sloc dloc order)
-*/
+           // During a unit's death animation (when action is "die" but the
+           // unit still has its original type, i.e. it's still not a corpse)
+           // the unit is already removed from map and from player's
+           // unit list (=the unit went through LetUnitDie() which
+           // calls RemoveUnit() and UnitLost()).  Such a unit should not
+           // be put on player's unit list!  However, this state is not
+           // easily detected from this place.  It seems that it is
+           // characterized by unit->HP==0 and by
+           // unit->Orders[0].Action==UnitActionDie so we have to wait
+           // until we parsed at least Unit::Orders[].
+           DebugCheck(!type);
+           unit = UnitSlots[slot];
+           InitUnit(unit, type);
+           unit->SeenType = seentype;
+           unit->Active = 0;
+           unit->Removed = 0;
+           unit->Reset = 0;            // JOHNS ????
+           DebugCheck(unit->Slot != slot);
+       } else if (!strcmp(value, "next")) {
+           unit->Next = UnitSlots[(int)LuaToNumber(l, j + 1)];
+       } else if (!strcmp(value, "current-sight-range")) {
+           unit->CurrentSightRange = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "host-info")) {
+           int x;
+           int y;
+           int w;
+           int h;
+
+           if (!lua_istable(l, j + 1) || luaL_getn(l, j + 1) != 4) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, j + 1, 1);
+           x = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, j + 1, 2);
+           y = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, j + 1, 3);
+           w = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, j + 1, 4);
+           h = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           MapMarkSight(player, x, y, w, h, unit->CurrentSightRange);
+       } else if (!strcmp(value, "tile")) {
+           if (!lua_istable(l, j + 1) || luaL_getn(l, j + 1) != 2) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, j + 1, 1);
+           unit->X = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, j + 1, 2);
+           unit->Y = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "stats")) {
+           unit->Stats = &type->Stats[(int)LuaToNumber(l, j + 1)];
+       } else if (!strcmp(value, "pixel")) {
+           if (!lua_istable(l, j + 1) || luaL_getn(l, j + 1) != 2) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, j + 1, 1);
+           unit->IX = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, j + 1, 2);
+           unit->IY = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "seen-pixel")) {
+           if (!lua_istable(l, j + 1) || luaL_getn(l, j + 1) != 2) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           lua_rawgeti(l, j + 1, 1);
+           unit->SeenIX = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+           lua_rawgeti(l, j + 1, 2);
+           unit->SeenIY = LuaToNumber(l, -1);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "frame")) {
+           unit->Frame = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "flipped-frame")) {
+           unit->Frame = -LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "seen")) {
+           unit->SeenFrame = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "flipped-seen")) {
+           unit->SeenFrame = -LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "not-seen")) {
+           unit->SeenFrame = UnitNotSeen;
+       } else if (!strcmp(value, "direction")) {
+           unit->Direction = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "attacked")) {
+           // FIXME : unsigned long should be better handled
+           unit->Attacked = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "burning")) {
+           unit->Burning = 1;
+           --j;
+       } else if (!strcmp(value, "destroyed")) {
+           unit->Destroyed = 1;
+           --j;
+       } else if (!strcmp(value, "seen-destroyed")) {
+           unit->SeenDestroyed = 1;
+           --j;
+       } else if (!strcmp(value, "removed")) {
+           unit->Removed = 1;
+           --j;
+       } else if (!strcmp(value, "selected")) {
+           unit->Selected = 1;
+           --j;
+       } else if (!strcmp(value, "rescued-from")) {
+           unit->RescuedFrom = &Players[(int)LuaToNumber(l, j + 1)];
+       } else if (!strcmp(value, "visible")) {
+           s = LuaToString(l, j + 1);
+           for (i = 0; i < PlayerMax && *s; ++i, ++s) {
+               if (*s == '-' || *s == '_' || *s == ' ') {
+                   unit->Visible &= ~(1 << i);
+               } else {
+                   unit->Visible |= (1 << i);
+               }
+           }
+       } else if (!strcmp(value, "constructed")) {
+           unit->Constructed = 1;
+           --j;
+       } else if (!strcmp(value, "seen-constructed")) {
+           unit->SeenConstructed = 1;
+           --j;
+       } else if (!strcmp(value, "seen-state")) {
+           unit->SeenState = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "active")) {
+           unit->Active = 1;
+           --j;
+       } else if (!strcmp(value, "resource-active")) {
+           unit->Data.Resource.Active = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "mana")) {
+           unit->Mana = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "hp")) {
+           unit->HP = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "xp")) {
+           unit->XP = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "kills")) {
+           unit->Kills = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "ttl")) {
+           // FIXME : unsigned long should be better handled
+           unit->TTL = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "bloodlust")) {
+           unit->Bloodlust = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "haste")) {
+           unit->Haste = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "slow")) {
+           unit->Slow = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "invisible")) {
+           unit->Invisible = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "flame-shield")) {
+           unit->FlameShield = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "unholy-armor")) {
+           unit->UnholyArmor = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "group-id")) {
+           unit->GroupId = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "last-group")) {
+           unit->LastGroup = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "value")) {
+           unit->Value = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "current-resource")) {
+           lua_pushvalue(l, j + 1);
+           unit->CurrentResource = CclGetResourceByName(l);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "sub-action")) {
+           unit->SubAction = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "wait")) {
+           unit->Wait = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "state")) {
+           unit->State = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "reset")) {
+           unit->Reset = 1;
+           --j;
+       } else if (!strcmp(value, "blink")) {
+           unit->Blink = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "moving")) {
+           unit->Moving = 1;
+           --j;
+       } else if (!strcmp(value, "rs")) {
+           unit->Rs = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "units-contained-count")) {
+           insidecount = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "units-contained")) {
+           int subargs;
+           int k;
+
+           if (!lua_istable(l, j + 1)) {
+               lua_pushstring(l, "incorrect argument");
+               lua_error(l);
+           }
+           subargs = luaL_getn(l, j + 1);
+           for (k = 0; k < subargs; ++k) {
+               lua_rawgeti(l, j + 1, k + 1);
+               value = LuaToString(l, -1);
+               lua_pop(l, 1);
+               slot = strtol(value + 1, NULL, 16);
+               AddUnitInContainer(UnitSlots[slot], unit);
+               DebugCheck(!UnitSlots[slot]);
+               ++UnitSlots[slot]->Refs;
+           }
+       } else if (!strcmp(value, "order-count")) {
+           unit->OrderCount = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "order-flush")) {
+           unit->OrderFlush = LuaToNumber(l, j + 1);
+       } else if (!strcmp(value, "orders")) {
+           int hp;
+
+           lua_pushvalue(l, j + 1);
+           CclParseOrders(l, unit);
+           lua_pop(l, 1);
+           // now we know unit's action so we can assign it to a player
+           hp = unit->HP;
+           AssignUnitToPlayer (unit, player);
+           unit->HP = hp;
+           if (unit->Orders[0].Action == UnitActionBuilded) {
+               // HACK: the building is not ready yet
+               unit->Player->UnitTypesCount[type->Type]--;
+           }
+           // FIXME: (mr-russ) Does not load CorpseList Properly
+           if (unit->Type->Building &&
+                   (unit->Orders[0].Action == UnitActionDie || 
unit->Destroyed)) {
+               DeadBuildingCacheInsert(unit);
+           } else if (unit->Orders[0].Action == UnitActionDie) {
+               CorpseCacheInsert(unit);
+           }
+#if 0
+           if (unit->Orders[0].Action == UnitActionDie &&
+                   unit->Type->CorpseScript) {
+               MapMarkUnitSight(unit);
+           }
+#endif
+       } else if (!strcmp(value, "saved-order")) {
+           lua_pushvalue(l, j + 1);
+           CclParseOrder(l, &unit->SavedOrder);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "new-order")) {
+           lua_pushvalue(l, j + 1);
+           CclParseOrder(l, &unit->NewOrder);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "data-builded")) {
+           lua_pushvalue(l, j + 1);
+           CclParseBuilded(l, unit);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "data-res-worker")) {
+           lua_pushvalue(l, j + 1);
+           CclParseResWorker(l, unit);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "data-research")) {
+           lua_pushvalue(l, j + 1);
+           CclParseResearch(l, unit);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "data-upgrade-to")) {
+           lua_pushvalue(l, j + 1);
+           CclParseUpgradeTo(l, unit);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "data-train")) {
+           lua_pushvalue(l, j + 1);
+           CclParseTrain(l, unit);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "data-move")) {
+           lua_pushvalue(l, j + 1);
+           CclParseMove(l, unit);
+           lua_pop(l, 1);
+       } else if (!strcmp(value, "goal")) {
+           unit->Goal = UnitSlots[(int)LuaToNumber(l, j + 1)];
+       } else if (!strcmp(value, "auto-cast")) {
+           s = LuaToString(l, j + 1);
+           unit->AutoCastSpell = SpellTypeByIdent(s);
+       } else {
+          // FIXME: this leaves a half initialized unit
+          lua_pushfstring(l, "Unsupported tag: %s", value);
+          lua_error(l);
+       }
+    }
+
+    if (!unit->Player) {
+       AssignUnitToPlayer (unit, player);
+       UpdateForNewUnit(unit, 0);
+       unit->HP = unit->Type->_HitPoints;
+    }
+
+    //  Revealers are units that can see while removed
+    if (unit->Removed && unit->Type->Revealer) {
+       MapMarkUnitSight(unit);
+    }
+
+    // Place on map
+    if (!unit->Removed && !unit->Destroyed && !unit->Type->Vanishes) {
+       unit->Removed = 1;
+       PlaceUnit(unit, unit->X, unit->Y);
+    }
+
+    // FIXME: johns: works only for debug code.
+    if (unit->Moving) {
+       NewResetPath(unit);
+    }
+    // Fix Colors for rescued units.
+    if (unit->RescuedFrom) {
+       unit->Colors = &unit->RescuedFrom->UnitColors;
+    }
+    DebugLevel3Fn("unit #%d parsed\n" _C_ slot);
+
+    return 0;
+}
+#endif
+
+/**
+**     Make a unit.
+**
+**     @param type     Unit-type of the unit,
+**     @param player   Owning player number of the unit.
+**
+**     @return         Returns the slot number of the made unit.
+*/
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local SCM CclMakeUnit(SCM type, SCM player)
+{
+    UnitType* unittype;
+    Unit* unit;
+
+    unittype = CclGetUnitType(type);
+    unit = MakeUnit(unittype, &Players[gh_scm2int(player)]);
+
+    return gh_int2scm(unit->Slot);
+}
+#elif defined(USE_LUA)
+local int CclMakeUnit(lua_State* l)
+{
+    UnitType* unittype;
+    Unit* unit;
+
+    if (lua_gettop(l) != 2) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 1);
+    unittype = CclGetUnitType(l);
+    lua_pop(l, 1);
+    unit = MakeUnit(unittype, &Players[(int)LuaToNumber(l, 2)]);
+
+    lua_pushnumber(l, unit->Slot);
+    return 1;
+}
+#endif
+
+/**
+**     Place a unit on map.
+**
+**     @param unit     Unit (slot number) to be placed.
+**     @param x        X map tile position.
+**     @param y        Y map tile position.
+**
+**     @return         Returns the slot number of the made placed.
+*/
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local SCM CclPlaceUnit(SCM unit, SCM x, SCM y)
+{
+    PlaceUnit(CclGetUnit(unit), gh_scm2int(x), gh_scm2int(y));
+    return unit;
+}
+#elif defined(USE_LUA)
+local int CclPlaceUnit(lua_State* l)
+{
+    Unit* unit;
+
+    if (lua_gettop(l) != 3) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 1);
+    unit = CclGetUnit(l);
+    lua_pop(l, 1);
+    PlaceUnit(unit, LuaToNumber(l, 2), LuaToNumber(l, 3));
+    lua_pushvalue(l, 1);
+    return 1;
+}
+#endif
+
+/**
+**     Create a unit and place it on the map
+**
+**     @param type     Unit-type of the unit,
+**     @param player   Owning player number of the unit.
+**     @param x        X map tile position.
+**     @param y        Y map tile position.
+**
+**     @return         Returns the slot number of the made unit.
+*/
+#if defined(USE_GUILE) || defined(USE_SIOD)
+local SCM CclCreateUnit(SCM type, SCM player, SCM x, SCM y)
+{
+    UnitType* unittype;
+    Unit* unit;
+    int heading;
+    int playerno;
+    int mask;
+    int ix;
+    int iy;
+
+    unittype = CclGetUnitType(type);
+    ix = gh_scm2int(x);
+    iy = gh_scm2int(y);
+
+    heading = SyncRand() % 256;
+    playerno = TriggerGetPlayer(player);
+    if (playerno == -1) {
+       printf("CreateUnit: You cannot use 'any in create-unit, specify a 
player\n");
+       errl("bad player", player);
+       return SCM_UNSPECIFIED;
+    }
+    unit = MakeUnit(unittype, &Players[playerno]);
+    mask = UnitMovementMask(unit);
+    if (CheckedCanMoveToMask(ix, iy, mask)) {
+       unit->Wait = 1;
+       PlaceUnit(unit, ix, iy);
+    } else {
+       unit->X = ix;
+       unit->Y = iy;
+       DropOutOnSide(unit, heading, unittype->TileWidth, unittype->TileHeight);
+    }
+
+    return gh_int2scm(unit->Slot);
+}
+#elif defined(USE_LUA)
+local int CclCreateUnit(lua_State* l)
+{
+    UnitType* unittype;
+    Unit* unit;
+    int heading;
+    int playerno;
+    int mask;
+    int ix;
+    int iy;
+
+    if (lua_gettop(l) != 4) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 1);
+    unittype = CclGetUnitType(l);
+    lua_pop(l, 1);
+    ix = LuaToNumber(l, 3);
+    iy = LuaToNumber(l, 4);
+
+    heading = SyncRand() % 256;
+    lua_pushvalue(l, 2);
+    playerno = TriggerGetPlayer(l);
+    lua_pop(l, 1);
+    if (playerno == -1) {
+       printf("CreateUnit: You cannot use 'any in create-unit, specify a 
player\n");
+       lua_pushfstring(l, "bad player");
+       lua_error(l);
+       return 0;
+    }
+    unit = MakeUnit(unittype, &Players[playerno]);
+    mask = UnitMovementMask(unit);
+    if (CheckedCanMoveToMask(ix, iy, mask)) {
+       unit->Wait = 1;
+       PlaceUnit(unit, ix, iy);
+    } else {
+       unit->X = ix;
+       unit->Y = iy;
+       DropOutOnSide(unit, heading, unittype->TileWidth, unittype->TileHeight);
+    }
+
+    lua_pushnumber(l, unit->Slot);
+    return 1;
+}
+#endif
+
+/**
+**     Order a unit
+**
+**     (order-unit player unit-type sloc dloc order)
+*/
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclOrderUnit(SCM list)
 {
     int plynr;
@@ -1058,7 +1933,7 @@
 
                    attack=TargetOnMap(unit, dx1, dy1, dx2, dy2);
                    CommandAttack(unit, (dx1 + dx2) / 2, (dy1 + dy2) / 2, 
attack, 1);
-               } else if (!strcmp(order,"patrol")) {
+               } else if (!strcmp(order, "patrol")) {
                    CommandPatrolUnit(unit, (dx1 + dx2) / 2, (dy1 + dy2) / 2, 
1);
                } else {
                    errl("Unsupported order", gh_car(list));
@@ -1070,6 +1945,108 @@
     free(order);
     return SCM_UNSPECIFIED;
 }
+#elif defined(USE_LUA)
+local int CclOrderUnit(lua_State* l)
+{
+    int plynr;
+    int x1;
+    int y1;
+    int x2;
+    int y2;
+    int dx1;
+    int dy1;
+    int dx2;
+    int dy2;
+    const UnitType* unittype;
+    Unit* table[UnitMax];
+    Unit* unit;
+    int an;
+    int j;
+    const char* order;
+
+    if (lua_gettop(l) != 5) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 1);
+    plynr = TriggerGetPlayer(l);
+    lua_pop(l, 1);
+    lua_pushvalue(l, 2);
+    unittype = TriggerGetUnitType(l);
+    lua_pop(l, 1);
+    if (!lua_istable(l, 3)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    lua_rawgeti(l, 3, 1);
+    x1 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    lua_rawgeti(l, 3, 2);
+    y1 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    if (luaL_getn(l, 3) == 4) {
+       lua_rawgeti(l, 3, 3);
+       x2 = LuaToNumber(l, -1);
+       lua_pop(l, 1);
+       lua_rawgeti(l, 3, 4);
+       y2 = LuaToNumber(l, -1);
+       lua_pop(l, 1);
+    } else {
+       x2 = x1;
+       y2 = y1;
+    }
+    if (!lua_istable(l, 4)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    lua_rawgeti(l, 4, 1);
+    dx1 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    lua_rawgeti(l, 4, 2);
+    dy1 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    if (luaL_getn(l, 4) == 4) {
+       lua_rawgeti(l, 4, 3);
+       dx2 = LuaToNumber(l, -1);
+       lua_pop(l, 1);
+       lua_rawgeti(l, 4, 4);
+       dy2 = LuaToNumber(l, -1);
+       lua_pop(l, 1);
+    } else {
+       dx2 = dx1;
+       dy2 = dy1;
+    }
+    order = LuaToString(l, 5);
+
+    an = SelectUnits(x1, y1, x2 + 1, y2 + 1, table);
+    for (j = 0; j < an; ++j) {
+       unit = table[j];
+       if (unittype == ANY_UNIT ||
+               (unittype == ALL_FOODUNITS && !unit->Type->Building) ||
+               (unittype == ALL_BUILDINGS && unit->Type->Building) ||
+               unittype == unit->Type) {
+           if (plynr == -1 || plynr == unit->Player->Player) {
+               if (!strcmp(order,"move")) {
+                   CommandMove(unit, (dx1 + dx2) / 2, (dy1 + dy2) / 2, 1);
+               } else if (!strcmp(order, "attack")) {
+                   Unit* attack;
+
+                   attack=TargetOnMap(unit, dx1, dy1, dx2, dy2);
+                   CommandAttack(unit, (dx1 + dx2) / 2, (dy1 + dy2) / 2, 
attack, 1);
+               } else if (!strcmp(order, "patrol")) {
+                   CommandPatrolUnit(unit, (dx1 + dx2) / 2, (dy1 + dy2) / 2, 
1);
+               } else {
+                   lua_pushfstring(l, "Unsupported order: %s", order);
+                   lua_error(l);
+               }
+           }
+       }
+    }
+
+    return 0;
+}
+#endif
 
 /**
 **     Kill a unit
@@ -1079,6 +2056,7 @@
 **
 **     @return         Returns true if a unit was killed.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclKillUnit(SCM type, SCM player)
 {
     int j;
@@ -1110,6 +2088,48 @@
 
     return SCM_BOOL_F;
 }
+#elif defined(USE_LUA)
+local int CclKillUnit(lua_State* l)
+{
+    int j;
+    int plynr;
+    const UnitType* unittype;
+    Unit* unit;
+    Unit** table;
+
+    if (lua_gettop(l) != 2) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 1);
+    unittype = TriggerGetUnitType(l);
+    lua_pop(l, 1);
+    plynr = TriggerGetPlayer(l);
+    if (plynr == -1) {
+       table = Units;
+       j = NumUnits - 1;
+    } else {
+       table = Players[plynr].Units;
+       j = Players[plynr].TotalNumUnits - 1;
+    }
+
+    for (; j >= 0; --j) {
+       unit = table[j];
+       if (unittype == ANY_UNIT ||
+               (unittype == ALL_FOODUNITS && !unit->Type->Building) ||
+               (unittype == ALL_BUILDINGS && unit->Type->Building) ||
+               unittype == unit->Type) {
+           LetUnitDie(unit);
+           lua_pushboolean(l, 1);
+           return 1;
+       }
+    }
+
+    lua_pushboolean(l, 0);
+    return 1;
+}
+#endif
 
 /**
 **     Kill a unit at a location
@@ -1121,6 +2141,7 @@
 **
 **     @return         Returns the number of units killed.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclKillUnitAt(SCM type, SCM player, SCM quantity, SCM loc)
 {
     int plynr;
@@ -1136,7 +2157,7 @@
     int j;
     int s;
 
-    plynr=TriggerGetPlayer(player);
+    plynr = TriggerGetPlayer(player);
     q = gh_scm2int(quantity);
     unittype = TriggerGetUnitType(type);
     x1 = gh_scm2int(gh_car(loc));
@@ -1144,7 +2165,7 @@
     x2 = gh_scm2int(gh_car(gh_cdr(gh_cdr(loc))));
     y2 = gh_scm2int(gh_car(gh_cdr(gh_cdr(gh_cdr(loc)))));
 
-    an=SelectUnits(x1, y1, x2 + 1, y2 + 1, table);
+    an = SelectUnits(x1, y1, x2 + 1, y2 + 1, table);
     for (j = s = 0; j < an && s < q; ++j) {
        unit = table[j];
        if (unittype == ANY_UNIT ||
@@ -1160,6 +2181,69 @@
 
     return gh_int2scm(s);
 }
+#elif defined(USE_LUA)
+local int CclKillUnitAt(lua_State* l)
+{
+    int plynr;
+    int q;
+    int x1;
+    int y1;
+    int x2;
+    int y2;
+    const UnitType* unittype;
+    Unit* table[UnitMax];
+    Unit* unit;
+    int an;
+    int j;
+    int s;
+
+    if (lua_gettop(l) != 2) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 2);
+    plynr = TriggerGetPlayer(l);
+    lua_pop(l, 1);
+    q = LuaToNumber(l, 3);
+    lua_pushvalue(l, 1);
+    unittype = TriggerGetUnitType(l);
+    lua_pop(l, 1);
+    if (!lua_istable(l, 4)) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+    lua_rawgeti(l, 4, 1);
+    x1 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    lua_rawgeti(l, 4, 2);
+    y1 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    lua_rawgeti(l, 4, 3);
+    x2 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+    lua_rawgeti(l, 4, 4);
+    y2 = LuaToNumber(l, -1);
+    lua_pop(l, 1);
+
+    an = SelectUnits(x1, y1, x2 + 1, y2 + 1, table);
+    for (j = s = 0; j < an && s < q; ++j) {
+       unit = table[j];
+       if (unittype == ANY_UNIT ||
+               (unittype == ALL_FOODUNITS && !unit->Type->Building) ||
+               (unittype == ALL_BUILDINGS && unit->Type->Building) ||
+               unittype==unit->Type) {
+           if (plynr == -1 || plynr == unit->Player->Player) {
+               LetUnitDie(unit);
+               ++s;
+           }
+       }
+    }
+
+    lua_pushnumber(l, s);
+    return 1;
+}
+#endif
 
 /**
 **     Get the unholy-armor of the unit structure.
@@ -1168,15 +2252,29 @@
 **
 **     @return         The unholy-armor of the unit.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclGetUnitUnholyArmor(SCM ptr)
 {
     const Unit* unit;
-    SCM value;
 
     unit = CclGetUnit(ptr);
-    value = gh_int2scm(unit->UnholyArmor);
-    return value;
+    return gh_int2scm(unit->UnholyArmor);
 }
+#elif defined(USE_LUA)
+local int CclGetUnitUnholyArmor(lua_State* l)
+{
+    const Unit* unit;
+
+    if (lua_gettop(l) != 1) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    unit = CclGetUnit(l);
+    lua_pushnumber(l, unit->UnholyArmor);
+    return 1;
+}
+#endif
 
 /**
 **     Set the unholy-armor of the unit structure.
@@ -1186,6 +2284,7 @@
 **
 **     @return         The value of the unit.
 */
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclSetUnitUnholyArmor(SCM ptr, SCM value)
 {
     Unit* unit;
@@ -1195,7 +2294,30 @@
 
     return value;
 }
+#elif defined(USE_LUA)
+local int CclSetUnitUnholyArmor(lua_State* l)
+{
+    Unit* unit;
+
+    if (lua_gettop(l) != 2) {
+       lua_pushstring(l, "incorrect argument");
+       lua_error(l);
+    }
+
+    lua_pushvalue(l, 1);
+    unit = CclGetUnit(l);
+    lua_pop(l, 1);
+    unit->UnholyArmor = LuaToNumber(l, 2);
+
+    lua_pushvalue(l, 2);
+    return 1;
+}
+#endif
 
+/**
+**     FIXME: docu
+*/
+#if defined(USE_GUILE) || defined(USE_SIOD)
 local SCM CclSlotUsage(SCM list)
 {
 #define SLOT_LEN MAX_UNIT_SLOTS / 8 + 1
@@ -1211,6 +2333,7 @@
        list = gh_cdr(list);
        if (gh_eq_p(value, gh_symbol2scm("-"))) {
            int range_end;
+
            value = gh_car(list);
            list = gh_cdr(list);
            range_end = gh_scm2int(value);
@@ -1242,6 +2365,53 @@
 #undef SLOT_LEN
 }
 #elif defined(USE_LUA)
+local int CclSlotUsage(lua_State* l)
+{
+#define SLOT_LEN MAX_UNIT_SLOTS / 8 + 1
+    unsigned char SlotUsage[SLOT_LEN];
+    int i;
+    int prev;
+    const char* value;
+    int args;
+    int j;
+
+    memset(SlotUsage, 0, SLOT_LEN);
+    prev = -1;
+    args = lua_gettop(l);
+    for (j = 0; j < args; ++j) {
+       if (lua_isstring(l, j + 1) &&
+               !strcmp((value = LuaToString(l, j + 1)), "-")) {
+           int range_end;
+
+           ++j;
+           range_end = LuaToNumber(l, j + 1);
+           for (i = prev; i <= range_end; ++i) {
+               SlotUsage[i / 8] |= 1 << (i % 8);
+           }
+           prev = -1;
+       } else {
+           if (prev >= 0) {
+               SlotUsage[prev / 8] |= 1 << (prev % 8);
+           }
+           prev = LuaToNumber(l, j + 1);
+       }
+    }
+    if (prev >= 0) {
+       SlotUsage[prev / 8] |= 1 << (prev % 8);
+    }
+
+    /* now walk through the bitfield and create the needed unit slots */
+    for (i = 0; i < SLOT_LEN * 8; ++i) {
+       if (SlotUsage[i / 8] & (1 << i % 8)) {
+           Unit* new_unit = (Unit*)calloc(1, sizeof(Unit));
+           UnitSlotFree = (void*)UnitSlots[i];
+           UnitSlots[i] = new_unit;
+           new_unit->Slot = i;
+       }
+    }
+    return 0;
+#undef SLOT_LEN
+}
 #endif
 
 // FIXME: write the missing access functions
@@ -1277,20 +2447,20 @@
     lua_register(Lua, "SetBuildingCapture", CclSetBuildingCapture);
     lua_register(Lua, "SetRevealAttacker", CclSetRevealAttacker);
 
-//    lua_register(Lua, "Unit", CclUnit);
+    lua_register(Lua, "Unit", CclUnit);
 
-//    lua_register(Lua, "MakeUnit", CclMakeUnit);
-//    lua_register(Lua, "PlaceUnit", CclPlaceUnit);
-//    lua_register(Lua, "CreateUnit", CclCreateUnit);
-//    lua_register(Lua, "OrderUnit", CclOrderUnit);
-//    lua_register(Lua, "KillUnit", CclKillUnit);
-//    lua_register(Lua, "KillUnitAt", CclKillUnitAt);
+    lua_register(Lua, "MakeUnit", CclMakeUnit);
+    lua_register(Lua, "PlaceUnit", CclPlaceUnit);
+    lua_register(Lua, "CreateUnit", CclCreateUnit);
+    lua_register(Lua, "OrderUnit", CclOrderUnit);
+    lua_register(Lua, "KillUnit", CclKillUnit);
+    lua_register(Lua, "KillUnitAt", CclKillUnitAt);
 
     // unit member access functions
-//    lua_register(Lua, "GetUnitUnholyArmor", CclGetUnitUnholyArmor);
-//    lua_register(Lua, "SetUnitUnholyArmor", CclSetUnitUnholyArmor);
+    lua_register(Lua, "GetUnitUnholyArmor", CclGetUnitUnholyArmor);
+    lua_register(Lua, "SetUnitUnholyArmor", CclSetUnitUnholyArmor);
 
-//    lua_register(Lua, "SlotUsage", CclSlotUsage);
+    lua_register(Lua, "SlotUsage", CclSlotUsage);
 #endif
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]