PHP Code:
AddStringValue(Handle:parser, Handle:trieHandle, const String:key[], const String:defValue[])
{
new String:strValueBuffer[PLATFORM_MAX_PATH];
KvGetString(parser, key, strValueBuffer, PLATFORM_MAX_PATH, defValue)
if (!SetTrieString(trieHandle, key, strValueBuffer, false))
SetFailState("We already got item %s", key);
FF2_Debug("Added %s to trie we were passed, value: %s", key, strValueBuffer);
}
AddIntValue(Handle:parser, Handle:trieHandle, const String:key[], defValue)
{
new result;
result = KvGetNum(parser, key, defValue);
if (!SetTrieValue(trieHandle, key, result, false))
SetFailState("We already got item %s", key);
FF2_Debug("Added %s to trie we were passed, value: %d", key, result);
}
AddBoolValue(Handle:parser, Handle:trieHandle, const String:key[], defValue)
{
new result;
result = KvGetNum(parser, key, defValue);
if (!SetTrieValue(trieHandle, key, bool:result, false))
SetFailState("We already got item %s", key);
FF2_Debug("Added %s to trie we were passed, value: %i", key, result);
}
AddFloatValue(Handle:parser, Handle:trieHandle, const String:key[], Float:defValue)
{
new Float:result;
result = KvGetFloat(parser, key, defValue);
if (!SetTrieValue(trieHandle, key, result, false))
SetFailState("We already got item %s", key);
FF2_Debug("Added %s to trie we were passed, value: %f", key, result);
}
ParseAttributes(Handle:parser, Handle:attriTrie)
{
FF2_Debug("Preparing to parse attributes");
FF2_Debug("{");
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(attriTrie, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
if (KvGotoFirstSubKey(parser, false))
{
FF2_Debug("Parsing attributes");
FF2_Debug("{");
do
{
KvGetSectionName(parser, strBuffer, MAX_BOSS_NAME_LENGTH);
new Handle:attriInfo = CreateTrie();
if (!SetTrieValue(attriTrie, strBuffer, attriInfo))
SetFailState("We already parsed attribute #%s", strBuffer);
PushArrayString(keyNames, strBuffer);
AddIntValue(parser, attriInfo, "index", -1);
AddFloatValue(parser, attriInfo, "value", 0.0);
}
while (KvGotoNextKey(parser, false));
KvGoBack(parser);
FF2_Debug("}");
}
FF2_Debug("}");
}
ParseWeapon(Handle:bossParser, Handle:weaponStatTrie)
{
FF2_Debug("Preparing to parse weapon info");
FF2_Debug("{");
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(weaponStatTrie, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
AddStringValue(bossParser, weaponStatTrie, "classname", "tf_weapon_bottle");
AddIntValue(bossParser, weaponStatTrie, "item_index", 1);
AddFloatValue(bossParser, weaponStatTrie, "damage", 2.0);
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
SetTrieValue(weaponStatTrie, "isSpecial", true);
FF2_Debug("Parsing weapon info");
FF2_Debug("{");
if (KvGotoFirstSubKey(bossParser, false))
{
do
{
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
if (StrEqual(strBuffer, "attributes"))
{
FF2_Debug("Found attributes.");
new Handle:attriTrie = CreateTrie();
if (!SetTrieValue(weaponStatTrie, "attributes", attriTrie))
SetFailState("How come we already got attributes?");
PushArrayString(keyNames, "attributes");
ParseAttributes(bossParser, attriTrie);
}
}
while (KvGotoNextKey(bossParser, false));
KvGoBack(bossParser);
}
FF2_Debug("}");
FF2_Debug("}");
}
ParseWeapons(Handle:bossParser, Handle:weaponTrie)
{
FF2_Debug("Preparing to parse weapons.");
FF2_Debug("{");
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(weaponTrie, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
if (KvGotoFirstSubKey(bossParser))
{
FF2_Debug("Parsing weapons");
FF2_Debug("{");
do
{
new Handle:weaponStatTrie = CreateTrie();
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(weaponTrie, strBuffer, weaponStatTrie, false))
SetFailState("Duplicate weapon info for %s", strBuffer);
PushArrayString(keyNames, strBuffer);
ParseWeapon(bossParser, weaponStatTrie);
}
while (KvGotoNextKey(bossParser, false));
KvGoBack(bossParser);
FF2_Debug("}");
}
FF2_Debug("}");
}
bool:FindAbility(Handle:bossParser)
{
FF2_Debug("Attempting to find an ability in registered abilities.");
decl String:abilityControlName[MAX_BOSS_NAME_LENGTH];
KvGetString(bossParser, "ability_controller", abilityControlName, MAX_BOSS_NAME_LENGTH, "");
if (StrEqual(abilityControlName, ""))
SetFailState("No ability_controller key, YOU MUST HAVE ONE!");
new Handle:plugHandle;
if (!GetTrieValue(g_hPluginInfo, abilityControlName, plugHandle))
SetFailState("Warning, can't find ability control plugin %s", abilityControlName);
new Handle:abilities, Handle:aKeyNames;
if (!GetTrieValue(plugHandle, "abilities", abilities))
SetFailState("How did this happen?");
if (!GetTrieValue(abilities, "keyNames", aKeyNames))
SetFailState("What no keyNames array?");
decl String:abilityName[MAX_BOSS_NAME_LENGTH], String:tempAbilityName[MAX_BOSS_NAME_LENGTH];
KvGetString(bossParser, "name", abilityName, MAX_BOSS_NAME_LENGTH, "");
if (StrEqual(abilityName, ""))
SetFailState("No ability name, YOU MUST HAVE ONE!");
for (new ii = 0; ii < GetArraySize(aKeyNames); ii++)
{
GetArrayString(aKeyNames, ii, tempAbilityName, MAX_BOSS_NAME_LENGTH);
if (StrEqual(abilityName, tempAbilityName))
{
FF2_Debug("Found ability %s", abilityName);
return true;
}
}
return false;
}
bool:ParseAbility(Handle:bossParser, Handle:ability)
{
FF2_Debug("Preparing to parse an ability.");
FF2_Debug("{");
if (!FindAbility(bossParser))
{
FF2_Debug("}");
return false;
}
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(ability, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
SetTrieValue(ability, "isSpecial", true);
decl String:abilityName[MAX_BOSS_NAME_LENGTH], String:controlName[MAX_BOSS_NAME_LENGTH], String:argNum[MAX_BOSS_NAME_LENGTH];
AddStringValue(bossParser, ability, "name", "");
AddStringValue(bossParser, ability, "ability_controller", "");
GetTrieString(ability, "name", abilityName, MAX_BOSS_NAME_LENGTH);
GetTrieString(ability, "ability_controller", controlName, MAX_BOSS_NAME_LENGTH);
new Handle:plugHandle, Handle:abilitiesHandle, Handle:abilityHandle, Handle:args, Handle:argKeyNames;
GetTrieValue(g_hPluginInfo, controlName, plugHandle);
GetTrieValue(plugHandle, "abilities", abilitiesHandle);
GetTrieValue(abilitiesHandle, abilityName, abilityHandle);
new Handle:cacheArgs = CreateTrie();
if (!SetTrieValue(ability, "args", cacheArgs))
SetFailState("Somehow we got args for this.");
PushArrayString(keyNames, "args");
new Handle:argInfo, FF2_A0Mode:abilityAct, ArgType:argType;
abilityAct = FF2_A0Mode:KvGetNum(bossParser, "0", 0);
FF2_Debug("Ability #%s is activated on mode #%d", abilityName, KvGetNum(bossParser, "0", 0));
SetTrieValue(cacheArgs, "0", abilityAct);
if (!GetTrieValue(abilityHandle, "args", args))
SetFailState("Config has args for %s and yet ability does not.", abilityName);
if (!GetTrieValue(args, "keyNames", argKeyNames))
SetFailState("Ability %s args has no keynames for the number!", abilityName);
if (KvJumpToKey(bossParser, "args"))
{
for (new i = 0; i < GetArraySize(argKeyNames); i++)
{
GetArrayString(argKeyNames, i, argNum, MAX_BOSS_NAME_LENGTH);
FF2_Debug("Attempting to parse arg #%s", argNum);
GetTrieValue(args, argNum, argInfo);
GetTrieValue(argInfo, "type", argType);
switch (argType)
{
case ArgType_Float:
{
new Float:defValue;
GetTrieValue(argInfo, "defValue", defValue);
AddFloatValue(bossParser, cacheArgs, argNum, defValue);
}
case ArgType_Int:
{
new defValue;
GetTrieValue(argInfo, "defValue", defValue);
AddIntValue(bossParser, cacheArgs, argNum, defValue);
}
case ArgType_String:
{
new String:defValue[MAX_BOSS_NAME_LENGTH];
GetTrieString(argInfo, "defValue", defValue, MAX_BOSS_NAME_LENGTH);
AddStringValue(bossParser, cacheArgs, argNum, defValue);
}
}
}
KvGoBack(bossParser);
}
else
{
for (new i = 0; i < GetArraySize(argKeyNames); i++)
{
GetArrayString(argKeyNames, i, argNum, MAX_BOSS_NAME_LENGTH);
FF2_Debug("Adding default value of #%s as args section isn't found", argNum);
GetTrieValue(args, argNum, argInfo);
GetTrieValue(argInfo, "type", argType);
switch (argType)
{
case ArgType_Float:
{
new Float:defValue;
GetTrieValue(argInfo, "defValue", defValue);
SetTrieValue(cacheArgs, argNum, defValue);
}
case ArgType_Int:
{
new defValue;
GetTrieValue(argInfo, "defValue", defValue);
SetTrieValue(cacheArgs, argNum, defValue);
}
case ArgType_String:
{
new String:defValue[MAX_BOSS_NAME_LENGTH];
GetTrieString(argInfo, "defValue", defValue, MAX_BOSS_NAME_LENGTH);
SetTrieString(cacheArgs, argNum, defValue);
}
}
}
}
FF2_Debug("}");
return true;
}
ParseAbilities(Handle:bossParser, Handle:abilities)
{
FF2_Debug("Preparing to parse abilities.");
FF2_Debug("{");
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(abilities, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
if (KvGotoFirstSubKey(bossParser, false))
{
do
{
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
new Handle:ability = CreateTrie();
FF2_Debug("Preparing to parse ability #%s", strBuffer);
FF2_Debug("{");
if (!ParseAbility(bossParser, ability))
{
if (!SetTrieValue(abilities, strBuffer, ability, false))
SetFailState("We already got ability number #%s", strBuffer);
PushArrayString(keyNames, strBuffer);
}
FF2_Debug("}");
}
while (KvGotoNextKey(bossParser,false));
KvGoBack(bossParser);
}
FF2_Debug("}");
}
ParseBoss(const String:bossFileName[], Handle:bossInfo)
{
FF2_Debug("Preparing to parse %s.", bossFileName);
FF2_Debug("{");
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(bossInfo, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
decl String:bossPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, bossPath, PLATFORM_MAX_PATH, "configs/%s/%s.cfg", FF2_CONFIG_FOLDER_NAME, bossFileName);
if (!FileExists(bossPath))
SetFailState("%T", "FF2 Missing File", LANG_SERVER, PLUGIN_NAME, bossPath);
new Handle:bossParser = CreateKeyValues("Freak Fortress 2 Boss Parser");
if (!FileToKeyValues(bossParser, bossPath))
SetFailState("Why can't I read the config?");
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
if (!StrEqual(strBuffer, "Freak Fortress 2 Boss"))
SetFailState("You boss config is corrupted.");
SetTrieValue(bossInfo, "isSpecial", true);
FF2_Debug("Begin parsing.");
FF2_Debug("{");
AddStringValue(bossParser, bossInfo, "name", "No name");
AddIntValue(bossParser, bossInfo, "class", 3);
AddStringValue(bossParser, bossInfo, "model", "");
AddFloatValue(bossParser, bossInfo, "ragedist", 800.0);
AddStringValue(bossParser, bossInfo, "health_formula", "((1000+n)*n)^1.13");
AddIntValue(bossParser, bossInfo, "lives", 1);
AddFloatValue(bossParser, bossInfo, "speed", 400.0);
AddBoolValue(bossParser, bossInfo, "sound_block_voice", 0);
AddIntValue(bossParser, bossInfo, "damage_before_rage", 1000);
AddBoolValue(bossParser, bossInfo, "no_single_rage", 1);
AddBoolValue(bossParser, bossInfo, "blocked", 0);
KvGotoFirstSubKey(bossParser, false)
do
{
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
if (StrEqual(strBuffer, "description"))
{
new Handle:descTrie = CreateTrie();
if (!SetTrieValue(bossInfo, "description", descTrie, false))
SetFailState("We already got a description!");
new Handle:langArray = CreateArray(MAX_DESCRIPTION_LENGTH);
if (!SetTrieValue(descTrie, "langs", langArray))
SetFailState("NOOOOOOOO! We already got a langArray.");
PushArrayString(keyNames, "description");
FF2_Debug("Parsing descriptions.");
FF2_Debug("{");
KvGotoFirstSubKey(bossParser, false)
do
{
decl String:desc[MAX_DESCRIPTION_LENGTH];
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
KvGetString(bossParser, NULL_STRING, desc, MAX_DESCRIPTION_LENGTH, "");
if (!SetTrieString(descTrie, strBuffer, desc, false))
SetFailState("We already have a description for %s language.", strBuffer);
PushArrayString(langArray, strBuffer);
FF2_Debug("Added description, lang %s, which reads: %s", strBuffer, desc);
}
while (KvGotoNextKey(bossParser, false));
KvGoBack(bossParser);
FF2_Debug("}");
}
if (StrEqual(strBuffer, "weapons"))
{
new Handle:weaponTrie = CreateTrie();
if (!SetTrieValue(bossInfo, "weapons", weaponTrie, false))
SetFailState("We already got weapons info!");
PushArrayString(keyNames, "weapons");
ParseWeapons(bossParser, weaponTrie);
}
if (StrEqual(strBuffer, "abilities"))
{
new Handle:abilities = CreateTrie();
if (!SetTrieValue(bossInfo, "abilities", abilities, false))
SetFailState("We already got abilities!");
PushArrayString(keyNames, "abilities");
ParseAbilities(bossParser, abilities);
}
}
while (KvGotoNextKey(bossParser, false));
KvGoBack(bossParser);
FF2_Debug("}");
FF2_Debug("}");
CloseHandle(bossParser);
}
ParsePack(Handle:bossParser, Handle:bossPackInfo)
{
FF2_Debug("Preparing to parse a boss pack.");
FF2_Debug("{");
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(bossPackInfo, "keyNames", keyNames))
SetFailState("Somehow I recieved what is supposed to be a freshly created trie and we failed to add a keyNames array :/");
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
if (KvGotoFirstSubKey(bossParser, false))
{
do
{
KvGetString(bossParser, NULL_STRING, strBuffer, MAX_BOSS_NAME_LENGTH);
new Handle:bossInfo = CreateTrie();
if (!SetTrieValue(bossPackInfo, strBuffer, bossInfo, false))
SetFailState("%T", "FF2 Boss Exist", LANG_SERVER, strBuffer);
FF2_Debug("Adding %s to cache.", strBuffer);
PushArrayString(keyNames, strBuffer);
ParseBoss(strBuffer, bossInfo);
}
while (KvGotoNextKey(bossParser, false));
KvGoBack(bossParser);
}
FF2_Debug("}");
}
ParseBosses()
{
FF2_Debug("Preparing to parse bosses.");
FF2_Debug("{");
DestroyBosses();
g_hBossCache = CreateTrie();
new Handle:keyNames = CreateArray(MAX_BOSS_NAME_LENGTH);
if (!SetTrieValue(g_hBossCache, "keyNames", keyNames))
SetFailState("Somehow I freshly created this trie and we failed to add a keyNames array :/");
decl String:bossMapPackPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, bossMapPackPath, PLATFORM_MAX_PATH, "configs/%s/ff2_boss_packs.cfg", FF2_CONFIG_FOLDER_NAME);
if (!FileExists(bossMapPackPath))
SetFailState("%T", "FF2 Missing File", LANG_SERVER, PLUGIN_NAME, bossMapPackPath);
new Handle:bossParser = CreateKeyValues("Freak Fortress 2 Boss Pack Parser");
if (!FileToKeyValues(bossParser, bossMapPackPath))
SetFailState("Why can't I read my config?");
decl String:strBuffer[MAX_BOSS_NAME_LENGTH];
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
if (!StrEqual(strBuffer, "Freak Fortress 2 Packs"))
SetFailState("You packs config is corrupted.");
if (KvGotoFirstSubKey(bossParser))
{
FF2_Debug("Begin parsing.");
FF2_Debug("{");
do
{
KvGetSectionName(bossParser, strBuffer, MAX_BOSS_NAME_LENGTH);
new Handle:bossPackInfo = CreateTrie();
if (!SetTrieValue(g_hBossCache, strBuffer, bossPackInfo, false))
SetFailState("%T", "FF2 Pack Exist", LANG_SERVER, strBuffer);
FF2_Debug("Adding pack %s to cache.", strBuffer);
PushArrayString(keyNames, strBuffer);
ParsePack(bossParser, bossPackInfo);
}
while (KvGotoNextKey(bossParser));
KvGoBack(bossParser);
FF2_Debug("}");
FF2_Debug("Done parsing.");
}
FF2_Debug("}");
CloseHandle(bossParser);
}