Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

BrushScript.cpp (14939B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 // BrushScript stuff
     23 //
     24 #include "stdafx.h"
     25 #include "qe3.h"
     26 #include "BSInput.h"
     27 #include "DialogInfo.h"
     28 
     29 
     30 //
     31 struct SVariableDef
     32 {
     33   CString m_strName;
     34   CString m_strInput;
     35   float m_fValue;
     36 };
     37 
     38 struct SVecVariableDef
     39 {
     40   CString m_strName;
     41   CString m_strInput;
     42   vec3_t m_vValue;
     43 };
     44 
     45 
     46 
     47 const int MAX_VARIABLES = 64;
     48 
     49 brush_t* g_pHold1 = NULL;
     50 brush_t* g_pHold2 = NULL;
     51 brush_t* g_pHold3 = NULL;
     52 bool g_bRotateAroundSelection;
     53 int g_nVariableCount;
     54 int g_nVecVariableCount;
     55 int g_nLoopCounter;
     56 float g_fDefault = 9999.9;
     57 vec3_t g_vDefault;
     58 bool g_bStartLoop;
     59 char* g_pLooper;
     60 bool g_bKeepGoing;
     61 
     62 SVariableDef g_Variables[MAX_VARIABLES];
     63 SVecVariableDef g_VecVariables[MAX_VARIABLES];
     64 
     65 void InitForScriptRun()
     66 {
     67   g_pHold1 = NULL;
     68   g_pHold2 = NULL;
     69   g_pHold3 = NULL;
     70   g_bRotateAroundSelection = true;
     71   g_nVariableCount = 0;
     72   g_nVecVariableCount = 0;
     73   g_nLoopCounter = 0;
     74   g_bStartLoop = false;
     75   g_pLooper = NULL;
     76   g_bKeepGoing = true;
     77 }
     78 
     79 void AddVariable(const char* pName, float fValue, const char* pInput = NULL)
     80 {
     81   if (g_nVariableCount < MAX_VARIABLES)
     82   {
     83     g_Variables[g_nVariableCount].m_strName = pName;
     84     g_Variables[g_nVariableCount].m_strName.MakeLower();
     85     g_Variables[g_nVariableCount].m_fValue = fValue;
     86     if (pInput)
     87       g_Variables[g_nVariableCount].m_strInput = pInput;
     88     g_nVariableCount++;
     89   }
     90   else
     91     g_pParentWnd->MessageBox("Maximum script variable limit reached!");
     92 }
     93 
     94 float VariableValue(const char* pName)
     95 {
     96   CString strName = pName;
     97   strName.MakeLower();
     98   for (int n = 0; n < g_nVariableCount; n++)
     99   {
    100     if (strName == g_Variables[n].m_strName)
    101       return g_Variables[n].m_fValue;
    102   }
    103   //strName.Format("Reference to non-existant varirable %s", pName);
    104   //g_pParentWnd->MessageBox(strName);
    105   return g_fDefault;
    106 }
    107 
    108 void SetVariableValue(const char* pName, float fValue)
    109 {
    110   CString strName = pName;
    111   strName.MakeLower();
    112   for (int n = 0; n < g_nVariableCount; n++)
    113   {
    114     if (strName == g_Variables[n].m_strName)
    115       g_Variables[n].m_fValue = fValue;
    116   }
    117 }
    118 
    119 
    120 
    121 void AddVectorVariable(const char* pName, const char* pInput = NULL)
    122 {
    123   if (g_nVecVariableCount < MAX_VARIABLES)
    124   {
    125     g_VecVariables[g_nVecVariableCount].m_strName = pName;
    126     g_VecVariables[g_nVecVariableCount].m_strName.MakeLower();
    127     if (pInput)
    128       g_VecVariables[g_nVariableCount].m_strInput = pInput;
    129     g_nVecVariableCount++;
    130   }
    131   else
    132     g_pParentWnd->MessageBox("Maximum script variable limit reached!");
    133 }
    134 
    135 void VectorVariableValue(const char* pName, vec3_t& v)
    136 {
    137   CString strName = pName;
    138   strName.MakeLower();
    139   for (int n = 0; n < g_nVecVariableCount; n++)
    140   {
    141     if (strName == g_VecVariables[n].m_strName)
    142     {
    143       VectorCopy(g_VecVariables[n].m_vValue, v);
    144       return;
    145     }
    146   }
    147   strName.Format("Reference to non-existant variable %s", pName);
    148   g_pParentWnd->MessageBox(strName);
    149 }
    150 
    151 void SetVectorVariableValue(const char* pName, vec3_t v)
    152 {
    153   CString strName = pName;
    154   strName.MakeLower();
    155   for (int n = 0; n < g_nVecVariableCount; n++)
    156   {
    157     if (strName == g_VecVariables[n].m_strName)
    158       VectorCopy(v, g_VecVariables[n].m_vValue);
    159   }
    160 }
    161 
    162 
    163 
    164 
    165 
    166 // commands
    167 //
    168 // _CopySelected(nHoldPos)  
    169 // copies selected brush to hold spot 1, 2 or 3
    170 //
    171 // _MoveSelected(x, y, z)
    172 // moves selected brush by coords provided
    173 //
    174 // _RotateSelected(x, y, z)
    175 // rotates selected brush by coords provided
    176 //
    177 // _MoveHold(nHoldPos, x, y, z)
    178 // moves brush in hold pos by coords provided
    179 //
    180 // _RotateHold(nHoldPos, x, y, z)
    181 // rotates brush in hold pos by coords provided
    182 //
    183 // _CopyToMap(nHoldPos)
    184 // copies hold brush to map
    185 //
    186 // _CopyAndSelect(nHoldPos)
    187 // copies hold brush to map and selects it
    188 //
    189 // _Input(VarName1, ... VarNamennn)
    190 // inputs a list of values from the user
    191 //
    192 
    193 typedef void (PFNScript)(char*&);
    194 
    195 
    196 struct SBrushScript
    197 {
    198   const char* m_pName;
    199   PFNScript* m_pProc;
    200 };
    201 
    202 
    203 const char* GetParam(char*& pBuffer)
    204 {
    205   static CString strParam;
    206   bool bStringMode = false;
    207 
    208   while (*pBuffer != NULL && isspace(*pBuffer))   // skip and whitespace
    209     pBuffer++;
    210 
    211   if (*pBuffer == '(') // if it's an opening paren, skip it
    212     pBuffer++;
    213 
    214   if (*pBuffer == '\"') // string ?
    215   {
    216     pBuffer++;
    217     bStringMode = true;
    218   }
    219 
    220   strParam = "";
    221 
    222   if (bStringMode)
    223   {
    224     while (*pBuffer != NULL && *pBuffer != '\"')
    225       strParam += *pBuffer++;
    226   }
    227   else
    228   {
    229     while (*pBuffer != NULL && *pBuffer != ' ' && *pBuffer != ')' && *pBuffer != ',')
    230       strParam += *pBuffer++;
    231   }
    232 
    233   if (*pBuffer != NULL)   // skip last char
    234     pBuffer++;
    235 
    236   if (strParam.GetLength() > 0)
    237   {
    238     if (strParam.GetAt(0) == '$') // ? variable name
    239     {
    240       float f = VariableValue(strParam);
    241       if (f != g_fDefault)
    242         strParam.Format("%f", f);
    243     }
    244   }
    245 
    246   return strParam;
    247 }
    248 
    249 brush_t* CopyBrush(brush_t* p)
    250 {                            
    251   brush_t* pCopy = Brush_Clone(p);
    252 	//Brush_AddToList (pCopy, &active_brushes);
    253 	//Entity_LinkBrush (world_entity, pCopy);
    254 	Brush_Build(pCopy, false);
    255   return pCopy;
    256 }
    257 
    258 
    259 void CopySelected(char*& pBuffer)
    260 {
    261   // expects one param
    262   CString strParam = GetParam(pBuffer);
    263   int n = atoi(strParam);
    264 
    265   brush_t* pCopy = NULL;
    266   if (selected_brushes.next != &selected_brushes && 
    267       selected_brushes.next->next == &selected_brushes)
    268     pCopy = selected_brushes.next;
    269 
    270   if (pCopy)
    271   {
    272     if (n == 1)
    273     {
    274       //if (g_pHold1)
    275         //Brush_Free(g_pHold1);
    276       g_pHold1 = CopyBrush(pCopy);
    277     }
    278     else if (n == 2)
    279     {
    280       //if (g_pHold2)
    281         //Brush_Free(g_pHold2);
    282       g_pHold2 = CopyBrush(pCopy);
    283     }
    284     else
    285     {
    286       //if (g_pHold3)
    287         //Brush_Free(g_pHold3);
    288       g_pHold3 = CopyBrush(pCopy);
    289     }
    290   }
    291 }
    292 
    293 void MoveSelected(char*& pBuffer)
    294 {
    295   vec3_t v;
    296   CString strParam = GetParam(pBuffer);
    297   v[0] = atof(strParam);
    298   strParam = GetParam(pBuffer);
    299   v[1] = atof(strParam);
    300   strParam = GetParam(pBuffer);
    301   v[2] = atof(strParam);
    302   Select_Move(v, false);
    303   Sys_UpdateWindows(W_ALL);
    304 }
    305 
    306 void RotateSelected(char*& pBuffer)
    307 {
    308   vec3_t v;
    309 
    310   if (g_bRotateAroundSelection)
    311   {
    312     Select_GetTrueMid(v);
    313     VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());
    314   }
    315 
    316   CString strParam = GetParam(pBuffer);
    317   v[0] = atof(strParam);
    318   strParam = GetParam(pBuffer);
    319   v[1] = atof(strParam);
    320   strParam = GetParam(pBuffer);
    321   v[2] = atof(strParam);
    322   for (int i = 0; i < 3; i++)
    323     if (v[i] != 0.0)
    324       Select_RotateAxis(i, v[i], false , true);
    325   Sys_UpdateWindows(W_ALL);
    326 }
    327 
    328 void MoveHold(char*& pBuffer)
    329 {
    330   CString strParam = GetParam(pBuffer);
    331   brush_t* pBrush = NULL;
    332   int nHold = atoi(strParam);
    333   if (nHold == 1)
    334     pBrush = g_pHold1;
    335   else if (nHold == 2)
    336     pBrush = g_pHold2;
    337   else 
    338     pBrush = g_pHold3;
    339 
    340   if (pBrush)
    341   {
    342     vec3_t v;
    343     strParam = GetParam(pBuffer);
    344     v[0] = atof(strParam);
    345     strParam = GetParam(pBuffer);
    346     v[1] = atof(strParam);
    347     strParam = GetParam(pBuffer);
    348     v[2] = atof(strParam);
    349 		Brush_Move (pBrush, v, false);
    350   }
    351 }
    352 
    353 void RotateHold(char*& pBuffer)
    354 {
    355   CString strParam = GetParam(pBuffer);
    356   brush_t* pBrush = NULL;
    357   int nHold = atoi(strParam);
    358   if (nHold == 1)
    359     pBrush = g_pHold1;
    360   else if (nHold == 2)
    361     pBrush = g_pHold2;
    362   else 
    363     pBrush = g_pHold3;
    364 
    365   if (pBrush)
    366   {
    367     vec3_t v;
    368     strParam = GetParam(pBuffer);
    369     v[0] = atof(strParam);
    370     strParam = GetParam(pBuffer);
    371     v[1] = atof(strParam);
    372     strParam = GetParam(pBuffer);
    373     v[2] = atof(strParam);
    374     for (int i = 0; i < 3; i++)
    375       if (v[i] != 0.0)
    376         Select_RotateAxis(i, v[i]);
    377   }
    378 }
    379 
    380 void CopyToMap(char*& pBuffer)
    381 {
    382   CString strParam = GetParam(pBuffer);
    383   brush_t* pBrush = NULL;
    384   int nHold = atoi(strParam);
    385   if (nHold == 1)
    386     pBrush = g_pHold1;
    387   else if (nHold == 2)
    388     pBrush = g_pHold2;
    389   else 
    390     pBrush = g_pHold3;
    391 
    392   if (pBrush)
    393   {
    394     Brush_AddToList(pBrush, &active_brushes);
    395 		Entity_LinkBrush (world_entity, pBrush);
    396 		Brush_Build(pBrush, false);
    397     Sys_UpdateWindows(W_ALL);
    398   }
    399 }
    400 
    401 void CopyAndSelect(char*& pBuffer)
    402 {
    403   CString strParam = GetParam(pBuffer);
    404   brush_t* pBrush = NULL;
    405   int nHold = atoi(strParam);
    406   if (nHold == 1)
    407     pBrush = g_pHold1;
    408   else if (nHold == 2)
    409     pBrush = g_pHold2;
    410   else 
    411     pBrush = g_pHold3;
    412 
    413   if (pBrush)
    414   {
    415     Select_Deselect();
    416     Brush_AddToList(pBrush, &active_brushes);
    417 		Entity_LinkBrush (world_entity, pBrush);
    418 		Brush_Build(pBrush, false);
    419     Select_Brush(pBrush);
    420     Sys_UpdateWindows(W_ALL);
    421   }
    422 }
    423 
    424 void Input(char*& pBuffer)
    425 {
    426   CBSInput dlg;
    427   bool bGo = false;
    428   for (int n = 0; n < g_nVariableCount; n++)
    429   {
    430     if (g_Variables[n].m_strInput.GetLength() > 0)
    431     {
    432       bGo = true;
    433       if (n < 5)
    434       {
    435         switch (n)
    436         {
    437           case 0 : dlg.m_strField1 = g_Variables[n].m_strInput; break;
    438           case 1 : dlg.m_strField2 = g_Variables[n].m_strInput; break;
    439           case 2 : dlg.m_strField3 = g_Variables[n].m_strInput; break;
    440           case 3 : dlg.m_strField4 = g_Variables[n].m_strInput; break;
    441           case 4 : dlg.m_strField5 = g_Variables[n].m_strInput; break;
    442         }
    443       }
    444     }
    445   }
    446   if (bGo)
    447   {
    448     if (dlg.DoModal() == IDOK)
    449     {
    450       for (int n = 0; n < g_nVariableCount; n++)
    451       {
    452         if (g_Variables[n].m_strInput.GetLength() > 0)
    453         {
    454           if (n < 5)
    455           {
    456             switch (n)
    457             {
    458               case 0 : g_Variables[n].m_fValue = dlg.m_fField1; break;
    459               case 1 : g_Variables[n].m_fValue = dlg.m_fField2; break;
    460               case 2 : g_Variables[n].m_fValue = dlg.m_fField3; break;
    461               case 3 : g_Variables[n].m_fValue = dlg.m_fField4; break;
    462               case 4 : g_Variables[n].m_fValue = dlg.m_fField5; break;
    463             }
    464           }
    465         }
    466       }
    467     }
    468     else g_bKeepGoing = false;
    469   }
    470 }
    471 
    472 bool g_bWaiting;
    473 void _3DPointDone(bool b, int n)
    474 {
    475   g_bWaiting = false;
    476 }
    477 
    478 void _3DPointInput(char*& pBuffer)
    479 {
    480   CString strParam = GetParam(pBuffer);
    481   CString strParam2 = GetParam(pBuffer);
    482   ShowInfoDialog(strParam2);
    483   AddVectorVariable(strParam, strParam2);
    484   g_bWaiting = true;
    485   AcquirePath(2, &_3DPointDone);
    486   while (g_bWaiting)
    487   {
    488     MSG msg;
    489     if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 
    490     { 
    491       TranslateMessage(&msg);
    492       DispatchMessage(&msg);
    493     }
    494   }
    495   HideInfoDialog();
    496   SetVectorVariableValue(strParam, g_PathPoints[0]);
    497 }
    498 
    499 void SetRotateOrigin(char*& pBuffer)
    500 {
    501   vec3_t v;
    502   CString strParam = GetParam(pBuffer);
    503   VectorVariableValue(strParam, v);
    504   VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());
    505   g_bRotateAroundSelection = false;
    506 }
    507 
    508 void InputVar(char*& pBuffer)
    509 {
    510   CString strParam = GetParam(pBuffer);
    511   CString strParam2 = GetParam(pBuffer);
    512   AddVariable(strParam, 0.0, strParam2);
    513 }
    514 
    515 void LoopCount(char*& pBuffer)
    516 {
    517   CString strParam = GetParam(pBuffer);
    518   g_nLoopCounter = atoi(strParam);
    519   if (g_nLoopCounter == 0)
    520     g_nLoopCounter = VariableValue(strParam);
    521   if (g_nLoopCounter > 0)
    522     g_pLooper = pBuffer;
    523 }
    524 
    525 void LoopRun(char*& pBuffer)
    526 {
    527   if (g_bStartLoop == true)
    528   {
    529     g_nLoopCounter--;
    530     if (g_nLoopCounter == 0)
    531     {
    532       g_bStartLoop = false;
    533       GetParam(pBuffer);
    534     }
    535     else
    536       pBuffer = g_pLooper;
    537   }
    538   else
    539   {
    540     if (g_pLooper && g_nLoopCounter > 0)
    541     {
    542       g_bStartLoop = true;
    543       pBuffer = g_pLooper;
    544     }
    545     else
    546     {
    547       GetParam(pBuffer);
    548     }
    549   }
    550 }
    551 
    552 
    553 void ConfirmMessage(char*& pBuffer)
    554 {
    555   CString strParam = GetParam(pBuffer);
    556   if (g_pParentWnd->MessageBox(strParam, "Script Info", MB_OKCANCEL) == IDCANCEL)
    557     g_bKeepGoing = false;
    558 }
    559 
    560 void Spherize(char*& pBuffer)
    561 {
    562   g_bScreenUpdates = false;
    563   for (int n = 0; n < 120; n += 36)
    564   {
    565     for (int i = 0; i < 360; i += 36)
    566     {
    567       Select_RotateAxis(0, i, false , true);
    568       CSG_Subtract();
    569     }
    570     Select_RotateAxis(2, n, false , true);
    571   }
    572   g_bScreenUpdates = true;
    573 }
    574 
    575 void RunIt(char*& pBuffer);
    576 SBrushScript g_ScriptCmds[] =
    577 {
    578   {"_CopySelected", &CopySelected},
    579   {"_MoveSelected", &MoveSelected},
    580   {"_RotateSelected", &RotateSelected},
    581   {"_MoveHold", &MoveHold},
    582   {"_RotateHold", &RotateHold},
    583   {"_CopyToMap", &CopyToMap},
    584   {"_CopyAndSelect", &CopyAndSelect},
    585   {"_Input", &Input},
    586   {"_3DPointInput", &_3DPointInput},
    587   {"_SetRotateOrigin", &SetRotateOrigin},
    588   {"_InputVar", &InputVar},
    589   {"_LoopCount", &LoopCount},
    590   {"_LoopRun", &LoopRun},
    591   {"_ConfirmMessage", &ConfirmMessage},
    592   {"_Spherize", &Spherize},
    593   {"_RunScript", RunIt}
    594 };
    595 
    596 const int g_nScriptCmdCount = sizeof(g_ScriptCmds) / sizeof(SBrushScript);
    597 
    598 void RunScript(char* pBuffer)
    599 {
    600   g_pHold1 = NULL;
    601   g_pHold2 = NULL;
    602   g_pHold3 = NULL;
    603 
    604   while (g_bKeepGoing && pBuffer && *pBuffer)
    605   {
    606     while (*pBuffer != NULL && *pBuffer != '_')
    607       pBuffer++;
    608 
    609     char* pTemp = pBuffer;
    610     int nLen = 0;
    611     while (*pTemp != NULL && *pTemp != '(')
    612     {
    613       pTemp++;
    614       nLen++;
    615     }
    616     if (*pBuffer != NULL)
    617     {
    618       bool bFound = false;
    619       for (int i = 0; i < g_nScriptCmdCount; i++)
    620       {
    621         //if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, strlen(g_ScriptCmds[i].m_pName)) ==  0)
    622         if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, nLen) ==  0)
    623         {
    624           pBuffer += strlen(g_ScriptCmds[i].m_pName);
    625           g_ScriptCmds[i].m_pProc(pBuffer);
    626           if (g_bStartLoop)
    627           {
    628           }
    629           bFound = true;
    630           break;
    631         }
    632       }
    633       if (!bFound)
    634         pBuffer++;
    635     }
    636   }
    637 }
    638 
    639 
    640 void RunScriptByName(char* pBuffer, bool bInit)
    641 {
    642   if (bInit)
    643     InitForScriptRun();
    644   char* pScript = new char[4096];
    645   CString strINI = g_strAppPath;
    646   strINI += "\\scripts.ini";
    647   GetPrivateProfileSection(pBuffer, pScript, 16384, strINI);
    648   CString strScript;
    649   char* pWorkScript = pScript;
    650   while (*pWorkScript != NULL)
    651   {
    652     strScript += pWorkScript;
    653     pWorkScript += strlen(pWorkScript) + 1;
    654   }
    655   RunScript(strScript.GetBuffer(0));
    656 }
    657 
    658 
    659 void RunIt(char*& pBuffer)
    660 {
    661   brush_t* p1 = g_pHold1;
    662   brush_t* p2 = g_pHold2;
    663   brush_t* p3 = g_pHold3;
    664 
    665   CString strParam = GetParam(pBuffer);
    666   RunScriptByName(strParam.GetBuffer(0), false);
    667 
    668   g_pHold3 = p3;
    669   g_pHold2 = p2;
    670   g_pHold1 = p1;
    671 }
    672