static symbolNode_t *Insert(char *name, symbolType_t type,\r
symbolNode_t **root);\r
static void FreeNodes(symbolNode_t *root);\r
+static void FreeNodesAtDepth(symbolNode_t **root, int depth);\r
+static void DeleteNode(symbolNode_t *node, symbolNode_t **parent_p);\r
static void ClearShared(symbolNode_t *root);\r
\r
// EXTERNAL DATA DECLARATIONS ----------------------------------------------\r
{\r
{ "tagwait", PCD_TAGWAITDIRECT, PCD_TAGWAIT, 1, 0, 0, NO, YES },\r
{ "polywait", PCD_POLYWAITDIRECT, PCD_POLYWAIT, 1, 0, 0, NO, YES },\r
- { "scriptwait", PCD_SCRIPTWAITDIRECT, PCD_SCRIPTWAIT, 1, 0, 0, NO, YES},\r
+ { "scriptwait", PCD_SCRIPTWAITDIRECT, PCD_SCRIPTWAIT, 1, 0, 0, NO, YES },\r
+ { "namedscriptwait", PCD_NOP, PCD_SCRIPTWAITNAMED, 1, 0, 0, NO, YES },\r
{ "delay", PCD_DELAYDIRECT, PCD_DELAY, 1, 0, 0, NO, YES },\r
{ "random", PCD_RANDOMDIRECT, PCD_RANDOM, 2, 0, 0, YES, NO },\r
{ "thingcount", PCD_THINGCOUNTDIRECT, PCD_THINGCOUNT, 2, 0, 0, YES, NO },\r
{ "bluescore", PCD_NOP, PCD_BLUETEAMSCORE, 0, 0, 0, YES, NO },\r
{ "redscore", PCD_NOP, PCD_REDTEAMSCORE, 0, 0, 0, YES, NO },\r
{ "isoneflagctf", PCD_NOP, PCD_ISONEFLAGCTF, 0, 0, 0, YES, NO },\r
+ { "getinvasionwave", PCD_NOP, PCD_GETINVASIONWAVE, 0, 0, 0, YES, NO },\r
+ { "getinvasionstate", PCD_NOP, PCD_GETINVASIONSTATE, 0, 0, 0, YES, NO },\r
{ "music_change", PCD_NOP, PCD_MUSICCHANGE, 2, 0, 0, NO, NO },\r
{ "consolecommand", PCD_CONSOLECOMMANDDIRECT, PCD_CONSOLECOMMAND, 3, 2|4, 0, NO, NO },\r
{ "singleplayer", PCD_NOP, PCD_SINGLEPLAYER, 0, 0, 0, YES, NO },\r
{ "setactorangle", PCD_NOP, PCD_SETACTORANGLE, 2, 0, 0, NO, NO },\r
{ "spawnprojectile", PCD_NOP, PCD_SPAWNPROJECTILE, 7, 0, 0, NO, NO },\r
{ "getsectorlightlevel", PCD_NOP, PCD_GETSECTORLIGHTLEVEL, 1, 0, 0, YES, NO },\r
-\r
+ { "playerclass", PCD_NOP, PCD_PLAYERCLASS, 1, 0, 0, YES, NO },\r
+ { "getplayerinfo", PCD_NOP, PCD_GETPLAYERINFO, 2, 0, 0, YES, NO },\r
+ { "changelevel", PCD_NOP, PCD_CHANGELEVEL, 4, 8, 0, NO, NO },\r
+ { "sectordamage", PCD_NOP, PCD_SECTORDAMAGE, 5, 0, 0, NO, NO },\r
+ { "replacetextures", PCD_NOP, PCD_REPLACETEXTURES, 3, 4, 0, NO, NO },\r
+ { "getactorpitch", PCD_NOP, PCD_GETACTORPITCH, 1, 0, 0, YES, NO },\r
+ { "setactorpitch", PCD_NOP, PCD_SETACTORPITCH, 2, 0, 0, NO, NO },\r
+ { "setactorstate", PCD_NOP, PCD_SETACTORSTATE, 3, 4, 0, YES, NO },\r
+ { "thing_damage2", PCD_NOP, PCD_THINGDAMAGE2, 3, 0, 0, YES, NO },\r
+ { "useinventory", PCD_NOP, PCD_USEINVENTORY, 1, 0, 0, YES, NO },\r
+ { "useactorinventory", PCD_NOP, PCD_USEACTORINVENTORY, 2, 0, 0, YES, NO },\r
+ { "checkactorceilingtexture", PCD_NOP, PCD_CHECKACTORCEILINGTEXTURE, 2, 0, 0, YES, NO },\r
+ { "checkactorfloortexture", PCD_NOP, PCD_CHECKACTORFLOORTEXTURE, 2, 0, 0, YES, NO },\r
+ { "getactorlightlevel", PCD_NOP, PCD_GETACTORLIGHTLEVEL, 1, 0, 0, YES, NO },\r
+ { "setmugshotstate", PCD_NOP, PCD_SETMUGSHOTSTATE, 1, 0, 0, NO, NO },\r
+ { "thingcountsector", PCD_NOP, PCD_THINGCOUNTSECTOR, 3, 0, 0, YES, NO },\r
+ { "thingcountnamesector", PCD_NOP, PCD_THINGCOUNTNAMESECTOR, 3, 0, 0, YES, NO },\r
+ { "checkplayercamera", PCD_NOP, PCD_CHECKPLAYERCAMERA, 1, 0, 0, YES, NO },\r
+ { "morphactor", PCD_NOP, PCD_MORPHACTOR, 7, 2|4|8|16|32|64, 0, YES, NO },\r
+ { "unmorphactor", PCD_NOP, PCD_UNMORPHACTOR, 2, 2, 0, YES, NO },\r
+ { "getplayerinput", PCD_NOP, PCD_GETPLAYERINPUT, 2, 0, 0, YES, NO },\r
+ { "classifyactor", PCD_NOP, PCD_CLASSIFYACTOR, 1, 0, 0, YES, NO },\r
+ \r
{ NULL, PCD_NOP, PCD_NOP, 0, 0, 0, NO, NO }\r
};\r
\r
\r
//==========================================================================\r
//\r
+// SY_FreeConstants\r
+//\r
+//==========================================================================\r
+\r
+void SY_FreeConstants(int depth)\r
+{\r
+ MS_Message(MSG_DEBUG, "Freeing constants for depth %d\n", depth);\r
+ FreeNodesAtDepth(&GlobalRoot, depth);\r
+}\r
+\r
+//==========================================================================\r
+//\r
+// FreeNodesAtDepth\r
+//\r
+// Like FreeNodes, but it only frees the nodes of type SY_CONSTANT that are\r
+// marked at the specified depth. The other nodes are relinked to maintain a\r
+// proper binary tree.\r
+//\r
+//==========================================================================\r
+\r
+static void FreeNodesAtDepth(symbolNode_t **root, int depth)\r
+{\r
+ symbolNode_t *node = *root;\r
+\r
+ if(node == NULL)\r
+ {\r
+ return;\r
+ }\r
+ FreeNodesAtDepth(&node->left, depth);\r
+ FreeNodesAtDepth(&node->right, depth);\r
+ if(node->type == SY_CONSTANT && node->info.constant.fileDepth == depth)\r
+ {\r
+ MS_Message(MSG_DEBUG, "Deleting constant %s\n", node->name);\r
+ DeleteNode(node, root);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+//\r
+// DeleteNode\r
+//\r
+//==========================================================================\r
+\r
+static void DeleteNode(symbolNode_t *node, symbolNode_t **parent_p)\r
+{\r
+ symbolNode_t **temp;\r
+ char *nametemp;\r
+\r
+ if(node->left == NULL)\r
+ {\r
+ *parent_p = node->right;\r
+ free(node->name);\r
+ free(node);\r
+ }\r
+ else if(node->right == NULL)\r
+ {\r
+ *parent_p = node->left;\r
+ free(node->name);\r
+ free(node);\r
+ }\r
+ else\r
+ {\r
+ // "Randomly" pick the in-order successor or predecessor to take\r
+ // the place of the deleted node.\r
+ if(rand() & 1)\r
+ {\r
+ // predecessor\r
+ temp = &node->left;\r
+ while((*temp)->right != NULL)\r
+ {\r
+ temp = &(*temp)->right;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // successor\r
+ temp = &node->right;\r
+ while((*temp)->left != NULL)\r
+ {\r
+ temp = &(*temp)->left;\r
+ }\r
+ }\r
+ nametemp = node->name;\r
+ node->name = (*temp)->name;\r
+ (*temp)->name = nametemp;\r
+ node->type = (*temp)->type;\r
+ node->unused = (*temp)->unused;\r
+ node->imported = (*temp)->imported;\r
+ node->info = (*temp)->info;\r
+ DeleteNode(*temp, temp);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+//\r
// SY_ClearShared\r
//\r
//==========================================================================\r