Added LUA support:

Control over rain and ambient light, as well as light fixtures
 Ability to change number of static enemies in a sector
 Ability to create enemy groups and set their waypoints
 Ability to set soldier APs, change stance, and change level


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1529 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Overhaul
2007-10-20 07:01:16 +00:00
parent ea68cd14ff
commit b25087e3e8
6 changed files with 697 additions and 176 deletions
+12
View File
@@ -11,9 +11,21 @@ typedef struct {
lua_CFunction get;
lua_CFunction set;
lua_CFunction call;
lua_CFunction staticcall;
} LuaAttrib;
void InitializeLua( );
int EvalLua (const wchar_t* buff) ; // The return value is whether to clear the input line, not whether the call succeeded.
void ShutdownLua( );
extern luaL_Reg WStringMethods[];
extern LuaAttrib Environment[];
extern LuaAttrib Soldier[];
extern LuaAttrib Sector[];
void CreateLuaClass( lua_State *L, STR8 ClassName, LuaAttrib *Attribs );
void NewLuaObject( lua_State *L, STR8 ClsName, void *Ptr );
void LuaStrategicSetup(lua_State *L);
void LuaTacticalSetup(lua_State *L);
void LuaEnvironmentSetup(lua_State *L);
+18 -176
View File
@@ -2,20 +2,14 @@
#include <string.h>
#include <iostream>
#include "Lua Interpreter.h"
#include "lwstring.h"
#include "Overhead.h"
#include "Isometric Utils.h"
#include "soldier tile.h"
#include "Soldier Profile.h"
#include "ai.h"
#include <Windows.h>
#include "MemMan.h"
lua_State *L;
#define ARRAY_INDEX " idx" // The space is intentional to make this an out-of-band field
#define SOLDIER_CLASS "ja2_SoldierClass"
void CreateLuaType( lua_State *L, STR8 TypeName, luaL_Reg *LuaAccessors )
{
luaL_Reg *idx;
@@ -123,6 +117,7 @@ luaL_Reg ClassList[] = {
void CreateLuaClass( lua_State *L, STR8 ClassName, LuaAttrib *Attribs )
{
luaL_Reg *i;
LuaAttrib *idx;
luaL_newmetatable( L, ClassName );
for (i = ClassList; i->name; i++)
@@ -132,6 +127,16 @@ void CreateLuaClass( lua_State *L, STR8 ClassName, LuaAttrib *Attribs )
lua_pushcclosure( L, i->func, 1);
lua_rawset( L, -3);
}
for (idx=Attribs; idx->name; idx++)
{
if (idx->staticcall)
{
lua_pushstring( L, idx->name);
lua_pushcfunction( L, idx->staticcall);
lua_rawset( L, -3 );
}
}
}
@@ -170,167 +175,9 @@ void NewLuaObject( lua_State *L, STR8 ClsName, void *Ptr )
static int LuaGetMercPtr( lua_State *L)
{
int v = lua_tointeger( L, 2 );
luaL_argcheck( L, (v >= 0 && v < TOTAL_SOLDIERS), 2, "The soldier index is out of range");
if (MercPtrs[ v ] )
{
NewLuaObject( L, "ja2_SoldierClass", MercPtrs[ v ] );
}
else
{
lua_pushnil( L );
}
return 1;
}
static luaL_Reg SoldierList[] = {
{ "__index", LuaGetMercPtr, },
{ NULL, },
};
int LuaGetSoldierName( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
luaWS_newstr( L, pSoldier->name);
}
return 1;
}
int LuaGetSoldierFullName( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
if (pSoldier->ubProfile < NUM_PROFILES)
{
luaWS_newstr( L, gMercProfiles[pSoldier->ubProfile].zName );
}
else
{
return LuaGetSoldierName( L);
}
}
return 1;
}
int LuaGetSoldierGrid( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSoldier->sGridNo);
}
return 1;
}
int LuaSetSoldierGrid( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newgrid = luaL_checkinteger( L, 3);
luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" );
TeleportSoldier( pSoldier, newgrid, TRUE);
return 0;
}
int LuaGetSoldierAPs( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSoldier->bActionPoints);
}
return 1;
}
int LuaSetSoldierAPs( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newaps = luaL_checkinteger( L, 3);
luaL_argcheck( L, newaps > 0 && newaps < 256, 2, "The grid number must be on screen!" );
pSoldier->bActionPoints = (INT8) newaps;
return 0;
}
int LuaSoldierWalkTo( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newgrid = luaL_checkinteger( L, 2);
luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" );
pSoldier->bAction = AI_ACTION_WALK;
pSoldier->usActionData = newgrid;
pSoldier->bPathStored = FALSE;
pSoldier->bActionInProgress = ExecuteAction( pSoldier);
return 0;
}
int LuaSoldierRunTo( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newgrid = luaL_checkinteger( L, 2);
luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" );
pSoldier->bAction = AI_ACTION_RUN;
pSoldier->usActionData = newgrid;
pSoldier->bPathStored = FALSE;
pSoldier->bActionInProgress = ExecuteAction( pSoldier);
return 0;
}
int LuaSoldierChangeStance( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newstance = luaL_checkinteger( L, 2);
ChangeSoldierStance( pSoldier, (UINT8) newstance);
return 0;
}
LuaAttrib Soldier[] = {
{ "name", LuaGetSoldierName, },
{ "fullname", LuaGetSoldierFullName, },
{ "grid", LuaGetSoldierGrid, LuaSetSoldierGrid },
{ "APs", LuaGetSoldierAPs, LuaSetSoldierAPs },
{ "walkto", NULL, NULL, LuaSoldierWalkTo },
{ "runto", NULL, NULL, LuaSoldierRunTo },
{ "changestance", NULL, NULL, LuaSoldierChangeStance },
{ NULL, },
};
extern luaL_Reg WStringMethods[];
void InitializeLua( )
{
L = lua_open();
@@ -345,15 +192,10 @@ void InitializeLua( )
CreateLuaType( L, "wstring", WStringMethods);
lua_setglobal( L, "wstring"); // We also want this class to be known to the script
// Create a soldier type
CreateLuaClass( L, SOLDIER_CLASS, Soldier );
lua_setglobal( L, SOLDIER_CLASS); // We also want this class to be known to the script
// Create a soldier list type and create its object
CreateLuaType( L, "ja2_SoldierListClass", SoldierList);
CreateLuaObject( L, NULL );
// Give this new object a name
lua_setglobal( L, "Soldiers" );
// Set up the game info
LuaTacticalSetup( L);
LuaStrategicSetup( L);
LuaEnvironmentSetup( L);
}
int EvalLua (const wchar_t* buff) {
@@ -379,7 +221,7 @@ int EvalLua (const wchar_t* buff) {
lua_pop(L, 1); /* pop error message from the stack */
return FALSE;
}
cout << lua_tostring(L, -1) << endl;
printf( "%s\n", lua_tostring(L, -1));
lua_pop(L, 1); /* pop error message from the stack */
return TRUE;
}
+12
View File
@@ -184,6 +184,18 @@
RelativePath=".\lua.cpp"
>
</File>
<File
RelativePath=".\lua_env.cpp"
>
</File>
<File
RelativePath=".\lua_strategic.cpp"
>
</File>
<File
RelativePath=".\lua_tactical.cpp"
>
</File>
<File
RelativePath=".\lwstring.cpp"
>
+87
View File
@@ -0,0 +1,87 @@
#include "Lua Interpreter.h"
#include "environment.h"
#define ENVIRONMENT_CLASS "ja2_EnvironmentClass"
static int LuaGetRainVal( lua_State *L )
{
lua_pushinteger( L, guiEnvWeather);
return 1;
}
static int LuaSetRainVal( lua_State *L )
{
int newrain = luaL_checkinteger( L, 3);
luaL_argcheck( L, newrain >= 0 && newrain <= 2, 2, "The rain must be between 0 and 2" );
if (newrain == 0)
{
EnvEndRainStorm();
}
else
{
EnvBeginRainStorm( (UINT8)(newrain-1));
}
return 0;
}
static int LuaGetAmbient( lua_State *L )
{
lua_pushinteger( L, gubEnvLightValue);
return 1;
}
static int LuaSetAmbient( lua_State *L )
{
int newambient = luaL_checkinteger( L, 3);
luaL_argcheck( L, newambient >= 0 && newambient <= 255, 2, "The ambience must be between 0 and 255" );
gubEnvLightValue = (UINT8)newambient;
if( !gfBasement && !gfCaves )
gfDoLighting = TRUE;
return 0;
}
static int LuaSetNightLights( lua_State *L )
{
int newprime = luaL_checkinteger( L, 1);
if (newprime)
{
TurnOnNightLights();
}
else
{
TurnOffNightLights();
}
return 0;
}
static int LuaSetPrimeLights( lua_State *L )
{
int newprime = luaL_checkinteger( L, 1);
if (newprime)
{
TurnOnPrimeLights();
}
else
{
TurnOffPrimeLights();
}
return 0;
}
static LuaAttrib Environment[] = {
{ "rain", LuaGetRainVal, LuaSetRainVal },
{ "ambient", LuaGetAmbient, LuaSetAmbient },
{ "nightlights", NULL, NULL, LuaSetNightLights },
{ "primelights", NULL, NULL, LuaSetPrimeLights },
{ NULL, },
};
void LuaEnvironmentSetup(lua_State *L)
{
// Create the environment object
lua_newtable( L);
CreateLuaClass( L, ENVIRONMENT_CLASS, Environment );
lua_setmetatable( L, -2);
lua_setglobal( L, "Environment"); // We also want this class to be known to the script
}
+369
View File
@@ -0,0 +1,369 @@
#include "Lua Interpreter.h"
#include "Campaign Types.h"
#include "Strategic Movement.h"
#define SECTOR_CLASS "ja2_SectorClass"
#define MOBILEGROUP_CLASS "ja2_MobileGroup"
static int LuaGetSectorNumAdmins( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
if (!pSector)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSector->ubNumAdmins);
}
return 1;
}
static int LuaSetSectorNumAdmins( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
int newnum = luaL_checkinteger( L, 3);
luaL_argcheck( L, newnum >= 0 && newnum < 256, 2, "The number of soldiers must be between 0 and 255" );
pSector->ubNumAdmins = (UINT8) newnum;
return 0;
}
static int LuaGetSectorNumTroops( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
if (!pSector)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSector->ubNumTroops);
}
return 1;
}
static int LuaSetSectorNumTroops( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
int newnum = luaL_checkinteger( L, 3);
luaL_argcheck( L, newnum >= 0 && newnum < 256, 2, "The number of soldiers must be between 0 and 255" );
pSector->ubNumTroops = (UINT8) newnum;
return 0;
}
static int LuaGetSectorNumElites( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
if (!pSector)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSector->ubNumElites);
}
return 1;
}
static int LuaSetSectorNumElites( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
int newnum = luaL_checkinteger( L, 3);
luaL_argcheck( L, newnum >= 0 && newnum < 256, 2, "The number of soldiers must be between 0 and 255" );
pSector->ubNumElites = (UINT8) newnum;
return 0;
}
static int LuaGetSectorNumCreatures( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
if (!pSector)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSector->ubNumCreatures);
}
return 1;
}
static int LuaSetSectorNumCreatures( lua_State *L )
{
SECTORINFO **ppSector = (SECTORINFO**) lua_touserdata( L, 1 );
SECTORINFO *pSector = *ppSector;
int newnum = luaL_checkinteger( L, 3);
luaL_argcheck( L, newnum >= 0 && newnum < 256, 2, "The number of soldiers must be between 0 and 255" );
pSector->ubNumCreatures = (UINT8) newnum;
return 0;
}
LuaAttrib Sector[] = {
{ "numadmins", LuaGetSectorNumAdmins, LuaSetSectorNumAdmins },
{ "numtroops", LuaGetSectorNumTroops, LuaSetSectorNumTroops },
{ "numelites", LuaGetSectorNumElites, LuaSetSectorNumElites },
{ "numcreatures", LuaGetSectorNumCreatures, LuaSetSectorNumCreatures },
{ NULL, },
};
static int LuaGetGroupList( lua_State *L )
{
GROUP *pGroup = gpGroupList;
int idx = 0;
lua_newtable( L);
//Count the number of active groups
while( pGroup )
{
lua_pushinteger( L, pGroup->ubGroupID);
lua_rawseti( L, -2, idx++);
pGroup = pGroup->next;
}
return 1;
}
static int LuaGetGroup( lua_State *L )
{
int grp = luaL_checkinteger( L, 1);
GROUP *pGroup = GetGroup( (UINT8) grp);
if (pGroup)
{
NewLuaObject( L, MOBILEGROUP_CLASS, pGroup);
}
else
{
lua_pushnil( L );
}
return 1;
}
static int LuaGroupCreate( lua_State *L )
{
UINT32 Sector = luaL_checkinteger( L, 1);
UINT8 NumAdmins = (UINT8) luaL_checkinteger( L, 2);
UINT8 NumTroops = (UINT8) luaL_checkinteger( L, 3);
UINT8 NumElites = (UINT8) luaL_checkinteger( L, 4);
GROUP *pGroup = CreateNewEnemyGroupDepartingFromSector( Sector, NumAdmins, NumTroops, NumElites );
if (pGroup)
{
NewLuaObject( L, MOBILEGROUP_CLASS, pGroup);
}
else
{
lua_pushnil( L );
}
return 1;
}
static int LuaGetGroupID( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->ubGroupID);
}
return 1;
}
static int LuaGetGroupX( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->ubSectorX);
}
return 1;
}
static int LuaGetGroupY( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->ubSectorY);
}
return 1;
}
static int LuaGetGroupZ( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->ubSectorZ);
}
return 1;
}
static int LuaGetGroupWaypoints( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup)
{
lua_pushnil( L );
}
else
{
WAYPOINT *waypoint = pGroup->pWaypoints;
int idx = 0;
lua_newtable(L);
while (waypoint)
{
lua_newtable(L);
lua_pushstring(L, "x");
lua_pushinteger(L, waypoint->x);
lua_rawset(L, -3);
lua_pushstring(L, "y");
lua_pushinteger(L, waypoint->y);
lua_rawset(L, -3);
lua_rawseti(L, -2, idx++);
waypoint = waypoint->next;
}
}
return 1;
}
static int LuaGetGroupNumAdmins( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup || !pGroup->pEnemyGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->pEnemyGroup->ubNumAdmins);
}
return 1;
}
static int LuaGetGroupNumTroops( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup || !pGroup->pEnemyGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->pEnemyGroup->ubNumTroops);
}
return 1;
}
static int LuaGetGroupNumElites( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup || !pGroup->pEnemyGroup)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pGroup->pEnemyGroup->ubNumElites);
}
return 1;
}
static int LuaGroupAddWaypoint( lua_State *L )
{
GROUP **ppGroup = (GROUP**) lua_touserdata( L, 1 );
GROUP *pGroup = *ppGroup;
if (!pGroup)
{
lua_pushinteger( L, 0 );
}
else
{
int x = lua_tointeger(L, 2);
int y = lua_tointeger(L, 3);
lua_pushinteger( L, AddWaypointToPGroup( pGroup, (UINT8) x, (UINT8) y) );
}
return 1;
}
static LuaAttrib MobileGroup[] = {
{ "grouplist", NULL, NULL, NULL, LuaGetGroupList },
{ "get", NULL, NULL, NULL, LuaGetGroup },
{ "new", NULL, NULL, NULL, LuaGroupCreate },
{ "ID", LuaGetGroupID },
{ "X", LuaGetGroupX },
{ "Y", LuaGetGroupY },
{ "Z", LuaGetGroupZ },
{ "waypoints", LuaGetGroupWaypoints },
{ "numadmins", LuaGetGroupNumAdmins },
{ "numtroops", LuaGetGroupNumTroops },
{ "numelites", LuaGetGroupNumElites },
{ "addwaypoint", NULL, NULL, LuaGroupAddWaypoint },
{ NULL, },
};
void LuaStrategicSetup(lua_State *L)
{
// Create a sector type
CreateLuaClass( L, SECTOR_CLASS, Sector );
//lua_setglobal( L, SECTOR_CLASS); // We also want this class to be known to the script
// Create a sector list type and create its object
lua_createtable (L, 256, 0);
for (int sect=0; sect < 256; sect++)
{
lua_pushinteger( L, sect);
NewLuaObject( L, SECTOR_CLASS, SectorInfo + sect );
lua_settable( L, -3);
}
// Give this new object a name
lua_setglobal( L, "Sectors" );
// Create a mobile group type
CreateLuaClass( L, MOBILEGROUP_CLASS, MobileGroup );
lua_setglobal( L, "MobileGroups"); // We also want this class to be known to the script
}
+199
View File
@@ -0,0 +1,199 @@
#include "Lua Interpreter.h"
#include "lwstring.h"
#include "Overhead.h"
#include "Isometric Utils.h"
#include "soldier tile.h"
#include "Soldier Profile.h"
#include "Soldier Functions.h"
#include "ai.h"
#define SOLDIER_CLASS "ja2_SoldierClass"
static int LuaGetSoldierName( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
luaWS_newstr( L, pSoldier->name);
}
return 1;
}
static int LuaGetSoldierFullName( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
if (pSoldier->ubProfile < NUM_PROFILES)
{
luaWS_newstr( L, gMercProfiles[pSoldier->ubProfile].zName );
}
else
{
return LuaGetSoldierName( L);
}
}
return 1;
}
static int LuaGetSoldierGrid( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSoldier->sGridNo);
}
return 1;
}
static int LuaSetSoldierGrid( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newgrid = luaL_checkinteger( L, 3);
luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on map" );
TeleportSoldier( pSoldier, (INT16) newgrid, TRUE);
return 0;
}
static int LuaGetSoldierLevel( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSoldier->bLevel);
}
return 1;
}
static int LuaSetSoldierLevel( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newlevel = luaL_checkinteger( L, 3);
luaL_argcheck( L, newlevel >= 0 && newlevel <= 1, 2, "The level must be 1 or 0" );
HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, (BOOLEAN) newlevel, TRUE );
SetSoldierHeight( pSoldier, (FLOAT)50*newlevel );
HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, (BOOLEAN) newlevel, TRUE );
return 0;
}
static int LuaGetSoldierAPs( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
if (!pSoldier)
{
lua_pushnil( L );
}
else
{
lua_pushinteger( L, pSoldier->bActionPoints);
}
return 1;
}
static int LuaSetSoldierAPs( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newaps = luaL_checkinteger( L, 3);
luaL_argcheck( L, newaps > 0 && newaps < 256, 2, "The grid number must be on screen!" );
pSoldier->bActionPoints = (INT8) newaps;
return 0;
}
static int LuaSoldierWalkTo( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newgrid = luaL_checkinteger( L, 2);
luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" );
pSoldier->bAction = AI_ACTION_WALK;
pSoldier->usActionData = (INT16) newgrid;
pSoldier->bPathStored = FALSE;
pSoldier->bActionInProgress = ExecuteAction( pSoldier);
return 0;
}
static int LuaSoldierRunTo( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newgrid = luaL_checkinteger( L, 2);
luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" );
pSoldier->bAction = AI_ACTION_RUN;
pSoldier->usActionData = (INT16) newgrid;
pSoldier->bPathStored = FALSE;
pSoldier->bActionInProgress = ExecuteAction( pSoldier);
return 0;
}
static int LuaSoldierChangeStance( lua_State *L )
{
SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS );
SOLDIERTYPE *pSoldier = *ppSoldier;
int newstance = luaL_checkinteger( L, 2);
ChangeSoldierStance( pSoldier, (UINT8) newstance);
return 0;
}
static LuaAttrib Soldier[] = {
{ "name", LuaGetSoldierName, },
{ "fullname", LuaGetSoldierFullName, },
{ "grid", LuaGetSoldierGrid, LuaSetSoldierGrid },
{ "level", LuaGetSoldierLevel, LuaSetSoldierLevel },
{ "APs", LuaGetSoldierAPs, LuaSetSoldierAPs },
{ "walkto", NULL, NULL, LuaSoldierWalkTo },
{ "runto", NULL, NULL, LuaSoldierRunTo },
{ "changestance", NULL, NULL, LuaSoldierChangeStance },
{ NULL, },
};
void LuaTacticalSetup(lua_State *L)
{
// Create a soldier type
CreateLuaClass( L, SOLDIER_CLASS, Soldier );
lua_setglobal( L, SOLDIER_CLASS); // We also want this class to be known to the script
// Create a soldier list type and create its object
lua_createtable (L, 256, 0);
for (int sold=0; sold < 256; sold++)
{
lua_pushinteger( L, sold);
if (MercPtrs[ sold ] )
{
NewLuaObject( L, SOLDIER_CLASS, MercPtrs[ sold ] );
}
else
{
lua_pushnil( L );
}
lua_settable( L, -3);
}
// Give this new object a name
lua_setglobal( L, "Soldiers" );
}