mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-11 17:49:53 -10:00
324 lines
8.5 KiB
C++
324 lines
8.5 KiB
C++
/*
|
|
* Created by Ian "Goober5000" Warfield for the Freespace2 Source Code Project.
|
|
* You may not sell or otherwise commercially exploit the source or things you
|
|
* create based on the source.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* $Logfile: /Freespace2/code/iff_defs/iff_defs.cpp $
|
|
* $Revision: 1.3 $
|
|
* $Date: 2005-09-30 03:40:40 $
|
|
* $Author: Goober5000 $
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 1.2 2005/09/29 04:26:08 Goober5000
|
|
* parse fixage
|
|
* --Goober5000
|
|
*
|
|
* Revision 1.1 2005/09/27 05:25:18 Goober5000
|
|
* initial commit of basic IFF code
|
|
* --Goober5000
|
|
*
|
|
*/
|
|
|
|
|
|
#include "iff_defs/iff_defs.h"
|
|
#include "parse/parselo.h"
|
|
#include "cfile/cfile.h"
|
|
#include "hud/hud.h"
|
|
#include "mission/missionparse.h"
|
|
|
|
|
|
int Num_iffs;
|
|
iff_info Iff_info[MAX_IFFS];
|
|
|
|
int Iff_traitor;
|
|
|
|
color Iff_colors[MAX_IFF_COLORS][2];
|
|
|
|
|
|
//=============================================================================
|
|
|
|
// This is the default table
|
|
// Please note that the {\n\}s should be removed from the end of each line and
|
|
// the {\"}s should be replaced with {"}s if you intend to use this to format
|
|
// your own iff_defs.tbl.
|
|
|
|
char *default_iff_table = "\
|
|
\n\
|
|
#IFFs \n\
|
|
\n\
|
|
;; Every iff_defs.tbl must contain a Traitor entry. Traitors attack one \n\
|
|
;; another (required by the dogfighting code) but it is up to you to \n\
|
|
;; decide who attacks the traitor or whom else the traitor attacks. \n\
|
|
$Traitor IFF: Traitor \n\
|
|
\n\
|
|
;------------------------ \n\
|
|
; Friendly \n\
|
|
;------------------------ \n\
|
|
$IFF Name: Friendly \n\
|
|
$Color: ( 0, 255, 0 ) \n\
|
|
$Attacks: ( \"Hostile\" \"Neutral\" \"Traitor\" ) \n\
|
|
$Default Ship Flags: ( \"cargo-known\" ) \n\
|
|
\n\
|
|
;------------------------ \n\
|
|
; Hostile \n\
|
|
;------------------------ \n\
|
|
$IFF Name: Hostile \n\
|
|
$Color: ( 255, 0, 0 ) \n\
|
|
$Attacks: ( \"Friendly\" \"Neutral\" \"Traitor\" ) \n\
|
|
+Sees Friendly As: ( 255, 0, 0 ) \n\
|
|
+Sees Hostile As: ( 0, 255, 0 ) \n\
|
|
\n\
|
|
;------------------------ \n\
|
|
; Neutral \n\
|
|
;------------------------ \n\
|
|
$IFF Name: Neutral \n\
|
|
$Color: ( 255, 0, 0 ) \n\
|
|
$Attacks: ( \"Friendly\" \"Traitor\" ) \n\
|
|
+Sees Friendly As: ( 255, 0, 0 ) \n\
|
|
+Sees Hostile As: ( 0, 255, 0 ) \n\
|
|
+Sees Neutral As: ( 0, 255, 0 ) \n\
|
|
\n\
|
|
;------------------------ \n\
|
|
; Unknown \n\
|
|
;------------------------ \n\
|
|
$IFF Name: Unknown \n\
|
|
$Color: ( 255, 0, 255 ) \n\
|
|
$Attacks: ( \"Hostile\" ) \n\
|
|
+Sees Neutral As: ( 0, 255, 0 ) \n\
|
|
+Sees Traitor As: ( 0, 255, 0 ) \n\
|
|
$Flags: ( \"exempt from all teams at war\" ) \n\
|
|
\n\
|
|
;------------------------ \n\
|
|
; Traitor \n\
|
|
;------------------------ \n\
|
|
$IFF Name: Traitor \n\
|
|
$Color: ( 255, 0, 0 ) \n\
|
|
$Attacks: ( \"Friendly\" \"Hostile\" \"Neutral\" \"Traitor\" ) \n\
|
|
+Sees Friendly As: ( 255, 0, 0 ) \n\
|
|
\n\
|
|
#End \n\
|
|
";
|
|
|
|
//=============================================================================
|
|
|
|
|
|
// borrowed from ship.cpp, ship_iff_init_colors
|
|
int iff_get_alpha_value(bool alpha_on)
|
|
{
|
|
int iff_bright_delta = 4;
|
|
|
|
if (!alpha_on)
|
|
return (HUD_COLOR_ALPHA_MAX - iff_bright_delta) * 16;
|
|
else
|
|
return HUD_COLOR_ALPHA_MAX * 16;
|
|
}
|
|
|
|
int iff_init_color(int r, int g, int b)
|
|
{
|
|
typedef struct temp_color_t {
|
|
int r;
|
|
int g;
|
|
int b;
|
|
} temp_color_t;
|
|
|
|
int i, idx;
|
|
temp_color_t *c;
|
|
|
|
static int num_iff_colors = 0;
|
|
static temp_color_t temp_colors[MAX_IFF_COLORS];
|
|
|
|
|
|
// make sure we're under the limit
|
|
if (num_iff_colors >= MAX_IFF_COLORS)
|
|
{
|
|
Warning(LOCATION, "Too many iff colors! Ignoring the rest...\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
// find out if this color is in use
|
|
for (i = 0; i < num_iff_colors; i++)
|
|
{
|
|
c = &temp_colors[i];
|
|
|
|
if (c->r == r && c->g == g && c->b == b)
|
|
return i;
|
|
}
|
|
|
|
|
|
// not in use, so add a new slot
|
|
idx = num_iff_colors;
|
|
num_iff_colors++;
|
|
|
|
// save the values
|
|
c = &temp_colors[idx];
|
|
c->r = r;
|
|
c->g = g;
|
|
c->b = b;
|
|
|
|
// init it
|
|
gr_init_alphacolor(&Iff_colors[idx][0], r, g, b, iff_get_alpha_value(false));
|
|
gr_init_alphacolor(&Iff_colors[idx][1], r, g, b, iff_get_alpha_value(true));
|
|
|
|
|
|
// return the new slot
|
|
return idx;
|
|
}
|
|
|
|
void iff_init()
|
|
{
|
|
char traitor_name[NAME_LENGTH];
|
|
char attack_names[MAX_IFFS][MAX_IFFS][NAME_LENGTH];
|
|
|
|
struct {
|
|
char iff_name[NAME_LENGTH];
|
|
int color_index;
|
|
} observed_color_table[MAX_IFFS][MAX_IFFS];
|
|
|
|
int num_attack_names[MAX_IFFS];
|
|
int num_observed_colors[MAX_IFFS];
|
|
|
|
|
|
// Goober5000 - condensed check for table file
|
|
CFILE *idt = cfopen("iff_defs.tbl", "rb");
|
|
int table_exists = (idt != NULL);
|
|
if (table_exists)
|
|
cfclose(idt);
|
|
|
|
// Goober5000 - if table doesn't exist, use the default table (see above)
|
|
if (table_exists)
|
|
read_file_text("iff_defs.tbl");
|
|
else
|
|
read_file_text_from_array(default_iff_table);
|
|
|
|
reset_parse();
|
|
|
|
|
|
// before parsing, set up the predefined colors
|
|
// NOTE: THESE MUST OCCUR IN THE ORDER DEFINED IN IFF_DEFS.H!!
|
|
iff_init_color(0xff, 0xff, 0xff); // IFF_COLOR_SELECTION
|
|
iff_init_color(0x7f, 0x7f, 0x7f); // IFF_COLOR_MESSAGE
|
|
iff_init_color(0xff, 0xff, 0x00); // IFF_COLOR_TAGGED
|
|
|
|
|
|
// parse the table --------------------------------------------------------
|
|
|
|
required_string("#IFFs");
|
|
|
|
// get the traitor
|
|
required_string("$Traitor IFF:");
|
|
stuff_string(traitor_name, F_NAME, NULL, NAME_LENGTH);
|
|
|
|
// begin reading data
|
|
Num_iffs = 0;
|
|
while (required_string_either("#End","$IFF Name:"))
|
|
{
|
|
iff_info *iff;
|
|
int rgb[3];
|
|
int cur_iff;
|
|
|
|
// make sure we're under the limit
|
|
if (Num_iffs >= MAX_IFFS)
|
|
{
|
|
Warning(LOCATION, "Too many iffs in iffs_defs.tbl! Max is %d.\n", MAX_IFFS);
|
|
skip_to_start_of_string("#End", NULL);
|
|
break;
|
|
}
|
|
|
|
// add new IFF
|
|
iff = &Iff_info[Num_iffs];
|
|
cur_iff = Num_iffs;
|
|
Num_iffs++;
|
|
|
|
|
|
// get required IFF info ----------------------------------------------
|
|
|
|
// get the iff name
|
|
required_string("$IFF Name:");
|
|
stuff_string(iff->iff_name, F_NAME, NULL, NAME_LENGTH);
|
|
|
|
// get the iff color
|
|
if (check_for_string("$Colour:"))
|
|
required_string("$Colour:");
|
|
else
|
|
required_string("$Color:");
|
|
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
|
iff->color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
|
|
|
|
|
// get relationships between IFFs -------------------------------------
|
|
|
|
// get the list of iffs attacked
|
|
if (optional_string("$Attacks:"))
|
|
num_attack_names[cur_iff] = stuff_string_list(attack_names[cur_iff], MAX_IFFS);
|
|
else
|
|
num_attack_names[cur_iff] = 0;
|
|
|
|
// get the list of observed colors
|
|
num_observed_colors[cur_iff] = 0;
|
|
while (optional_string("+Sees"))
|
|
{
|
|
// get iff observed
|
|
stuff_string_until(observed_color_table[cur_iff][num_observed_colors[cur_iff]].iff_name, "As:", NAME_LENGTH);
|
|
required_string("As:");
|
|
|
|
// get color observed
|
|
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
|
observed_color_table[cur_iff][num_observed_colors[cur_iff]].color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
|
|
|
// increment
|
|
num_observed_colors[cur_iff]++;
|
|
}
|
|
|
|
|
|
// get flags ----------------------------------------------------------
|
|
|
|
// get iff flags
|
|
iff->flags = 0;
|
|
if (optional_string("$Flags:"))
|
|
{
|
|
int i;
|
|
char flag_strings[MAX_IFF_FLAGS][NAME_LENGTH];
|
|
int num_strings = stuff_string_list(flag_strings, MAX_IFF_FLAGS);
|
|
for (i = 0; i < num_strings; i++)
|
|
{
|
|
if (!stricmp(NOX("exempt from all teams at war"), flag_strings[i]))
|
|
iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
|
|
else
|
|
Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[i]);
|
|
}
|
|
}
|
|
|
|
// get default ship flags
|
|
iff->default_ship_flags = 0;
|
|
if (optional_string("$Default Ship Flags:"))
|
|
{
|
|
int i, j;
|
|
char flag_strings[MAX_PARSE_OBJECT_FLAGS][NAME_LENGTH];
|
|
int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS);
|
|
for (i = 0; i < num_strings; i++)
|
|
{
|
|
for (j = 0; j < MAX_PARSE_OBJECT_FLAGS; j++)
|
|
{
|
|
if (!stricmp(flag_strings[i], Parse_object_flags[j]))
|
|
{
|
|
iff->default_ship_flags |= (1 << j);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (j == MAX_PARSE_OBJECT_FLAGS)
|
|
Warning(LOCATION, "Bogus string in iff default ship flags: %s\n", flag_strings[i]);
|
|
}
|
|
}
|
|
|
|
required_string("#End");
|
|
|
|
|
|
// now resolve the relationships ------------------------------------------
|
|
}
|