NS/main/source/mod/AvHScriptServer.cpp~
2014-12-16 14:36:27 +01:00

588 lines
14 KiB
C++

//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
//
// The copyright to the contents herein is the property of Charles G. Cleveland.
// The contents may be used and/or copied only with the written permission of
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: AvHScriptServer.cpp $
// $Date: 2002/07/24 18:45:42 $
//
//-------------------------------------------------------------------------------
// $Log: AvHScriptServer.cpp,v $
// Revision 1.3 2002/07/24 18:45:42 Flayra
// - Linux and scripting changes
//
// Revision 1.2 2002/06/25 18:15:52 Flayra
// - Some enhancements and bugfixes for tutorial
//
// Revision 1.1 2002/05/23 02:33:20 Flayra
// - Post-crash checkin. Restored @Backup from around 4/16. Contains changes for last four weeks of development.
//
//===============================================================================
#include "../util/nowarnings.h"
#include "dlls/extdll.h"
#include "dlls/util.h"
#include "dlls/cbase.h"
#include "dlls/player.h"
#include "dlls/weapons.h"
#include "AvHScriptManager.h"
#include "AvHGamerules.h"
#include "../util/Checksum.h"
#include "../util/STLUtil.h"
#ifdef USE_LUA
extern "C" {
#include <lua.h>
}
static int errormessage(lua_State* inState)
{
const char *s = lua_tostring(inState, 1);
if (s == NULL) s = "(no message)";
char theErrorMessage[2048];
sprintf(theErrorMessage, "Script error: %s\n", s);
//fprintf(stderr, "error: %s\n", s);
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, theErrorMessage);
return 0;
}
//static int execute(lua_State* inState)
//{
// // Lame hook to call into server tick
// int theNumServerTicks = GetGameRules()->GetServerTick();
//
// lua_getglobal(inState, "serverTick");
// lua_pushnumber(inState, theNumServerTicks);
// lua_call(inState, 1, 0);
//
// return 0;
//}
/* a simple "print". based on the code in lbaselib.c */
static int print(lua_State* inState)
{
int n = lua_gettop(inState);
int i;
string theString;
for (i=1; i<=n; i++)
{
if (i>1) theString = "\t";
if (lua_isstring(inState, i))
theString += string(lua_tostring(inState, i));
else
{
char theBuffer[512];
sprintf(theBuffer, "%s:%p",lua_typename(inState, lua_type(inState, i)),lua_topointer(inState,i));
theString += string(theBuffer);
}
}
//theString += string("\n");
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, theString.c_str());
return 0;
}
// inEntityIndex, returns x, y, z
static int getPos(lua_State* inState)
{
int theNumReturned = 0;
// Get entity index
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
// Return it's angle
lua_pushnumber(inState, theEntity->pev->origin.x);
lua_pushnumber(inState, theEntity->pev->origin.y);
lua_pushnumber(inState, theEntity->pev->origin.z);
theNumReturned = 3;
}
}
return theNumReturned;
}
// inEntityIndex, x, y, z
static int setPos(lua_State* inState)
{
// Get entity index
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
// Set it's position
float theX = lua_tonumber(inState, 2);
float theY = lua_tonumber(inState, 3);
float theZ = lua_tonumber(inState, 4);
theEntity->pev->origin = vec3_t(theX, theY, theZ);
}
}
// Return true or false
return 0;
}
// inEntityIndex, returns yaw, pitch, roll
static int getAngles(lua_State* inState)
{
int theNumReturned = 0;
// Get entity index
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
// Return it's angle
lua_pushnumber(inState, theEntity->pev->angles.x);
lua_pushnumber(inState, theEntity->pev->angles.y);
lua_pushnumber(inState, theEntity->pev->angles.z);
theNumReturned = 3;
}
}
return theNumReturned;
}
// string inEntityName
static int getEntityIndexWithName(lua_State* inState)
{
// Get entity name
int theEntityIndex = -1;
const char* theEntityName = lua_tostring(inState, 1);
if(theEntityName)
{
CBaseEntity* theEntity = UTIL_FindEntityByTargetname(NULL, theEntityName);
if(theEntity)
{
theEntityIndex = theEntity->entindex();
}
}
lua_pushnumber(inState, theEntityIndex);
return 1;
}
// string targetName, int entityIndexActivator, int entityIndexCaller, useType, value
static int fireTargets(lua_State* inState)
{
int theNumArgs = lua_gettop(inState);
if(theNumArgs == 5)
{
const char* theTargetName = lua_tostring(inState, 1);
if(theTargetName)
{
int theActivatorIndex = lua_tonumber(inState, 2);
int theCallerIndex = lua_tonumber(inState, 3);
int theIntUseType = lua_tonumber(inState, 4);
float theValue = lua_tonumber(inState, 5);
// Trim to valid use types
theIntUseType = min(max(theIntUseType, 0), 3);
// Lookup entity indices (it's OK if either of these return NULL)
CBaseEntity* theActivatorEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theActivatorIndex));
CBaseEntity* theCallerEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theCallerIndex));
USE_TYPE theUseType = USE_TYPE(theIntUseType);
FireTargets(theTargetName, theActivatorEntity, theCallerEntity, theUseType, theValue);
}
}
return 0;
}
// inEntityIndex, yaw, pitch, roll
static int setAngles(lua_State* inState)
{
bool theSuccess = false;
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
// Return it's angle
theEntity->pev->angles.x = lua_tonumber(inState, 2);
theEntity->pev->angles.y = lua_tonumber(inState, 3);
theEntity->pev->angles.z = lua_tonumber(inState, 4);
theEntity->pev->fixangle = TRUE;
theSuccess = true;
}
}
lua_pushnumber(inState, theSuccess);
return 1;
}
// int inEntityIndex, returns success, health
static int getHealth(lua_State* inState)
{
bool theSuccess = false;
float theHealth = -1;
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
theHealth = theEntity->pev->health;
theSuccess = true;
}
}
lua_pushnumber(inState, theSuccess);
lua_pushnumber(inState, theHealth);
return 2;
}
// int inEntityIndex, int inHealth
static int setHealth(lua_State* inState)
{
bool theSuccess = false;
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
int theHealth = lua_tonumber(inState, 2);
theEntity->pev->health = theHealth;
theSuccess = true;
}
}
lua_pushnumber(inState, theSuccess);
return 1;
}
// int inEntityIndex, returns success, team
static int getTeam(lua_State* inState)
{
bool theSuccess = false;
int theTeam = 0;
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
theTeam = theEntity->pev->team;
theSuccess = true;
}
}
lua_pushnumber(inState, theSuccess);
lua_pushnumber(inState, theTeam);
return 2;
}
// takes filename, returns whether errors were encountered, returns whether checksums are identical or not
static int compareWorldChecksum(lua_State* inState)
{
bool theSuccess = false;
bool theChecksumsAreEqual = false;
const char* theFileName = lua_tostring(inState, 1);
Checksum theOldChecksum;
theSuccess = theOldChecksum.ReadFromFile(theFileName);
Checksum theNewChecksum;
GetGameRules()->ComputeWorldChecksum(theNewChecksum);
if(theSuccess)
{
StringList theErrors;
theChecksumsAreEqual = theNewChecksum.Compare(theOldChecksum, theErrors);
}
// Return function success
lua_pushnumber(inState, theSuccess);
// Return checksums are equal
lua_pushnumber(inState, theChecksumsAreEqual);
return 2;
}
// takes filename, returns success
static int saveWorldChecksum(lua_State* inState)
{
bool theSuccess = false;
Checksum theChecksum;
GetGameRules()->ComputeWorldChecksum(theChecksum);
const char* theFileName = lua_tostring(inState, 1);
theSuccess = theChecksum.SaveToFile(theFileName);
// Return success
lua_pushnumber(inState, theSuccess);
return 1;
}
// int inEntityID, string itemName
static int giveNamedItem(lua_State* inState)
{
// Get entity index
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity);
if(thePlayer)
{
const char* theItemName = lua_tostring(inState, 2);
if(theItemName != NULL)
{
thePlayer->GiveNamedItem(theItemName);
}
}
}
}
return 0;
}
// int destination, string formattedString, returns success
static int printMessage(lua_State* inState)
{
bool theSuccess = false;
int theNumArgs = lua_gettop(inState);
if(theNumArgs == 2)
{
int theMessageDest = lua_tonumber(inState, 1);
ALERT_TYPE theAlertType = ALERT_TYPE(min(max(theMessageDest, 0), 5));
const char* theFormattedCString = lua_tostring(inState, 2);
if(theFormattedCString)
{
char theCharArray[kMaxStrLen];
strcpy(theCharArray, theFormattedCString);
ALERT(theAlertType, theCharArray);
theSuccess = true;
}
}
lua_pushnumber(inState, theSuccess);
return 1;
}
// int thePlayerIndex, string string (in titles.txt), returns success
static int sendMessage(lua_State* inState)
{
bool theSuccess = false;
int theNumArgs = lua_gettop(inState);
if(theNumArgs == 2)
{
int thePlayerIndex = lua_tonumber(inState, 1);
const char* theCString = lua_tostring(inState, 2);
if(theCString)
{
char theCharArray[kMaxStrLen];
strcpy(theCharArray, theCString);
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(thePlayerIndex));
if(theEntity)
{
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity);
if(thePlayer)
{
thePlayer->SendMessage(theCString, TOOLTIP);
theSuccess = true;
}
}
}
}
lua_pushnumber(inState, theSuccess);
return 1;
}
// nothing passed in, nothing returned
static int resetWorld(lua_State* inState)
{
GetGameRules()->DeleteAndResetEntities();
return 0;
}
// plays a precached sound
static int playSound(lua_State* inState)
{
int theNumArgs = lua_gettop(inState);
if(theNumArgs >= 2)
{
int theEntIndex = lua_tonumber(inState, 1);
const char* theSoundName = lua_tostring(inState, 2);
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theEntIndex));
if(theEntity)
{
float theVolume = 1.0f;
if(theNumArgs >= 3)
{
theVolume = lua_tonumber(inState, 3);
}
float theAttenuation = ATTN_NORM;
if(theNumArgs >= 4)
{
theAttenuation = lua_tonumber(inState, 4);
}
EMIT_SOUND(theEntity->edict(), CHAN_AUTO, theSoundName, theVolume, theAttenuation);
}
}
return 0;
}
// int playerIndex, string command
static int serverCommand(lua_State* inState)
{
// Get entity index
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity);
if(thePlayer)
{
const char* theServerCommand = lua_tostring(inState, 2);
if(theServerCommand != NULL)
{
GetGameRules()->ClientCommand(thePlayer, theServerCommand);
}
}
}
}
return 0;
}
static int runClientScript(lua_State* inState)
{
// Get entity index
int theIndex = lua_tonumber(inState, 1);
if(theIndex > 0)
{
// Look it up
CBaseEntity* theEntity = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(theIndex));
if(theEntity)
{
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theEntity);
if(thePlayer)
{
const char* theScript = lua_tostring(inState, 2);
if(theScript != NULL)
{
thePlayer->RunClientScript(theScript);
}
}
}
}
return 0;
}
static int setServerVariable(lua_State* inState)
{
// Get variable name
const char* theVariableName = lua_tostring(inState, 1);
if(theVariableName)
{
float theValue = lua_tonumber(inState, 2);
CVAR_SET_FLOAT(theVariableName, theValue);
}
return 0;
}
#endif
void AvHScriptInstance::InitServer()
{
#ifdef USE_LUA
//lua_register(this->mState, LUA_ERRORMESSAGE, errormessage);
//lua_register(this->mState, "execute", execute);
lua_register(this->mState, "print", print);
lua_register(this->mState, "getAngles", getAngles);
lua_register(this->mState, "setAngles", setAngles);
lua_register(this->mState, "getEntityIndexWithName", getEntityIndexWithName);
lua_register(this->mState, "fireTargets", fireTargets);
lua_register(this->mState, "getPos", getPos);
lua_register(this->mState, "setPos", setPos);
lua_register(this->mState, "getHealth", getHealth);
lua_register(this->mState, "setHealth", setHealth);
lua_register(this->mState, "getTeam", getTeam);
lua_register(this->mState, "compareWorldChecksum", compareWorldChecksum);
lua_register(this->mState, "saveWorldChecksum", saveWorldChecksum);
lua_register(this->mState, "printMessage", printMessage);
lua_register(this->mState, "sendMessage", sendMessage);
lua_register(this->mState, "giveNamedItem", giveNamedItem);
lua_register(this->mState, "playSound", playSound);
lua_register(this->mState, "resetWorld", resetWorld);
lua_register(this->mState, "serverCommand", serverCommand);
lua_register(this->mState, "runClientScript", runClientScript);
lua_register(this->mState, "setServerVariable", setServerVariable);
#endif
}