Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

be_ai_weight.c File Reference

#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_libvar.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_ai_weight.h"

Include dependency graph for be_ai_weight.c:

Include dependency graph

Go to the source code of this file.

Defines

#define EVALUATERECURSIVELY
#define MAX_INVENTORYVALUE   999999
#define MAX_WEIGHT_FILES   128

Functions

void BotShutdownWeights (void)
void EvolveFuzzySeperator_r (fuzzyseperator_t *fs)
void EvolveWeightConfig (weightconfig_t *config)
int FindFuzzyWeight (weightconfig_t *wc, char *name)
void FreeFuzzySeperators_r (fuzzyseperator_t *fs)
void FreeWeightConfig (weightconfig_t *config)
void FreeWeightConfig2 (weightconfig_t *config)
float FuzzyWeight (int *inventory, weightconfig_t *wc, int weightnum)
float FuzzyWeight_r (int *inventory, fuzzyseperator_t *fs)
float FuzzyWeightUndecided (int *inventory, weightconfig_t *wc, int weightnum)
float FuzzyWeightUndecided_r (int *inventory, fuzzyseperator_t *fs)
int InterbreedFuzzySeperator_r (fuzzyseperator_t *fs1, fuzzyseperator_t *fs2, fuzzyseperator_t *fsout)
void InterbreedWeightConfigs (weightconfig_t *config1, weightconfig_t *config2, weightconfig_t *configout)
fuzzyseperator_tReadFuzzySeperators_r (source_t *source)
int ReadFuzzyWeight (source_t *source, fuzzyseperator_t *fs)
int ReadValue (source_t *source, float *value)
weightconfig_tReadWeightConfig (char *filename)
void ScaleFuzzyBalanceRange (weightconfig_t *config, float scale)
void ScaleFuzzySeperator_r (fuzzyseperator_t *fs, float scale)
void ScaleFuzzySeperatorBalanceRange_r (fuzzyseperator_t *fs, float scale)
void ScaleWeight (weightconfig_t *config, char *name, float scale)

Variables

weightconfig_tweightFileList [MAX_WEIGHT_FILES]


Define Documentation

#define EVALUATERECURSIVELY
 

Definition at line 48 of file be_ai_weight.c.

#define MAX_INVENTORYVALUE   999999
 

Definition at line 47 of file be_ai_weight.c.

#define MAX_WEIGHT_FILES   128
 

Definition at line 50 of file be_ai_weight.c.


Function Documentation

void BotShutdownWeights void   ) 
 

Definition at line 900 of file be_ai_weight.c.

References FreeWeightConfig2(), i, and weightFileList.

Referenced by Export_BotLibShutdown().

00901 {
00902     int i;
00903 
00904     for( i = 0; i < MAX_WEIGHT_FILES; i++ )
00905     {
00906         if (weightFileList[i])
00907         {
00908             FreeWeightConfig2(weightFileList[i]);
00909             weightFileList[i] = NULL;
00910         } //end if
00911     } //end for
00912 } //end of the function BotShutdownWeights

Here is the call graph for this function:

void EvolveFuzzySeperator_r fuzzyseperator_t fs  ) 
 

Definition at line 706 of file be_ai_weight.c.

References fuzzyseperator_s::child, crandom, fuzzyseperator_t, fuzzyseperator_s::maxweight, fuzzyseperator_s::minweight, fuzzyseperator_s::next, random, fuzzyseperator_s::type, and fuzzyseperator_s::weight.

Referenced by EvolveWeightConfig().

00707 {
00708     if (fs->child)
00709     {
00710         EvolveFuzzySeperator_r(fs->child);
00711     } //end if
00712     else if (fs->type == WT_BALANCE)
00713     {
00714         //every once in a while an evolution leap occurs, mutation
00715         if (random() < 0.01) fs->weight += crandom() * (fs->maxweight - fs->minweight);
00716         else fs->weight += crandom() * (fs->maxweight - fs->minweight) * 0.5;
00717         //modify bounds if necesary because of mutation
00718         if (fs->weight < fs->minweight) fs->minweight = fs->weight;
00719         else if (fs->weight > fs->maxweight) fs->maxweight = fs->weight;
00720     } //end else if
00721     if (fs->next) EvolveFuzzySeperator_r(fs->next);
00722 } //end of the function EvolveFuzzySeperator_r

void EvolveWeightConfig weightconfig_t config  ) 
 

Definition at line 729 of file be_ai_weight.c.

References EvolveFuzzySeperator_r(), weight_s::firstseperator, i, weightconfig_s::numweights, weightconfig_t, and weightconfig_s::weights.

Referenced by BotMutateGoalFuzzyLogic().

00730 {
00731     int i;
00732 
00733     for (i = 0; i < config->numweights; i++)
00734     {
00735         EvolveFuzzySeperator_r(config->weights[i].firstseperator);
00736     } //end for
00737 } //end of the function EvolveWeightConfig

Here is the call graph for this function:

int FindFuzzyWeight weightconfig_t wc,
char *  name
 

Definition at line 557 of file be_ai_weight.c.

References i, weight_s::name, name, weightconfig_s::numweights, strcmp(), weightconfig_t, and weightconfig_s::weights.

Referenced by ItemWeightIndex(), and WeaponWeightIndex().

00558 {
00559     int i;
00560 
00561     for (i = 0; i < wc->numweights; i++)
00562     {
00563         if (!strcmp(wc->weights[i].name, name))
00564         {
00565             return i;
00566         } //end if
00567     } //end if
00568     return -1;
00569 } //end of the function FindFuzzyWeight

Here is the call graph for this function:

void FreeFuzzySeperators_r fuzzyseperator_t fs  ) 
 

Definition at line 112 of file be_ai_weight.c.

References fuzzyseperator_s::child, FreeMemory(), fuzzyseperator_t, and fuzzyseperator_s::next.

Referenced by FreeWeightConfig2(), and ReadFuzzySeperators_r().

00113 {
00114     if (!fs) return;
00115     if (fs->child) FreeFuzzySeperators_r(fs->child);
00116     if (fs->next) FreeFuzzySeperators_r(fs->next);
00117     FreeMemory(fs);
00118 } //end of the function FreeFuzzySeperators

Here is the call graph for this function:

void FreeWeightConfig weightconfig_t config  ) 
 

Definition at line 142 of file be_ai_weight.c.

References FreeWeightConfig2(), LibVarGetValue(), and weightconfig_t.

Referenced by BotFreeItemWeights(), BotFreeWeaponWeights(), and ReadWeightConfig().

00143 {
00144     if (!LibVarGetValue("bot_reloadcharacters")) return;
00145     FreeWeightConfig2(config);
00146 } //end of the function FreeWeightConfig

Here is the call graph for this function:

void FreeWeightConfig2 weightconfig_t config  ) 
 

Definition at line 125 of file be_ai_weight.c.

References weight_s::firstseperator, FreeFuzzySeperators_r(), FreeMemory(), i, weight_s::name, weightconfig_s::numweights, weightconfig_t, and weightconfig_s::weights.

Referenced by BotShutdownWeights(), and FreeWeightConfig().

00126 {
00127     int i;
00128 
00129     for (i = 0; i < config->numweights; i++)
00130     {
00131         FreeFuzzySeperators_r(config->weights[i].firstseperator);
00132         if (config->weights[i].name) FreeMemory(config->weights[i].name);
00133     } //end for
00134     FreeMemory(config);
00135 } //end of the function FreeWeightConfig2

Here is the call graph for this function:

float FuzzyWeight int *  inventory,
weightconfig_t wc,
int  weightnum
 

Definition at line 644 of file be_ai_weight.c.

References fuzzyseperator_s::child, weight_s::firstseperator, fuzzyseperator_t, FuzzyWeight_r(), fuzzyseperator_s::index, fuzzyseperator_s::next, s, fuzzyseperator_s::value, fuzzyseperator_s::weight, weightconfig_t, and weightconfig_s::weights.

Referenced by BotChooseBestFightWeapon(), BotChooseLTGItem(), and BotChooseNBGItem().

00645 {
00646 #ifdef EVALUATERECURSIVELY
00647     return FuzzyWeight_r(inventory, wc->weights[weightnum].firstseperator);
00648 #else
00649     fuzzyseperator_t *s;
00650 
00651     s = wc->weights[weightnum].firstseperator;
00652     if (!s) return 0;
00653     while(1)
00654     {
00655         if (inventory[s->index] < s->value)
00656         {
00657             if (s->child) s = s->child;
00658             else return s->weight;
00659         } //end if
00660         else
00661         {
00662             if (s->next) s = s->next;
00663             else return s->weight;
00664         } //end else
00665     } //end if
00666     return 0;
00667 #endif
00668 } //end of the function FuzzyWeight

Here is the call graph for this function:

float FuzzyWeight_r int *  inventory,
fuzzyseperator_t fs
 

Definition at line 576 of file be_ai_weight.c.

References fuzzyseperator_s::child, fuzzyseperator_t, fuzzyseperator_s::index, fuzzyseperator_s::next, fuzzyseperator_s::value, and fuzzyseperator_s::weight.

Referenced by FuzzyWeight(), and FuzzyWeightUndecided_r().

00577 {
00578     float scale, w1, w2;
00579 
00580     if (inventory[fs->index] < fs->value)
00581     {
00582         if (fs->child) return FuzzyWeight_r(inventory, fs->child);
00583         else return fs->weight;
00584     } //end if
00585     else if (fs->next)
00586     {
00587         if (inventory[fs->index] < fs->next->value)
00588         {
00589             //first weight
00590             if (fs->child) w1 = FuzzyWeight_r(inventory, fs->child);
00591             else w1 = fs->weight;
00592             //second weight
00593             if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
00594             else w2 = fs->next->weight;
00595             //the scale factor
00596             scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
00597             //scale between the two weights
00598             return scale * w1 + (1 - scale) * w2;
00599         } //end if
00600         return FuzzyWeight_r(inventory, fs->next);
00601     } //end else if
00602     return fs->weight;
00603 } //end of the function FuzzyWeight_r

float FuzzyWeightUndecided int *  inventory,
weightconfig_t wc,
int  weightnum
 

Definition at line 675 of file be_ai_weight.c.

References fuzzyseperator_s::child, weight_s::firstseperator, fuzzyseperator_t, FuzzyWeightUndecided_r(), fuzzyseperator_s::index, fuzzyseperator_s::maxweight, fuzzyseperator_s::minweight, fuzzyseperator_s::next, random, s, fuzzyseperator_s::value, weightconfig_t, and weightconfig_s::weights.

Referenced by BotChooseLTGItem(), and BotChooseNBGItem().

00676 {
00677 #ifdef EVALUATERECURSIVELY
00678     return FuzzyWeightUndecided_r(inventory, wc->weights[weightnum].firstseperator);
00679 #else
00680     fuzzyseperator_t *s;
00681 
00682     s = wc->weights[weightnum].firstseperator;
00683     if (!s) return 0;
00684     while(1)
00685     {
00686         if (inventory[s->index] < s->value)
00687         {
00688             if (s->child) s = s->child;
00689             else return s->minweight + random() * (s->maxweight - s->minweight);
00690         } //end if
00691         else
00692         {
00693             if (s->next) s = s->next;
00694             else return s->minweight + random() * (s->maxweight - s->minweight);
00695         } //end else
00696     } //end if
00697     return 0;
00698 #endif
00699 } //end of the function FuzzyWeightUndecided

Here is the call graph for this function:

float FuzzyWeightUndecided_r int *  inventory,
fuzzyseperator_t fs
 

Definition at line 610 of file be_ai_weight.c.

References fuzzyseperator_s::child, fuzzyseperator_t, FuzzyWeight_r(), fuzzyseperator_s::index, fuzzyseperator_s::maxweight, fuzzyseperator_s::minweight, fuzzyseperator_s::next, random, fuzzyseperator_s::value, and fuzzyseperator_s::weight.

Referenced by FuzzyWeightUndecided().

00611 {
00612     float scale, w1, w2;
00613 
00614     if (inventory[fs->index] < fs->value)
00615     {
00616         if (fs->child) return FuzzyWeightUndecided_r(inventory, fs->child);
00617         else return fs->minweight + random() * (fs->maxweight - fs->minweight);
00618     } //end if
00619     else if (fs->next)
00620     {
00621         if (inventory[fs->index] < fs->next->value)
00622         {
00623             //first weight
00624             if (fs->child) w1 = FuzzyWeightUndecided_r(inventory, fs->child);
00625             else w1 = fs->minweight + random() * (fs->maxweight - fs->minweight);
00626             //second weight
00627             if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
00628             else w2 = fs->next->minweight + random() * (fs->next->maxweight - fs->next->minweight);
00629             //the scale factor
00630             scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
00631             //scale between the two weights
00632             return scale * w1 + (1 - scale) * w2;
00633         } //end if
00634         return FuzzyWeightUndecided_r(inventory, fs->next);
00635     } //end else if
00636     return fs->weight;
00637 } //end of the function FuzzyWeightUndecided_r

Here is the call graph for this function:

int InterbreedFuzzySeperator_r fuzzyseperator_t fs1,
fuzzyseperator_t fs2,
fuzzyseperator_t fsout
 

Definition at line 829 of file be_ai_weight.c.

References botimport, fuzzyseperator_s::child, fuzzyseperator_t, fuzzyseperator_s::maxweight, fuzzyseperator_s::minweight, fuzzyseperator_s::next, PRT_ERROR, fuzzyseperator_s::type, fuzzyseperator_s::weight, and WT_BALANCE.

Referenced by InterbreedWeightConfigs().

00831 {
00832     if (fs1->child)
00833     {
00834         if (!fs2->child || !fsout->child)
00835         {
00836             botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal child\n");
00837             return qfalse;
00838         } //end if
00839         if (!InterbreedFuzzySeperator_r(fs2->child, fs2->child, fsout->child))
00840         {
00841             return qfalse;
00842         } //end if
00843     } //end if
00844     else if (fs1->type == WT_BALANCE)
00845     {
00846         if (fs2->type != WT_BALANCE || fsout->type != WT_BALANCE)
00847         {
00848             botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal balance\n");
00849             return qfalse;
00850         } //end if
00851         fsout->weight = (fs1->weight + fs2->weight) / 2;
00852         if (fsout->weight > fsout->maxweight) fsout->maxweight = fsout->weight;
00853         if (fsout->weight > fsout->minweight) fsout->minweight = fsout->weight;
00854     } //end else if
00855     if (fs1->next)
00856     {
00857         if (!fs2->next || !fsout->next)
00858         {
00859             botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal next\n");
00860             return qfalse;
00861         } //end if
00862         if (!InterbreedFuzzySeperator_r(fs1->next, fs2->next, fsout->next))
00863         {
00864             return qfalse;
00865         } //end if
00866     } //end if
00867     return qtrue;
00868 } //end of the function InterbreedFuzzySeperator_r

void InterbreedWeightConfigs weightconfig_t config1,
weightconfig_t config2,
weightconfig_t configout
 

Definition at line 876 of file be_ai_weight.c.

References botimport, weight_s::firstseperator, i, InterbreedFuzzySeperator_r(), weightconfig_s::numweights, PRT_ERROR, weightconfig_t, and weightconfig_s::weights.

Referenced by BotInterbreedGoalFuzzyLogic().

00878 {
00879     int i;
00880 
00881     if (config1->numweights != config2->numweights ||
00882         config1->numweights != configout->numweights)
00883     {
00884         botimport.Print(PRT_ERROR, "cannot interbreed weight configs, unequal numweights\n");
00885         return;
00886     } //end if
00887     for (i = 0; i < config1->numweights; i++)
00888     {
00889         InterbreedFuzzySeperator_r(config1->weights[i].firstseperator,
00890                                     config2->weights[i].firstseperator,
00891                                     configout->weights[i].firstseperator);
00892     } //end for
00893 } //end of the function InterbreedWeightConfigs

Here is the call graph for this function:

fuzzyseperator_t* ReadFuzzySeperators_r source_t source  ) 
 

Definition at line 153 of file be_ai_weight.c.

References fuzzyseperator_s::child, FreeFuzzySeperators_r(), fuzzyseperator_t, GetClearedMemory(), fuzzyseperator_s::index, token_s::intvalue, fuzzyseperator_s::next, PC_ExpectAnyToken(), PC_ExpectTokenString(), PC_ExpectTokenType(), ReadFuzzyWeight(), source, source_t, SourceError(), SourceWarning(), strcmp(), token_s::string, token, token_t, TT_INTEGER, TT_NUMBER, fuzzyseperator_s::value, and fuzzyseperator_s::weight.

Referenced by ReadWeightConfig().

00154 {
00155     int newindent, index, def, founddefault;
00156     token_t token;
00157     fuzzyseperator_t *fs, *lastfs, *firstfs;
00158 
00159     founddefault = qfalse;
00160     firstfs = NULL;
00161     lastfs = NULL;
00162     if (!PC_ExpectTokenString(source, "(")) return NULL;
00163     if (!PC_ExpectTokenType(source, TT_NUMBER, TT_INTEGER, &token)) return NULL;
00164     index = token.intvalue;
00165     if (!PC_ExpectTokenString(source, ")")) return NULL;
00166     if (!PC_ExpectTokenString(source, "{")) return NULL;
00167     if (!PC_ExpectAnyToken(source, &token)) return NULL;
00168     do
00169     {
00170         def = !strcmp(token.string, "default");
00171         if (def || !strcmp(token.string, "case"))
00172         {
00173             fs = (fuzzyseperator_t *) GetClearedMemory(sizeof(fuzzyseperator_t));
00174             fs->index = index;
00175             if (lastfs) lastfs->next = fs;
00176             else firstfs = fs;
00177             lastfs = fs;
00178             if (def)
00179             {
00180                 if (founddefault)
00181                 {
00182                     SourceError(source, "switch already has a default\n");
00183                     FreeFuzzySeperators_r(firstfs);
00184                     return NULL;
00185                 } //end if
00186                 fs->value = MAX_INVENTORYVALUE;
00187                 founddefault = qtrue;
00188             } //end if
00189             else
00190             {
00191                 if (!PC_ExpectTokenType(source, TT_NUMBER, TT_INTEGER, &token))
00192                 {
00193                     FreeFuzzySeperators_r(firstfs);
00194                     return NULL;
00195                 } //end if
00196                 fs->value = token.intvalue;
00197             } //end else
00198             if (!PC_ExpectTokenString(source, ":") || !PC_ExpectAnyToken(source, &token))
00199             {
00200                 FreeFuzzySeperators_r(firstfs);
00201                 return NULL;
00202             } //end if
00203             newindent = qfalse;
00204             if (!strcmp(token.string, "{"))
00205             {
00206                 newindent = qtrue;
00207                 if (!PC_ExpectAnyToken(source, &token))
00208                 {
00209                     FreeFuzzySeperators_r(firstfs);
00210                     return NULL;
00211                 } //end if
00212             } //end if
00213             if (!strcmp(token.string, "return"))
00214             {
00215                 if (!ReadFuzzyWeight(source, fs))
00216                 {
00217                     FreeFuzzySeperators_r(firstfs);
00218                     return NULL;
00219                 } //end if
00220             } //end if
00221             else if (!strcmp(token.string, "switch"))
00222             {
00223                 fs->child = ReadFuzzySeperators_r(source);
00224                 if (!fs->child)
00225                 {
00226                     FreeFuzzySeperators_r(firstfs);
00227                     return NULL;
00228                 } //end if
00229             } //end else if
00230             else
00231             {
00232                 SourceError(source, "invalid name %s\n", token.string);
00233                 return NULL;
00234             } //end else
00235             if (newindent)
00236             {
00237                 if (!PC_ExpectTokenString(source, "}"))
00238                 {
00239                     FreeFuzzySeperators_r(firstfs);
00240                     return NULL;
00241                 } //end if
00242             } //end if
00243         } //end if
00244         else
00245         {
00246             FreeFuzzySeperators_r(firstfs);
00247             SourceError(source, "invalid name %s\n", token.string);
00248             return NULL;
00249         } //end else
00250         if (!PC_ExpectAnyToken(source, &token))
00251         {
00252             FreeFuzzySeperators_r(firstfs);
00253             return NULL;
00254         } //end if
00255     } while(strcmp(token.string, "}"));
00256     //
00257     if (!founddefault)
00258     {
00259         SourceWarning(source, "switch without default\n");
00260         fs = (fuzzyseperator_t *) GetClearedMemory(sizeof(fuzzyseperator_t));
00261         fs->index = index;
00262         fs->value = MAX_INVENTORYVALUE;
00263         fs->weight = 0;
00264         fs->next = NULL;
00265         fs->child = NULL;
00266         if (lastfs) lastfs->next = fs;
00267         else firstfs = fs;
00268         lastfs = fs;
00269     } //end if
00270     //
00271     return firstfs;
00272 } //end of the function ReadFuzzySeperators_r

Here is the call graph for this function:

int ReadFuzzyWeight source_t source,
fuzzyseperator_t fs
 

Definition at line 83 of file be_ai_weight.c.

References fuzzyseperator_t, fuzzyseperator_s::maxweight, fuzzyseperator_s::minweight, PC_CheckTokenString(), PC_ExpectTokenString(), ReadValue(), source, source_t, fuzzyseperator_s::type, and fuzzyseperator_s::weight.

Referenced by ReadFuzzySeperators_r(), and ReadWeightConfig().

00084 {
00085     if (PC_CheckTokenString(source, "balance"))
00086     {
00087         fs->type = WT_BALANCE;
00088         if (!PC_ExpectTokenString(source, "(")) return qfalse;
00089         if (!ReadValue(source, &fs->weight)) return qfalse;
00090         if (!PC_ExpectTokenString(source, ",")) return qfalse;
00091         if (!ReadValue(source, &fs->minweight)) return qfalse;
00092         if (!PC_ExpectTokenString(source, ",")) return qfalse;
00093         if (!ReadValue(source, &fs->maxweight)) return qfalse;
00094         if (!PC_ExpectTokenString(source, ")")) return qfalse;
00095     } //end if
00096     else
00097     {
00098         fs->type = 0;
00099         if (!ReadValue(source, &fs->weight)) return qfalse;
00100         fs->minweight = fs->weight;
00101         fs->maxweight = fs->weight;
00102     } //end if
00103     if (!PC_ExpectTokenString(source, ";")) return qfalse;
00104     return qtrue;
00105 } //end of the function ReadFuzzyWeight

Here is the call graph for this function:

int ReadValue source_t source,
float *  value
 

Definition at line 59 of file be_ai_weight.c.

References token_s::floatvalue, PC_ExpectAnyToken(), PC_ExpectTokenType(), source, source_t, SourceError(), SourceWarning(), strcmp(), token_s::string, token, token_t, TT_NUMBER, token_s::type, and value.

Referenced by ReadFuzzyWeight().

00060 {
00061     token_t token;
00062 
00063     if (!PC_ExpectAnyToken(source, &token)) return qfalse;
00064     if (!strcmp(token.string, "-"))
00065     {
00066         SourceWarning(source, "negative value set to zero\n");
00067         if (!PC_ExpectTokenType(source, TT_NUMBER, 0, &token)) return qfalse;
00068     } //end if
00069     if (token.type != TT_NUMBER)
00070     {
00071         SourceError(source, "invalid return value %s\n", token.string);
00072         return qfalse;
00073     } //end if
00074     *value = token.floatvalue;
00075     return qtrue;
00076 } //end of the function ReadValue

Here is the call graph for this function:

weightconfig_t* ReadWeightConfig char *  filename  ) 
 

Definition at line 279 of file be_ai_weight.c.

References BOTFILESBASEFOLDER, botimport, fuzzyseperator_s::child, weightconfig_s::filename, weight_s::firstseperator, FreeMemory(), FreeSource(), FreeWeightConfig(), fuzzyseperator_t, GetClearedMemory(), fuzzyseperator_s::index, LibVarGetValue(), LoadSourceFile(), n, weight_s::name, fuzzyseperator_s::next, weightconfig_s::numweights, PC_ExpectAnyToken(), PC_ExpectTokenString(), PC_ExpectTokenType(), PC_ReadToken(), PC_SetBaseFolder(), PRT_ERROR, PRT_MESSAGE, Q_strncpyz(), ReadFuzzySeperators_r(), ReadFuzzyWeight(), source, source_t, SourceError(), SourceWarning(), strcmp(), strcpy(), token_s::string, StripDoubleQuotes(), strlen(), Sys_MilliSeconds(), token, token_t, TT_STRING, fuzzyseperator_s::value, weightconfig_t, weightFileList, and weightconfig_s::weights.

Referenced by BotLoadItemWeights(), and BotLoadWeaponWeights().

00280 {
00281     int newindent, avail = 0, n;
00282     token_t token;
00283     source_t *source;
00284     fuzzyseperator_t *fs;
00285     weightconfig_t *config = NULL;
00286 #ifdef DEBUG
00287     int starttime;
00288 
00289     starttime = Sys_MilliSeconds();
00290 #endif //DEBUG
00291 
00292     if (!LibVarGetValue("bot_reloadcharacters"))
00293     {
00294         avail = -1;
00295         for( n = 0; n < MAX_WEIGHT_FILES; n++ )
00296         {
00297             config = weightFileList[n];
00298             if( !config )
00299             {
00300                 if( avail == -1 )
00301                 {
00302                     avail = n;
00303                 } //end if
00304                 continue;
00305             } //end if
00306             if( strcmp( filename, config->filename ) == 0 )
00307             {
00308                 //botimport.Print( PRT_MESSAGE, "retained %s\n", filename );
00309                 return config;
00310             } //end if
00311         } //end for
00312 
00313         if( avail == -1 )
00314         {
00315             botimport.Print( PRT_ERROR, "weightFileList was full trying to load %s\n", filename );
00316             return NULL;
00317         } //end if
00318     } //end if
00319 
00320     PC_SetBaseFolder(BOTFILESBASEFOLDER);
00321     source = LoadSourceFile(filename);
00322     if (!source)
00323     {
00324         botimport.Print(PRT_ERROR, "counldn't load %s\n", filename);
00325         return NULL;
00326     } //end if
00327     //
00328     config = (weightconfig_t *) GetClearedMemory(sizeof(weightconfig_t));
00329     config->numweights = 0;
00330     Q_strncpyz( config->filename, filename, sizeof(config->filename) );
00331     //parse the item config file
00332     while(PC_ReadToken(source, &token))
00333     {
00334         if (!strcmp(token.string, "weight"))
00335         {
00336             if (config->numweights >= MAX_WEIGHTS)
00337             {
00338                 SourceWarning(source, "too many fuzzy weights\n");
00339                 break;
00340             } //end if
00341             if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
00342             {
00343                 FreeWeightConfig(config);
00344                 FreeSource(source);
00345                 return NULL;
00346             } //end if
00347             StripDoubleQuotes(token.string);
00348             config->weights[config->numweights].name = (char *) GetClearedMemory(strlen(token.string) + 1);
00349             strcpy(config->weights[config->numweights].name, token.string);
00350             if (!PC_ExpectAnyToken(source, &token))
00351             {
00352                 FreeWeightConfig(config);
00353                 FreeSource(source);
00354                 return NULL;
00355             } //end if
00356             newindent = qfalse;
00357             if (!strcmp(token.string, "{"))
00358             {
00359                 newindent = qtrue;
00360                 if (!PC_ExpectAnyToken(source, &token))
00361                 {
00362                     FreeWeightConfig(config);
00363                     FreeSource(source);
00364                     return NULL;
00365                 } //end if
00366             } //end if
00367             if (!strcmp(token.string, "switch"))
00368             {
00369                 fs = ReadFuzzySeperators_r(source);
00370                 if (!fs)
00371                 {
00372                     FreeWeightConfig(config);
00373                     FreeSource(source);
00374                     return NULL;
00375                 } //end if
00376                 config->weights[config->numweights].firstseperator = fs;
00377             } //end if
00378             else if (!strcmp(token.string, "return"))
00379             {
00380                 fs = (fuzzyseperator_t *) GetClearedMemory(sizeof(fuzzyseperator_t));
00381                 fs->index = 0;
00382                 fs->value = MAX_INVENTORYVALUE;
00383                 fs->next = NULL;
00384                 fs->child = NULL;
00385                 if (!ReadFuzzyWeight(source, fs))
00386                 {
00387                     FreeMemory(fs);
00388                     FreeWeightConfig(config);
00389                     FreeSource(source);
00390                     return NULL;
00391                 } //end if
00392                 config->weights[config->numweights].firstseperator = fs;
00393             } //end else if
00394             else
00395             {
00396                 SourceError(source, "invalid name %s\n", token.string);
00397                 FreeWeightConfig(config);
00398                 FreeSource(source);
00399                 return NULL;
00400             } //end else
00401             if (newindent)
00402             {
00403                 if (!PC_ExpectTokenString(source, "}"))
00404                 {
00405                     FreeWeightConfig(config);
00406                     FreeSource(source);
00407                     return NULL;
00408                 } //end if
00409             } //end if
00410             config->numweights++;
00411         } //end if
00412         else
00413         {
00414             SourceError(source, "invalid name %s\n", token.string);
00415             FreeWeightConfig(config);
00416             FreeSource(source);
00417             return NULL;
00418         } //end else
00419     } //end while
00420     //free the source at the end of a pass
00421     FreeSource(source);
00422     //if the file was located in a pak file
00423     botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
00424 #ifdef DEBUG
00425     if (bot_developer)
00426     {
00427         botimport.Print(PRT_MESSAGE, "weights loaded in %d msec\n", Sys_MilliSeconds() - starttime);
00428     } //end if
00429 #endif //DEBUG
00430     //
00431     if (!LibVarGetValue("bot_reloadcharacters"))
00432     {
00433         weightFileList[avail] = config;
00434     } //end if
00435     //
00436     return config;
00437 } //end of the function ReadWeightConfig

Here is the call graph for this function:

void ScaleFuzzyBalanceRange weightconfig_t config,
float  scale
 

Definition at line 812 of file be_ai_weight.c.

References weight_s::firstseperator, i, weightconfig_s::numweights, ScaleFuzzySeperatorBalanceRange_r(), weightconfig_t, and weightconfig_s::weights.

00813 {
00814     int i;
00815 
00816     if (scale < 0) scale = 0;
00817     else if (scale > 100) scale = 100;
00818     for (i = 0; i < config->numweights; i++)
00819     {
00820         ScaleFuzzySeperatorBalanceRange_r(config->weights[i].firstseperator, scale);
00821     } //end for
00822 } //end of the function ScaleFuzzyBalanceRange

Here is the call graph for this function:

void ScaleFuzzySeperator_r fuzzyseperator_t fs,
float  scale
 

Definition at line 744 of file be_ai_weight.c.

References fuzzyseperator_s::child, fuzzyseperator_t, fuzzyseperator_s::maxweight, fuzzyseperator_s::minweight, fuzzyseperator_s::next, fuzzyseperator_s::type, and fuzzyseperator_s::weight.

Referenced by ScaleWeight().

00745 {
00746     if (fs->child)
00747     {
00748         ScaleFuzzySeperator_r(fs->