aboutsummaryrefslogtreecommitdiffstats
path: root/q3radiant/BrushScript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'q3radiant/BrushScript.cpp')
-rwxr-xr-xq3radiant/BrushScript.cpp672
1 files changed, 672 insertions, 0 deletions
diff --git a/q3radiant/BrushScript.cpp b/q3radiant/BrushScript.cpp
new file mode 100755
index 0000000..6a0614a
--- /dev/null
+++ b/q3radiant/BrushScript.cpp
@@ -0,0 +1,672 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+
+This file is part of Quake III Arena source code.
+
+Quake III Arena source code is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the License,
+or (at your option) any later version.
+
+Quake III Arena source code is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Foobar; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+// BrushScript stuff
+//
+#include "stdafx.h"
+#include "qe3.h"
+#include "BSInput.h"
+#include "DialogInfo.h"
+
+
+//
+struct SVariableDef
+{
+ CString m_strName;
+ CString m_strInput;
+ float m_fValue;
+};
+
+struct SVecVariableDef
+{
+ CString m_strName;
+ CString m_strInput;
+ vec3_t m_vValue;
+};
+
+
+
+const int MAX_VARIABLES = 64;
+
+brush_t* g_pHold1 = NULL;
+brush_t* g_pHold2 = NULL;
+brush_t* g_pHold3 = NULL;
+bool g_bRotateAroundSelection;
+int g_nVariableCount;
+int g_nVecVariableCount;
+int g_nLoopCounter;
+float g_fDefault = 9999.9;
+vec3_t g_vDefault;
+bool g_bStartLoop;
+char* g_pLooper;
+bool g_bKeepGoing;
+
+SVariableDef g_Variables[MAX_VARIABLES];
+SVecVariableDef g_VecVariables[MAX_VARIABLES];
+
+void InitForScriptRun()
+{
+ g_pHold1 = NULL;
+ g_pHold2 = NULL;
+ g_pHold3 = NULL;
+ g_bRotateAroundSelection = true;
+ g_nVariableCount = 0;
+ g_nVecVariableCount = 0;
+ g_nLoopCounter = 0;
+ g_bStartLoop = false;
+ g_pLooper = NULL;
+ g_bKeepGoing = true;
+}
+
+void AddVariable(const char* pName, float fValue, const char* pInput = NULL)
+{
+ if (g_nVariableCount < MAX_VARIABLES)
+ {
+ g_Variables[g_nVariableCount].m_strName = pName;
+ g_Variables[g_nVariableCount].m_strName.MakeLower();
+ g_Variables[g_nVariableCount].m_fValue = fValue;
+ if (pInput)
+ g_Variables[g_nVariableCount].m_strInput = pInput;
+ g_nVariableCount++;
+ }
+ else
+ g_pParentWnd->MessageBox("Maximum script variable limit reached!");
+}
+
+float VariableValue(const char* pName)
+{
+ CString strName = pName;
+ strName.MakeLower();
+ for (int n = 0; n < g_nVariableCount; n++)
+ {
+ if (strName == g_Variables[n].m_strName)
+ return g_Variables[n].m_fValue;
+ }
+ //strName.Format("Reference to non-existant varirable %s", pName);
+ //g_pParentWnd->MessageBox(strName);
+ return g_fDefault;
+}
+
+void SetVariableValue(const char* pName, float fValue)
+{
+ CString strName = pName;
+ strName.MakeLower();
+ for (int n = 0; n < g_nVariableCount; n++)
+ {
+ if (strName == g_Variables[n].m_strName)
+ g_Variables[n].m_fValue = fValue;
+ }
+}
+
+
+
+void AddVectorVariable(const char* pName, const char* pInput = NULL)
+{
+ if (g_nVecVariableCount < MAX_VARIABLES)
+ {
+ g_VecVariables[g_nVecVariableCount].m_strName = pName;
+ g_VecVariables[g_nVecVariableCount].m_strName.MakeLower();
+ if (pInput)
+ g_VecVariables[g_nVariableCount].m_strInput = pInput;
+ g_nVecVariableCount++;
+ }
+ else
+ g_pParentWnd->MessageBox("Maximum script variable limit reached!");
+}
+
+void VectorVariableValue(const char* pName, vec3_t& v)
+{
+ CString strName = pName;
+ strName.MakeLower();
+ for (int n = 0; n < g_nVecVariableCount; n++)
+ {
+ if (strName == g_VecVariables[n].m_strName)
+ {
+ VectorCopy(g_VecVariables[n].m_vValue, v);
+ return;
+ }
+ }
+ strName.Format("Reference to non-existant variable %s", pName);
+ g_pParentWnd->MessageBox(strName);
+}
+
+void SetVectorVariableValue(const char* pName, vec3_t v)
+{
+ CString strName = pName;
+ strName.MakeLower();
+ for (int n = 0; n < g_nVecVariableCount; n++)
+ {
+ if (strName == g_VecVariables[n].m_strName)
+ VectorCopy(v, g_VecVariables[n].m_vValue);
+ }
+}
+
+
+
+
+
+// commands
+//
+// _CopySelected(nHoldPos)
+// copies selected brush to hold spot 1, 2 or 3
+//
+// _MoveSelected(x, y, z)
+// moves selected brush by coords provided
+//
+// _RotateSelected(x, y, z)
+// rotates selected brush by coords provided
+//
+// _MoveHold(nHoldPos, x, y, z)
+// moves brush in hold pos by coords provided
+//
+// _RotateHold(nHoldPos, x, y, z)
+// rotates brush in hold pos by coords provided
+//
+// _CopyToMap(nHoldPos)
+// copies hold brush to map
+//
+// _CopyAndSelect(nHoldPos)
+// copies hold brush to map and selects it
+//
+// _Input(VarName1, ... VarNamennn)
+// inputs a list of values from the user
+//
+
+typedef void (PFNScript)(char*&);
+
+
+struct SBrushScript
+{
+ const char* m_pName;
+ PFNScript* m_pProc;
+};
+
+
+const char* GetParam(char*& pBuffer)
+{
+ static CString strParam;
+ bool bStringMode = false;
+
+ while (*pBuffer != NULL && isspace(*pBuffer)) // skip and whitespace
+ pBuffer++;
+
+ if (*pBuffer == '(') // if it's an opening paren, skip it
+ pBuffer++;
+
+ if (*pBuffer == '\"') // string ?
+ {
+ pBuffer++;
+ bStringMode = true;
+ }
+
+ strParam = "";
+
+ if (bStringMode)
+ {
+ while (*pBuffer != NULL && *pBuffer != '\"')
+ strParam += *pBuffer++;
+ }
+ else
+ {
+ while (*pBuffer != NULL && *pBuffer != ' ' && *pBuffer != ')' && *pBuffer != ',')
+ strParam += *pBuffer++;
+ }
+
+ if (*pBuffer != NULL) // skip last char
+ pBuffer++;
+
+ if (strParam.GetLength() > 0)
+ {
+ if (strParam.GetAt(0) == '$') // ? variable name
+ {
+ float f = VariableValue(strParam);
+ if (f != g_fDefault)
+ strParam.Format("%f", f);
+ }
+ }
+
+ return strParam;
+}
+
+brush_t* CopyBrush(brush_t* p)
+{
+ brush_t* pCopy = Brush_Clone(p);
+ //Brush_AddToList (pCopy, &active_brushes);
+ //Entity_LinkBrush (world_entity, pCopy);
+ Brush_Build(pCopy, false);
+ return pCopy;
+}
+
+
+void CopySelected(char*& pBuffer)
+{
+ // expects one param
+ CString strParam = GetParam(pBuffer);
+ int n = atoi(strParam);
+
+ brush_t* pCopy = NULL;
+ if (selected_brushes.next != &selected_brushes &&
+ selected_brushes.next->next == &selected_brushes)
+ pCopy = selected_brushes.next;
+
+ if (pCopy)
+ {
+ if (n == 1)
+ {
+ //if (g_pHold1)
+ //Brush_Free(g_pHold1);
+ g_pHold1 = CopyBrush(pCopy);
+ }
+ else if (n == 2)
+ {
+ //if (g_pHold2)
+ //Brush_Free(g_pHold2);
+ g_pHold2 = CopyBrush(pCopy);
+ }
+ else
+ {
+ //if (g_pHold3)
+ //Brush_Free(g_pHold3);
+ g_pHold3 = CopyBrush(pCopy);
+ }
+ }
+}
+
+void MoveSelected(char*& pBuffer)
+{
+ vec3_t v;
+ CString strParam = GetParam(pBuffer);
+ v[0] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[1] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[2] = atof(strParam);
+ Select_Move(v, false);
+ Sys_UpdateWindows(W_ALL);
+}
+
+void RotateSelected(char*& pBuffer)
+{
+ vec3_t v;
+
+ if (g_bRotateAroundSelection)
+ {
+ Select_GetTrueMid(v);
+ VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());
+ }
+
+ CString strParam = GetParam(pBuffer);
+ v[0] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[1] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[2] = atof(strParam);
+ for (int i = 0; i < 3; i++)
+ if (v[i] != 0.0)
+ Select_RotateAxis(i, v[i], false , true);
+ Sys_UpdateWindows(W_ALL);
+}
+
+void MoveHold(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ brush_t* pBrush = NULL;
+ int nHold = atoi(strParam);
+ if (nHold == 1)
+ pBrush = g_pHold1;
+ else if (nHold == 2)
+ pBrush = g_pHold2;
+ else
+ pBrush = g_pHold3;
+
+ if (pBrush)
+ {
+ vec3_t v;
+ strParam = GetParam(pBuffer);
+ v[0] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[1] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[2] = atof(strParam);
+ Brush_Move (pBrush, v, false);
+ }
+}
+
+void RotateHold(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ brush_t* pBrush = NULL;
+ int nHold = atoi(strParam);
+ if (nHold == 1)
+ pBrush = g_pHold1;
+ else if (nHold == 2)
+ pBrush = g_pHold2;
+ else
+ pBrush = g_pHold3;
+
+ if (pBrush)
+ {
+ vec3_t v;
+ strParam = GetParam(pBuffer);
+ v[0] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[1] = atof(strParam);
+ strParam = GetParam(pBuffer);
+ v[2] = atof(strParam);
+ for (int i = 0; i < 3; i++)
+ if (v[i] != 0.0)
+ Select_RotateAxis(i, v[i]);
+ }
+}
+
+void CopyToMap(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ brush_t* pBrush = NULL;
+ int nHold = atoi(strParam);
+ if (nHold == 1)
+ pBrush = g_pHold1;
+ else if (nHold == 2)
+ pBrush = g_pHold2;
+ else
+ pBrush = g_pHold3;
+
+ if (pBrush)
+ {
+ Brush_AddToList(pBrush, &active_brushes);
+ Entity_LinkBrush (world_entity, pBrush);
+ Brush_Build(pBrush, false);
+ Sys_UpdateWindows(W_ALL);
+ }
+}
+
+void CopyAndSelect(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ brush_t* pBrush = NULL;
+ int nHold = atoi(strParam);
+ if (nHold == 1)
+ pBrush = g_pHold1;
+ else if (nHold == 2)
+ pBrush = g_pHold2;
+ else
+ pBrush = g_pHold3;
+
+ if (pBrush)
+ {
+ Select_Deselect();
+ Brush_AddToList(pBrush, &active_brushes);
+ Entity_LinkBrush (world_entity, pBrush);
+ Brush_Build(pBrush, false);
+ Select_Brush(pBrush);
+ Sys_UpdateWindows(W_ALL);
+ }
+}
+
+void Input(char*& pBuffer)
+{
+ CBSInput dlg;
+ bool bGo = false;
+ for (int n = 0; n < g_nVariableCount; n++)
+ {
+ if (g_Variables[n].m_strInput.GetLength() > 0)
+ {
+ bGo = true;
+ if (n < 5)
+ {
+ switch (n)
+ {
+ case 0 : dlg.m_strField1 = g_Variables[n].m_strInput; break;
+ case 1 : dlg.m_strField2 = g_Variables[n].m_strInput; break;
+ case 2 : dlg.m_strField3 = g_Variables[n].m_strInput; break;
+ case 3 : dlg.m_strField4 = g_Variables[n].m_strInput; break;
+ case 4 : dlg.m_strField5 = g_Variables[n].m_strInput; break;
+ }
+ }
+ }
+ }
+ if (bGo)
+ {
+ if (dlg.DoModal() == IDOK)
+ {
+ for (int n = 0; n < g_nVariableCount; n++)
+ {
+ if (g_Variables[n].m_strInput.GetLength() > 0)
+ {
+ if (n < 5)
+ {
+ switch (n)
+ {
+ case 0 : g_Variables[n].m_fValue = dlg.m_fField1; break;
+ case 1 : g_Variables[n].m_fValue = dlg.m_fField2; break;
+ case 2 : g_Variables[n].m_fValue = dlg.m_fField3; break;
+ case 3 : g_Variables[n].m_fValue = dlg.m_fField4; break;
+ case 4 : g_Variables[n].m_fValue = dlg.m_fField5; break;
+ }
+ }
+ }
+ }
+ }
+ else g_bKeepGoing = false;
+ }
+}
+
+bool g_bWaiting;
+void _3DPointDone(bool b, int n)
+{
+ g_bWaiting = false;
+}
+
+void _3DPointInput(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ CString strParam2 = GetParam(pBuffer);
+ ShowInfoDialog(strParam2);
+ AddVectorVariable(strParam, strParam2);
+ g_bWaiting = true;
+ AcquirePath(2, &_3DPointDone);
+ while (g_bWaiting)
+ {
+ MSG msg;
+ if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ HideInfoDialog();
+ SetVectorVariableValue(strParam, g_PathPoints[0]);
+}
+
+void SetRotateOrigin(char*& pBuffer)
+{
+ vec3_t v;
+ CString strParam = GetParam(pBuffer);
+ VectorVariableValue(strParam, v);
+ VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());
+ g_bRotateAroundSelection = false;
+}
+
+void InputVar(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ CString strParam2 = GetParam(pBuffer);
+ AddVariable(strParam, 0.0, strParam2);
+}
+
+void LoopCount(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ g_nLoopCounter = atoi(strParam);
+ if (g_nLoopCounter == 0)
+ g_nLoopCounter = VariableValue(strParam);
+ if (g_nLoopCounter > 0)
+ g_pLooper = pBuffer;
+}
+
+void LoopRun(char*& pBuffer)
+{
+ if (g_bStartLoop == true)
+ {
+ g_nLoopCounter--;
+ if (g_nLoopCounter == 0)
+ {
+ g_bStartLoop = false;
+ GetParam(pBuffer);
+ }
+ else
+ pBuffer = g_pLooper;
+ }
+ else
+ {
+ if (g_pLooper && g_nLoopCounter > 0)
+ {
+ g_bStartLoop = true;
+ pBuffer = g_pLooper;
+ }
+ else
+ {
+ GetParam(pBuffer);
+ }
+ }
+}
+
+
+void ConfirmMessage(char*& pBuffer)
+{
+ CString strParam = GetParam(pBuffer);
+ if (g_pParentWnd->MessageBox(strParam, "Script Info", MB_OKCANCEL) == IDCANCEL)
+ g_bKeepGoing = false;
+}
+
+void Spherize(char*& pBuffer)
+{
+ g_bScreenUpdates = false;
+ for (int n = 0; n < 120; n += 36)
+ {
+ for (int i = 0; i < 360; i += 36)
+ {
+ Select_RotateAxis(0, i, false , true);
+ CSG_Subtract();
+ }
+ Select_RotateAxis(2, n, false , true);
+ }
+ g_bScreenUpdates = true;
+}
+
+void RunIt(char*& pBuffer);
+SBrushScript g_ScriptCmds[] =
+{
+ {"_CopySelected", &CopySelected},
+ {"_MoveSelected", &MoveSelected},
+ {"_RotateSelected", &RotateSelected},
+ {"_MoveHold", &MoveHold},
+ {"_RotateHold", &RotateHold},
+ {"_CopyToMap", &CopyToMap},
+ {"_CopyAndSelect", &CopyAndSelect},
+ {"_Input", &Input},
+ {"_3DPointInput", &_3DPointInput},
+ {"_SetRotateOrigin", &SetRotateOrigin},
+ {"_InputVar", &InputVar},
+ {"_LoopCount", &LoopCount},
+ {"_LoopRun", &LoopRun},
+ {"_ConfirmMessage", &ConfirmMessage},
+ {"_Spherize", &Spherize},
+ {"_RunScript", RunIt}
+};
+
+const int g_nScriptCmdCount = sizeof(g_ScriptCmds) / sizeof(SBrushScript);
+
+void RunScript(char* pBuffer)
+{
+ g_pHold1 = NULL;
+ g_pHold2 = NULL;
+ g_pHold3 = NULL;
+
+ while (g_bKeepGoing && pBuffer && *pBuffer)
+ {
+ while (*pBuffer != NULL && *pBuffer != '_')
+ pBuffer++;
+
+ char* pTemp = pBuffer;
+ int nLen = 0;
+ while (*pTemp != NULL && *pTemp != '(')
+ {
+ pTemp++;
+ nLen++;
+ }
+ if (*pBuffer != NULL)
+ {
+ bool bFound = false;
+ for (int i = 0; i < g_nScriptCmdCount; i++)
+ {
+ //if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, strlen(g_ScriptCmds[i].m_pName)) == 0)
+ if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, nLen) == 0)
+ {
+ pBuffer += strlen(g_ScriptCmds[i].m_pName);
+ g_ScriptCmds[i].m_pProc(pBuffer);
+ if (g_bStartLoop)
+ {
+ }
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ pBuffer++;
+ }
+ }
+}
+
+
+void RunScriptByName(char* pBuffer, bool bInit)
+{
+ if (bInit)
+ InitForScriptRun();
+ char* pScript = new char[4096];
+ CString strINI = g_strAppPath;
+ strINI += "\\scripts.ini";
+ GetPrivateProfileSection(pBuffer, pScript, 16384, strINI);
+ CString strScript;
+ char* pWorkScript = pScript;
+ while (*pWorkScript != NULL)
+ {
+ strScript += pWorkScript;
+ pWorkScript += strlen(pWorkScript) + 1;
+ }
+ RunScript(strScript.GetBuffer(0));
+}
+
+
+void RunIt(char*& pBuffer)
+{
+ brush_t* p1 = g_pHold1;
+ brush_t* p2 = g_pHold2;
+ brush_t* p3 = g_pHold3;
+
+ CString strParam = GetParam(pBuffer);
+ RunScriptByName(strParam.GetBuffer(0), false);
+
+ g_pHold3 = p3;
+ g_pHold2 = p2;
+ g_pHold1 = p1;
+}
+