/* Copyright (C) 1999-2007 id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant 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. GtkRadiant 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 GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // BrushScript stuff // /*! \todo is this still used / in working state? should we cleanup and remove it for good */ #include "stdafx.h" #include "gtkmisc.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.9f; 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 gtk_MessageBox(g_pParentWnd->m_pWidget, "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 gtk_MessageBox(g_pParentWnd->m_pWidget, "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); gtk_MessageBox(g_pParentWnd->m_pWidget, 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 != (char)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 != (char)NULL && *pBuffer != '\"') strParam += *pBuffer++; } else { while (*pBuffer != (char)NULL && *pBuffer != ' ' && *pBuffer != ')' && *pBuffer != ',') strParam += *pBuffer++; } if (*pBuffer != (char)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) { bool bGo = false; const char *fields[5] = { "", "", "", "", "" }; float values[5]; 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 : fields[1] = g_Variables[n].m_strInput.GetBuffer (); break; case 1 : fields[2] = g_Variables[n].m_strInput.GetBuffer (); break; case 2 : fields[3] = g_Variables[n].m_strInput.GetBuffer (); break; case 3 : fields[4] = g_Variables[n].m_strInput.GetBuffer (); break; case 4 : fields[5] = g_Variables[n].m_strInput.GetBuffer (); break; } } } } if (bGo) { if (DoBSInputDlg (fields, values) == 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 = values[1]; break; case 1 : g_Variables[n].m_fValue = values[2]; break; case 2 : g_Variables[n].m_fValue = values[3]; break; case 3 : g_Variables[n].m_fValue = values[4]; break; case 4 : g_Variables[n].m_fValue = values[5]; 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) gtk_main_iteration (); 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 = (int)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 (gtk_MessageBox(g_pParentWnd->m_pWidget, 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 != (char)NULL && *pBuffer != '_') pBuffer++; char* pTemp = pBuffer; int nLen = 0; while (*pTemp != (char)NULL && *pTemp != '(') { pTemp++; nLen++; } if (*pBuffer != (char)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; strINI = g_strGameToolsPath; strINI += "/scripts.ini"; CString strScript; FILE *f; f = fopen (strINI.GetBuffer(), "rt"); if (f != NULL) { char line[1024], *ptr; // read section names while (fgets (line, 1024, f) != 0) { if (line[0] != '[') continue; ptr = strchr (line, ']'); *ptr = '\0'; if (strcmp (line, pScript) == 0) { while (fgets (line, 1024, f) != 0) { if ((strchr (line, '=') == NULL) || strlen (line) == 0) break; strScript += line; } break; } } fclose (f); } RunScript((char*)strScript.GetBuffer()); } void RunIt(char*& pBuffer) { brush_t* p1 = g_pHold1; brush_t* p2 = g_pHold2; brush_t* p3 = g_pHold3; CString strParam = GetParam(pBuffer); RunScriptByName((char*)strParam.GetBuffer(), false); g_pHold3 = p3; g_pHold2 = p2; g_pHold1 = p1; }