entityDef: add support for condition based tweaks
This commit is contained in:
parent
3eb2ec1b37
commit
0dc8f4ec75
1 changed files with 218 additions and 3 deletions
|
@ -49,17 +49,32 @@
|
|||
#define ENTITYDEF_MAX 128
|
||||
#endif
|
||||
|
||||
var string g_lastSpawnData;
|
||||
|
||||
enum
|
||||
{
|
||||
EDEFTWEAK_EQ = 0,
|
||||
EDEFTWEAK_LT,
|
||||
EDEFTWEAK_GT,
|
||||
EDEFTWEAK_NOT
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string entClass;
|
||||
string spawnClass;
|
||||
string spawnData;
|
||||
string inheritKeys;
|
||||
|
||||
string tweakDefs;
|
||||
string tweakKeys;
|
||||
} entityDef_t;
|
||||
|
||||
entityDef_t g_entDefTable[ENTITYDEF_MAX];
|
||||
var int g_entDefCount;
|
||||
|
||||
string g_entDefInclude;
|
||||
|
||||
void
|
||||
EntityDef_ReadFile(string filePath)
|
||||
{
|
||||
|
@ -73,6 +88,8 @@ EntityDef_ReadFile(string filePath)
|
|||
currentDef.spawnClass = "";
|
||||
currentDef.spawnData = "";
|
||||
currentDef.inheritKeys = "";
|
||||
currentDef.tweakDefs = "";
|
||||
currentDef.tweakKeys = "";
|
||||
|
||||
/* bounds check */
|
||||
if (g_entDefCount >= ENTITYDEF_MAX) {
|
||||
|
@ -108,6 +125,8 @@ EntityDef_ReadFile(string filePath)
|
|||
g_entDefTable[g_entDefCount].spawnClass = currentDef.spawnClass;
|
||||
g_entDefTable[g_entDefCount].spawnData = currentDef.spawnData;
|
||||
g_entDefTable[g_entDefCount].inheritKeys = currentDef.inheritKeys;
|
||||
g_entDefTable[g_entDefCount].tweakDefs = currentDef.tweakDefs;
|
||||
g_entDefTable[g_entDefCount].tweakKeys = currentDef.tweakKeys;
|
||||
|
||||
/* increment the def count */
|
||||
if (g_entDefCount < ENTITYDEF_MAX)
|
||||
|
@ -117,12 +136,23 @@ EntityDef_ReadFile(string filePath)
|
|||
currentDef.spawnClass = "";
|
||||
currentDef.spawnData = "";
|
||||
currentDef.inheritKeys = "";
|
||||
currentDef.tweakDefs = "";
|
||||
currentDef.tweakKeys = "";
|
||||
}
|
||||
|
||||
/* we came out of a tweak */
|
||||
if (braceDepth == 1) {
|
||||
if (currentDef.tweakDefs != "") {
|
||||
currentDef.tweakKeys = strcat(currentDef.tweakKeys, ";"); /* mark the end of a key chain */
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* anything outside braces defines the classname for the next def */
|
||||
if (braceDepth == 0 && lastWord == "entityDef") {
|
||||
currentDef.entClass = word;
|
||||
} else if (braceDepth == 0 && lastWord == "include") {
|
||||
g_entDefInclude = strcat(g_entDefInclude, word, ";");
|
||||
} else if (braceDepth == 1) {
|
||||
/* spawnclass is reserved and the next keyword specs it */
|
||||
if (word == "spawnclass") {
|
||||
|
@ -134,9 +164,57 @@ EntityDef_ReadFile(string filePath)
|
|||
} else if (substring(word, 0, 7) == "editor_") {
|
||||
/* do nothing */
|
||||
i++;
|
||||
} else if (substring(word, 0, 4) == "when") {
|
||||
switch (argv(i+2)) {
|
||||
case "equals":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 0 ", argv(i+3), ";");
|
||||
break;
|
||||
case "less-than":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 1 ", argv(i+3), ";");
|
||||
break;
|
||||
case "greater-than":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 2 ", argv(i+3), ";");
|
||||
break;
|
||||
case "is-not":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 3 ", argv(i+3), ";");
|
||||
break;
|
||||
|
||||
}
|
||||
i+=3;
|
||||
} else { /* rest gets dumped into spawndata */
|
||||
currentDef.spawnData = strcat(currentDef.spawnData, "\"", word, "\"", " ");
|
||||
}
|
||||
} else if (braceDepth == 2) {
|
||||
/* spawnclass is reserved and the next keyword specs it */
|
||||
if (word == "spawnclass") {
|
||||
currentDef.spawnClass = argv(i+1);
|
||||
i++;
|
||||
} else if (word == "inherit") {
|
||||
currentDef.inheritKeys = argv(i+1);
|
||||
i++;
|
||||
} else if (substring(word, 0, 7) == "editor_") {
|
||||
/* do nothing */
|
||||
i++;
|
||||
} else if (substring(word, 0, 4) == "when") {
|
||||
switch (argv(i+2)) {
|
||||
case "equals":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 0 ", argv(i+3), ";");
|
||||
break;
|
||||
case "less-than":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 1 ", argv(i+3), ";");
|
||||
break;
|
||||
case "greater-than":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 2 ", argv(i+3), ";");
|
||||
break;
|
||||
case "is-not":
|
||||
currentDef.tweakDefs = strcat(currentDef.tweakDefs, argv(i+1), " 3 ", argv(i+3), ";");
|
||||
break;
|
||||
|
||||
}
|
||||
i+=3;
|
||||
} else { /* rest gets dumped into spawndata */
|
||||
currentDef.tweakKeys = strcat(currentDef.tweakKeys, "\"", word, "\"", " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
lastWord = word;
|
||||
|
@ -151,19 +229,36 @@ void
|
|||
EntityDef_Init(void)
|
||||
{
|
||||
searchhandle pm;
|
||||
|
||||
g_entDefInclude = "";
|
||||
|
||||
pm = search_begin("def/*.def", TRUE, TRUE);
|
||||
for (int i = 0; i < search_getsize(pm); i++) {
|
||||
EntityDef_ReadFile(search_getfilename(pm, i));
|
||||
}
|
||||
search_end(pm);
|
||||
|
||||
//print(sprintf("includes: %S\n", g_entDefInclude));
|
||||
|
||||
if (g_entDefInclude != "") {
|
||||
int includeCount = tokenizebyseparator(g_entDefInclude, ";");
|
||||
|
||||
for (int i = 0; i < (includeCount-1); i++) {
|
||||
string fileName = strcat("def/", argv(i));
|
||||
EntityDef_ReadFile(fileName);
|
||||
includeCount = tokenizebyseparator(g_entDefInclude, ";");
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
int numKeys = tokenize_console(g_entDefTable[i].spawnData);
|
||||
print(sprintf("edef %i: %S\n", i, g_entDefTable[i].entClass));
|
||||
print(sprintf("\tspawnclass: %S\n", g_entDefTable[i].spawnClass));
|
||||
print(sprintf("\tinheritKeys: %S\n", g_entDefTable[i].inheritKeys));
|
||||
print(sprintf("\tspawnData:\n", g_entDefTable[i].spawnData));
|
||||
print(sprintf("\ttweakDefs %S\n", g_entDefTable[i].tweakDefs));
|
||||
print(sprintf("\ttweakKeys %S\n", g_entDefTable[i].tweakKeys));
|
||||
print("\tspawnData:\n");
|
||||
|
||||
for (int c = 0; c < numKeys; c+=2) {
|
||||
print(sprintf("\t\t%S %S\n", argv(c), argv(c+1)));
|
||||
|
@ -172,6 +267,54 @@ EntityDef_Init(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
EntityDef_CheckCondition(int id, string keyWord, float tweakCondition, string keyValue)
|
||||
{
|
||||
int spawnWords = tokenize_console(g_lastSpawnData);
|
||||
string key, value;
|
||||
float tmp1, tmp2;
|
||||
|
||||
//print(sprintf("%i %S %d %S\n", id, keyWord, tweakCondition, keyValue));
|
||||
|
||||
for (int i = 1; i < (spawnWords - 1); i+= 2) {
|
||||
key = argv(i);
|
||||
value = argv(i+1);
|
||||
|
||||
//print(sprintf("comparing %S with %S\n", key, value));
|
||||
|
||||
/* fforward out */
|
||||
if (key != keyWord)
|
||||
continue;
|
||||
|
||||
switch (tweakCondition) {
|
||||
case EDEFTWEAK_EQ:
|
||||
if (key == keyWord && value == keyValue)
|
||||
return true;
|
||||
break;
|
||||
case EDEFTWEAK_LT:
|
||||
tmp1 = stof(keyValue);
|
||||
tmp2 = stof(value);
|
||||
|
||||
if (key == keyWord && tmp2 < tmp1)
|
||||
return true;
|
||||
break;
|
||||
case EDEFTWEAK_GT:
|
||||
tmp1 = stof(keyValue);
|
||||
tmp2 = stof(value);
|
||||
|
||||
if (key == keyWord && tmp2 > tmp1)
|
||||
return true;
|
||||
break;
|
||||
case EDEFTWEAK_NOT:
|
||||
if (key == keyWord && value != keyValue)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static NSEntity
|
||||
EntityDef_PrepareEntity(entity target, int id)
|
||||
{
|
||||
|
@ -226,27 +369,87 @@ EntityDef_PrepareEntity(entity target, int id)
|
|||
}
|
||||
|
||||
/* now we load our own spawndata, which starts and ends with braces */
|
||||
spawnWords = tokenize_console(__fullspawndata);
|
||||
spawnWords = tokenize_console(g_lastSpawnData);
|
||||
for (int i = 1; i < (spawnWords - 1); i+= 2) {
|
||||
|
||||
/* ignore this, always */
|
||||
if (argv(i) != "classname")
|
||||
targetEnt.SpawnKey(argv(i), argv(i+1));
|
||||
}
|
||||
|
||||
/* now after everything else is done, check our entityDef tweaks */
|
||||
spawnWords = tokenizebyseparator(g_entDefTable[id].tweakDefs, ";");
|
||||
for (int i = 0; i < spawnWords; i++) {
|
||||
string groupSegment = argv(i);
|
||||
|
||||
//print(sprintf("group: %S\n", groupSegment));
|
||||
tokenize_console(groupSegment); /* split the group segment into 3 */
|
||||
|
||||
string keyWord = argv(0);
|
||||
float tweakCondition = stof(argv(1));
|
||||
string keyValue = argv(2);
|
||||
|
||||
/* iterate through a bunch of different data to check our condition */
|
||||
if (EntityDef_CheckCondition(id, keyWord, tweakCondition, keyValue)) {
|
||||
int tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";");
|
||||
|
||||
//print(sprintf("%S passed the check\n", keyWord));
|
||||
|
||||
/* iterate through the ; key groups */
|
||||
for (int x = 0; x < tweakGroups; x++) {
|
||||
int tweakSpawns = tokenize_console(argv(x));
|
||||
|
||||
/* ignore any other key group */
|
||||
if (x == i) {
|
||||
/* iterate through key/value pairs within the ; key groups */
|
||||
for (int y = 0; y < tweakSpawns; y+= 2) {
|
||||
//print(sprintf("applying %S and %S\n", argv(y), argv(y+1)));
|
||||
targetEnt.SpawnKey(argv(y), argv(y+1));
|
||||
}
|
||||
}
|
||||
|
||||
/* retokenize */
|
||||
tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";");
|
||||
}
|
||||
}
|
||||
|
||||
/* retokenize our condition */
|
||||
spawnWords = tokenizebyseparator(g_entDefTable[id].tweakDefs, ";");
|
||||
}
|
||||
|
||||
targetEnt.Spawned();
|
||||
targetEnt.Respawn();
|
||||
|
||||
/* now we rename the classname for better visibility */
|
||||
targetEnt.classname = g_entDefTable[id].entClass;
|
||||
__fullspawndata = "";
|
||||
g_lastSpawnData = "";
|
||||
return targetEnt;
|
||||
}
|
||||
|
||||
/* precache resources inside an entityDef */
|
||||
static void
|
||||
EntityDef_Precaches(int index)
|
||||
{
|
||||
int spawnWords = tokenize_console(g_entDefTable[index].spawnData);
|
||||
for (int i = 0; i < spawnWords; i+= 2) {
|
||||
string strKey = argv(i);
|
||||
string strValue = argv(i+1);
|
||||
|
||||
if (substring(strKey, 0, 4) == "snd_") {
|
||||
Sound_Precache(strValue);
|
||||
spawnWords = tokenize_console(g_entDefTable[index].spawnData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSEntity
|
||||
EntityDef_SpawnClassname(string className)
|
||||
{
|
||||
g_lastSpawnData = __fullspawndata;
|
||||
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
if (className == g_entDefTable[i].entClass) {
|
||||
EntityDef_Precaches(i);
|
||||
return EntityDef_PrepareEntity(self, i);
|
||||
}
|
||||
}
|
||||
|
@ -304,4 +507,16 @@ EntityDef_GetKeyValue(string className, string keyName)
|
|||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool
|
||||
EntityDef_HasSpawnClass(string className)
|
||||
{
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
if (className == g_entDefTable[i].entClass) {
|
||||
return (g_entDefTable[i].spawnClass != "") ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
Loading…
Reference in a new issue