Initial script engine implementation.

git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@282 67975925-1194-0748-b3d5-c16f83f1a3a1
This commit is contained in:
tankefugl 2005-07-14 18:26:04 +00:00
parent d6fe442379
commit d995257c31
17 changed files with 912 additions and 8 deletions

View File

@ -189,7 +189,8 @@ typedef enum
MAP_MODE_NS = 1,
MAP_MODE_CS = 2,
MAP_MODE_DM = 3,
MAP_MODE_CO = 4
MAP_MODE_CO = 4,
MAP_MODE_NSC = 5
}
AvHMapMode;

View File

@ -264,6 +264,11 @@ int kProfileRunConfig = 0xFFFFFFFF;
std::string GetLogStringForPlayer( edict_t *pEntity );
// SCRIPTENGINE:
#include "scriptengine/AvHLUA.h"
extern AvHLUA *gLUA;
// :SCRIPTENGINE
const AvHMapExtents& GetMapExtents()
{
return GetGameRules()->GetMapExtents();
@ -1338,6 +1343,11 @@ bool AvHGamerules::GetIsNSMode(void) const
return (this->GetMapMode() == MAP_MODE_NS);
}
bool AvHGamerules::GetIsScriptedMode(void) const
{
return (this->GetMapMode() == MAP_MODE_NSC);
}
bool AvHGamerules::GetIsHamboneMode() const
{
return this->GetIsCombatMode() && (CVAR_GET_FLOAT(kvIronMan) == 2);
@ -2510,6 +2520,10 @@ void AvHGamerules::RecalculateMapMode( void )
{
this->mMapMode = MAP_MODE_CO;
}
else if(!strnicmp(theCStrLevelName, "nsc_", 4))
{
this->mMapMode = MAP_MODE_NSC;
}
}
}
// Check for CS entities
@ -3688,6 +3702,13 @@ void AvHGamerules::UpdateCheats()
void AvHGamerules::UpdateCountdown(float inTime)
{
if (this->GetIsScriptedMode())
{
// this->SetGameStarted(true);
// TODO: SCRIPTENGINE START
return;
}
const float kTimeWontStartInterval = 8.0f;
int kSecondsToCountdown = 5;
@ -3864,6 +3885,11 @@ void AvHGamerules::UpdateVictoryStatus(void)
{
bool theCheckVictoryWithCheats = !this->GetCheatsEnabled() || this->GetIsCheatEnabled(kcEndGame1) || this->GetIsCheatEnabled(kcEndGame2);
if (this->GetIsScriptedMode())
{
// SCRIPTENGINE: Check for victory status
}
else
if((this->mVictoryTeam == TEAM_IND) && this->mGameStarted && theCheckVictoryWithCheats && !this->GetIsTrainingMode())
{
char* theVictoryMessage = NULL;

View File

@ -263,6 +263,7 @@ public:
virtual bool GetIsCombatMode(void) const;
virtual AvHTeamNumber GetCombatAttackingTeamNumber() const;
virtual bool GetIsNSMode(void) const;
virtual bool GetIsScriptedMode(void) const;
virtual bool GetIsTrainingMode(void) const;
int GetBaseHealthForMessageID(AvHMessageID inMessageID) const;

View File

@ -190,6 +190,11 @@
#include <sstream>
#include "mod/AvHNetworkMessages.h"
// SCRIPTENGINE:
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
// :SCRIPTENGINE
//#include "cl_dll/studio_util.h"
//#include "cl_dll/r_studioint.h"
@ -2570,8 +2575,33 @@ void AvHHud::ResetGame(bool inMapChanged)
this->mCenterText.clear();
this->mCenterTextTime = -1;
// :tankefugl
// SCRIPTENGINE:
if (inMapChanged)
{
gLUA->Init();
gLUA->LoadLUAForMap(this->GetMapName().c_str());
}
// :SCRIPTENGINE
}
// SCRIPTENGINE:
BIND_MESSAGE(LUAmsg);
int AvHHud::LUAmsg(const char* pszName, int iSize, void* pbuf)
{
int arguments;
lua_State *L = lua_newthread(gLUA->mGlobalContext);
NetMsg_LUAMessage(pbuf, iSize, L, arguments);
if (lua_resume(L, arguments))
{
AvHLUA_OnError(lua_tostring(L, -1));
}
return 1;
}
// :SCRIPTENGINE
BIND_MESSAGE(SetGmma);
int AvHHud::SetGmma(const char* pszName, int iSize, void* pbuf)
{
@ -4881,6 +4911,11 @@ bool AvHHud::GetIsNSMode() const
return (this->mMapMode == MAP_MODE_NS);
}
bool AvHHud::GetIsScriptedMode() const
{
return (this->mMapMode == MAP_MODE_NSC);
}
bool AvHHud::GetIsMouseInRegion(int inX, int inY, int inWidth, int inHeight)
{
bool theMouseIsInRegion = false;

View File

@ -336,6 +336,7 @@ public:
bool SwitchUIMode(UIMode inNewMode);
bool GetIsCombatMode() const;
bool GetIsNSMode() const;
bool GetIsScriptedMode() const;
void HideResearchProgressStatus();
void SetResearchProgressStatus(float inPercentage);
@ -397,9 +398,8 @@ public:
int GameStatus(const char* pszName, int iSize, void* pbuf);
int MiniMap(const char* pszName, int iSize, void* pbuf);
// tankefugl: 0000971
int IssueOrder(const char* pszName, int iSize, void* pbuf);
// :tankefugl
int LUAmsg(const char* pszName, int iSize, void* pbuf);
int Progress(const char* pszName, int iSize, void* pbuf);
int SetGmma(const char* pszName, int iSize, void* pbuf);
int SetSelect(const char* pszName, int iSize, void* pbuf);

View File

@ -24,7 +24,7 @@ int g_msgAmmoPickup = 0, g_msgAmmoX, g_msgBattery, g_msgCurWeapon, g_msgDamage,
g_msgServerVar, g_msgSetGammaRamp, g_msgSetOrder, g_msgSetParticleTemplates,
g_msgSetSelect, g_msgSetRequest, g_msgSetSoundNames, g_msgSetTechNodes, g_msgSetTechSlots,
g_msgSetTopDown, g_msgSetupMap, g_msgUpdateCountdown, g_msgUpdateEntityHierarchy,
g_msgProfileInfo, g_msgNexusBytes, g_msgIssueOrder;
g_msgProfileInfo, g_msgNexusBytes, g_msgIssueOrder, g_msgLUAMessage;
void Net_InitializeMessages(void)
{
@ -47,7 +47,6 @@ void Net_InitializeMessages(void)
g_msgMOTD = REG_USER_MSG( "MOTD", -1 );
g_msgResetHUD = REG_USER_MSG( "ResetHUD", 0 );
g_msgSayText = REG_USER_MSG( "SayText", -1 );
// puzl: 0001073
g_msgScoreInfo = REG_USER_MSG( "ScoreInfo", -1 );
g_msgServerName = REG_USER_MSG( "ServerName", -1 );
g_msgSetFOV = REG_USER_MSG( "SetFOV", 1 );
@ -90,9 +89,8 @@ void Net_InitializeMessages(void)
g_msgUpdateEntityHierarchy = REG_USER_MSG( "EntHier", -1 );
g_msgProfileInfo = REG_USER_MSG( "ProfileInfo", 8 );
g_msgNexusBytes = REG_USER_MSG( "NexusBytes", -1 );
// tankefugl: 0000971
g_msgIssueOrder = REG_USER_MSG( "IssueOrder", 9);
// :tankefugl
g_msgLUAMessage = REG_USER_MSG( "LUAmsg", -1);
}
#endif
@ -2159,4 +2157,85 @@ const int kEntHierFlagDeletion = 0x02;
MESSAGE_END();
}
#endif
// :tankefugl
// :tankefugl
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef AVH_SERVER
void NetMsg_LUAMessage( void* const buffer, const int size, lua_State *L, int &arguments)
{
BEGIN_READ( buffer, size );
arguments = READ_BYTE();
for (int i = arguments; i > 0; i--)
{
if (i == arguments)
{
std::string temp = READ_STRING();
lua_getglobal(L, temp.c_str());
continue;
}
int theLuaType = READ_BYTE();
switch (theLuaType)
{
case LUA_TBOOLEAN:
lua_pushboolean(L, READ_BYTE());
break;
case LUA_TNUMBER:
lua_pushnumber(L, (float)(READ_LONG()));
break;
case LUA_TSTRING:
lua_pushstring(L, READ_STRING());
break;
default:
ASSERT(false);
break;
}
}
END_READ();
arguments--;
}
#else
void NetMsg_LUAMessage(entvars_t* const pev, lua_State *L)
{
luaL_checktype(L, 2, LUA_TSTRING);
int arguments = lua_gettop(L);
for (int i = 3; i <= arguments; i++)
{
int theLuaType = lua_type(L, i);
if (!(theLuaType == LUA_TBOOLEAN ||
theLuaType == LUA_TNUMBER ||
theLuaType == LUA_TSTRING))
luaL_typerror(L, i, "boolean|number|string");
}
MESSAGE_BEGIN( MSG_ONE, g_msgLUAMessage, NULL, pev );
WRITE_BYTE(arguments - 1);
WRITE_STRING(lua_tostring(L, 2));
int top = lua_gettop(L);
int current = 3;
while (current <= top)
{
int theLuaType = lua_type(L, current);
WRITE_BYTE(theLuaType);
switch (theLuaType)
{
case LUA_TBOOLEAN:
WRITE_BYTE(lua_toboolean(L, current));
break;
case LUA_TNUMBER:
WRITE_LONG((float)(lua_tonumber(L, current)));
break;
case LUA_TSTRING:
WRITE_STRING(lua_tostring(L, current));
break;
default:
ASSERT(false);
break;
}
current++;
}
MESSAGE_END();
}
#endif

View File

@ -34,6 +34,11 @@
#include "AvHEntityHierarchy.h"
#include "../engine/shake.h"
#include "../common/weaponinfo.h"
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
//FUNCTION PROTOTYPES
#ifdef AVH_SERVER
@ -107,6 +112,7 @@
void NetMsg_SetupMap_Location( entvars_t* const pev, const string& name, const float* const min_extents, const float* const max_extents );
void NetMsg_UpdateEntityHierarchy( entvars_t* const pev, const MapEntityMap& NewItems, const EntityListType& OldItems );
void NetMsg_IssueOrder(entvars_t* const pev, const int ordertype, const int ordersource, const int ordertarget);
void NetMsg_LUAMessage(entvars_t* const pev, lua_State *L);
//BROADCAST MESSAGE TRANSMISSION
void NetMsg_DeathMsg( const int killer_index, const int victim_index, string& weapon_name );
@ -197,6 +203,8 @@
void NetMsg_UpdateCountdown( void* const buffer, const int size, int& countdown );
void NetMsg_UpdateEntityHierarchy( void* const buffer, const int size, MapEntityMap& NewItems, EntityListType& OldItems );
void NetMsg_IssueOrder( void* const buffer, const int size, int& ordertype, int& ordersource, int& ordertarget );
void NetMsg_LUAMessage( void* const buffer, const int size, lua_State *L, int &arguments);
// 60
#endif //AVH_SERVER

View File

@ -0,0 +1,161 @@
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
#include <string>
#ifdef AVH_CLIENT
extern double gClientTimeLastUpdate;
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AvHLUA::AvHLUA()
{
this->mGlobalContext = NULL;
this->mLoaded = false;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AvHLUA::~AvHLUA()
{
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::Init()
{
this->mTimetable.clear();
bool isRestricted = false;
#ifdef AVH_SERVER
this->mNextCallTime = gpGlobals->time + 99999;
isRestricted = GetGameRules()->GetIsCombatMode() || GetGameRules()->GetIsNSMode();
#else
this->mNextCallTime = gClientTimeLastUpdate + 99999;
isRestricted = gHUD.GetIsCombatMode() || gHUD.GetIsNSMode();
#endif
if (this->mGlobalContext != NULL)
{
lua_close(this->mGlobalContext);
}
this->mGlobalContext = lua_open();
// load libs for context -- give full access to servers, limited to clients
#ifdef AVH_SERVER
luaopen_io(this->mGlobalContext);
#endif
luaopen_base(this->mGlobalContext);
luaopen_table(this->mGlobalContext);
luaopen_string(this->mGlobalContext);
luaopen_math(this->mGlobalContext);
// SERVER and CLIENT replacements
lua_register(this->mGlobalContext, "print", AvHLUABase_Print);
#ifdef AVH_CLIENT
// CLIENT replacements
//lua_register(this->mGlobalContext, "assert", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "collectgarbage", AvHLUABase_Blank);
lua_register(this->mGlobalContext, "dofile", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "error", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "_G", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "getfenv", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "getmetatable", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "gcinfo", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "ipairs", AvHLUABase_Blank);
lua_register(this->mGlobalContext, "loadfile", AvHLUABase_Blank);
lua_register(this->mGlobalContext, "loadlib", AvHLUABase_Blank);
lua_register(this->mGlobalContext, "loadstring", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "next", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "pairs", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "pcall", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "rawequal", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "rawget", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "rawset", AvHLUABase_Blank);
lua_register(this->mGlobalContext, "require", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "setfenv", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "setmetatable", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "tonumber", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "tostring", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "type", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "unpack", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "_VERSION", AvHLUABase_Blank);
//lua_register(this->mGlobalContext, "xpcall", AvHLUABase_Blank);
#endif
this->RegisterNamespace_Time();
#ifdef AVH_SERVER
// SERVER API: common
this->RegisterNamespace_Player();
this->RegisterNamespace_Team();
lua_register(this->mGlobalContext, "client", AvHLUABase_Client);
// SERVER API: non-restricted
if (!isRestricted)
{
}
#endif
#ifdef AVH_CLIENT
// CLIENT API: common
lua_register(this->mGlobalContext, "client", AvHLUABase_Blank);
// CLIENT API: non-restricted
if (!isRestricted)
{
}
#endif
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool AvHLUA::LoadLUAForMap(const char *inMapName)
{
ASSERT(this->mGlobalContext != NULL);
std::string filename;
filename = getModDirectory();
filename += "/maps/";
filename += inMapName;
filename += ".lua";
std::string msg;
bool result = false;
if (luaL_loadfile(this->mGlobalContext, filename.c_str()) || lua_pcall(this->mGlobalContext, 0, 0, 0))
{
AvHLUA_OnError(lua_tostring(this->mGlobalContext, -1));
}
else
{
#ifdef AVH_SERVER
msg = "[LUA] ";
#else
msg = "[LUA CLIENT] ";
#endif
msg += LUA_VERSION;
msg += "\n[LUA] ";
msg += filename;
msg += " is loaded\n";
this->mLoaded = true;
result = true;
}
#ifdef AVH_SERVER
ALERT(at_console, UTIL_VarArgs("%s", msg.c_str()));
#else
gEngfuncs.pfnConsolePrint(msg.c_str());
#endif
return result;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AvHLUA *gLUA = new AvHLUA();

View File

@ -0,0 +1,113 @@
#ifndef AVHLUA_H
#define AVHLUA_H
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#ifdef AVH_CLIENT
#include "cl_dll/wrect.h"
#include "cl_dll/cl_dll.h"
#include "engine/progdefs.h"
#include "mod/AvHHud.h"
#include "common/cl_entity.h"
extern cl_enginefunc_t gEngfuncs;
extern AvHHud gHUD;
#endif
#ifdef AVH_SERVER
#include "util/nowarnings.h"
#include "mod/AvHPlayer.h"
#include "mod/AvHMessage.h"
#include "mod/AvHParticleTemplateServer.h"
#include "mod/AvHEntities.h"
#include "mod/AvHGamerules.h"
#include "mod/AvHServerVariables.h"
#include "mod/AvHConstants.h"
#include "mod/AvHMarineWeapons.h"
#include "dlls/client.h"
#include "dlls/util.h"
#include "mod/AvHSoundListManager.h"
#include "mod/AvHServerUtil.h"
#include "mod/AvHMarineEquipment.h"
#include "mod/AvHTitles.h"
#include "mod/AvHMarineEquipmentConstants.h"
#include "mod/AvHParticleTemplate.h"
#include "common/vector_util.h"
#include "dlls/roach.h"
#include "mod/AvHSelectionHelper.h"
#include "mod/AvHPlayerUpgrade.h"
#include "mod/AvHSharedUtil.h"
#include "mod/AvHDramaticPriority.h"
#include "mod/AvHHulls.h"
#include "mod/AvHMovementUtil.h"
#include "mod/AvHAlienWeaponConstants.h"
#include "mod/AvHParticleSystemEntity.h"
#include "mod/AvHAlienAbilities.h"
#include "mod/AvHAlienAbilityConstants.h"
#include "mod/AvHAlienEquipmentConstants.h"
#include "mod/AvHMarineTurret.h"
#include "mod/AvHSiegeTurret.h"
#include "mod/AvHBlipConstants.h"
#include "mod/AvHParticleConstants.h"
#include "util/MathUtil.h"
#include "types.h"
#include "mod/AvHNetworkMessages.h"
#include "mod/AvHNexusServer.h"
#include "dlls/cbase.h"
#endif
#include "mod/AvHConstants.h"
#include "engine/edict.h"
#include "engine/eiface.h"
#include "common/const.h"
#include <map>
#include <list>
#include "scriptengine/AvHLUABase.h"
typedef pair<int, lua_State*> LUATimetableCallbackType;
typedef multimap<int, LUATimetableCallbackType> LUATimetableType;
class AvHLUA
{
public:
AvHLUA();
~AvHLUA();
void Init();
bool LoadLUAForMap(const char *inMapName);
void OnLoad();
void OnStart();
void OnStarted();
void OnJointeam(int inEntindex, AvHTeamNumber inTeamToJoin);
bool mLoaded;
lua_State *mGlobalContext;
bool ExecuteCallbacks(float time);
int Suspend(lua_State *L, float delay);
int DelayedExecute(lua_State *L, float time);
private:
void RegisterNamespace_Time();
#ifdef AVH_SERVER
void RegisterNamespace_Player();
void RegisterNamespace_Team();
#else
#endif
int Resume(lua_State *L, int numargs);
float mNextCallTime;
LUATimetableType mTimetable;
};
extern AvHLUA *gLUA;
#endif

View File

@ -0,0 +1,59 @@
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// replacement: blank
int AvHLUABase_Blank(lua_State *L)
{
return 0;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// replacement: print
int AvHLUABase_Print(lua_State *L)
{
if (lua_gettop(L) > 0)
{
std::string theConsoleString;
#ifdef AVH_CLIENT
theConsoleString = "[LUA CLIENT] ";
theConsoleString += lua_tostring(L, 1);
theConsoleString += "\n";
gEngfuncs.pfnConsolePrint(theConsoleString.c_str());
#else
theConsoleString = "[LUA] ";
theConsoleString += lua_tostring(L, 1);
theConsoleString += "\n";
ALERT(at_console, UTIL_VarArgs("%s", theConsoleString.c_str()));
#endif
}
return 0;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int AvHLUABase_Client(lua_State *L)
{
#ifdef AVH_SERVER
luaL_checktype(L, 1, LUA_TNUMBER);
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(lua_tonumber(L, 1)));
if (theEntity && theEntity->IsPlayer())
NetMsg_LUAMessage(theEntity->pev, L);
else
int a = 0; // TODO: ADD ERROR CHECK
return 0;
#endif
#ifdef AVH_CLIENT
return 0;
#endif
}

View File

@ -0,0 +1,14 @@
#ifndef AVHLUABASE_H
#define AVHLUABASE_H
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
int AvHLUABase_Blank(lua_State *L);
int AvHLUABase_Print(lua_State *L);
int AvHLUABase_Client(lua_State *L);
#endif

View File

@ -0,0 +1,66 @@
// ---------------------------------------------------------------------
// SERVER ENTITY
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static int AvHLUAEntity_IsPlayer(lua_State *L)
{
int entindex = luaL_checkint(L, 1);
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(entindex));
// TODO: Errorcheck- and handling
if (theEntity)
lua_pushboolean(L, theEntity->IsPlayer());
return 1;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static int AvHLUAEntity_GetPlayer(lua_State *L)
{
int entindex = luaL_checkint(L, 1);
// TODO: Optimization based on entindex?
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(entindex));
if (theEntity && theEntity->IsPlayer())
lua_pushnumber(L, entindex);
else
// TODO: Error
lua_pushnumber(L, 0);
return 1;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static int AvHLUAEntity_Name(lua_State *L)
{
int entindex = luaL_checkint(L, 1);
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(entindex));
// TODO: Errorcheck and handling
if (theEntity && theEntity->pev->netname)
lua_pushstring(L, STRING(theEntity->pev->netname));
else
lua_pushstring(L, "unnamed");
return 1;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static const luaL_reg meta_methods [] = {
{0,0}
};
static const luaL_reg player_methods [] = {
{"IsPlayer", AvHLUAEntity_IsPlayer},
{"GetPlayer", AvHLUAEntity_GetPlayer},
{"Name", AvHLUAEntity_Name},
{0,0}
};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::RegisterNamespace_Player()
{
UTIL_LUARegisterObject(this->mGlobalContext, player_methods, meta_methods, "Player");
}

View File

@ -0,0 +1,60 @@
// ---------------------------------------------------------------------
// SERVER EVENTS
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::OnLoad()
{
if (this->mLoaded)
{
lua_getglobal(this->mGlobalContext, "OnLoad");
AvHLUA_Pcall(this->mGlobalContext, 0, 0);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::OnStart()
{
if (this->mLoaded)
{
lua_getglobal(this->mGlobalContext, "OnStart");
AvHLUA_Pcall(this->mGlobalContext, 0, 0);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::OnStarted()
{
if (this->mLoaded)
{
lua_getglobal(this->mGlobalContext, "OnStarted");
AvHLUA_Pcall(this->mGlobalContext, 0, 0);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::OnJointeam(int inEntindex, AvHTeamNumber inTeamToJoin)
{
if (this->mLoaded)
{
lua_State *threadState = lua_newthread(this->mGlobalContext);
lua_getglobal(threadState, "OnJointeam");
lua_pushnumber(threadState, inEntindex);
lua_pushnumber(threadState, (int)(inTeamToJoin));
if (int errorcode = lua_resume(threadState, 2))
{
AvHLUA_OnError(lua_tostring(threadState, -1));
}
else
{
// all values returned are on the stack
}
}
}
// ---------------------------------------------------------------------

View File

@ -0,0 +1,15 @@
// ---------------------------------------------------------------------
// SERVER TEAM
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA::RegisterNamespace_Team()
{
}

View File

@ -0,0 +1,164 @@
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUA.h"
#include "scriptengine/AvHLUAUtil.h"
#ifdef AVH_CLIENT
extern double gClientTimeLastUpdate;
#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static int AvHLUATime_Now(lua_State *L)
{
#ifdef AVH_SERVER
float now = gpGlobals->time;
#else
float now = gClientTimeLastUpdate;
#endif
lua_pushnumber(L, (float)(now));
return 1;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static int AvHLUATime_Sleep(lua_State *L)
{
float sleeptime = (float)(luaL_checknumber(L, 1));
if (sleeptime > 0)
{
return gLUA->Suspend(L, sleeptime);
}
else
{
return gLUA->Suspend(L, 0);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static int AvHLUATime_At(lua_State *L)
{
float time = (float)(luaL_checknumber(L, 1));
luaL_checktype(L, 2, LUA_TSTRING);
gLUA->DelayedExecute(L, time);
return 0;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static const luaL_reg meta_methods [] = {
{0,0}
};
static const luaL_reg time_methods [] = {
{"Now", AvHLUATime_Now},
{"Sleep", AvHLUATime_Sleep},
{"At", AvHLUATime_At},
{0,0}
};
void AvHLUA::RegisterNamespace_Time()
{
UTIL_LUARegisterObject(this->mGlobalContext, time_methods, meta_methods, "Time");
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int AvHLUA::DelayedExecute(lua_State *L, float time)
{
int args = lua_gettop(L) - 2;
lua_State *threadContext = lua_newthread(L);
lua_getglobal(threadContext, lua_tostring(L, 2));
if (args > 0)
{
lua_xmove(L, threadContext, args + 1);
lua_pop(threadContext, 1);
}
this->mTimetable.insert(pair<float, LUATimetableCallbackType>((float)(time), LUATimetableCallbackType(args, threadContext)));
LUATimetableType::iterator firstCall = this->mTimetable.begin();
this->mNextCallTime = (float)((*firstCall).first);
return 0;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int AvHLUA::Suspend(lua_State *L, float delay)
{
#ifdef AVH_SERVER
float now = gpGlobals->time;
#else
float now = gClientTimeLastUpdate;
#endif
this->mTimetable.insert(pair<float, LUATimetableCallbackType>((float)(now + delay), LUATimetableCallbackType(0, L)));
LUATimetableType::iterator firstCall = this->mTimetable.begin();
this->mNextCallTime = (float)((*firstCall).first);
return (lua_yield(L, 0));
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int AvHLUA::Resume(lua_State *L, int numargs)
{
int errorcode = lua_resume(L, numargs);
if (errorcode)
{
AvHLUA_OnError(lua_tostring(L, -1));
}
return errorcode;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool AvHLUA::ExecuteCallbacks(float time)
{
if (time < this->mNextCallTime)
return false;
LUATimetableType::iterator TimetableStart = this->mTimetable.begin();
LUATimetableType::iterator TimetableEnd = this->mTimetable.end();
list<LUATimetableType::iterator> eraseList;
LUATimetableType::iterator current = TimetableStart;
while (current != TimetableEnd)
{
float calltime = (float)((*current).first);
if (calltime < time)
{
LUATimetableCallbackType callbackfunc = (*current).second;
int numargs = callbackfunc.first;
lua_State *L = callbackfunc.second;
this->Resume(L, numargs);
eraseList.push_back(current);
current++;
}
else
{
this->mNextCallTime = calltime;
break;
}
}
if (current == TimetableEnd)
{
#ifdef AVH_SERVER
this->mNextCallTime = gpGlobals->time + 99999;
#else
this->mNextCallTime = gClientTimeLastUpdate + 99999;
#endif
}
while (eraseList.size() > 0)
{
LUATimetableType::iterator toErase = eraseList.front();
this->mTimetable.erase(toErase);
eraseList.pop_front();
}
return true;
}

View File

@ -0,0 +1,73 @@
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include "scriptengine/AvHLUAUtil.h"
#include "scriptengine/AvHLUA.h"
extern AvHLUA *gLUA;
/*
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void UTIL_LUATablePair(char *key, const char *value)
{
lua_pushstring(gLUA->mGlobalContext, key);
lua_pushstring(gLUA->mGlobalContext, value);
lua_settable(gLUA->mGlobalContext, -3);
}
void UTIL_LUATablePair(char *key, lua_Number value)
{
lua_pushstring(gLUA->mGlobalContext, key);
lua_pushnumber(gLUA->mGlobalContext, value);
lua_settable(gLUA->mGlobalContext, -3);
}
void UTIL_LUATablePair(char *key, bool value)
{
lua_pushstring(gLUA->mGlobalContext, key);
lua_pushboolean(gLUA->mGlobalContext, value);
lua_settable(gLUA->mGlobalContext, -3);
}
void UTIL_LUATablePair(char *key, lua_CFunction function)
{
lua_pushstring(gLUA->mGlobalContext, key);
lua_pushcfunction(gLUA->mGlobalContext, function);
lua_settable(gLUA->mGlobalContext, -3);
}
*/
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void UTIL_LUARegisterObject(lua_State *L, const luaL_reg *mainmethods, const luaL_reg *metamethods, char *objName)
{
lua_pushstring(L, objName);
int methods = newtable(L);
int metatable = newtable(L);
lua_pushliteral(L, "__index");
lua_pushvalue(L, methods);
lua_settable(L, metatable);
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, methods);
lua_settable(L, metatable);
luaL_openlib(L, 0, metamethods, 0);
luaL_openlib(L, 0, mainmethods, 1);
lua_settable(L, LUA_GLOBALSINDEX);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AvHLUA_OnError(const char *errorMsg)
{
std::string msg;
#ifdef AVH_CLIENT
msg = "[LUA CLIENT] Error: ";
msg += errorMsg;
msg += "\n";
gEngfuncs.pfnConsolePrint(msg.c_str());
#else
msg += "[LUA] Error: ";
msg += errorMsg;
msg += "\n";
ALERT(at_console, UTIL_VarArgs("%s", msg.c_str()));
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef AVHLUAUTIL_H
#define AVHLUAUTIL_H
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#define newtable(L) (lua_newtable(L), lua_gettop(L))
/*
void UTIL_LUATablePair(char *key, const char *value);
void UTIL_LUATablePair(char *key, lua_Number value);
void UTIL_LUATablePair(char *key, bool value);
void UTIL_LUATablePair(char *key, lua_CFunction function);
*/
void UTIL_LUARegisterObject(lua_State *L, const luaL_reg *mainmethods, const luaL_reg *metamethods, char *objName);
void AvHLUA_OnError(const char *errorMsg);
#define AvHLUA_Pcall(L, a, b) \
if (lua_pcall(L, a, b, 0)) \
{ \
AvHLUA_OnError(lua_tostring(L, -1)); \
}
#endif