mirror of
https://github.com/1dot13/source.git
synced 2026-09-16 14:47:17 +02:00
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:
@@ -11,9 +11,21 @@ typedef struct {
|
|||||||
lua_CFunction get;
|
lua_CFunction get;
|
||||||
lua_CFunction set;
|
lua_CFunction set;
|
||||||
lua_CFunction call;
|
lua_CFunction call;
|
||||||
|
lua_CFunction staticcall;
|
||||||
} LuaAttrib;
|
} LuaAttrib;
|
||||||
|
|
||||||
void InitializeLua( );
|
void InitializeLua( );
|
||||||
int EvalLua (const wchar_t* buff) ; // The return value is whether to clear the input line, not whether the call succeeded.
|
int EvalLua (const wchar_t* buff) ; // The return value is whether to clear the input line, not whether the call succeeded.
|
||||||
void ShutdownLua( );
|
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
@@ -2,20 +2,14 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Lua Interpreter.h"
|
#include "Lua Interpreter.h"
|
||||||
#include "lwstring.h"
|
|
||||||
|
|
||||||
#include "Overhead.h"
|
#include <Windows.h>
|
||||||
#include "Isometric Utils.h"
|
#include "MemMan.h"
|
||||||
#include "soldier tile.h"
|
|
||||||
#include "Soldier Profile.h"
|
|
||||||
#include "ai.h"
|
|
||||||
|
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
|
||||||
#define ARRAY_INDEX " idx" // The space is intentional to make this an out-of-band field
|
#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 )
|
void CreateLuaType( lua_State *L, STR8 TypeName, luaL_Reg *LuaAccessors )
|
||||||
{
|
{
|
||||||
luaL_Reg *idx;
|
luaL_Reg *idx;
|
||||||
@@ -123,6 +117,7 @@ luaL_Reg ClassList[] = {
|
|||||||
void CreateLuaClass( lua_State *L, STR8 ClassName, LuaAttrib *Attribs )
|
void CreateLuaClass( lua_State *L, STR8 ClassName, LuaAttrib *Attribs )
|
||||||
{
|
{
|
||||||
luaL_Reg *i;
|
luaL_Reg *i;
|
||||||
|
LuaAttrib *idx;
|
||||||
|
|
||||||
luaL_newmetatable( L, ClassName );
|
luaL_newmetatable( L, ClassName );
|
||||||
for (i = ClassList; i->name; i++)
|
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_pushcclosure( L, i->func, 1);
|
||||||
lua_rawset( L, -3);
|
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( )
|
void InitializeLua( )
|
||||||
{
|
{
|
||||||
L = lua_open();
|
L = lua_open();
|
||||||
@@ -345,15 +192,10 @@ void InitializeLua( )
|
|||||||
CreateLuaType( L, "wstring", WStringMethods);
|
CreateLuaType( L, "wstring", WStringMethods);
|
||||||
lua_setglobal( L, "wstring"); // We also want this class to be known to the script
|
lua_setglobal( L, "wstring"); // We also want this class to be known to the script
|
||||||
|
|
||||||
// Create a soldier type
|
// Set up the game info
|
||||||
CreateLuaClass( L, SOLDIER_CLASS, Soldier );
|
LuaTacticalSetup( L);
|
||||||
lua_setglobal( L, SOLDIER_CLASS); // We also want this class to be known to the script
|
LuaStrategicSetup( L);
|
||||||
|
LuaEnvironmentSetup( L);
|
||||||
// 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" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int EvalLua (const wchar_t* buff) {
|
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 */
|
lua_pop(L, 1); /* pop error message from the stack */
|
||||||
return FALSE;
|
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 */
|
lua_pop(L, 1); /* pop error message from the stack */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,18 @@
|
|||||||
RelativePath=".\lua.cpp"
|
RelativePath=".\lua.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lua_env.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lua_strategic.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\lua_tactical.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\lwstring.cpp"
|
RelativePath=".\lwstring.cpp"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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" );
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user