Carnivores Wiki
Advertisement

_RES.TXT is the main configuration file for Carnivores 2 and Carnivores Ice Age, located in the "HUNTDAT" folder. It is a text file divided into three main blocks, delineated by curly braces ({}): "weapons", "characters", and "prices". The "weapons" and "characters" blocks are further divided into separate sub-blocks for each weapon and animal.

History and technical details[]

_RES.TXT was first introduced during the development of Carnivores 2. At this time, the existing animal and weapon definitions in Game.cpp were left intact, simply being commented out.

    WeapInfo[0].Name = "Shotgun";
    WeapInfo[0].Power = 1.5f;
    WeapInfo[0].Prec  = 1.1f;
    WeapInfo[0].Loud  = 0.3f;
    WeapInfo[0].Rate  = 1.6f;
    WeapInfo[0].Shots = 6;

    WeapInfo[1].Name = "X-Bow";
    WeapInfo[1].Power = 1.1f;
    WeapInfo[1].Prec  = 0.7f;
    WeapInfo[1].Loud  = 1.9f;
    WeapInfo[1].Rate  = 1.2f;
    WeapInfo[1].Shots = 8;

    WeapInfo[2].Name = "Sniper Rifle";
    WeapInfo[2].Power = 1.0f;
    WeapInfo[2].Prec  = 1.8f;
    WeapInfo[2].Loud  = 0.6f;
    WeapInfo[2].Rate  = 1.0f;
    WeapInfo[2].Shots = 6;



    DinoInfo[ 0].Name = "Moschops";
    DinoInfo[ 0].Health0 = 2;
    DinoInfo[ 0].Mass = 0.15f;

    DinoInfo[ 1].Name = "Galimimus";
    DinoInfo[ 1].Health0 = 2;
    DinoInfo[ 1].Mass = 0.1f;

    DinoInfo[ 2].Name = "Dimorphodon";
    DinoInfo[ 2].Health0 = 1;
    DinoInfo[ 2].Mass = 0.05f;

    DinoInfo[ 3].Name = "Dimetrodon";
    DinoInfo[ 3].Health0 = 2;
    DinoInfo[ 3].Mass = 0.22f;	


    DinoInfo[ 5].Name = "Parasaurolophus";
    DinoInfo[ 5].Mass = 1.5f;
    DinoInfo[ 5].Length = 5.8f;
    DinoInfo[ 5].Radius = 320.f;
    DinoInfo[ 5].Health0 = 5;
    DinoInfo[ 5].BaseScore = 6;
    DinoInfo[ 5].SmellK = 0.8f; DinoInfo[ 4].HearK = 1.f; DinoInfo[ 4].LookK = 0.4f;
    DinoInfo[ 5].ShDelta = 48;

    DinoInfo[ 6].Name = "Pachycephalosaurus";
    DinoInfo[ 6].Mass = 0.8f;
    DinoInfo[ 6].Length = 4.5f;
    DinoInfo[ 6].Radius = 280.f;
    DinoInfo[ 6].Health0 = 4;
    DinoInfo[ 6].BaseScore = 8;
    DinoInfo[ 6].SmellK = 0.4f; DinoInfo[ 5].HearK = 0.8f; DinoInfo[ 5].LookK = 0.6f;
    DinoInfo[ 6].ShDelta = 36;

    DinoInfo[ 7].Name = "Stegosaurus";
    DinoInfo[ 7].Mass = 7.f;
    DinoInfo[ 7].Length = 7.f;
    DinoInfo[ 7].Radius = 480.f;
    DinoInfo[ 7].Health0 = 5;
    DinoInfo[ 7].BaseScore = 7;
    DinoInfo[ 7].SmellK = 0.4f; DinoInfo[ 6].HearK = 0.8f; DinoInfo[ 6].LookK = 0.6f;
    DinoInfo[ 7].ShDelta = 128;

    DinoInfo[ 8].Name = "Allosaurus";
    DinoInfo[ 8].Mass = 0.5;
    DinoInfo[ 8].Length = 4.2f;
    DinoInfo[ 8].Radius = 256.f;
    DinoInfo[ 8].Health0 = 3;
    DinoInfo[ 8].BaseScore = 12;
    DinoInfo[ 8].Scale0 = 1000;
    DinoInfo[ 8].ScaleA = 600;
    DinoInfo[ 8].SmellK = 1.0f; DinoInfo[ 7].HearK = 0.3f; DinoInfo[ 7].LookK = 0.5f;
    DinoInfo[ 8].ShDelta = 32;
    DinoInfo[ 8].DangerCall = TRUE;

    DinoInfo[ 9].Name = "Chasmosaurus";
    DinoInfo[ 9].Mass = 3.f;
    DinoInfo[ 9].Length = 5.0f;
    DinoInfo[ 9].Radius = 400.f;	
    DinoInfo[ 9].Health0 = 8;
    DinoInfo[ 9].BaseScore = 9;
    DinoInfo[ 9].SmellK = 0.6f; DinoInfo[ 8].HearK = 0.5f; DinoInfo[ 8].LookK = 0.4f;
    //DinoInfo[ 8].ShDelta = 148;
    DinoInfo[ 9].ShDelta = 108;

    DinoInfo[10].Name = "Velociraptor";
    DinoInfo[10].Mass = 0.3f;
    DinoInfo[10].Length = 4.0f;
    DinoInfo[10].Radius = 256.f;
    DinoInfo[10].Health0 = 3;
    DinoInfo[10].BaseScore = 16;
    DinoInfo[10].ScaleA = 400;
    DinoInfo[10].SmellK = 1.0f; DinoInfo[ 9].HearK = 0.5f; DinoInfo[ 9].LookK = 0.4f;
    DinoInfo[10].ShDelta =-24;
    DinoInfo[10].DangerCall = TRUE;

    DinoInfo[11].Name = "T-Rex";
    DinoInfo[11].Mass = 6.f;
    DinoInfo[11].Length = 12.f;
    DinoInfo[11].Radius = 400.f;
    DinoInfo[11].Health0 = 1024;
    DinoInfo[11].BaseScore = 20;
    DinoInfo[11].SmellK = 0.85f; DinoInfo[10].HearK = 0.8f; DinoInfo[10].LookK = 0.8f;
    DinoInfo[11].ShDelta = 168;
    DinoInfo[11].DangerCall = TRUE;

    DinoInfo[ 4].Name = "Brahiosaurus";
    DinoInfo[ 4].Mass = 9.f;
    DinoInfo[ 4].Length = 12.f;
    DinoInfo[ 4].Radius = 400.f;
    DinoInfo[ 4].Health0 = 1024;
    DinoInfo[ 4].BaseScore = 0;
    DinoInfo[ 4].SmellK = 0.85f; DinoInfo[16].HearK = 0.8f; DinoInfo[16].LookK = 0.8f;
    DinoInfo[ 4].ShDelta = 168;
    DinoInfo[ 4].DangerCall = FALSE;

This code shows that _RES.TXT was created after Dimetrodon and Brachiosaurus (at that time misspelled as "Brahiosaurus") had been added and Triceratops had been changed to Chasmosaurus, and before Pachycephalosaurus had been removed (no weapons had been added or changed yet). Furthermore, looking at the array index numbers on the line DinoInfo[ 4].SmellK = 0.85f; DinoInfo[16].HearK = 0.8f; DinoInfo[16].LookK = 0.8f; for the Brachiosaurus (especially in comparison to the same line for other animals) shows that it had originally been added as a pointable animal, probably with a higher price than Tyrannosaurus, but was changed to an ambient animal at some point before the introduction of _RES.TXT.

This comment block is part of the function initGameInfo(), the rest of which shows that, if not defined in _RES.TXT, scale0, scaleA, and shipdelta default to 800, 600, and 0, respectively:

void InitGameInfo()
{
    for (int c=0; c<32; c++) {
        DinoInfo[c].Scale0 = 800;
        DinoInfo[c].ScaleA = 600;
        DinoInfo[c].ShDelta = 0;
/*
    above code block is here
*/
    }
    LoadResourcesScript();
}

LoadResourcesScript()[]

_RES.TXT is initially read by the function LoadResourcesScript() in Resources.cpp:

void LoadResourcesScript()
{
    FILE *stream;
    char line[256];

    stream = fopen("HUNTDAT\\_res.txt", "r");
    if (!stream) DoHalt("Can't open resources file _res.txt");

    while (fgets( line, 255, stream)) {
        if (line[0] == '.') break;
        if (strstr(line, "weapons") ) ReadWeapons(stream);
        if (strstr(line, "characters") ) ReadCharacters(stream);
    }

    fclose (stream);
}

This code shows a few things: each line in _RES.TXT is expected to be 255 or fewer characters in length, any line beginning with a "." (period) is treated as the end of the file (EOF), and lines containing the strings "weapons" or "characters" cause the functions ReadWeapons() and ReadCharacters(), respectively, to be called.

ReadWeapons()[]

ReadWeapons(), defined in Resources.cpp, is responsible for loading the information for each weapon from _RES.TXT:

void ReadWeapons(FILE *stream)
{
    TotalW = 0;	
    char line[256], *value;
    while (fgets( line, 255, stream)) 
    {		
        if (strstr(line, "}")) break;
        if (strstr(line, "{")) 
            while (fgets( line, 255, stream)) {								
                if (strstr(line, "}")) { TotalW++; break; }
                value = strstr(line, "=");
                if (!value) DoHalt("Script loading error");
                value++;

                if (strstr(line, "power"))  WeapInfo[TotalW].Power = (float)atof(value);
                if (strstr(line, "prec"))   WeapInfo[TotalW].Prec  = (float)atof(value);
                if (strstr(line, "loud"))   WeapInfo[TotalW].Loud  = (float)atof(value);
                if (strstr(line, "rate"))   WeapInfo[TotalW].Rate  = (float)atof(value);
                if (strstr(line, "shots"))  WeapInfo[TotalW].Shots =        atoi(value);
                if (strstr(line, "reload")) WeapInfo[TotalW].Reload=        atoi(value);
                if (strstr(line, "trace"))  WeapInfo[TotalW].TraceC=        atoi(value)-1;
                if (strstr(line, "optic"))  WeapInfo[TotalW].Optic =        atoi(value);
                if (strstr(line, "fall"))   WeapInfo[TotalW].Fall  =        atoi(value);
                //if (strstr(line, "price")) WeapInfo[TotalW].Price =        atoi(value);

                if (strstr(line, "name")) {					
                    value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
                    value[strlen(value)-2] = 0;
                    strcpy(WeapInfo[TotalW].Name, &value[1]); }				

                if (strstr(line, "file")) {					
                    value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
                    value[strlen(value)-2] = 0;
                    strcpy(WeapInfo[TotalW].FName, &value[1]);}

                if (strstr(line, "pic")) {					
                    value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
                    value[strlen(value)-2] = 0;
                    strcpy(WeapInfo[TotalW].BFName, &value[1]);}
            }

    }

}

ReadCharacters()[]

ReadCharacters(), defined in Resources.cpp, is responsible for loading the information for each animal from _RES.TXT:

void ReadCharacters(FILE *stream)
{
    TotalC = 0;
    char line[256], *value;
    while (fgets( line, 255, stream)) 
    {
        if (strstr(line, "}")) break;
        if (strstr(line, "{")) 
            while (fgets( line, 255, stream)) {				

                if (strstr(line, "}")) { 
                    AI_to_CIndex[DinoInfo[TotalC].AI] = TotalC;
                    TotalC++; 
                    break; 
                }

                value = strstr(line, "=");
                if (!value) 
                    DoHalt("Script loading error");
                value++;

                if (strstr(line, "mass"     )) DinoInfo[TotalC].Mass      = (float)atof(value);
                if (strstr(line, "length"   )) DinoInfo[TotalC].Length    = (float)atof(value);
                if (strstr(line, "radius"   )) DinoInfo[TotalC].Radius    = (float)atof(value);
                if (strstr(line, "health"   )) DinoInfo[TotalC].Health0   = atoi(value);
                if (strstr(line, "basescore")) DinoInfo[TotalC].BaseScore = atoi(value);
                if (strstr(line, "ai"       )) DinoInfo[TotalC].AI        = atoi(value);
                if (strstr(line, "smell"    )) DinoInfo[TotalC].SmellK    = (float)atof(value);
                if (strstr(line, "hear"     )) DinoInfo[TotalC].HearK     = (float)atof(value);
                if (strstr(line, "look"     )) DinoInfo[TotalC].LookK     = (float)atof(value);
                if (strstr(line, "shipdelta")) DinoInfo[TotalC].ShDelta   = (float)atof(value);
                if (strstr(line, "scale0"   )) DinoInfo[TotalC].Scale0    = atoi(value);
                if (strstr(line, "scaleA"   )) DinoInfo[TotalC].ScaleA    = atoi(value);
                if (strstr(line, "danger"   )) DinoInfo[TotalC].DangerCall= TRUE;

                if (strstr(line, "name")) {					
                    value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
                    value[strlen(value)-2] = 0;
                    strcpy(DinoInfo[TotalC].Name, &value[1]); }

                if (strstr(line, "file")) {					
                    value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
                    value[strlen(value)-2] = 0;
                    strcpy(DinoInfo[TotalC].FName, &value[1]);}

                if (strstr(line, "pic")) {					
                    value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
                    value[strlen(value)-2] = 0;
                    strcpy(DinoInfo[TotalC].PName, &value[1]);}
            }

    }
}

This code suggests that hearK and lookK are left over from when _RES.TXT was created and the information moved out of the source.

Weapons[]

This block contains a sub-block for each weapon available in the game. Each of these sub-blocks uses several variables. All variable names are lowercase.

name[]

The name of the weapon, displayed in-game.

file[]

The filename of the weapon's .CAR file, relative to \HUNTDAT\WEAPONS. The filename specified here is case-insensitive.

pic[]

The filename of the weapon's TGA bullet icon, again relative to \HUNTDAT\WEAPONS and case-insensitive.

power[]

The weapon's power, with 0 being the lowest meaningful value (a weapon with 0 power does no damage). Power translates one-to-one with health, so that a weapon with a power of 2 must hit an animal with a health of 4 twice to kill it.

prec[]

The weapon's accuracy, on a scale from 0.0 to 2.0.

loud[]

How much noise a shot makes, on a scale from 0.0 to 2.0.

rate[]

How fast a weapon can fire, on a scale from 0.0 to 2.0. This value usually doesn't actually do anything; a weapon's base fire rate is instead controlled by the length of the reload animation and the shot sound.

shots[]

How many shots a weapon has; by default, weapons have between 6 and 8 shots, though the number can be anywhere from 0 up.

trace[]

Short for "tracer" or "tracers"; how many individual bullets are shot when the weapon is fired once. This is only used on the shotgun and DB Shotgun, both of which have 6 tracers to a shot. The default is 1.

fall[]

How fast a shot curves downward after being shot. The DB Shotgun is the only weapon to use this, where it is set to 1.

reload[]

How many shots are fired before a weapon must be reloaded. The only weapon which uses this is the DB Shotgun, which has 2 shots to each reload; the default value is 1.

optic[]

The zoom factor of the weapon, either 0 or 1. The sniper rifle is the only weapon to use this; the default value is 0.

It is worth noting that, unlike the sniper rifle, the binoculars can be zoomed in and out via the + and - keys, respectively, on the keypad.

Characters[]

This block contains a sub-block for each character (the hunter and all animals) in the game. Each of these sub-blocks uses several variables. All variable names are lowercase unless otherwise noted.

name[]

The name of the character, displayed in-game.

file[]

The filename of the character's .CAR file, relative to \HUNTDAT and case-insensitive.

ai[]

The AI number of the character. The hunter is 0, ambient animals are between 1 and 9, and pointable animals are from 10 to 18. Because the animations and sounds, and their order, in the .CAR files differ from animal to animal, changing AI values can have very interesting results and some combinations will cause the game to crash.

health[]

How much health the character has, from 0 (dies as soon as the hunt begins) to 1024 (invincible, or so). Even though the hunter's health is set to 1, changing it will not make him less vulnerable to damage or attack. Both the Brachiosaurus and the T-Rex have health of 1024, but they can both be killed if they are shot enough. The Brachiosaurus, however, does not have a death noise or animation, so the only visible indication it has died is that its information no longer displays in the binoculars (some users have also reported that killing the Brachiosaurus causes the game to crash, but this hasn't been confirmed by anyone else).

mass[]

The animal's weight. scaleA and scale0 are used to calculate the animal's weight in the following code from RenderSoft.cpp (the code is almost identical in Renderd3d.cpp and Render3DFX.cpp):

if (OptSys)     sprintf(t,"%3.2ft ", DinoInfo[dtype].Mass * scale * scale / 0.907);
       else     sprintf(t,"%3.2fT ", DinoInfo[dtype].Mass * scale * scale);

In this code, OptSys is true if measurements are set to "Imperial", and false if they are set to "Metric". The animal's Metric weight is determined by taking its mass value from _RES.TXT and multiplying it by scale (as calculated with scale0 and scaleA), then multiplying it by scale again:

For imperial measurements, the same algorithm is followed, but the result is then divided by 0.907:

In spite of the setting being named "Imperial", the unit of weight shown in-game is the US (short) ton, not the imperial (British, long, or displacement) ton; the actual, exact conversion factor from metric to short tons is 0.907 184 74 (one pound is defined as exactly 0.453 592 37 kilograms, and a short ton is 2,000 pounds).

length[]

The animal's length. Similar to mass above, scale0 and scaleA are used to calculate it in the following code from RenderSoft.cpp (again, the code is almost identical in Renderd3d.cpp and Render3DFX.cpp):

if (OptSys)     sprintf(t,"%3.2fft", DinoInfo[dtype].Length * scale / 0.3);
       else     sprintf(t,"%3.2fm", DinoInfo[dtype].Length * scale);

OptSys again determines what the measurement system is, and the metric length of the animal is determined by taking its length value from _RES.TXT and multiplying it by scale:

For imperial measurements, this is then divided by 0.3:

This variable is only set on pointable animals and the Brachiosaurus; if not set, it displays as 0.

radius[]

The bounding radius used on animals in the trophy room to determine how close the player can get to the animal. This variable is only used on pointable animals and the Brachiosaurus; if not set, the player can walk through the animal.

basescore[]

The base number of points earned for killing the animal. This score is affected by a number of factors, including the equipped equipment, whether the tranquilizer is equipped, and how many pointable animals have already been killed or tranquilized during that hunt. If a pointable animal which was not selected for hunting is shot, this also affects the points awarded. This variable is only used on pointable animals and the Brachiosaurus.

smell[]

The acuity of the animal's sense of smell, ranging from 0.0 to 1.0. This variable is only used on pointable animals and the Brachiosaurus.

hear[]

The acuity of the animal's hearing, ranging from 0.0 to 1.0. This variable is only used on pointable animals and the Brachiosaurus.

look[]

The acuity of the animal's sight, ranging from 0.0 to 1.0. This variable is only used on pointable animals and the Brachiosaurus.

shipdelta[]

The height above ground level that the "hook" on the dropship stops when picking up a trophy. This variable is only used on pointable animals and the Brachiosaurus, and defaults to 0.

scale0 and scaleA[]

scale0 and scaleA together are used to calculate "scale", which is used to determine each animal's weight and length, in the following code from Characters.cpp:

cptr->scale =  (float)(DinoInfo[cptr->CType].Scale0 + rRand(DinoInfo[cptr->CType].ScaleA)) / 1000.f;

A floating-point number is calculated by getting a random number between 0 and scaleA, adding it to scale0, and dividing the result by 1000:

If scale0 or scaleA are not set for a given animal in _RES.TXT, they default to "800" and "600" respectively (as seen above), making the default minimum and maximum scale values 0.8 and 1.4, respectively.

scale0[]

One of the size modifiers used for length and weight, scale0 is the base scale. It's important to note that this uses the numeral 0, not the capital letter O, in its name. This variable is only used on Ankylosaurus and Allosaurus. The name "scale0" is probably short for "scale original".

scaleA[]

One of the size modifiers used for length and weight, scaleA is the amount of possible variation. This variable is only used on Ankylosaurus, Allosaurus, Velociraptor, Spinosaurus, and Ceratosaurus. The name "scaleA" is probably short for "scale additional".

danger[]

This variable determines whether ambient animals and herbivores run away when the animal's call is used, and is only used when it is set to "TRUE".

One user has reported that setting this to "FALSE" on carnivores, or adding it with "TRUE" to herbivores, will change their behavior appropriately, but examination of the source code has confirmed that the only effect this has is on ambient animals and herbivores, as noted above.

hearK and lookK[]

Used only on Velociraptor, Spinosaurus, and Ceratosaurus, these variables are left over from when the information was first moved from the source to _RES.TXT - the programmers overlooked them when they should have changed them to hear and look.

Prices[]

This section contains variables which set the number of points a player starts with ("start"; defaults to 100) and the price of each area ("area"), animal ("dino"), and weapon ("weapon"). There is also one entry for each accessory ("acces"), but these are all set to 0 and changing them doesn't appear to have an effect in-game.

External links[]

Advertisement