luaui.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 2,574 行 · 第 1/5 页
CPP
2,574 行
#include "StdAfx.h"
// LuaUI.cpp: implementation of the CLuaUI class.
//
//////////////////////////////////////////////////////////////////////
#include "LuaUI.h"
#include <set>
#include <cctype>
#include <SDL_keysym.h>
#include <SDL_mouse.h>
#include <SDL_timer.h>
using namespace std;
#include "LuaInclude.h"
#include "Lua/LuaCallInHandler.h"
#include "Lua/LuaUtils.h"
#include "Lua/LuaConstGL.h"
#include "Lua/LuaConstCMD.h"
#include "Lua/LuaConstCMDTYPE.h"
#include "Lua/LuaConstGame.h"
#include "Lua/LuaSyncedRead.h"
#include "Lua/LuaUnsyncedCall.h"
#include "Lua/LuaUnsyncedCtrl.h"
#include "Lua/LuaUnsyncedRead.h"
#include "Lua/LuaFeatureDefs.h"
#include "Lua/LuaUnitDefs.h"
#include "Lua/LuaWeaponDefs.h"
#include "Lua/LuaScream.h"
#include "Lua/LuaOpenGL.h"
#include "Lua/LuaVFS.h"
#include "ExternalAI/GlobalAIHandler.h"
#include "ExternalAI/Group.h"
#include "ExternalAI/GroupHandler.h"
#include "Sim/Units/CommandAI/Command.h"
#include "Game/Camera.h"
#include "Game/Camera/CameraController.h"
#include "Game/Game.h"
#include "Game/GameHelper.h"
#include "Game/PlayerRoster.h"
#include "Game/SelectedUnits.h"
#include "Game/Team.h"
#include "Game/UI/CommandColors.h"
#include "Game/UI/CursorIcons.h"
#include "Game/UI/GuiHandler.h"
#include "Game/UI/InfoConsole.h"
#include "Game/UI/KeyCodes.h"
#include "Game/UI/KeySet.h"
#include "Game/UI/KeyBindings.h"
#include "Game/UI/MiniMap.h"
#include "Game/UI/MouseHandler.h"
#include "Map/ReadMap.h"
#include "Map/BaseGroundDrawer.h"
#include "Rendering/InMapDraw.h"
#include "Rendering/FontTexture.h"
#include "Sim/Misc/LosHandler.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/UnitDef.h"
#include "Sim/Units/UnitHandler.h"
#include "Sim/Units/UnitDefHandler.h"
#include "System/LogOutput.h"
#include "System/NetProtocol.h"
#include "System/FileSystem/FileHandler.h"
#include "System/FileSystem/VFSHandler.h"
#include "System/Platform/ConfigHandler.h"
#include "System/Platform/FileSystem.h"
#if (LUA_VERSION_NUM < 500)
# define LUA_OPEN_LIB(L, lib) lib(L)
#else
# define LUA_OPEN_LIB(L, lib) \
lua_pushcfunction((L), lib); \
lua_pcall((L), 0, 0, 0);
#endif
extern Uint8 *keys;
extern GLfloat LightDiffuseLand[];
extern GLfloat LightAmbientLand[];
CLuaUI* luaUI = NULL;
const int CMD_INDEX_OFFSET = 1; // starting index for command descriptions
/******************************************************************************/
/******************************************************************************/
void CLuaUI::LoadHandler()
{
if (luaUI) {
return;
}
SAFE_NEW CLuaUI();
if (luaUI->L == NULL) {
delete luaUI;
}
}
void CLuaUI::FreeHandler()
{
delete luaUI;
}
/******************************************************************************/
CLuaUI::CLuaUI()
: CLuaHandle("LuaUI", LUA_HANDLE_ORDER_UI, true, NULL)
{
luaUI = this;
if (L == NULL) {
return;
}
UpdateTeams();
haveShockFront = false;
shockFrontMinArea = 0.0f;
shockFrontMinPower = 0.0f;
shockFrontDistAdj = 100.0f;
haveWorldTooltip = false;
haveMapDrawCmd = false;
const string code = LoadFile("gui.lua");
if (code.empty()) {
KillLua();
return;
}
// load the standard libraries
LUA_OPEN_LIB(L, luaopen_base);
LUA_OPEN_LIB(L, luaopen_io);
LUA_OPEN_LIB(L, luaopen_os);
LUA_OPEN_LIB(L, luaopen_math);
LUA_OPEN_LIB(L, luaopen_table);
LUA_OPEN_LIB(L, luaopen_string);
LUA_OPEN_LIB(L, luaopen_package);
LUA_OPEN_LIB(L, luaopen_debug);
// remove a few dangerous calls
lua_getglobal(L, "io");
lua_pushstring(L, "popen"); lua_pushnil(L); lua_rawset(L, -3);
lua_pop(L, 1);
lua_getglobal(L, "os");
lua_pushstring(L, "exit"); lua_pushnil(L); lua_rawset(L, -3);
lua_pushstring(L, "execute"); lua_pushnil(L); lua_rawset(L, -3);
lua_pop(L, 1);
lua_pushvalue(L, LUA_GLOBALSINDEX);
AddBasicCalls(); // into Global
lua_pushstring(L, "Script");
lua_rawget(L, -2);
LuaPushNamedCFunc(L, "UpdateCallIn", CallOutUnsyncedUpdateCallIn);
lua_pop(L, 1);
// load the spring libraries
if (!LoadCFunctions(L) ||
!AddEntriesToTable(L, "VFS", LuaVFS::PushUnsynced) ||
!AddEntriesToTable(L, "UnitDefs", LuaUnitDefs::PushEntries) ||
!AddEntriesToTable(L, "WeaponDefs", LuaWeaponDefs::PushEntries) ||
!AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries) ||
!AddEntriesToTable(L, "Script", LuaUnsyncedCall::PushEntries) ||
!AddEntriesToTable(L, "Script", LuaScream::PushEntries) ||
!AddEntriesToTable(L, "Spring", LuaSyncedRead::PushEntries) ||
!AddEntriesToTable(L, "Spring", LuaUnsyncedCtrl::PushEntries) ||
!AddEntriesToTable(L, "Spring", LuaUnsyncedRead::PushEntries) ||
!AddEntriesToTable(L, "gl", LuaOpenGL::PushEntries) ||
!AddEntriesToTable(L, "GL", LuaConstGL::PushEntries) ||
!AddEntriesToTable(L, "Game", LuaConstGame::PushEntries) ||
!AddEntriesToTable(L, "CMD", LuaConstCMD::PushEntries) ||
!AddEntriesToTable(L, "CMDTYPE", LuaConstCMDTYPE::PushEntries)) {
KillLua();
return;
}
lua_settop(L, 0);
if (!LoadCode(code, "gui.lua")) {
KillLua();
return;
}
// register for call-ins
luaCallIns.AddHandle(this);
// update extra call-ins
UnsyncedUpdateCallIn("WorldTooltip");
UnsyncedUpdateCallIn("MapDrawCmd");
lua_settop(L, 0);
}
CLuaUI::~CLuaUI()
{
if (L != NULL) {
Shutdown();
KillLua();
}
luaUI = NULL;
}
string CLuaUI::LoadFile(const string& filename) const
{
const char* accessMode = SPRING_VFS_RAW;
CFileHandler lockFile("gamedata/LockLuaUI.txt", SPRING_VFS_MOD);
if (lockFile.FileExists()) {
if (!CLuaHandle::GetDevMode()) {
logOutput.Print("This mod has locked LuaUI access");
accessMode = SPRING_VFS_MOD;
} else {
logOutput.Print("Bypassing this mod's LuaUI access lock");
accessMode = SPRING_VFS_RAW SPRING_VFS_MOD;
}
}
CFileHandler f(filename, accessMode);
string code;
if (!f.LoadStringData(code)) {
code.clear();
}
return code;
}
bool CLuaUI::HasCallIn(const string& name)
{
if (L == NULL) {
return false;
}
// never allow these calls
if (name == "Explosion") {
return false;
}
lua_getglobal(L, name.c_str());
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
return false;
}
lua_pop(L, 1);
return true;
}
bool CLuaUI::UnsyncedUpdateCallIn(const string& name)
{
// never allow this call-in
if (name == "Explosion") {
return false;
}
if (name == "WorldTooltip") {
haveWorldTooltip = HasCallIn(name);
return true;
}
if (name == "MapDrawCmd") {
haveMapDrawCmd = HasCallIn(name);
return true;
}
if (HasCallIn(name)) {
luaCallIns.InsertCallIn(this, name);
} else {
luaCallIns.RemoveCallIn(this, name);
}
return true;
}
void CLuaUI::UpdateTeams()
{
if (luaUI) {
luaUI->fullCtrl = gs->godMode;
luaUI->ctrlTeam = gs->godMode ? AllAccessTeam :
(gu->spectating ? NoAccessTeam : gu->myTeam);
luaUI->fullRead = gu->spectatingFullView;
luaUI->readTeam = luaUI->fullRead ? AllAccessTeam : gu->myTeam;
luaUI->readAllyTeam = luaUI->fullRead ? AllAccessTeam : gu->myAllyTeam;
luaUI->selectTeam = gu->spectatingFullSelect ? AllAccessTeam : gu->myTeam;
}
}
/******************************************************************************/
/******************************************************************************/
bool CLuaUI::LoadCFunctions(lua_State* L)
{
lua_newtable(L);
#define REGISTER_LUA_CFUNC(x) \
lua_pushstring(L, #x); \
lua_pushcfunction(L, x); \
lua_rawset(L, -3)
REGISTER_LUA_CFUNC(SendCommands);
REGISTER_LUA_CFUNC(GiveOrder);
REGISTER_LUA_CFUNC(GiveOrderToUnit);
REGISTER_LUA_CFUNC(GiveOrderToUnitMap);
REGISTER_LUA_CFUNC(GiveOrderToUnitArray);
REGISTER_LUA_CFUNC(GiveOrderArrayToUnitMap);
REGISTER_LUA_CFUNC(GiveOrderArrayToUnitArray);
REGISTER_LUA_CFUNC(SendLuaUIMsg);
REGISTER_LUA_CFUNC(SendLuaCobMsg);
REGISTER_LUA_CFUNC(SendLuaGaiaMsg);
REGISTER_LUA_CFUNC(SendLuaRulesMsg);
REGISTER_LUA_CFUNC(GetFPS);
REGISTER_LUA_CFUNC(SetActiveCommand);
REGISTER_LUA_CFUNC(GetActiveCommand);
REGISTER_LUA_CFUNC(GetDefaultCommand);
REGISTER_LUA_CFUNC(GetActiveCmdDescs);
REGISTER_LUA_CFUNC(GetActiveCmdDesc);
REGISTER_LUA_CFUNC(GetCmdDescIndex);
REGISTER_LUA_CFUNC(GetBuildFacing);
REGISTER_LUA_CFUNC(GetBuildSpacing);
REGISTER_LUA_CFUNC(GetGatherMode);
REGISTER_LUA_CFUNC(GetActivePage);
REGISTER_LUA_CFUNC(ForceLayoutUpdate);
REGISTER_LUA_CFUNC(GetMouseState);
REGISTER_LUA_CFUNC(GetMouseMiniMapState);
REGISTER_LUA_CFUNC(GetMouseStartPosition);
REGISTER_LUA_CFUNC(GetMouseCursor);
REGISTER_LUA_CFUNC(SetMouseCursor);
REGISTER_LUA_CFUNC(WarpMouse);
REGISTER_LUA_CFUNC(SetCameraOffset);
REGISTER_LUA_CFUNC(SetShockFrontFactors);
REGISTER_LUA_CFUNC(SetLosViewColors);
REGISTER_LUA_CFUNC(GetKeyState);
REGISTER_LUA_CFUNC(GetModKeyState);
REGISTER_LUA_CFUNC(GetPressedKeys);
REGISTER_LUA_CFUNC(GetInvertQueueKey);
REGISTER_LUA_CFUNC(GetKeyCode);
REGISTER_LUA_CFUNC(GetKeySymbol);
REGISTER_LUA_CFUNC(GetKeyBindings);
REGISTER_LUA_CFUNC(GetActionHotKeys);
REGISTER_LUA_CFUNC(GetConsoleBuffer);
REGISTER_LUA_CFUNC(GetCurrentTooltip);
REGISTER_LUA_CFUNC(GetConfigInt);
REGISTER_LUA_CFUNC(SetConfigInt);
REGISTER_LUA_CFUNC(GetConfigString);
REGISTER_LUA_CFUNC(SetConfigString);
REGISTER_LUA_CFUNC(CreateDir);
REGISTER_LUA_CFUNC(MakeFont);
REGISTER_LUA_CFUNC(SetUnitDefIcon);
REGISTER_LUA_CFUNC(GetMyAllyTeamID);
REGISTER_LUA_CFUNC(GetMyTeamID);
REGISTER_LUA_CFUNC(GetMyPlayerID);
REGISTER_LUA_CFUNC(GetGroupList);
REGISTER_LUA_CFUNC(GetSelectedGroup);
REGISTER_LUA_CFUNC(GetGroupAIName);
REGISTER_LUA_CFUNC(GetGroupAIList);
REGISTER_LUA_CFUNC(GetUnitGroup);
REGISTER_LUA_CFUNC(SetUnitGroup);
REGISTER_LUA_CFUNC(GetGroupUnits);
REGISTER_LUA_CFUNC(GetGroupUnitsSorted);
REGISTER_LUA_CFUNC(GetGroupUnitsCounts);
REGISTER_LUA_CFUNC(GetGroupUnitsCount);
REGISTER_LUA_CFUNC(SetShareLevel);
REGISTER_LUA_CFUNC(ShareResources);
REGISTER_LUA_CFUNC(MarkerAddPoint);
REGISTER_LUA_CFUNC(MarkerAddLine);
REGISTER_LUA_CFUNC(MarkerErasePosition);
REGISTER_LUA_CFUNC(GetPlayerTraffic);
lua_setglobal(L, "Spring");
return true;
}
/******************************************************************************/
/******************************************************************************/
void CLuaUI::Shutdown()
{
static const LuaHashString cmdStr("Shutdown");
if (!cmdStr.GetGlobalFunc(L)) {
return;
}
// call the routine
RunCallIn(cmdStr, 0, 0);
return;
}
void CLuaUI::GameFrame(int frameNumber)
{
static const LuaHashString cmdStr("GameFrame");
if (!cmdStr.GetGlobalFunc(L)) {
return;
}
lua_pushnumber(L, frameNumber);
// call the routine
RunCallIn(cmdStr, 1, 0);
return;
}
bool CLuaUI::ConfigCommand(const string& command)
{
static const LuaHashString cmdStr("ConfigureLayout");
if (!cmdStr.GetGlobalFunc(L)) {
return true; // the call is not defined
}
lua_pushstring(L, command.c_str());
// call the routine
if (!RunCallIn(cmdStr, 1, 0)) {
return false;
}
return true;
}
bool CLuaUI::AddConsoleLines()
{
CInfoConsole* ic = game->infoConsole;
if (ic == NULL) {
return true;
}
vector<CInfoConsole::RawLine> lines;
ic->GetNewRawLines(lines);
const int count = (int)lines.size();
for (int i = 0; i < count; i++) {
const CInfoConsole::RawLine& rl = lines[i];
static const LuaHashString cmdStr("AddConsoleLine");
if (!cmdStr.GetGlobalFunc(L)) {
return true; // the call is not defined
}
lua_pushstring(L, rl.text.c_str());
lua_pushnumber(L, rl.zone);
// call the function
if (!RunCallIn(cmdStr, 2, 0)) {
return false;
}
}
return true;
}
bool CLuaUI::CommandNotify(const Command& cmd)
{
static const LuaHashString cmdStr("CommandNotify");
if (!cmdStr.GetGlobalFunc(L)) {
return false; // the call is not defined
}
// push the command id
lua_pushnumber(L, cmd.id);
// push the params list
lua_newtable(L);
for (int p = 0; p < (int)cmd.params.size(); p++) {
lua_pushnumber(L, p + 1);
lua_pushnumber(L, cmd.params[p]);
lua_rawset(L, -3);
}
// push the options table
lua_newtable(L);
HSTR_PUSH_NUMBER(L, "coded", cmd.options);
HSTR_PUSH_BOOL(L, "alt", !!(cmd.options & ALT_KEY));
HSTR_PUSH_BOOL(L, "ctrl", !!(cmd.options & CONTROL_KEY));
HSTR_PUSH_BOOL(L, "shift", !!(cmd.options & SHIFT_KEY));
HSTR_PUSH_BOOL(L, "right", !!(cmd.options & RIGHT_MOUSE_KEY));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?