mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
Replace longjmp with exceptions
Also added a EditorConfig file
This commit is contained in:
1 parent
f187522238
commit
9aed627ce7
44 files changed
+4549
-4354
No files matched your search
@@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*.{h,cpp}]
|
||||
indent_style = tab
|
||||
+407
-404
@@ -69,445 +69,448 @@ int ai_path_type_match(char *p)
|
||||
|
||||
void parse_ai_profiles_tbl(const char *filename)
|
||||
{
|
||||
int i, rval;
|
||||
int i;
|
||||
char profile_name[NAME_LENGTH];
|
||||
ai_profile_t dummy_profile;
|
||||
char *saved_Mp = NULL;
|
||||
char buf[NAME_LENGTH];
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default ai_profiles.tbl>", rval));
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
required_string("#AI Profiles");
|
||||
|
||||
// new default?
|
||||
if (optional_string("$Default Profile:"))
|
||||
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#End","$Profile Name:"))
|
||||
{
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
bool no_create = false;
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
stuff_string(profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// see if it exists
|
||||
for (i = 0; i < Num_ai_profiles; i++)
|
||||
{
|
||||
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
|
||||
{
|
||||
previous_profile = &Ai_profiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// modular table stuff
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
no_create = true;
|
||||
|
||||
// use the previous one if possible,
|
||||
// otherwise continue to use the dummy one
|
||||
if (previous_profile != NULL)
|
||||
profile = previous_profile;
|
||||
}
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("ai_profiles.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
required_string("#AI Profiles");
|
||||
|
||||
// new default?
|
||||
if (optional_string("$Default Profile:"))
|
||||
stuff_string(Default_profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#End", "$Profile Name:"))
|
||||
{
|
||||
// don't create multiple profiles with the same name
|
||||
if (previous_profile != NULL)
|
||||
ai_profile_t *profile = &dummy_profile;
|
||||
ai_profile_t *previous_profile = NULL;
|
||||
bool no_create = false;
|
||||
|
||||
// get the name
|
||||
required_string("$Profile Name:");
|
||||
stuff_string(profile_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// see if it exists
|
||||
for (i = 0; i < Num_ai_profiles; i++)
|
||||
{
|
||||
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we're under the limit
|
||||
if (Num_ai_profiles >= MAX_AI_PROFILES)
|
||||
if (!stricmp(Ai_profiles[i].profile_name, profile_name))
|
||||
{
|
||||
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES-1); // -1 because one is built-in
|
||||
skip_to_string("#End", NULL);
|
||||
previous_profile = &Ai_profiles[i];
|
||||
break;
|
||||
}
|
||||
|
||||
profile = &Ai_profiles[Num_ai_profiles];
|
||||
Num_ai_profiles++;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize profile if we're not building from a previously parsed one
|
||||
if (!no_create)
|
||||
{
|
||||
// base profile, so zero it out
|
||||
if (profile == &Ai_profiles[0])
|
||||
// modular table stuff
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
memset(profile, 0, sizeof(ai_profile_t));
|
||||
no_create = true;
|
||||
|
||||
// use the previous one if possible,
|
||||
// otherwise continue to use the dummy one
|
||||
if (previous_profile != NULL)
|
||||
profile = previous_profile;
|
||||
}
|
||||
// brand new profile, so set it to the base defaults
|
||||
else
|
||||
{
|
||||
memcpy(profile, &Ai_profiles[0], sizeof(ai_profile_t));
|
||||
}
|
||||
}
|
||||
|
||||
// set the name
|
||||
strcpy_s(profile->profile_name, profile_name);
|
||||
|
||||
|
||||
// fill in any and all settings; they're all optional and can be in any order
|
||||
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
|
||||
{
|
||||
if (optional_string("$Player Afterburner Recharge Scale:"))
|
||||
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Beam Friendly Fire Damage:"))
|
||||
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Countermeasure Life Scale:"))
|
||||
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Countermeasure Firing Chance:"))
|
||||
parse_float_list(profile->cmeasure_fire_chance, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI In Range Time:"))
|
||||
parse_float_list(profile->in_range_time, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Primary Ammo Burst Multiplier:"))
|
||||
parse_float_list(profile->primary_ammo_burst_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Missles Locked on Player:") || optional_string("$Max Missiles Locked on Player:"))
|
||||
parse_int_list(profile->max_allowed_player_homers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Player Attackers:"))
|
||||
parse_int_list(profile->max_attackers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Incoming Asteroids:"))
|
||||
parse_int_list(profile->max_incoming_asteroids, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Damage Factor:") || optional_string("$AI Damage Reduction to Player Hull:"))
|
||||
parse_float_list(profile->player_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
|
||||
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
// represented in fractions of F1_0
|
||||
if (optional_string("$Predict Position Delay:"))
|
||||
{
|
||||
int iLoop;
|
||||
float temp_list[NUM_SKILL_LEVELS];
|
||||
|
||||
parse_float_list(temp_list, NUM_SKILL_LEVELS);
|
||||
|
||||
for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++)
|
||||
profile->predict_position_delay[iLoop] = fl2f(temp_list[iLoop]);
|
||||
}
|
||||
|
||||
if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:"))
|
||||
parse_float_list(profile->shield_manage_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Turn Time Scale:"))
|
||||
parse_float_list(profile->turn_time_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Glide Attack Percent:")) {
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Attack Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_attack_percent[i]);
|
||||
profile->glide_attack_percent[i] = 0.0f;
|
||||
}
|
||||
profile->glide_attack_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Circle Strafe Percent:")) {
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Circle Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->circle_strafe_percent[i]);
|
||||
profile->circle_strafe_percent[i] = 0.0f;
|
||||
}
|
||||
profile->circle_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Glide Strafe Percent:")) {
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_strafe_percent[i]);
|
||||
profile->glide_strafe_percent[i] = 0.0f;
|
||||
}
|
||||
profile->glide_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
profile->random_sidethrust_percent[i] = 0.0f;
|
||||
}
|
||||
profile->random_sidethrust_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Stalemate Time Threshold:"))
|
||||
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Stalemate Distance Threshold:"))
|
||||
parse_float_list(profile->stalemate_dist_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Shield Recharge Scale:"))
|
||||
parse_float_list(profile->shield_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Weapon Recharge Scale:"))
|
||||
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Target Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Player Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Kill Scale:"))
|
||||
parse_float_list(profile->kill_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Assist Scale:"))
|
||||
parse_float_list(profile->assist_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Awarded For Capship Assist:"))
|
||||
parse_float_list(profile->assist_award_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Repair Penalty:"))
|
||||
parse_int_list(profile->repair_penalty, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Delay Before Allowing Bombs to Be Shot Down:"))
|
||||
parse_float_list(profile->delay_bomb_arm_timer, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Chance AI Has to Fire Missiles at Player:"))
|
||||
parse_int_list(profile->chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Aim Update Delay:"))
|
||||
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Turret Max Aim Update Delay:"))
|
||||
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Autoaim FOV:"))
|
||||
{
|
||||
float fov_list[NUM_SKILL_LEVELS];
|
||||
parse_float_list(fov_list, NUM_SKILL_LEVELS);
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++)
|
||||
// don't create multiple profiles with the same name
|
||||
if (previous_profile != NULL)
|
||||
{
|
||||
//Enforce range
|
||||
if (fov_list[i] < 0.0f || fov_list[i] >= 360.0f)
|
||||
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we're under the limit
|
||||
if (Num_ai_profiles >= MAX_AI_PROFILES)
|
||||
{
|
||||
Warning(LOCATION, "$Player Autoaim FOV should be >= 0 and < 360.0 (read %f). Setting to 0.", fov_list[i]);
|
||||
fov_list[i] = 0.0f;
|
||||
Warning(LOCATION, "Too many profiles in ai_profiles.tbl! Max is %d.\n", MAX_AI_PROFILES - 1); // -1 because one is built-in
|
||||
skip_to_string("#End", NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
//Convert units
|
||||
profile->player_autoaim_fov[i] = fov_list[i] * PI / 180.0f;
|
||||
profile = &Ai_profiles[Num_ai_profiles];
|
||||
Num_ai_profiles++;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Detail Distance Multiplier:"))
|
||||
parse_float_list(profile->detail_distance_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$perform fewer checks for death screams:", AIPF2_PERFORM_FEWER_SCREAM_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$advanced turret fov edge checks:", AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$require turrets to have target in fov:", AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai aims from ship center:", AIPF2_AI_AIMS_FROM_SHIP_CENTER, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow primary link at mission start:", AIPF2_ALLOW_PRIMARY_LINK_AT_START, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow beams to damage bombs:", AIPF2_BEAMS_DAMAGE_WEAPONS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling for player:", AIPF2_PLAYER_WEAPON_SCALE_FIX, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$countermeasures affect aspect seekers:", AIPF2_ASPECT_LOCK_COUNTERMEASURE, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai guards specific ship in wing:", AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING, AIP_FLAG2);
|
||||
|
||||
profile->ai_path_mode = AI_PATH_MODE_NORMAL;
|
||||
if(optional_string("$ai path mode:"))
|
||||
// initialize profile if we're not building from a previously parsed one
|
||||
if (!no_create)
|
||||
{
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
int j = ai_path_type_match(buf);
|
||||
if(j >= 0) {
|
||||
profile->ai_path_mode = j;
|
||||
} else {
|
||||
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
|
||||
// base profile, so zero it out
|
||||
if (profile == &Ai_profiles[0])
|
||||
{
|
||||
memset(profile, 0, sizeof(ai_profile_t));
|
||||
}
|
||||
// brand new profile, so set it to the base defaults
|
||||
else
|
||||
{
|
||||
memcpy(profile, &Ai_profiles[0], sizeof(ai_profile_t));
|
||||
}
|
||||
}
|
||||
|
||||
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
|
||||
// set the name
|
||||
strcpy_s(profile->profile_name, profile_name);
|
||||
|
||||
set_flag(profile, "$fix ai path order bug:", AIPF2_FIX_AI_PATH_ORDER_BUG, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
|
||||
|
||||
// ----------
|
||||
|
||||
// compatibility
|
||||
if (optional_string("$perform less checks for death screams:"))
|
||||
// fill in any and all settings; they're all optional and can be in any order
|
||||
while (!check_for_string("$Profile Name:") && !check_for_string("#End"))
|
||||
{
|
||||
mprintf(("Warning: \"$perform less checks for death screams\" flag is deprecated in favor of \"$perform fewer checks for death screams\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
if (temp)
|
||||
profile->flags2 |= AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
|
||||
else
|
||||
profile->flags2 &= ~AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
|
||||
if (optional_string("$Player Afterburner Recharge Scale:"))
|
||||
parse_float_list(profile->afterburner_recharge_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Beam Friendly Fire Damage:"))
|
||||
parse_float_list(profile->beam_friendly_damage_cap, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Countermeasure Life Scale:"))
|
||||
parse_float_list(profile->cmeasure_life_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Countermeasure Firing Chance:"))
|
||||
parse_float_list(profile->cmeasure_fire_chance, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI In Range Time:"))
|
||||
parse_float_list(profile->in_range_time, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Ammo Weapons:"))
|
||||
parse_float_list(profile->link_ammo_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Primary Ammo Burst Multiplier:"))
|
||||
parse_float_list(profile->primary_ammo_burst_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Always Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_always, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Maybe Links Energy Weapons:"))
|
||||
parse_float_list(profile->link_energy_levels_maybe, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Missles Locked on Player:") || optional_string("$Max Missiles Locked on Player:"))
|
||||
parse_int_list(profile->max_allowed_player_homers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Player Attackers:"))
|
||||
parse_int_list(profile->max_attackers, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Incoming Asteroids:"))
|
||||
parse_int_list(profile->max_incoming_asteroids, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Damage Factor:") || optional_string("$AI Damage Reduction to Player Hull:"))
|
||||
parse_float_list(profile->player_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Subsys Damage Factor:") || optional_string("$AI Damage Reduction to Player Subsys:"))
|
||||
parse_float_list(profile->subsys_damage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
// represented in fractions of F1_0
|
||||
if (optional_string("$Predict Position Delay:"))
|
||||
{
|
||||
int iLoop;
|
||||
float temp_list[NUM_SKILL_LEVELS];
|
||||
|
||||
parse_float_list(temp_list, NUM_SKILL_LEVELS);
|
||||
|
||||
for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++)
|
||||
profile->predict_position_delay[iLoop] = fl2f(temp_list[iLoop]);
|
||||
}
|
||||
|
||||
if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:"))
|
||||
parse_float_list(profile->shield_manage_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Friendly AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_friendly, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Hostile AI Secondary Fire Delay Scale:"))
|
||||
parse_float_list(profile->ship_fire_secondary_delay_scale_hostile, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$AI Turn Time Scale:"))
|
||||
parse_float_list(profile->turn_time_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Glide Attack Percent:")) {
|
||||
parse_float_list(profile->glide_attack_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_attack_percent[i] < 0.0f || profile->glide_attack_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Attack Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_attack_percent[i]);
|
||||
profile->glide_attack_percent[i] = 0.0f;
|
||||
}
|
||||
profile->glide_attack_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Circle Strafe Percent:")) {
|
||||
parse_float_list(profile->circle_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->circle_strafe_percent[i] < 0.0f || profile->circle_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Circle Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->circle_strafe_percent[i]);
|
||||
profile->circle_strafe_percent[i] = 0.0f;
|
||||
}
|
||||
profile->circle_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Glide Strafe Percent:")) {
|
||||
parse_float_list(profile->glide_strafe_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->glide_strafe_percent[i] < 0.0f || profile->glide_strafe_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Glide Strafe Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->glide_strafe_percent[i]);
|
||||
profile->glide_strafe_percent[i] = 0.0f;
|
||||
}
|
||||
profile->glide_strafe_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Random Sidethrust Percent:")) {
|
||||
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
|
||||
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
|
||||
//While we're at it, verify the range
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++) {
|
||||
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
|
||||
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
|
||||
profile->random_sidethrust_percent[i] = 0.0f;
|
||||
}
|
||||
profile->random_sidethrust_percent[i] /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Stalemate Time Threshold:"))
|
||||
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Stalemate Distance Threshold:"))
|
||||
parse_float_list(profile->stalemate_dist_thresh, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Shield Recharge Scale:"))
|
||||
parse_float_list(profile->shield_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Weapon Recharge Scale:"))
|
||||
parse_float_list(profile->weapon_energy_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Target Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_target, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Turret Player Ownage:"))
|
||||
parse_int_list(profile->max_turret_ownage_player, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Kill Scale:"))
|
||||
parse_float_list(profile->kill_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Required For Assist Scale:"))
|
||||
parse_float_list(profile->assist_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Percentage Awarded For Capship Assist:"))
|
||||
parse_float_list(profile->assist_award_percentage_scale, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Repair Penalty:"))
|
||||
parse_int_list(profile->repair_penalty, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Delay Before Allowing Bombs to Be Shot Down:"))
|
||||
parse_float_list(profile->delay_bomb_arm_timer, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Chance AI Has to Fire Missiles at Player:"))
|
||||
parse_int_list(profile->chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Max Aim Update Delay:"))
|
||||
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Turret Max Aim Update Delay:"))
|
||||
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
|
||||
|
||||
if (optional_string("$Player Autoaim FOV:"))
|
||||
{
|
||||
float fov_list[NUM_SKILL_LEVELS];
|
||||
parse_float_list(fov_list, NUM_SKILL_LEVELS);
|
||||
for (i = 0; i < NUM_SKILL_LEVELS; i++)
|
||||
{
|
||||
//Enforce range
|
||||
if (fov_list[i] < 0.0f || fov_list[i] >= 360.0f)
|
||||
{
|
||||
Warning(LOCATION, "$Player Autoaim FOV should be >= 0 and < 360.0 (read %f). Setting to 0.", fov_list[i]);
|
||||
fov_list[i] = 0.0f;
|
||||
}
|
||||
|
||||
//Convert units
|
||||
profile->player_autoaim_fov[i] = fov_list[i] * PI / 180.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Detail Distance Multiplier:"))
|
||||
parse_float_list(profile->detail_distance_mult, NUM_SKILL_LEVELS);
|
||||
|
||||
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG);
|
||||
|
||||
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$perform fewer checks for death screams:", AIPF2_PERFORM_FEWER_SCREAM_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$advanced turret fov edge checks:", AIPF2_ADVANCED_TURRET_FOV_EDGE_CHECKS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$require turrets to have target in fov:", AIPF2_REQUIRE_TURRET_TO_HAVE_TARGET_IN_FOV, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$all ships manage shields:", AIPF2_ALL_SHIPS_MANAGE_SHIELDS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai aims from ship center:", AIPF2_AI_AIMS_FROM_SHIP_CENTER, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow primary link at mission start:", AIPF2_ALLOW_PRIMARY_LINK_AT_START, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$allow beams to damage bombs:", AIPF2_BEAMS_DAMAGE_WEAPONS, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling for player:", AIPF2_PLAYER_WEAPON_SCALE_FIX, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$countermeasures affect aspect seekers:", AIPF2_ASPECT_LOCK_COUNTERMEASURE, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$ai guards specific ship in wing:", AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING, AIP_FLAG2);
|
||||
|
||||
profile->ai_path_mode = AI_PATH_MODE_NORMAL;
|
||||
if (optional_string("$ai path mode:"))
|
||||
{
|
||||
stuff_string(buf, F_NAME, NAME_LENGTH);
|
||||
int j = ai_path_type_match(buf);
|
||||
if (j >= 0) {
|
||||
profile->ai_path_mode = j;
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
|
||||
}
|
||||
}
|
||||
|
||||
set_flag(profile, "$no warp camera:", AIPF2_NO_WARP_CAMERA, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$fix ai path order bug:", AIPF2_FIX_AI_PATH_ORDER_BUG, AIP_FLAG2);
|
||||
|
||||
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
|
||||
|
||||
// ----------
|
||||
|
||||
// compatibility
|
||||
if (optional_string("$perform less checks for death screams:"))
|
||||
{
|
||||
mprintf(("Warning: \"$perform less checks for death screams\" flag is deprecated in favor of \"$perform fewer checks for death screams\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
if (temp)
|
||||
profile->flags2 |= AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
|
||||
else
|
||||
profile->flags2 &= ~AIPF2_PERFORM_FEWER_SCREAM_CHECKS;
|
||||
}
|
||||
if (optional_string("$allow primary link delay:"))
|
||||
{
|
||||
mprintf(("Warning: \"$allow primary link delay\" flag is deprecated in favor of \"$allow primary link at mission start\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
if (temp)
|
||||
profile->flags2 &= ~AIPF2_ALLOW_PRIMARY_LINK_AT_START;
|
||||
else
|
||||
profile->flags2 |= AIPF2_ALLOW_PRIMARY_LINK_AT_START;
|
||||
}
|
||||
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if (saved_Mp && (saved_Mp == Mp))
|
||||
{
|
||||
char tmp[60];
|
||||
memset(tmp, 0, 60);
|
||||
strncpy(tmp, Mp, 59);
|
||||
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", tmp));
|
||||
|
||||
Mp++;
|
||||
}
|
||||
|
||||
// find next valid option
|
||||
skip_to_start_of_string_either("$", "#");
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
if (optional_string("$allow primary link delay:"))
|
||||
{
|
||||
mprintf(("Warning: \"$allow primary link delay\" flag is deprecated in favor of \"$allow primary link at mission start\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
if (temp)
|
||||
profile->flags2 &= ~AIPF2_ALLOW_PRIMARY_LINK_AT_START;
|
||||
else
|
||||
profile->flags2 |= AIPF2_ALLOW_PRIMARY_LINK_AT_START;
|
||||
}
|
||||
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if ( saved_Mp && (saved_Mp == Mp) )
|
||||
{
|
||||
char tmp[60];
|
||||
memset(tmp, 0, 60);
|
||||
strncpy(tmp, Mp, 59);
|
||||
mprintf(("WARNING: Unrecognized parameter in ai_profiles: %s\n", tmp));
|
||||
|
||||
Mp++;
|
||||
}
|
||||
|
||||
// find next valid option
|
||||
skip_to_start_of_string_either("$", "#");
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default ai_profiles.tbl>", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
|
||||
+8
-7
@@ -826,13 +826,14 @@ LOCAL int ai_inited = 0;
|
||||
void ai_init()
|
||||
{
|
||||
if ( !ai_inited ) {
|
||||
// Do the first time initialization stuff here
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "ai.tbl", rval));
|
||||
} else {
|
||||
parse_aitbl();
|
||||
// Do the first time initialization stuff here
|
||||
try
|
||||
{
|
||||
parse_aitbl();
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "ai.tbl", e.what()));
|
||||
}
|
||||
|
||||
ai_inited = 1;
|
||||
|
||||
+124
-119
@@ -1887,143 +1887,148 @@ that is being protected.
|
||||
void asteroid_parse_tbl()
|
||||
{
|
||||
char impact_ani_file[MAX_FILENAME_LEN];
|
||||
int rval;
|
||||
|
||||
// How did we get here without having any species defined?
|
||||
Assertion(Species_info.size() > 0,
|
||||
"Cannot parse asteroids/debris if there "
|
||||
"are no species for them to belong to."
|
||||
);
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "asteroid.tbl", rval));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("asteroid.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Asteroid Types");
|
||||
|
||||
int tally = 0;
|
||||
int max_asteroids =
|
||||
NUM_DEBRIS_SIZES + Species_info.size() * NUM_DEBRIS_SIZES;
|
||||
|
||||
#ifndef NDEBUG
|
||||
SCP_vector<SCP_string> parsed_asteroids;
|
||||
#endif
|
||||
|
||||
// parse and tally each asteroid
|
||||
while (required_string_either("#End","$Name:"))
|
||||
|
||||
try
|
||||
{
|
||||
asteroid_info new_asteroid;
|
||||
read_file_text("asteroid.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
asteroid_parse_section( &new_asteroid );
|
||||
required_string("#Asteroid Types");
|
||||
|
||||
int tally = 0;
|
||||
int max_asteroids =
|
||||
NUM_DEBRIS_SIZES + Species_info.size() * NUM_DEBRIS_SIZES;
|
||||
|
||||
int species = tally / NUM_DEBRIS_SIZES;
|
||||
if (tally >= max_asteroids)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
// Bump the warning count in release so they get something
|
||||
// even if the message never gets displayed.
|
||||
Warning(LOCATION, "Ignoring extra asteroid/debris");
|
||||
#else
|
||||
SCP_string msg("Ignoring extra asteroid/debris '");
|
||||
msg.append(new_asteroid.name);
|
||||
msg.append("'\n");
|
||||
Warning(LOCATION,msg.c_str());
|
||||
parsed_asteroids.push_back(msg);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
SCP_string msg;
|
||||
msg.append("Parsing asteroid: '");
|
||||
msg.append(new_asteroid.name);
|
||||
msg.append("' as a '");
|
||||
msg.append((species == 0)?"generic":Species_info[species-1].species_name);
|
||||
msg.append("'");
|
||||
switch(tally % NUM_DEBRIS_SIZES) {
|
||||
case ASTEROID_TYPE_SMALL:
|
||||
msg.append(" small\n");
|
||||
break;
|
||||
case ASTEROID_TYPE_MEDIUM:
|
||||
msg.append(" medium\n");
|
||||
break;
|
||||
case ASTEROID_TYPE_LARGE:
|
||||
msg.append(" large\n");
|
||||
break;
|
||||
default:
|
||||
Error(LOCATION, "Get a coder! Math has broken!\n"
|
||||
"Important numbers:\n"
|
||||
"\ttally: %d\n"
|
||||
"\tNUM_DEBRIS_SIZES: %d\n",
|
||||
tally, NUM_DEBRIS_SIZES
|
||||
);
|
||||
msg.append(" unknown\n");
|
||||
SCP_vector<SCP_string> parsed_asteroids;
|
||||
#endif
|
||||
|
||||
// parse and tally each asteroid
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
asteroid_info new_asteroid;
|
||||
|
||||
asteroid_parse_section(&new_asteroid);
|
||||
|
||||
int species = tally / NUM_DEBRIS_SIZES;
|
||||
if (tally >= max_asteroids)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
// Bump the warning count in release so they get something
|
||||
// even if the message never gets displayed.
|
||||
Warning(LOCATION, "Ignoring extra asteroid/debris");
|
||||
#else
|
||||
SCP_string msg("Ignoring extra asteroid/debris '");
|
||||
msg.append(new_asteroid.name);
|
||||
msg.append("'\n");
|
||||
Warning(LOCATION, msg.c_str());
|
||||
parsed_asteroids.push_back(msg);
|
||||
#endif
|
||||
}
|
||||
parsed_asteroids.push_back(msg);
|
||||
#endif
|
||||
Asteroid_info.push_back(new_asteroid);
|
||||
}
|
||||
tally++;
|
||||
}
|
||||
required_string("#End");
|
||||
|
||||
if (tally != max_asteroids)
|
||||
{
|
||||
else
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
for(SCP_vector<SCP_string>::iterator iter = parsed_asteroids.begin();
|
||||
iter != parsed_asteroids.end(); ++iter)
|
||||
{
|
||||
mprintf(("Asteroid.tbl as parsed:\n"));
|
||||
mprintf((iter->c_str()));
|
||||
SCP_string msg;
|
||||
msg.append("Parsing asteroid: '");
|
||||
msg.append(new_asteroid.name);
|
||||
msg.append("' as a '");
|
||||
msg.append((species == 0) ? "generic" : Species_info[species - 1].species_name);
|
||||
msg.append("'");
|
||||
switch (tally % NUM_DEBRIS_SIZES) {
|
||||
case ASTEROID_TYPE_SMALL:
|
||||
msg.append(" small\n");
|
||||
break;
|
||||
case ASTEROID_TYPE_MEDIUM:
|
||||
msg.append(" medium\n");
|
||||
break;
|
||||
case ASTEROID_TYPE_LARGE:
|
||||
msg.append(" large\n");
|
||||
break;
|
||||
default:
|
||||
Error(LOCATION, "Get a coder! Math has broken!\n"
|
||||
"Important numbers:\n"
|
||||
"\ttally: %d\n"
|
||||
"\tNUM_DEBRIS_SIZES: %d\n",
|
||||
tally, NUM_DEBRIS_SIZES
|
||||
);
|
||||
msg.append(" unknown\n");
|
||||
}
|
||||
parsed_asteroids.push_back(msg);
|
||||
#endif
|
||||
Asteroid_info.push_back(new_asteroid);
|
||||
}
|
||||
tally++;
|
||||
}
|
||||
required_string("#End");
|
||||
|
||||
if (tally != max_asteroids)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
for (SCP_vector<SCP_string>::iterator iter = parsed_asteroids.begin();
|
||||
iter != parsed_asteroids.end(); ++iter)
|
||||
{
|
||||
mprintf(("Asteroid.tbl as parsed:\n"));
|
||||
mprintf((iter->c_str()));
|
||||
}
|
||||
#endif
|
||||
Error(LOCATION,
|
||||
"Found %d asteroids/debris when %d expected\n\n"
|
||||
"<Number expected> = <Number of species> * %d + %d generic asteroids\n"
|
||||
"%d = %d*%d + %d\n\n"
|
||||
Error(LOCATION,
|
||||
"Found %d asteroids/debris when %d expected\n\n"
|
||||
"<Number expected> = <Number of species> * %d + %d generic asteroids\n"
|
||||
"%d = %d*%d + %d\n\n"
|
||||
#ifdef NDEBUG
|
||||
"Run a debug build to see a list of all parsed asteroids\n",
|
||||
"Run a debug build to see a list of all parsed asteroids\n",
|
||||
#else
|
||||
"See the debug.log for a listing of all parsed asteroids\n",
|
||||
"See the debug.log for a listing of all parsed asteroids\n",
|
||||
#endif
|
||||
tally, max_asteroids,
|
||||
NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES,
|
||||
max_asteroids, Species_info.size(), NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES
|
||||
);
|
||||
tally, max_asteroids,
|
||||
NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES,
|
||||
max_asteroids, Species_info.size(), NUM_DEBRIS_SIZES, NUM_DEBRIS_SIZES
|
||||
);
|
||||
}
|
||||
|
||||
Asteroid_impact_explosion_ani = -1;
|
||||
required_string("$Impact Explosion:");
|
||||
stuff_string(impact_ani_file, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (VALID_FNAME(impact_ani_file)) {
|
||||
int num_frames;
|
||||
Asteroid_impact_explosion_ani = bm_load_animation(impact_ani_file, &num_frames, NULL, NULL, 1);
|
||||
}
|
||||
|
||||
required_string("$Impact Explosion Radius:");
|
||||
stuff_float(&Asteroid_impact_explosion_radius);
|
||||
|
||||
if (optional_string("$Briefing Icon Closeup Model:")) {
|
||||
stuff_string(Asteroid_icon_closeup_model, F_NAME, NAME_LENGTH);
|
||||
}
|
||||
else {
|
||||
strcpy_s(Asteroid_icon_closeup_model, Asteroid_info[ASTEROID_TYPE_LARGE].pof_files[0]); // magic file from retail
|
||||
}
|
||||
|
||||
if (optional_string("$Briefing Icon Closeup Position:")) {
|
||||
stuff_vec3d(&Asteroid_icon_closeup_position);
|
||||
}
|
||||
else {
|
||||
vm_vec_make(&Asteroid_icon_closeup_position, 0.0f, 0.0f, -334.0f); // magic numbers from retail
|
||||
}
|
||||
|
||||
if (optional_string("$Briefing Icon Closeup Zoom:")) {
|
||||
stuff_float(&Asteroid_icon_closeup_zoom);
|
||||
}
|
||||
else {
|
||||
Asteroid_icon_closeup_zoom = 0.5f; // magic number from retail
|
||||
}
|
||||
}
|
||||
|
||||
Asteroid_impact_explosion_ani = -1;
|
||||
required_string("$Impact Explosion:");
|
||||
stuff_string(impact_ani_file, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if ( VALID_FNAME(impact_ani_file) ) {
|
||||
int num_frames;
|
||||
Asteroid_impact_explosion_ani = bm_load_animation( impact_ani_file, &num_frames, NULL, NULL, 1);
|
||||
}
|
||||
|
||||
required_string("$Impact Explosion Radius:");
|
||||
stuff_float(&Asteroid_impact_explosion_radius);
|
||||
|
||||
if (optional_string("$Briefing Icon Closeup Model:")) {
|
||||
stuff_string(Asteroid_icon_closeup_model, F_NAME, NAME_LENGTH);
|
||||
} else {
|
||||
strcpy_s(Asteroid_icon_closeup_model, Asteroid_info[ASTEROID_TYPE_LARGE].pof_files[0]); // magic file from retail
|
||||
}
|
||||
|
||||
if (optional_string("$Briefing Icon Closeup Position:")) {
|
||||
stuff_vec3d(&Asteroid_icon_closeup_position);
|
||||
} else {
|
||||
vm_vec_make(&Asteroid_icon_closeup_position, 0.0f, 0.0f, -334.0f); // magic numbers from retail
|
||||
}
|
||||
|
||||
if (optional_string("$Briefing Icon Closeup Zoom:")) {
|
||||
stuff_float(&Asteroid_icon_closeup_zoom);
|
||||
} else {
|
||||
Asteroid_icon_closeup_zoom = 0.5f; // magic number from retail
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "asteroid.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1271,68 +1271,69 @@ void NavSystem_Init()
|
||||
|
||||
void parse_autopilot_table(char *filename)
|
||||
{
|
||||
int rval;
|
||||
SCP_vector<SCP_string> lines;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default autopilot.tbl>", rval));
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("autopilot.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
required_string("#Autopilot");
|
||||
|
||||
// autopilot link distance
|
||||
required_string("$Link Distance:");
|
||||
stuff_int(&NavLinkDistance);
|
||||
|
||||
if (optional_string("$Interrupt autopilot if enemy within distance:"))
|
||||
stuff_int(&AutopilotMinEnemyDistance);
|
||||
else
|
||||
AutopilotMinEnemyDistance = 5000;
|
||||
|
||||
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
|
||||
stuff_int(&AutopilotMinAsteroidDistance);
|
||||
else
|
||||
AutopilotMinAsteroidDistance = 1000;
|
||||
|
||||
if (optional_string("$Lock Weapons During Autopilot:"))
|
||||
stuff_boolean(&LockWeaponsDuringAutopilot);
|
||||
else
|
||||
LockWeaponsDuringAutopilot = false;
|
||||
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Cutscene_Bars"))
|
||||
UseCutsceneBars = false;
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Autopilot_Interrupt"))
|
||||
Cmdline_autopilot_interruptable = 0;
|
||||
|
||||
// No Nav selected message
|
||||
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
|
||||
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
|
||||
"$Support Present:", "$Support Working:" };
|
||||
for (int i = 0; i < NP_NUM_MESSAGES; i++)
|
||||
{
|
||||
required_string(msg_tags[i]);
|
||||
|
||||
required_string("+Msg:");
|
||||
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
|
||||
|
||||
required_string("+Snd File:");
|
||||
stuff_string(NavMsgs[i].filename, F_NAME, 256);
|
||||
}
|
||||
|
||||
|
||||
required_string("#END");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default autopilot.tbl>", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("autopilot.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
required_string("#Autopilot");
|
||||
|
||||
// autopilot link distance
|
||||
required_string("$Link Distance:");
|
||||
stuff_int(&NavLinkDistance);
|
||||
|
||||
if (optional_string("$Interrupt autopilot if enemy within distance:"))
|
||||
stuff_int(&AutopilotMinEnemyDistance);
|
||||
else
|
||||
AutopilotMinEnemyDistance = 5000;
|
||||
|
||||
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
|
||||
stuff_int(&AutopilotMinAsteroidDistance);
|
||||
else
|
||||
AutopilotMinAsteroidDistance = 1000;
|
||||
|
||||
if (optional_string("$Lock Weapons During Autopilot:"))
|
||||
stuff_boolean(&LockWeaponsDuringAutopilot);
|
||||
else
|
||||
LockWeaponsDuringAutopilot = false;
|
||||
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Cutscene_Bars"))
|
||||
UseCutsceneBars = false;
|
||||
// optional no cutscene bars
|
||||
if (optional_string("+No_Autopilot_Interrupt"))
|
||||
Cmdline_autopilot_interruptable = 0;
|
||||
|
||||
// No Nav selected message
|
||||
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
|
||||
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
|
||||
"$Support Present:", "$Support Working:" };
|
||||
for (int i = 0; i < NP_NUM_MESSAGES; i++)
|
||||
{
|
||||
required_string(msg_tags[i]);
|
||||
|
||||
required_string("+Msg:");
|
||||
stuff_string(NavMsgs[i].message, F_MESSAGE, 256);
|
||||
|
||||
required_string("+Snd File:");
|
||||
stuff_string(NavMsgs[i].filename, F_NAME, 256);
|
||||
}
|
||||
|
||||
|
||||
required_string("#END");
|
||||
}
|
||||
|
||||
|
||||
|
||||
+22
-19
@@ -1027,7 +1027,7 @@ int bm_load(const SCP_string& filename) {
|
||||
}
|
||||
|
||||
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type) {
|
||||
int frames = 0, fps = 30, keyframe = 0, rval;
|
||||
int frames = 0, fps = 30, keyframe = 0;
|
||||
char ext[8];
|
||||
ubyte c_type = BM_TYPE_NONE;
|
||||
char file_text[1024];
|
||||
@@ -1040,28 +1040,31 @@ int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
|
||||
// pause anything that may happen to be parsing right now
|
||||
pause_parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("BMPMAN: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
try
|
||||
{
|
||||
// now start parsing the EFF
|
||||
read_file_text(filename, dir_type, file_text, file_text_raw);
|
||||
reset_parse(file_text);
|
||||
|
||||
required_string("$Type:");
|
||||
stuff_string(ext, F_NAME, sizeof(ext));
|
||||
|
||||
required_string("$Frames:");
|
||||
stuff_int(&frames);
|
||||
|
||||
if (optional_string("$FPS:"))
|
||||
stuff_int(&fps);
|
||||
|
||||
if (optional_string("$Keyframe:"))
|
||||
stuff_int(&keyframe);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("BMPMAN: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
unpause_parse();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now start parsing the EFF
|
||||
read_file_text(filename, dir_type, file_text, file_text_raw);
|
||||
reset_parse(file_text);
|
||||
|
||||
required_string("$Type:");
|
||||
stuff_string(ext, F_NAME, sizeof(ext));
|
||||
|
||||
required_string("$Frames:");
|
||||
stuff_int(&frames);
|
||||
|
||||
if (optional_string("$FPS:"))
|
||||
stuff_int(&fps);
|
||||
|
||||
if (optional_string("$Keyframe:"))
|
||||
stuff_int(&keyframe);
|
||||
|
||||
// done with EFF so unpause parsing so whatever can continue
|
||||
unpause_parse();
|
||||
|
||||
|
||||
+52
-50
@@ -52,59 +52,61 @@ void cutscene_init()
|
||||
{
|
||||
atexit(cutscene_close);
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
int rval;
|
||||
cutscene_info cutinfo;
|
||||
cutscene_info cutinfo;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "cutscenes.tbl", rval));
|
||||
try
|
||||
{
|
||||
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse in all the cutscenes
|
||||
Cutscenes.clear();
|
||||
skip_to_string("#Cutscenes");
|
||||
ignore_white_space();
|
||||
|
||||
bool isFirstCutscene = true;
|
||||
|
||||
while (required_string_either("#End", "$Filename:"))
|
||||
{
|
||||
required_string("$Filename:");
|
||||
stuff_string(cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN);
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(cutinfo.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string("$Description:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
cutinfo.description = vm_strdup(buf);
|
||||
|
||||
if (optional_string("$cd:"))
|
||||
stuff_int(&cutinfo.cd);
|
||||
else
|
||||
cutinfo.cd = 0;
|
||||
|
||||
cutinfo.viewable = false;
|
||||
|
||||
if (isFirstCutscene) {
|
||||
isFirstCutscene = false;
|
||||
// The original code assumes the first movie is the intro, so always viewable
|
||||
cutinfo.viewable = true;
|
||||
}
|
||||
|
||||
if (optional_string("$Always Viewable:")) {
|
||||
stuff_boolean(&cutinfo.viewable);
|
||||
}
|
||||
|
||||
Cutscenes.push_back(cutinfo);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "cutscenes.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse in all the cutscenes
|
||||
Cutscenes.clear();
|
||||
skip_to_string("#Cutscenes");
|
||||
ignore_white_space();
|
||||
|
||||
bool isFirstCutscene = true;
|
||||
|
||||
while ( required_string_either("#End", "$Filename:") )
|
||||
{
|
||||
required_string("$Filename:");
|
||||
stuff_string( cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN );
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string( cutinfo.name, F_NAME, NAME_LENGTH );
|
||||
|
||||
required_string("$Description:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
cutinfo.description = vm_strdup(buf);
|
||||
|
||||
if (optional_string("$cd:"))
|
||||
stuff_int( &cutinfo.cd );
|
||||
else
|
||||
cutinfo.cd = 0;
|
||||
|
||||
cutinfo.viewable = false;
|
||||
|
||||
if (isFirstCutscene) {
|
||||
isFirstCutscene = false;
|
||||
// The original code assumes the first movie is the intro, so always viewable
|
||||
cutinfo.viewable = true;
|
||||
}
|
||||
|
||||
if (optional_string("$Always Viewable:")) {
|
||||
stuff_boolean(&cutinfo.viewable);
|
||||
}
|
||||
|
||||
Cutscenes.push_back(cutinfo);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// function to return 0 based index of which CD a particular movie is on
|
||||
|
||||
+82
-73
@@ -159,84 +159,93 @@ static void fireball_set_default_color(int idx)
|
||||
*/
|
||||
void parse_fireball_tbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
lod_checker lod_check;
|
||||
color fb_color;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Start");
|
||||
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
memset(&lod_check, 0, sizeof(lod_checker));
|
||||
|
||||
// base filename
|
||||
required_string("$Name:");
|
||||
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
lod_check.override = -1;
|
||||
|
||||
// these entries should only be in TBMs, and it has to include at least one
|
||||
if (Parsing_modular_table) {
|
||||
if (optional_string("+Explosion_Medium")) {
|
||||
lod_check.override = FIREBALL_EXPLOSION_MEDIUM;
|
||||
}
|
||||
else if (optional_string("+Warp_Effect")) {
|
||||
lod_check.override = FIREBALL_WARP;
|
||||
}
|
||||
else if (optional_string("+Knossos_Effect")) {
|
||||
lod_check.override = FIREBALL_KNOSSOS;
|
||||
}
|
||||
else if (optional_string("+Asteroid")) {
|
||||
lod_check.override = FIREBALL_ASTEROID;
|
||||
}
|
||||
else if (optional_string("+Explosion_Large1")) {
|
||||
lod_check.override = FIREBALL_EXPLOSION_LARGE1;
|
||||
}
|
||||
else if (optional_string("+Explosion_Large2")){
|
||||
lod_check.override = FIREBALL_EXPLOSION_LARGE2;
|
||||
}
|
||||
else {
|
||||
required_string("+Custom_Fireball");
|
||||
stuff_int(&lod_check.override);
|
||||
}
|
||||
}
|
||||
|
||||
lod_check.num_lods = 1;
|
||||
|
||||
// Do we have an LOD num
|
||||
if (optional_string("$LOD:")) {
|
||||
stuff_int(&lod_check.num_lods);
|
||||
}
|
||||
|
||||
if (lod_check.num_lods > MAX_FIREBALL_LOD) {
|
||||
lod_check.num_lods = MAX_FIREBALL_LOD;
|
||||
}
|
||||
|
||||
// check for particular lighting color
|
||||
if (optional_string("$Light color:")) {
|
||||
int r, g, b;
|
||||
|
||||
stuff_int(&r);
|
||||
stuff_int(&g);
|
||||
stuff_int(&b);
|
||||
|
||||
CLAMP(r, 0, 255);
|
||||
CLAMP(g, 0, 255);
|
||||
CLAMP(b, 0, 255);
|
||||
|
||||
gr_init_color(&fb_color, r, g, b);
|
||||
}
|
||||
else {
|
||||
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
|
||||
memset(&fb_color, 0, sizeof(color));
|
||||
}
|
||||
|
||||
// we may use one filename for multiple entries so we'll have to handle dupes post parse
|
||||
LOD_checker.push_back(lod_check);
|
||||
LOD_color.push_back(fb_color);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Start");
|
||||
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
memset( &lod_check, 0, sizeof(lod_checker) );
|
||||
|
||||
// base filename
|
||||
required_string("$Name:");
|
||||
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
lod_check.override = -1;
|
||||
|
||||
// these entries should only be in TBMs, and it has to include at least one
|
||||
if ( Parsing_modular_table ) {
|
||||
if (optional_string("+Explosion_Medium")) {
|
||||
lod_check.override = FIREBALL_EXPLOSION_MEDIUM;
|
||||
} else if (optional_string("+Warp_Effect")) {
|
||||
lod_check.override = FIREBALL_WARP;
|
||||
} else if (optional_string("+Knossos_Effect")) {
|
||||
lod_check.override = FIREBALL_KNOSSOS;
|
||||
} else if (optional_string("+Asteroid")) {
|
||||
lod_check.override = FIREBALL_ASTEROID;
|
||||
} else if (optional_string("+Explosion_Large1")) {
|
||||
lod_check.override = FIREBALL_EXPLOSION_LARGE1;
|
||||
} else if (optional_string("+Explosion_Large2")){
|
||||
lod_check.override = FIREBALL_EXPLOSION_LARGE2;
|
||||
} else {
|
||||
required_string("+Custom_Fireball");
|
||||
stuff_int(&lod_check.override);
|
||||
}
|
||||
}
|
||||
|
||||
lod_check.num_lods = 1;
|
||||
|
||||
// Do we have an LOD num
|
||||
if (optional_string("$LOD:")) {
|
||||
stuff_int(&lod_check.num_lods);
|
||||
}
|
||||
|
||||
if (lod_check.num_lods > MAX_FIREBALL_LOD) {
|
||||
lod_check.num_lods = MAX_FIREBALL_LOD;
|
||||
}
|
||||
|
||||
// check for particular lighting color
|
||||
if ( optional_string("$Light color:") ) {
|
||||
int r, g, b;
|
||||
|
||||
stuff_int(&r);
|
||||
stuff_int(&g);
|
||||
stuff_int(&b);
|
||||
|
||||
CLAMP(r, 0, 255);
|
||||
CLAMP(g, 0, 255);
|
||||
CLAMP(b, 0, 255);
|
||||
|
||||
gr_init_color(&fb_color, r, g, b);
|
||||
} else {
|
||||
// to keep things simple, we just use 0 alpha to indicate that a default value should be used
|
||||
memset( &fb_color, 0, sizeof(color) );
|
||||
}
|
||||
|
||||
// we may use one filename for multiple entries so we'll have to handle dupes post parse
|
||||
LOD_checker.push_back(lod_check);
|
||||
LOD_color.push_back(fb_color);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
void fireball_parse_tbl()
|
||||
|
||||
+151
-145
@@ -323,7 +323,7 @@ void parse_helptbl(const char *filename)
|
||||
int overlay_id, currcount, vtxcount;
|
||||
char name[HELP_MAX_NAME_LENGTH];
|
||||
char buf[HELP_MAX_STRING_LENGTH + 1];
|
||||
int i, j, rval;
|
||||
int i, j;
|
||||
|
||||
SCP_vector<help_pline> pline_temp;
|
||||
help_pline pline_temp2;
|
||||
@@ -335,160 +335,166 @@ void parse_helptbl(const char *filename)
|
||||
help_left_bracket lbracket_temp2;
|
||||
vec3d vec3d_temp;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
// for each overlay...
|
||||
while (optional_string("$")) {
|
||||
|
||||
// for each overlay...
|
||||
while (optional_string("$")) {
|
||||
stuff_string(name, F_NAME, HELP_MAX_NAME_LENGTH);
|
||||
|
||||
stuff_string(name, F_NAME, HELP_MAX_NAME_LENGTH);
|
||||
overlay_id = help_overlay_get_index(name);
|
||||
|
||||
overlay_id = help_overlay_get_index(name);
|
||||
if (overlay_id < 0) {
|
||||
if (num_help_overlays >= MAX_HELP_OVERLAYS) {
|
||||
Warning(LOCATION, "Could not load help overlay after '%s' as maximum number of help overlays was reached (Max is %d)", help_overlaylist[overlay_id - 1].name, MAX_HELP_OVERLAYS);
|
||||
|
||||
if (overlay_id < 0) {
|
||||
if (num_help_overlays >= MAX_HELP_OVERLAYS) {
|
||||
Warning(LOCATION, "Could not load help overlay after '%s' as maximum number of help overlays was reached (Max is %d)", help_overlaylist[overlay_id - 1].name, MAX_HELP_OVERLAYS);
|
||||
|
||||
if (!skip_to_string("$end")) {
|
||||
Error(LOCATION, "Couldn't find $end. Help.tbl or -hlp.tbm is invalid.\n");
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
overlay_id = num_help_overlays;
|
||||
strcpy_s(help_overlaylist[overlay_id].name, name);
|
||||
num_help_overlays++;
|
||||
}
|
||||
}
|
||||
|
||||
// clear out counters in the overlay struct
|
||||
help_overlaylist[overlay_id].plinecount = 0;
|
||||
help_overlaylist[overlay_id].textcount = 0;
|
||||
help_overlaylist[overlay_id].rbracketcount = 0;
|
||||
help_overlaylist[overlay_id].lbracketcount = 0;
|
||||
|
||||
help_overlaylist[overlay_id].fontlist.clear();
|
||||
help_overlaylist[overlay_id].plinelist.clear();
|
||||
help_overlaylist[overlay_id].textlist.clear();
|
||||
help_overlaylist[overlay_id].rbracketlist.clear();
|
||||
help_overlaylist[overlay_id].lbracketlist.clear();
|
||||
|
||||
if (optional_string("+resolutions")) {
|
||||
stuff_int(&help_overlaylist[overlay_id].num_resolutions);
|
||||
} else {
|
||||
help_overlaylist[overlay_id].num_resolutions = 2;
|
||||
}
|
||||
|
||||
if (help_overlaylist[overlay_id].num_resolutions < 1) {
|
||||
Error(LOCATION, "+resolutions in %s is %d. (Must be 1 or greater)", filename, help_overlaylist[overlay_id].num_resolutions);
|
||||
}
|
||||
|
||||
if (optional_string("+font")) {
|
||||
int font;
|
||||
for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
stuff_int(&font);
|
||||
help_overlaylist[overlay_id].fontlist.push_back(font);
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].fontlist.push_back(FONT1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].plinelist.push_back(pline_temp);
|
||||
help_overlaylist[overlay_id].textlist.push_back(text_temp);
|
||||
help_overlaylist[overlay_id].rbracketlist.push_back(rbracket_temp);
|
||||
help_overlaylist[overlay_id].lbracketlist.push_back(lbracket_temp);
|
||||
}
|
||||
|
||||
int type;
|
||||
// read in all elements for this overlay
|
||||
while ((type = required_string_one_of(5, "+pline", "+text", "+right_bracket", "+left_bracket", "$end")) != 4) { // Doing it this way means an error lists "$end" at the end, which seems appropriate. -MageKing17
|
||||
|
||||
switch (type) {
|
||||
case 0: // +pline
|
||||
required_string("+pline");
|
||||
currcount = help_overlaylist[overlay_id].plinecount;
|
||||
int a, b; // temp vars to read in int before cast to float;
|
||||
|
||||
// read number of pline vertices
|
||||
stuff_int(&vtxcount);
|
||||
// get vertex coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].plinelist.at(i).push_back(pline_temp2);
|
||||
for (j = 0; j < vtxcount; j++) {
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.push_back(vec3d_temp);
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtxcount = vtxcount;
|
||||
stuff_int(&a);
|
||||
stuff_int(&b);
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.x = (float)a;
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.y = (float)b;
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.z = 0.0f;
|
||||
if (!skip_to_string("$end")) {
|
||||
Error(LOCATION, "Couldn't find $end. Help.tbl or -hlp.tbm is invalid.\n");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
help_overlaylist[overlay_id].plinecount++;
|
||||
break;
|
||||
case 1: // +text
|
||||
required_string("+text");
|
||||
currcount = help_overlaylist[overlay_id].textcount;
|
||||
|
||||
// get coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].textlist.at(i).push_back(text_temp2);
|
||||
stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).x_coord));
|
||||
stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).y_coord));
|
||||
else {
|
||||
overlay_id = num_help_overlays;
|
||||
strcpy_s(help_overlaylist[overlay_id].name, name);
|
||||
num_help_overlays++;
|
||||
}
|
||||
|
||||
// get string (always use the first resolution)
|
||||
stuff_string(buf, F_MESSAGE, sizeof(buf));
|
||||
help_overlaylist[overlay_id].textlist.at(0).at(currcount).string = vm_strdup(buf);
|
||||
|
||||
help_overlaylist[overlay_id].textcount++;
|
||||
break;
|
||||
case 2: // +right_bracket
|
||||
required_string("+right_bracket");
|
||||
currcount = help_overlaylist[overlay_id].rbracketcount;
|
||||
|
||||
// get coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].rbracketlist.at(i).push_back(rbracket_temp2);
|
||||
stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).x_coord));
|
||||
stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).y_coord));
|
||||
}
|
||||
|
||||
help_overlaylist[overlay_id].rbracketcount++;
|
||||
break;
|
||||
case 3: // +left_bracket
|
||||
required_string("+left_bracket");
|
||||
currcount = help_overlaylist[overlay_id].lbracketcount;
|
||||
|
||||
// get coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].lbracketlist.at(i).push_back(lbracket_temp2);
|
||||
stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).x_coord));
|
||||
stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).y_coord));
|
||||
}
|
||||
|
||||
help_overlaylist[overlay_id].lbracketcount++;
|
||||
break;
|
||||
case -1:
|
||||
// -noparseerrors is set
|
||||
break;
|
||||
case 4: // $end
|
||||
default:
|
||||
Assertion(false, "This should never happen.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// clear out counters in the overlay struct
|
||||
help_overlaylist[overlay_id].plinecount = 0;
|
||||
help_overlaylist[overlay_id].textcount = 0;
|
||||
help_overlaylist[overlay_id].rbracketcount = 0;
|
||||
help_overlaylist[overlay_id].lbracketcount = 0;
|
||||
|
||||
help_overlaylist[overlay_id].fontlist.clear();
|
||||
help_overlaylist[overlay_id].plinelist.clear();
|
||||
help_overlaylist[overlay_id].textlist.clear();
|
||||
help_overlaylist[overlay_id].rbracketlist.clear();
|
||||
help_overlaylist[overlay_id].lbracketlist.clear();
|
||||
|
||||
if (optional_string("+resolutions")) {
|
||||
stuff_int(&help_overlaylist[overlay_id].num_resolutions);
|
||||
}
|
||||
else {
|
||||
help_overlaylist[overlay_id].num_resolutions = 2;
|
||||
}
|
||||
|
||||
if (help_overlaylist[overlay_id].num_resolutions < 1) {
|
||||
Error(LOCATION, "+resolutions in %s is %d. (Must be 1 or greater)", filename, help_overlaylist[overlay_id].num_resolutions);
|
||||
}
|
||||
|
||||
if (optional_string("+font")) {
|
||||
int font;
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
stuff_int(&font);
|
||||
help_overlaylist[overlay_id].fontlist.push_back(font);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].fontlist.push_back(FONT1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].plinelist.push_back(pline_temp);
|
||||
help_overlaylist[overlay_id].textlist.push_back(text_temp);
|
||||
help_overlaylist[overlay_id].rbracketlist.push_back(rbracket_temp);
|
||||
help_overlaylist[overlay_id].lbracketlist.push_back(lbracket_temp);
|
||||
}
|
||||
|
||||
int type;
|
||||
// read in all elements for this overlay
|
||||
while ((type = required_string_one_of(5, "+pline", "+text", "+right_bracket", "+left_bracket", "$end")) != 4) { // Doing it this way means an error lists "$end" at the end, which seems appropriate. -MageKing17
|
||||
|
||||
switch (type) {
|
||||
case 0: // +pline
|
||||
required_string("+pline");
|
||||
currcount = help_overlaylist[overlay_id].plinecount;
|
||||
int a, b; // temp vars to read in int before cast to float;
|
||||
|
||||
// read number of pline vertices
|
||||
stuff_int(&vtxcount);
|
||||
// get vertex coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].plinelist.at(i).push_back(pline_temp2);
|
||||
for (j = 0; j < vtxcount; j++) {
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.push_back(vec3d_temp);
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtxcount = vtxcount;
|
||||
stuff_int(&a);
|
||||
stuff_int(&b);
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.x = (float)a;
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.y = (float)b;
|
||||
help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.z = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
help_overlaylist[overlay_id].plinecount++;
|
||||
break;
|
||||
case 1: // +text
|
||||
required_string("+text");
|
||||
currcount = help_overlaylist[overlay_id].textcount;
|
||||
|
||||
// get coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].textlist.at(i).push_back(text_temp2);
|
||||
stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).x_coord));
|
||||
stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).y_coord));
|
||||
}
|
||||
|
||||
// get string (always use the first resolution)
|
||||
stuff_string(buf, F_MESSAGE, sizeof(buf));
|
||||
help_overlaylist[overlay_id].textlist.at(0).at(currcount).string = vm_strdup(buf);
|
||||
|
||||
help_overlaylist[overlay_id].textcount++;
|
||||
break;
|
||||
case 2: // +right_bracket
|
||||
required_string("+right_bracket");
|
||||
currcount = help_overlaylist[overlay_id].rbracketcount;
|
||||
|
||||
// get coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].rbracketlist.at(i).push_back(rbracket_temp2);
|
||||
stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).x_coord));
|
||||
stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).y_coord));
|
||||
}
|
||||
|
||||
help_overlaylist[overlay_id].rbracketcount++;
|
||||
break;
|
||||
case 3: // +left_bracket
|
||||
required_string("+left_bracket");
|
||||
currcount = help_overlaylist[overlay_id].lbracketcount;
|
||||
|
||||
// get coordinates for each resolution
|
||||
for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
|
||||
help_overlaylist[overlay_id].lbracketlist.at(i).push_back(lbracket_temp2);
|
||||
stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).x_coord));
|
||||
stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).y_coord));
|
||||
}
|
||||
|
||||
help_overlaylist[overlay_id].lbracketcount++;
|
||||
break;
|
||||
case -1:
|
||||
// -noparseerrors is set
|
||||
break;
|
||||
case 4: // $end
|
||||
default:
|
||||
Assertion(false, "This should never happen.\n");
|
||||
break;
|
||||
}
|
||||
} // end while
|
||||
required_string("$end");
|
||||
} // end while
|
||||
required_string("$end");
|
||||
} // end while
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1374,12 +1374,8 @@ void parse_menumusic()
|
||||
//
|
||||
void event_music_parse_musictbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
|
||||
} else {
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
@@ -1399,6 +1395,10 @@ void event_music_parse_musictbl(const char *filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
+74
-74
@@ -693,83 +693,83 @@ static SCP_vector<species_info> missingFlybySounds;
|
||||
|
||||
void parse_sound_table(const char* filename)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// Parse the gameplay sounds section
|
||||
if (optional_string("#Game Sounds Start"))
|
||||
{
|
||||
while (!check_for_string("#Game Sounds End"))
|
||||
{
|
||||
game_snd tempSound;
|
||||
if (gamesnd_parse_line(&tempSound, "$Name:", &Snds))
|
||||
{
|
||||
Snds.push_back(game_snd(tempSound));
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#Game Sounds End");
|
||||
}
|
||||
|
||||
// Parse the interface sounds section
|
||||
if (optional_string("#Interface Sounds Start"))
|
||||
{
|
||||
while (!check_for_string("#Interface Sounds End"))
|
||||
{
|
||||
game_snd tempSound;
|
||||
if (gamesnd_parse_line(&tempSound, "$Name:", &Snds_iface))
|
||||
{
|
||||
Snds_iface.push_back(game_snd(tempSound));
|
||||
Snds_iface_handle.push_back(-1);
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#Interface Sounds End");
|
||||
}
|
||||
|
||||
// parse flyby sound section
|
||||
if (optional_string("#Flyby Sounds Start"))
|
||||
{
|
||||
char species_name_tag[NAME_LENGTH + 2];
|
||||
int sanity_check = 0;
|
||||
size_t i;
|
||||
|
||||
while (!check_for_string("#Flyby Sounds End") && (sanity_check <= (int)Species_info.size()))
|
||||
{
|
||||
for (i = 0; i < Species_info.size(); i++)
|
||||
{
|
||||
species_info *species = &Species_info[i];
|
||||
|
||||
sprintf(species_name_tag, "$%s:", species->species_name);
|
||||
|
||||
if (check_for_string(species_name_tag))
|
||||
{
|
||||
gamesnd_parse_line(&species->snd_flyby_fighter, species_name_tag);
|
||||
gamesnd_parse_line(&species->snd_flyby_bomber, species_name_tag);
|
||||
sanity_check--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sanity_check++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#Flyby Sounds End");
|
||||
}
|
||||
|
||||
if (optional_string("#Sound Environments Start"))
|
||||
{
|
||||
parse_sound_environments();
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// Parse the gameplay sounds section
|
||||
if (optional_string("#Game Sounds Start"))
|
||||
{
|
||||
while (!check_for_string("#Game Sounds End"))
|
||||
{
|
||||
game_snd tempSound;
|
||||
if (gamesnd_parse_line(&tempSound, "$Name:", &Snds))
|
||||
{
|
||||
Snds.push_back(game_snd(tempSound));
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#Game Sounds End");
|
||||
}
|
||||
|
||||
// Parse the interface sounds section
|
||||
if (optional_string("#Interface Sounds Start"))
|
||||
{
|
||||
while (!check_for_string("#Interface Sounds End"))
|
||||
{
|
||||
game_snd tempSound;
|
||||
if (gamesnd_parse_line( &tempSound, "$Name:", &Snds_iface))
|
||||
{
|
||||
Snds_iface.push_back(game_snd(tempSound));
|
||||
Snds_iface_handle.push_back(-1);
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#Interface Sounds End");
|
||||
}
|
||||
|
||||
// parse flyby sound section
|
||||
if (optional_string("#Flyby Sounds Start"))
|
||||
{
|
||||
char species_name_tag[NAME_LENGTH + 2];
|
||||
int sanity_check = 0;
|
||||
size_t i;
|
||||
|
||||
while (!check_for_string("#Flyby Sounds End") && (sanity_check <= (int)Species_info.size()))
|
||||
{
|
||||
for (i = 0; i < Species_info.size(); i++)
|
||||
{
|
||||
species_info *species = &Species_info[i];
|
||||
|
||||
sprintf(species_name_tag, "$%s:", species->species_name);
|
||||
|
||||
if (check_for_string(species_name_tag))
|
||||
{
|
||||
gamesnd_parse_line(&species->snd_flyby_fighter, species_name_tag);
|
||||
gamesnd_parse_line(&species->snd_flyby_bomber, species_name_tag);
|
||||
sanity_check--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sanity_check++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#Flyby Sounds End");
|
||||
}
|
||||
|
||||
if (optional_string("#Sound Environments Start"))
|
||||
{
|
||||
parse_sound_environments();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+320
-308
@@ -273,71 +273,74 @@ void parse_colors(const char *filename)
|
||||
{
|
||||
Assertion(filename != NULL, "parse_colors() called on NULL; get a coder!\n");
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
int err_code;
|
||||
if ((err_code = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %d.\n", filename, err_code));
|
||||
return;
|
||||
}
|
||||
|
||||
reset_parse();
|
||||
|
||||
// we search for the colors based on their order of definition above
|
||||
// if the color isn't found, we just use default values
|
||||
if (optional_string("#Start Colors"))
|
||||
|
||||
try
|
||||
{
|
||||
// vars for holding rgba values
|
||||
int rgba[4] = {0,0,0,0};
|
||||
int i, j;
|
||||
reset_parse();
|
||||
|
||||
char* color_names[TOTAL_COLORS] = {
|
||||
"$Blue:",
|
||||
"$Bright Blue:",
|
||||
"$Green:",
|
||||
"$Bright Green:",
|
||||
"$Black:",
|
||||
"$Grey:",
|
||||
"$Silver:",
|
||||
"$White:",
|
||||
"$Bright White:",
|
||||
"$Violet Gray:",
|
||||
"$Violet:",
|
||||
"$Dim Red:",
|
||||
"$Red:",
|
||||
"$Bright Red:",
|
||||
"$Pink:",
|
||||
"$Light Pink:",
|
||||
"$Yellow:",
|
||||
"$Bright Yellow:",
|
||||
"$UI Light Green:",
|
||||
"$UI Green:",
|
||||
"$UI Light Pink:",
|
||||
"$UI Pink:"
|
||||
};
|
||||
// we search for the colors based on their order of definition above
|
||||
// if the color isn't found, we just use default values
|
||||
if (optional_string("#Start Colors"))
|
||||
{
|
||||
// vars for holding rgba values
|
||||
int rgba[4] = { 0, 0, 0, 0 };
|
||||
int i, j;
|
||||
|
||||
// now for each color, check if it's corresponding string is there
|
||||
for (i = 0; i < TOTAL_COLORS; i++) {
|
||||
if (optional_string(color_names[i])) {
|
||||
// if so, get its rgba values and initialise it using them
|
||||
mprintf(("'%s' has been redefined.\n", color_names[i]));
|
||||
//if (check_for_string("(")) {
|
||||
char* color_names[TOTAL_COLORS] = {
|
||||
"$Blue:",
|
||||
"$Bright Blue:",
|
||||
"$Green:",
|
||||
"$Bright Green:",
|
||||
"$Black:",
|
||||
"$Grey:",
|
||||
"$Silver:",
|
||||
"$White:",
|
||||
"$Bright White:",
|
||||
"$Violet Gray:",
|
||||
"$Violet:",
|
||||
"$Dim Red:",
|
||||
"$Red:",
|
||||
"$Bright Red:",
|
||||
"$Pink:",
|
||||
"$Light Pink:",
|
||||
"$Yellow:",
|
||||
"$Bright Yellow:",
|
||||
"$UI Light Green:",
|
||||
"$UI Green:",
|
||||
"$UI Light Pink:",
|
||||
"$UI Pink:"
|
||||
};
|
||||
|
||||
// now for each color, check if it's corresponding string is there
|
||||
for (i = 0; i < TOTAL_COLORS; i++) {
|
||||
if (optional_string(color_names[i])) {
|
||||
// if so, get its rgba values and initialise it using them
|
||||
mprintf(("'%s' has been redefined.\n", color_names[i]));
|
||||
//if (check_for_string("(")) {
|
||||
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (rgba[j] < 0) {
|
||||
Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
|
||||
rgba[j] = 0;
|
||||
} else if (rgba[j] > 255) {
|
||||
}
|
||||
else if (rgba[j] > 255) {
|
||||
Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
|
||||
rgba[j] = 255;
|
||||
}
|
||||
}
|
||||
//} else {
|
||||
// stuff_hex_list(rgba, 4);
|
||||
//}
|
||||
gr_init_alphacolor(COLOR_LIST[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
//} else {
|
||||
// stuff_hex_list(rgba, 4);
|
||||
//}
|
||||
gr_init_alphacolor(COLOR_LIST[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,281 +349,290 @@ void parse_everything_else(const char *filename)
|
||||
Assertion(filename != NULL, "parse_everything_else() called on NULL; get a coder!\n");
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
int err_code;
|
||||
if ((err_code = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %d.\n", filename, err_code));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
reset_parse();
|
||||
|
||||
reset_parse();
|
||||
int rgba[4] = { 0, 0, 0, 0 };
|
||||
|
||||
int rgba[4] = {0,0,0,0};
|
||||
// reusable temp vars
|
||||
int i, j;
|
||||
SCP_string temp;
|
||||
|
||||
// reusable temp vars
|
||||
int i, j;
|
||||
SCP_string temp;
|
||||
|
||||
if (optional_string("#Start Colors")) {
|
||||
// Skip this section; we already parsed it in every file.
|
||||
skip_to_string("#End", NULL);
|
||||
}
|
||||
|
||||
//Team coloring
|
||||
if (optional_string("#Team Colors")) {
|
||||
|
||||
while (required_string_either("#End", "$Team Name:")) {
|
||||
required_string("$Team Name:"); // required to move the parse pointer forward
|
||||
team_color temp_color;
|
||||
|
||||
char temp2[NAME_LENGTH];
|
||||
stuff_string(temp2, F_NAME, NAME_LENGTH);
|
||||
temp = temp2;
|
||||
|
||||
if (!stricmp(temp2, "none")) {
|
||||
Warning(LOCATION, "Team color in '%s' defined with a name of '%s'; this won't be usable due to 'None' being used for a lack of a team color by the engine.\n", filename, temp2);
|
||||
}
|
||||
|
||||
if (required_string("$Team Stripe Color:")) {
|
||||
int rgb[3];
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++) {
|
||||
CLAMP(rgb[i], 0, 255);
|
||||
}
|
||||
|
||||
temp_color.stripe.r = rgb[0] / 255.0f;
|
||||
temp_color.stripe.g = rgb[1] / 255.0f;
|
||||
temp_color.stripe.b = rgb[2] / 255.0f;
|
||||
}
|
||||
|
||||
if (required_string("$Team Base Color:")) {
|
||||
int rgb[3];
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++) {
|
||||
CLAMP(rgb[i], 0, 255);
|
||||
}
|
||||
|
||||
temp_color.base.r = rgb[0] / 255.0f;
|
||||
temp_color.base.g = rgb[1] / 255.0f;
|
||||
temp_color.base.b = rgb[2] / 255.0f;
|
||||
}
|
||||
|
||||
if (Team_Colors.find(temp) == Team_Colors.end()) { // Only push to the vector if the team isn't already defined.
|
||||
Team_Names.push_back(temp);
|
||||
}
|
||||
Team_Colors[temp] = temp_color;
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Previously-hardcoded interface colors
|
||||
if (optional_string("#Interface Colors")) {
|
||||
char *color_names[INTERFACE_COLORS] = {
|
||||
"$Text Normal:",
|
||||
"$Text Subselected:",
|
||||
"$Text Selected:",
|
||||
"$Text Error:",
|
||||
"$Text Error Highlighted:",
|
||||
"$Text Active:",
|
||||
"$Text Active Highlighted:",
|
||||
"$Text Heading:",
|
||||
"$More Indicator:",
|
||||
"$Bright More Indicator:",
|
||||
"$Bright:",
|
||||
"$Normal:",
|
||||
"$Briefing Grid:",
|
||||
};
|
||||
|
||||
// now for each color, check if its corresponding string is there
|
||||
for (i = 0; i < INTERFACE_COLORS; i++) {
|
||||
if (optional_string(color_names[i])) {
|
||||
// if so, get its rgba values and initialise it using them
|
||||
mprintf(("'%s' has been redefined.\n", color_names[i]));
|
||||
if ( check_for_string("(") ) {
|
||||
// If we have a list of integers, use them.
|
||||
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (rgba[j] < 0)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
|
||||
rgba[j] = 0;
|
||||
}
|
||||
else if (rgba[j] > 255)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
|
||||
rgba[j] = 255;
|
||||
}
|
||||
}
|
||||
gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
//} else if (check_for_string("#")) {
|
||||
// stuff_hex_list(rgba, 4);
|
||||
// gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
} else {
|
||||
// We have a string; it should be the name of a color to use.
|
||||
stuff_string(temp, F_NAME);
|
||||
for (j = 0; j < TOTAL_COLORS; j++) {
|
||||
if ( !temp.compare(COLOR_NAMES[j]) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == TOTAL_COLORS ) {
|
||||
Warning(LOCATION, "Unknown color '%s' in %s, for definition of '%s'; using default ('%s').\n", temp.c_str(), filename, color_names[i], COLOR_NAMES[interface_defaults[i]]);
|
||||
} else {
|
||||
Assertion(j >= 0 && j < TOTAL_COLORS, "Attempting to copy nonexistant color (%d out of 0-%d)!\n", j, TOTAL_COLORS-1);
|
||||
memcpy(interface_colors[i], COLOR_LIST[j], sizeof(color));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Text color tags; for briefings, command briefings, debriefings, and the fiction viewer
|
||||
if (optional_string("#Color Tags")) {
|
||||
while (required_string_either("$Tag:", "#End") < 1) {
|
||||
required_string("$Tag:");
|
||||
color temp_color;
|
||||
char tag;
|
||||
|
||||
stuff_string(temp, F_RAW);
|
||||
if (temp[0] == '$') {
|
||||
if (temp[1] == '\0') {
|
||||
Error(LOCATION, "%s - found a '$Tag:' entry with a solitary '$'.\n", filename);
|
||||
}
|
||||
tag = temp[1];
|
||||
if (temp[2] != '\0') {
|
||||
Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
|
||||
}
|
||||
} else if (temp[0] == '\0') {
|
||||
Error(LOCATION, "%s - found a '$Tag:' entry with no tag.\n", filename);
|
||||
} else {
|
||||
tag = temp[0];
|
||||
if (temp[1] != '\0') {
|
||||
Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (Tagged_Colors.find(tag) == Tagged_Colors.end()) { // Only push the tag to our list of tags if it's actually new, not just a redefinition.
|
||||
Color_Tags.push_back(tag);
|
||||
}
|
||||
|
||||
switch(required_string_one_of(4, "+Color:", "+Friendly", "+Hostile", "+Neutral")) {
|
||||
case 0: // +Color
|
||||
required_string("+Color:");
|
||||
|
||||
rgba[0] = rgba[1] = rgba[2] = 0;
|
||||
rgba[3] = 255; // Odds are pretty high you want it to have full alpha...
|
||||
|
||||
if ( check_for_string("(") ) {
|
||||
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (rgba[j] < 0)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '$%c' in %s too low (%d), capping to 0.\n", tag, filename, rgba[j]);
|
||||
rgba[j] = 0;
|
||||
}
|
||||
else if (rgba[j] > 255)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '$%c' in %s too high (%d), capping to 255.\n", tag, filename, rgba[j]);
|
||||
rgba[j] = 255;
|
||||
}
|
||||
}
|
||||
gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
Custom_Colors[tag] = temp_color;
|
||||
Tagged_Colors[tag] = &Custom_Colors[tag];
|
||||
//} else if ( check_for_string ("#") ) {
|
||||
// stuff_hex_list(rgba, 4);
|
||||
// gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// Custom_Colors[tag] = temp_color;
|
||||
// Tagged_Colors[tag] = &Custom_Colors[tag];
|
||||
} else {
|
||||
// We have a string; it should be the name of a color to use.
|
||||
stuff_string(temp, F_NAME);
|
||||
for (j = 0; j < TOTAL_COLORS; j++) {
|
||||
if ( !temp.compare(COLOR_NAMES[j]) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == TOTAL_COLORS ) {
|
||||
Error(LOCATION, "Unknown color '%s' in %s, for definition of tag '$%c'.\n", temp.c_str(), filename, tag);
|
||||
}
|
||||
Tagged_Colors[tag] = COLOR_LIST[j];
|
||||
}
|
||||
break;
|
||||
case 1: // +Friendly
|
||||
required_string("+Friendly");
|
||||
Tagged_Colors[tag] = &Brief_color_green;
|
||||
break;
|
||||
case 2: // +Hostile
|
||||
required_string("+Hostile");
|
||||
Tagged_Colors[tag] = &Brief_color_red;
|
||||
break;
|
||||
case 3: // +Neutral
|
||||
required_string("+Neutral");
|
||||
Tagged_Colors[tag] = &Brief_color_legacy_neutral;
|
||||
break;
|
||||
case -1:
|
||||
// -noparseerrors is set
|
||||
if (Tagged_Colors.find(tag) == Tagged_Colors.end()) { // It was a new color, but since we haven't actually defined it...
|
||||
Color_Tags.pop_back();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Assertion(false, "MageKing17 made a coding error somewhere, and you should laugh at him (and report this error).\n");
|
||||
break;
|
||||
}
|
||||
if (optional_string("#Start Colors")) {
|
||||
// Skip this section; we already parsed it in every file.
|
||||
skip_to_string("#End", NULL);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
Assertion(Color_Tags.size() == Tagged_Colors.size(), "Color_Tags and Tagged_Colors size mismatch; get a coder!\n");
|
||||
//Team coloring
|
||||
if (optional_string("#Team Colors")) {
|
||||
|
||||
if (optional_string("#Default Text Colors")) {
|
||||
while (required_string_either("#End", "$Team Name:")) {
|
||||
required_string("$Team Name:"); // required to move the parse pointer forward
|
||||
team_color temp_color;
|
||||
|
||||
char* color_names[MAX_DEFAULT_TEXT_COLORS] = {
|
||||
"$Fiction Viewer:",
|
||||
"$Command Briefing:",
|
||||
"$Briefing:",
|
||||
"$Redalert Briefing:",
|
||||
"$Debriefing:",
|
||||
"$Recommendation:",
|
||||
"$Loop Briefing:",
|
||||
};
|
||||
char temp2[NAME_LENGTH];
|
||||
stuff_string(temp2, F_NAME, NAME_LENGTH);
|
||||
temp = temp2;
|
||||
|
||||
char *color_value[MAX_DEFAULT_TEXT_COLORS] = {
|
||||
&default_fiction_viewer_color,
|
||||
&default_command_briefing_color,
|
||||
&default_briefing_color,
|
||||
&default_redalert_briefing_color,
|
||||
&default_debriefing_color,
|
||||
&default_recommendation_color,
|
||||
&default_loop_briefing_color,
|
||||
};
|
||||
if (!stricmp(temp2, "none")) {
|
||||
Warning(LOCATION, "Team color in '%s' defined with a name of '%s'; this won't be usable due to 'None' being used for a lack of a team color by the engine.\n", filename, temp2);
|
||||
}
|
||||
|
||||
if (required_string("$Team Stripe Color:")) {
|
||||
int rgb[3];
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++) {
|
||||
CLAMP(rgb[i], 0, 255);
|
||||
}
|
||||
|
||||
temp_color.stripe.r = rgb[0] / 255.0f;
|
||||
temp_color.stripe.g = rgb[1] / 255.0f;
|
||||
temp_color.stripe.b = rgb[2] / 255.0f;
|
||||
}
|
||||
|
||||
if (required_string("$Team Base Color:")) {
|
||||
int rgb[3];
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++) {
|
||||
CLAMP(rgb[i], 0, 255);
|
||||
}
|
||||
|
||||
temp_color.base.r = rgb[0] / 255.0f;
|
||||
temp_color.base.g = rgb[1] / 255.0f;
|
||||
temp_color.base.b = rgb[2] / 255.0f;
|
||||
}
|
||||
|
||||
if (Team_Colors.find(temp) == Team_Colors.end()) { // Only push to the vector if the team isn't already defined.
|
||||
Team_Names.push_back(temp);
|
||||
}
|
||||
Team_Colors[temp] = temp_color;
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Previously-hardcoded interface colors
|
||||
if (optional_string("#Interface Colors")) {
|
||||
char *color_names[INTERFACE_COLORS] = {
|
||||
"$Text Normal:",
|
||||
"$Text Subselected:",
|
||||
"$Text Selected:",
|
||||
"$Text Error:",
|
||||
"$Text Error Highlighted:",
|
||||
"$Text Active:",
|
||||
"$Text Active Highlighted:",
|
||||
"$Text Heading:",
|
||||
"$More Indicator:",
|
||||
"$Bright More Indicator:",
|
||||
"$Bright:",
|
||||
"$Normal:",
|
||||
"$Briefing Grid:",
|
||||
};
|
||||
|
||||
// now for each color, check if its corresponding string is there
|
||||
for (i = 0; i < INTERFACE_COLORS; i++) {
|
||||
if (optional_string(color_names[i])) {
|
||||
// if so, get its rgba values and initialise it using them
|
||||
mprintf(("'%s' has been redefined.\n", color_names[i]));
|
||||
if (check_for_string("(")) {
|
||||
// If we have a list of integers, use them.
|
||||
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (rgba[j] < 0)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
|
||||
rgba[j] = 0;
|
||||
}
|
||||
else if (rgba[j] > 255)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
|
||||
rgba[j] = 255;
|
||||
}
|
||||
}
|
||||
gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
//} else if (check_for_string("#")) {
|
||||
// stuff_hex_list(rgba, 4);
|
||||
// gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
else {
|
||||
// We have a string; it should be the name of a color to use.
|
||||
stuff_string(temp, F_NAME);
|
||||
for (j = 0; j < TOTAL_COLORS; j++) {
|
||||
if (!temp.compare(COLOR_NAMES[j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == TOTAL_COLORS) {
|
||||
Warning(LOCATION, "Unknown color '%s' in %s, for definition of '%s'; using default ('%s').\n", temp.c_str(), filename, color_names[i], COLOR_NAMES[interface_defaults[i]]);
|
||||
}
|
||||
else {
|
||||
Assertion(j >= 0 && j < TOTAL_COLORS, "Attempting to copy nonexistant color (%d out of 0-%d)!\n", j, TOTAL_COLORS - 1);
|
||||
memcpy(interface_colors[i], COLOR_LIST[j], sizeof(color));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Text color tags; for briefings, command briefings, debriefings, and the fiction viewer
|
||||
if (optional_string("#Color Tags")) {
|
||||
while (required_string_either("$Tag:", "#End") < 1) {
|
||||
required_string("$Tag:");
|
||||
color temp_color;
|
||||
char tag;
|
||||
|
||||
for (i = 0; i < MAX_DEFAULT_TEXT_COLORS; i++) {
|
||||
if ( optional_string(color_names[i]) ) {
|
||||
stuff_string(temp, F_RAW);
|
||||
if (temp[0] == '$') {
|
||||
if (temp[1] == '\0') {
|
||||
Error(LOCATION, "%s - default text color '%s' entry with a solitary '$'.\n", filename, color_names[i]);
|
||||
Error(LOCATION, "%s - found a '$Tag:' entry with a solitary '$'.\n", filename);
|
||||
}
|
||||
*color_value[i] = temp[1];
|
||||
tag = temp[1];
|
||||
if (temp[2] != '\0') {
|
||||
Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
|
||||
}
|
||||
} else if (temp[0] == '\0') {
|
||||
Error(LOCATION, "%s - default text color '%s' entry with no tag.\n", filename, color_names[i]);
|
||||
} else {
|
||||
*color_value[i] = temp[0];
|
||||
if (temp[1] != '\0') {
|
||||
Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
|
||||
Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
|
||||
}
|
||||
}
|
||||
if (Tagged_Colors.find(*color_value[i]) == Tagged_Colors.end()) {
|
||||
// Just mprintf() this information instead of complaining with a Warning(); the tag might be defined in a later-loading TBM, and if it isn't, nothing too terrible will happen.
|
||||
mprintf(("%s - default text color '%s' set to non-existant tag '$%c'.\n", filename, color_names[i], *color_value[i]));
|
||||
else if (temp[0] == '\0') {
|
||||
Error(LOCATION, "%s - found a '$Tag:' entry with no tag.\n", filename);
|
||||
}
|
||||
else {
|
||||
tag = temp[0];
|
||||
if (temp[1] != '\0') {
|
||||
Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (Tagged_Colors.find(tag) == Tagged_Colors.end()) { // Only push the tag to our list of tags if it's actually new, not just a redefinition.
|
||||
Color_Tags.push_back(tag);
|
||||
}
|
||||
|
||||
switch (required_string_one_of(4, "+Color:", "+Friendly", "+Hostile", "+Neutral")) {
|
||||
case 0: // +Color
|
||||
required_string("+Color:");
|
||||
|
||||
rgba[0] = rgba[1] = rgba[2] = 0;
|
||||
rgba[3] = 255; // Odds are pretty high you want it to have full alpha...
|
||||
|
||||
if (check_for_string("(")) {
|
||||
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (rgba[j] < 0)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '$%c' in %s too low (%d), capping to 0.\n", tag, filename, rgba[j]);
|
||||
rgba[j] = 0;
|
||||
}
|
||||
else if (rgba[j] > 255)
|
||||
{
|
||||
Warning(LOCATION, "RGBA value for '$%c' in %s too high (%d), capping to 255.\n", tag, filename, rgba[j]);
|
||||
rgba[j] = 255;
|
||||
}
|
||||
}
|
||||
gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
Custom_Colors[tag] = temp_color;
|
||||
Tagged_Colors[tag] = &Custom_Colors[tag];
|
||||
//} else if ( check_for_string ("#") ) {
|
||||
// stuff_hex_list(rgba, 4);
|
||||
// gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// Custom_Colors[tag] = temp_color;
|
||||
// Tagged_Colors[tag] = &Custom_Colors[tag];
|
||||
}
|
||||
else {
|
||||
// We have a string; it should be the name of a color to use.
|
||||
stuff_string(temp, F_NAME);
|
||||
for (j = 0; j < TOTAL_COLORS; j++) {
|
||||
if (!temp.compare(COLOR_NAMES[j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == TOTAL_COLORS) {
|
||||
Error(LOCATION, "Unknown color '%s' in %s, for definition of tag '$%c'.\n", temp.c_str(), filename, tag);
|
||||
}
|
||||
Tagged_Colors[tag] = COLOR_LIST[j];
|
||||
}
|
||||
break;
|
||||
case 1: // +Friendly
|
||||
required_string("+Friendly");
|
||||
Tagged_Colors[tag] = &Brief_color_green;
|
||||
break;
|
||||
case 2: // +Hostile
|
||||
required_string("+Hostile");
|
||||
Tagged_Colors[tag] = &Brief_color_red;
|
||||
break;
|
||||
case 3: // +Neutral
|
||||
required_string("+Neutral");
|
||||
Tagged_Colors[tag] = &Brief_color_legacy_neutral;
|
||||
break;
|
||||
case -1:
|
||||
// -noparseerrors is set
|
||||
if (Tagged_Colors.find(tag) == Tagged_Colors.end()) { // It was a new color, but since we haven't actually defined it...
|
||||
Color_Tags.pop_back();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Assertion(false, "MageKing17 made a coding error somewhere, and you should laugh at him (and report this error).\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
required_string("#End");
|
||||
Assertion(Color_Tags.size() == Tagged_Colors.size(), "Color_Tags and Tagged_Colors size mismatch; get a coder!\n");
|
||||
|
||||
if (optional_string("#Default Text Colors")) {
|
||||
|
||||
char* color_names[MAX_DEFAULT_TEXT_COLORS] = {
|
||||
"$Fiction Viewer:",
|
||||
"$Command Briefing:",
|
||||
"$Briefing:",
|
||||
"$Redalert Briefing:",
|
||||
"$Debriefing:",
|
||||
"$Recommendation:",
|
||||
"$Loop Briefing:",
|
||||
};
|
||||
|
||||
char *color_value[MAX_DEFAULT_TEXT_COLORS] = {
|
||||
&default_fiction_viewer_color,
|
||||
&default_command_briefing_color,
|
||||
&default_briefing_color,
|
||||
&default_redalert_briefing_color,
|
||||
&default_debriefing_color,
|
||||
&default_recommendation_color,
|
||||
&default_loop_briefing_color,
|
||||
};
|
||||
|
||||
for (i = 0; i < MAX_DEFAULT_TEXT_COLORS; i++) {
|
||||
if (optional_string(color_names[i])) {
|
||||
stuff_string(temp, F_RAW);
|
||||
if (temp[0] == '$') {
|
||||
if (temp[1] == '\0') {
|
||||
Error(LOCATION, "%s - default text color '%s' entry with a solitary '$'.\n", filename, color_names[i]);
|
||||
}
|
||||
*color_value[i] = temp[1];
|
||||
if (temp[2] != '\0') {
|
||||
Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
|
||||
}
|
||||
}
|
||||
else if (temp[0] == '\0') {
|
||||
Error(LOCATION, "%s - default text color '%s' entry with no tag.\n", filename, color_names[i]);
|
||||
}
|
||||
else {
|
||||
*color_value[i] = temp[0];
|
||||
if (temp[1] != '\0') {
|
||||
Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
|
||||
}
|
||||
}
|
||||
if (Tagged_Colors.find(*color_value[i]) == Tagged_Colors.end()) {
|
||||
// Just mprintf() this information instead of complaining with a Warning(); the tag might be defined in a later-loading TBM, and if it isn't, nothing too terrible will happen.
|
||||
mprintf(("%s - default text color '%s' set to non-existant tag '$%c'.\n", filename, color_names[i], *color_value[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
+97
-92
@@ -579,7 +579,7 @@ void gr_set_font(int fontnum)
|
||||
|
||||
void parse_fonts_tbl(char *only_parse_first_font, size_t only_parse_first_font_size)
|
||||
{
|
||||
int rval, i;
|
||||
int i;
|
||||
char *filename;
|
||||
|
||||
// choose file name
|
||||
@@ -591,99 +591,104 @@ void parse_fonts_tbl(char *only_parse_first_font, size_t only_parse_first_font_s
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : NOX("<default fonts.tbl>"), rval));
|
||||
try
|
||||
{
|
||||
if (filename != NULL) {
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
}
|
||||
else {
|
||||
read_file_text_from_array(defaults_get_file("fonts.tbl"));
|
||||
}
|
||||
|
||||
reset_parse();
|
||||
|
||||
// start parsing
|
||||
required_string("#Fonts");
|
||||
|
||||
// read fonts
|
||||
while (required_string_either("#End", "$Font:")) {
|
||||
char font_filename[MAX_FILENAME_LEN];
|
||||
|
||||
// grab font
|
||||
required_string("$Font:");
|
||||
stuff_string(font_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// if we only need the first font, copy it and bail
|
||||
if (only_parse_first_font != NULL) {
|
||||
strcpy_s(only_parse_first_font, only_parse_first_font_size, font_filename);
|
||||
return;
|
||||
}
|
||||
|
||||
// create font
|
||||
int font_id = gr_create_font(font_filename);
|
||||
if (font_id < 0) {
|
||||
Warning(LOCATION, "Could not create font from typeface '%s'!", font_filename);
|
||||
skip_to_start_of_string_either("#End", "$Font:");
|
||||
}
|
||||
else {
|
||||
// max allowed special char index; i.e. 7 special chars in retail fonts 1 & 3
|
||||
static const int MAX_SPECIAL_CHAR_IDX = UCHAR_MAX - 6;
|
||||
|
||||
// 'default' special char index for all languages using this font
|
||||
int default_special_char_index = 0;
|
||||
if (optional_string("+Default Special Character Index:")) {
|
||||
stuff_int(&default_special_char_index);
|
||||
|
||||
if (default_special_char_index < 0 || default_special_char_index >= MAX_SPECIAL_CHAR_IDX) {
|
||||
Error(LOCATION, "Default special character index (%d) for font (%s), must be 0 - %u", default_special_char_index, font_filename, MAX_SPECIAL_CHAR_IDX);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)Lcl_languages.size(); ++i) {
|
||||
Lcl_languages[i].special_char_indexes[font_id] = (ubyte)default_special_char_index;
|
||||
}
|
||||
}
|
||||
|
||||
while (optional_string("+Language:")) {
|
||||
char lang_name[LCL_LANG_NAME_LEN + 1];
|
||||
int special_char_index, lang_idx = -1;
|
||||
|
||||
stuff_string(lang_name, F_NAME, LCL_LANG_NAME_LEN + 1);
|
||||
|
||||
// find language and set the index, or if not found move to the next one
|
||||
for (i = 0; i < (int)Lcl_languages.size(); ++i) {
|
||||
if (!strcmp(Lcl_languages[i].lang_name, lang_name)) {
|
||||
lang_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lang_idx == -1) {
|
||||
Warning(LOCATION, "Ignoring invalid language (%s) specified by font (%s); not built-in or in strings.tbl", lang_name, font_filename);
|
||||
skip_to_start_of_string_either("+Language:", "$Font:", "#End");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (optional_string("+Special Character Index:")) {
|
||||
stuff_int(&special_char_index);
|
||||
|
||||
if (special_char_index < 0 || special_char_index >= MAX_SPECIAL_CHAR_IDX) {
|
||||
Error(LOCATION, "Special character index (%d) for font (%s), language (%s) is invalid, must be 0 - %u", special_char_index, font_filename, lang_name, MAX_SPECIAL_CHAR_IDX);
|
||||
}
|
||||
|
||||
Lcl_languages[lang_idx].special_char_indexes[font_id] = (ubyte)special_char_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// done parsing
|
||||
required_string("#End");
|
||||
|
||||
// double check
|
||||
if (Num_fonts < 3) {
|
||||
Error(LOCATION, "There must be at least three fonts in %s!", (filename) ? filename : NOX("<default fonts.tbl>"));
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : NOX("<default fonts.tbl>"), e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename != NULL) {
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
} else {
|
||||
read_file_text_from_array(defaults_get_file("fonts.tbl"));
|
||||
}
|
||||
|
||||
reset_parse();
|
||||
|
||||
// start parsing
|
||||
required_string("#Fonts");
|
||||
|
||||
// read fonts
|
||||
while (required_string_either("#End","$Font:")) {
|
||||
char font_filename[MAX_FILENAME_LEN];
|
||||
|
||||
// grab font
|
||||
required_string("$Font:");
|
||||
stuff_string(font_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// if we only need the first font, copy it and bail
|
||||
if (only_parse_first_font != NULL) {
|
||||
strcpy_s(only_parse_first_font, only_parse_first_font_size, font_filename);
|
||||
return;
|
||||
}
|
||||
|
||||
// create font
|
||||
int font_id = gr_create_font(font_filename);
|
||||
if (font_id < 0) {
|
||||
Warning(LOCATION, "Could not create font from typeface '%s'!", font_filename);
|
||||
skip_to_start_of_string_either("#End","$Font:");
|
||||
} else {
|
||||
// max allowed special char index; i.e. 7 special chars in retail fonts 1 & 3
|
||||
static const int MAX_SPECIAL_CHAR_IDX = UCHAR_MAX-6;
|
||||
|
||||
// 'default' special char index for all languages using this font
|
||||
int default_special_char_index = 0;
|
||||
if (optional_string("+Default Special Character Index:")) {
|
||||
stuff_int(&default_special_char_index);
|
||||
|
||||
if (default_special_char_index < 0 || default_special_char_index >= MAX_SPECIAL_CHAR_IDX) {
|
||||
Error(LOCATION, "Default special character index (%d) for font (%s), must be 0 - %u", default_special_char_index, font_filename, MAX_SPECIAL_CHAR_IDX);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)Lcl_languages.size(); ++i) {
|
||||
Lcl_languages[i].special_char_indexes[font_id] = (ubyte)default_special_char_index;
|
||||
}
|
||||
}
|
||||
|
||||
while (optional_string("+Language:")) {
|
||||
char lang_name[LCL_LANG_NAME_LEN + 1];
|
||||
int special_char_index, lang_idx = -1;
|
||||
|
||||
stuff_string(lang_name, F_NAME, LCL_LANG_NAME_LEN + 1);
|
||||
|
||||
// find language and set the index, or if not found move to the next one
|
||||
for (i = 0; i < (int)Lcl_languages.size(); ++i) {
|
||||
if (!strcmp(Lcl_languages[i].lang_name, lang_name)) {
|
||||
lang_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lang_idx == -1) {
|
||||
Warning(LOCATION, "Ignoring invalid language (%s) specified by font (%s); not built-in or in strings.tbl", lang_name, font_filename );
|
||||
skip_to_start_of_string_either("+Language:","$Font:","#End");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (optional_string("+Special Character Index:")) {
|
||||
stuff_int(&special_char_index);
|
||||
|
||||
if (special_char_index < 0 || special_char_index >= MAX_SPECIAL_CHAR_IDX) {
|
||||
Error(LOCATION, "Special character index (%d) for font (%s), language (%s) is invalid, must be 0 - %u", special_char_index, font_filename, lang_name, MAX_SPECIAL_CHAR_IDX);
|
||||
}
|
||||
|
||||
Lcl_languages[lang_idx].special_char_indexes[font_id] = (ubyte)special_char_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// done parsing
|
||||
required_string("#End");
|
||||
|
||||
// double check
|
||||
if (Num_fonts < 3) {
|
||||
Error(LOCATION, "There must be at least three fonts in %s!", (filename) ? filename : NOX("<default fonts.tbl>"));
|
||||
}
|
||||
}
|
||||
|
||||
void gr_stuff_first_font(char *first_font, size_t first_font_size )
|
||||
|
||||
@@ -687,115 +687,118 @@ void gr_opengl_post_process_save_zbuffer()
|
||||
|
||||
static bool opengl_post_init_table()
|
||||
{
|
||||
int rval;
|
||||
bool warned = false;
|
||||
|
||||
if ( (rval = setjmp(parse_abort)) != 0 ) {
|
||||
mprintf(("Unable to parse 'post_processing.tbl'! Error code = %d.\n", rval));
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (cf_exists_full("post_processing.tbl", CF_TYPE_TABLES))
|
||||
read_file_text("post_processing.tbl", CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("post_processing.tbl"));
|
||||
|
||||
if (cf_exists_full("post_processing.tbl", CF_TYPE_TABLES))
|
||||
read_file_text("post_processing.tbl", CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("post_processing.tbl"));
|
||||
|
||||
reset_parse();
|
||||
reset_parse();
|
||||
|
||||
|
||||
if (optional_string("#Effects")) {
|
||||
while ( !required_string_one_of(3, "$Name:", "#Ship Effects", "#End") ) {
|
||||
char tbuf[NAME_LENGTH+1] = { 0 };
|
||||
post_effect_t eff;
|
||||
if (optional_string("#Effects")) {
|
||||
while (!required_string_one_of(3, "$Name:", "#Ship Effects", "#End")) {
|
||||
char tbuf[NAME_LENGTH + 1] = { 0 };
|
||||
post_effect_t eff;
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.name = tbuf;
|
||||
required_string("$Name:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.name = tbuf;
|
||||
|
||||
required_string("$Uniform:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.uniform_name = tbuf;
|
||||
required_string("$Uniform:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.uniform_name = tbuf;
|
||||
|
||||
required_string("$Define:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.define_name = tbuf;
|
||||
required_string("$Define:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.define_name = tbuf;
|
||||
|
||||
required_string("$AlwaysOn:");
|
||||
stuff_boolean(&eff.always_on);
|
||||
required_string("$AlwaysOn:");
|
||||
stuff_boolean(&eff.always_on);
|
||||
|
||||
required_string("$Default:");
|
||||
stuff_float(&eff.default_intensity);
|
||||
eff.intensity = eff.default_intensity;
|
||||
required_string("$Default:");
|
||||
stuff_float(&eff.default_intensity);
|
||||
eff.intensity = eff.default_intensity;
|
||||
|
||||
required_string("$Div:");
|
||||
stuff_float(&eff.div);
|
||||
required_string("$Div:");
|
||||
stuff_float(&eff.div);
|
||||
|
||||
required_string("$Add:");
|
||||
stuff_float(&eff.add);
|
||||
required_string("$Add:");
|
||||
stuff_float(&eff.add);
|
||||
|
||||
// Post_effects index is used for flag checks, so we can't have more than 32
|
||||
if (Post_effects.size() < 32) {
|
||||
Post_effects.push_back( eff );
|
||||
} else if ( !warned ) {
|
||||
mprintf(("WARNING: post_processing.tbl can only have a max of 32 effects! Ignoring extra...\n"));
|
||||
warned = true;
|
||||
// Post_effects index is used for flag checks, so we can't have more than 32
|
||||
if (Post_effects.size() < 32) {
|
||||
Post_effects.push_back(eff);
|
||||
}
|
||||
else if (!warned) {
|
||||
mprintf(("WARNING: post_processing.tbl can only have a max of 32 effects! Ignoring extra...\n"));
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Built-in per-ship effects
|
||||
ship_effect se1;
|
||||
strcpy_s(se1.name, "FS1 Ship select");
|
||||
se1.shader_effect = 0;
|
||||
se1.disables_rendering = false;
|
||||
se1.invert_timer = false;
|
||||
Ship_effects.push_back(se1);
|
||||
//Built-in per-ship effects
|
||||
ship_effect se1;
|
||||
strcpy_s(se1.name, "FS1 Ship select");
|
||||
se1.shader_effect = 0;
|
||||
se1.disables_rendering = false;
|
||||
se1.invert_timer = false;
|
||||
Ship_effects.push_back(se1);
|
||||
|
||||
if (optional_string("#Ship Effects")) {
|
||||
while ( !required_string_one_of(3, "$Name:", "#Light Shafts", "#End") ) {
|
||||
ship_effect se;
|
||||
char tbuf[NAME_LENGTH] = { 0 };
|
||||
if (optional_string("#Ship Effects")) {
|
||||
while (!required_string_one_of(3, "$Name:", "#Light Shafts", "#End")) {
|
||||
ship_effect se;
|
||||
char tbuf[NAME_LENGTH] = { 0 };
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
strcpy_s(se.name, tbuf);
|
||||
required_string("$Name:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
strcpy_s(se.name, tbuf);
|
||||
|
||||
required_string("$Shader Effect:");
|
||||
stuff_int(&se.shader_effect);
|
||||
required_string("$Shader Effect:");
|
||||
stuff_int(&se.shader_effect);
|
||||
|
||||
required_string("$Disables Rendering:");
|
||||
stuff_boolean(&se.disables_rendering);
|
||||
required_string("$Disables Rendering:");
|
||||
stuff_boolean(&se.disables_rendering);
|
||||
|
||||
required_string("$Invert timer:");
|
||||
stuff_boolean(&se.invert_timer);
|
||||
required_string("$Invert timer:");
|
||||
stuff_boolean(&se.invert_timer);
|
||||
|
||||
Ship_effects.push_back(se);
|
||||
Ship_effects.push_back(se);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("#Light Shafts")) {
|
||||
required_string("$AlwaysOn:");
|
||||
stuff_boolean(&ls_on);
|
||||
required_string("$Density:");
|
||||
stuff_float(&ls_density);
|
||||
required_string("$Falloff:");
|
||||
stuff_float(&ls_falloff);
|
||||
required_string("$Weight:");
|
||||
stuff_float(&ls_weight);
|
||||
required_string("$Intensity:");
|
||||
stuff_float(&ls_intensity);
|
||||
required_string("$Sample Number:");
|
||||
stuff_int(&ls_samplenum);
|
||||
|
||||
ls_cpintensity = ls_weight;
|
||||
for (int i = 1; i < ls_samplenum; i++)
|
||||
ls_cpintensity += ls_weight * pow(ls_falloff, i);
|
||||
ls_cpintensity *= ls_intensity;
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (optional_string("#Light Shafts")) {
|
||||
required_string("$AlwaysOn:");
|
||||
stuff_boolean(&ls_on);
|
||||
required_string("$Density:");
|
||||
stuff_float(&ls_density);
|
||||
required_string("$Falloff:");
|
||||
stuff_float(&ls_falloff);
|
||||
required_string("$Weight:");
|
||||
stuff_float(&ls_weight);
|
||||
required_string("$Intensity:");
|
||||
stuff_float(&ls_intensity);
|
||||
required_string("$Sample Number:");
|
||||
stuff_int(&ls_samplenum);
|
||||
|
||||
ls_cpintensity = ls_weight;
|
||||
for(int i = 1; i < ls_samplenum; i++)
|
||||
ls_cpintensity += ls_weight * pow(ls_falloff, i);
|
||||
ls_cpintensity *= ls_intensity;
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("Unable to parse 'post_processing.tbl'! Error message = %s.\n", e.what()));
|
||||
return false;
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *opengl_post_load_shader(char *filename, int flags, int flags2)
|
||||
|
||||
+59
-56
@@ -62,72 +62,75 @@ int ssm_info_lookup(char *name)
|
||||
// game init
|
||||
void ssm_init()
|
||||
{
|
||||
int rval;
|
||||
ssm_info bogus, *s;
|
||||
char weapon_name[NAME_LENGTH];
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "ssm.tbl", rval));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text("ssm.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
read_file_text("ssm.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
// parse the table
|
||||
Ssm_info_count = 0;
|
||||
while (!optional_string("#end")){
|
||||
// another ssm definition
|
||||
if (optional_string("$SSM:")){
|
||||
// pointer to info struct
|
||||
if (Ssm_info_count >= MAX_SSM_TYPES){
|
||||
s = &bogus;
|
||||
}
|
||||
else {
|
||||
s = &Ssm_info[Ssm_info_count];
|
||||
}
|
||||
|
||||
// parse the table
|
||||
Ssm_info_count = 0;
|
||||
while(!optional_string("#end")){
|
||||
// another ssm definition
|
||||
if(optional_string("$SSM:")){
|
||||
// pointer to info struct
|
||||
if(Ssm_info_count >= MAX_SSM_TYPES){
|
||||
s = &bogus;
|
||||
} else {
|
||||
s = &Ssm_info[Ssm_info_count];
|
||||
}
|
||||
// name
|
||||
stuff_string(s->name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// name
|
||||
stuff_string(s->name, F_NAME, NAME_LENGTH);
|
||||
// stuff data
|
||||
required_string("+Weapon:");
|
||||
stuff_string(weapon_name, F_NAME, NAME_LENGTH);
|
||||
required_string("+Count:");
|
||||
stuff_int(&s->count);
|
||||
required_string("+WarpRadius:");
|
||||
stuff_float(&s->warp_radius);
|
||||
required_string("+WarpTime:");
|
||||
stuff_float(&s->warp_time);
|
||||
// According to fireballs.cpp, "Warp lifetime must be at least 4 seconds!"
|
||||
if ((s->warp_time) < 4.0f) {
|
||||
// So let's warn them before they try to use it, shall we?
|
||||
Warning(LOCATION, "Expected a '+WarpTime:' value equal or greater than 4.0, found '%f' in weapon '%s'.\n Setting to 4.0, please check and set to a number 4.0 or greater!\n", s->warp_time, weapon_name);
|
||||
// And then make the Assert obsolete -- Zacam
|
||||
s->warp_time = 4.0f;
|
||||
}
|
||||
required_string("+Radius:");
|
||||
stuff_float(&s->radius);
|
||||
required_string("+Offset:");
|
||||
stuff_float(&s->offset);
|
||||
if (optional_string("+HUD Message:"))
|
||||
stuff_boolean(&s->send_message);
|
||||
else
|
||||
s->send_message = true;
|
||||
if (optional_string("+Custom Message:")) {
|
||||
stuff_string(s->message, F_NAME, NAME_LENGTH);
|
||||
s->use_custom_message = true;
|
||||
}
|
||||
parse_sound("+Alarm Sound:", &s->sound_index, s->name);
|
||||
|
||||
// stuff data
|
||||
required_string("+Weapon:");
|
||||
stuff_string(weapon_name, F_NAME, NAME_LENGTH);
|
||||
required_string("+Count:");
|
||||
stuff_int(&s->count);
|
||||
required_string("+WarpRadius:");
|
||||
stuff_float(&s->warp_radius);
|
||||
required_string("+WarpTime:");
|
||||
stuff_float(&s->warp_time);
|
||||
// According to fireballs.cpp, "Warp lifetime must be at least 4 seconds!"
|
||||
if ( (s->warp_time) < 4.0f) {
|
||||
// So let's warn them before they try to use it, shall we?
|
||||
Warning(LOCATION, "Expected a '+WarpTime:' value equal or greater than 4.0, found '%f' in weapon '%s'.\n Setting to 4.0, please check and set to a number 4.0 or greater!\n", s->warp_time, weapon_name);
|
||||
// And then make the Assert obsolete -- Zacam
|
||||
s->warp_time = 4.0f;
|
||||
}
|
||||
required_string("+Radius:");
|
||||
stuff_float(&s->radius);
|
||||
required_string("+Offset:");
|
||||
stuff_float(&s->offset);
|
||||
if (optional_string("+HUD Message:"))
|
||||
stuff_boolean(&s->send_message);
|
||||
else
|
||||
s->send_message = true;
|
||||
if (optional_string("+Custom Message:")) {
|
||||
stuff_string(s->message, F_NAME, NAME_LENGTH);
|
||||
s->use_custom_message = true;
|
||||
}
|
||||
parse_sound("+Alarm Sound:", &s->sound_index, s->name);
|
||||
|
||||
// see if we have a valid weapon
|
||||
s->weapon_info_index = -1;
|
||||
s->weapon_info_index = weapon_info_lookup(weapon_name);
|
||||
if(s->weapon_info_index >= 0){
|
||||
// valid
|
||||
Ssm_info_count++;
|
||||
// see if we have a valid weapon
|
||||
s->weapon_info_index = -1;
|
||||
s->weapon_info_index = weapon_info_lookup(weapon_name);
|
||||
if (s->weapon_info_index >= 0){
|
||||
// valid
|
||||
Ssm_info_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "ssm.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ssm_get_random_start_pos(vec3d *out, vec3d *start, matrix *orient, int ssm_index)
|
||||
|
||||
+26
-23
@@ -1641,40 +1641,43 @@ void hud_config_color_save(char *name)
|
||||
|
||||
void hud_config_color_load(char *name)
|
||||
{
|
||||
int idx, rval;
|
||||
int idx;
|
||||
char str[1024];
|
||||
char *fname;
|
||||
|
||||
fname = cf_add_ext(name, ".hcf");
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("HUDCONFIG: Unable to parse '%s'! Error code = %i.\n", fname, rval));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text(fname);
|
||||
reset_parse();
|
||||
|
||||
read_file_text(fname);
|
||||
reset_parse();
|
||||
// First, set all gauges to the current main color
|
||||
for (idx = 0; idx < NUM_HUD_GAUGES; idx++){
|
||||
gr_init_alphacolor(&HUD_config.clr[idx], HUD_color_red, HUD_color_green, HUD_color_blue, (HUD_color_alpha + 1) * 16);
|
||||
}
|
||||
|
||||
// First, set all gauges to the current main color
|
||||
for (idx=0; idx<NUM_HUD_GAUGES; idx++){
|
||||
gr_init_alphacolor(&HUD_config.clr[idx], HUD_color_red, HUD_color_green, HUD_color_blue, (HUD_color_alpha+1)*16);
|
||||
}
|
||||
// Now read in the color values for the gauges
|
||||
while (optional_string("+Gauge:")) {
|
||||
stuff_string(str, F_NAME, sizeof(str));
|
||||
|
||||
// Now read in the color values for the gauges
|
||||
while (optional_string("+Gauge:")) {
|
||||
stuff_string(str, F_NAME, sizeof(str));
|
||||
|
||||
for (idx=0; idx<NUM_HUD_GAUGES; idx++) {
|
||||
if (!stricmp(str, Hud_Gauge_Names[idx])) {
|
||||
required_string("+RGBA:");
|
||||
stuff_ubyte(&HUD_config.clr[idx].red);
|
||||
stuff_ubyte(&HUD_config.clr[idx].green);
|
||||
stuff_ubyte(&HUD_config.clr[idx].blue);
|
||||
stuff_ubyte(&HUD_config.clr[idx].alpha);
|
||||
break;
|
||||
for (idx = 0; idx < NUM_HUD_GAUGES; idx++) {
|
||||
if (!stricmp(str, Hud_Gauge_Names[idx])) {
|
||||
required_string("+RGBA:");
|
||||
stuff_ubyte(&HUD_config.clr[idx].red);
|
||||
stuff_ubyte(&HUD_config.clr[idx].green);
|
||||
stuff_ubyte(&HUD_config.clr[idx].blue);
|
||||
stuff_ubyte(&HUD_config.clr[idx].alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("HUDCONFIG: Unable to parse '%s'! Error message = %s.\n", fname, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void hud_config_alpha_slider_up()
|
||||
|
||||
+194
-183
@@ -164,7 +164,7 @@ int parse_ship_start()
|
||||
|
||||
void parse_hud_gauges_tbl(const char *filename)
|
||||
{
|
||||
int i, rval;
|
||||
int i;
|
||||
char *saved_Mp = NULL;
|
||||
|
||||
int colors[3] = {255, 255, 255};
|
||||
@@ -174,110 +174,108 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
color *ship_clr_p = NULL;
|
||||
bool scale_gauge = true;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if(optional_string("$Load Retail Configuration:")) {
|
||||
stuff_boolean(&Hud_retail);
|
||||
}
|
||||
|
||||
if ( optional_string("$Color:") ) {
|
||||
stuff_int_list(colors, 3);
|
||||
|
||||
check_color(colors);
|
||||
gr_init_alphacolor(&hud_color, colors[0], colors[1], colors[2], 255);
|
||||
hud_clr_p = &hud_color;
|
||||
}
|
||||
|
||||
if(optional_string("$Font:")) {
|
||||
stuff_int(&Hud_font);
|
||||
}
|
||||
|
||||
if(optional_string("$Max Directives:")) {
|
||||
stuff_int(&Max_directives);
|
||||
}
|
||||
|
||||
if(optional_string("$Max Escort Ships:")) {
|
||||
stuff_int(&Max_escort_ships);
|
||||
}
|
||||
|
||||
if(optional_string("$Length Unit Multiplier:")) {
|
||||
stuff_float(&Hud_unit_multiplier);
|
||||
|
||||
if (Hud_unit_multiplier <= 0.0f) {
|
||||
Warning(LOCATION, "\"$Length Unit Multiplier:\" value of \"%f\" is invalid! Resetting to default.", Hud_unit_multiplier);
|
||||
Hud_unit_multiplier = 1.0f;
|
||||
if (optional_string("$Load Retail Configuration:")) {
|
||||
stuff_boolean(&Hud_retail);
|
||||
}
|
||||
}
|
||||
|
||||
if(optional_string("$Speed Unit Multiplier:")) {
|
||||
stuff_float(&Hud_speed_multiplier);
|
||||
if (optional_string("$Color:")) {
|
||||
stuff_int_list(colors, 3);
|
||||
|
||||
if (Hud_speed_multiplier <= 0.0f) {
|
||||
Warning(LOCATION, "\"$Speed Unit Multiplier:\" value of \"%f\" is invalid! Resetting to default.", Hud_speed_multiplier);
|
||||
Hud_speed_multiplier = 1.0f;
|
||||
check_color(colors);
|
||||
gr_init_alphacolor(&hud_color, colors[0], colors[1], colors[2], 255);
|
||||
hud_clr_p = &hud_color;
|
||||
}
|
||||
} else {
|
||||
Hud_speed_multiplier = Hud_unit_multiplier;
|
||||
}
|
||||
|
||||
if (optional_string("$Wireframe Targetbox:")) {
|
||||
stuff_int(&Targetbox_wire);
|
||||
if ((Targetbox_wire < 0) || (Targetbox_wire > 3)) {
|
||||
Targetbox_wire = 0;
|
||||
if (optional_string("$Font:")) {
|
||||
stuff_int(&Hud_font);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Targetbox Shader Effect:")) {
|
||||
stuff_int(&Targetbox_shader_effect);
|
||||
if (Targetbox_shader_effect < 0) {
|
||||
Targetbox_shader_effect = 0;
|
||||
if (optional_string("$Max Directives:")) {
|
||||
stuff_int(&Max_directives);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Lock Wireframe Mode:")) {
|
||||
stuff_boolean(&Lock_targetbox_mode);
|
||||
}
|
||||
if (optional_string("$Max Escort Ships:")) {
|
||||
stuff_int(&Max_escort_ships);
|
||||
}
|
||||
|
||||
if (optional_string("$Scale Gauges:")) {
|
||||
stuff_boolean(&scale_gauge);
|
||||
Scale_retail_gauges = scale_gauge;
|
||||
}
|
||||
if (optional_string("$Length Unit Multiplier:")) {
|
||||
stuff_float(&Hud_unit_multiplier);
|
||||
|
||||
if(optional_string("$Reticle Style:")) {
|
||||
int temp = required_string_either("FS1", "FS2");
|
||||
if (Hud_unit_multiplier <= 0.0f) {
|
||||
Warning(LOCATION, "\"$Length Unit Multiplier:\" value of \"%f\" is invalid! Resetting to default.", Hud_unit_multiplier);
|
||||
Hud_unit_multiplier = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// using require_string_either won't advance the Mp pointer to the next token so force it instead
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
if (optional_string("$Speed Unit Multiplier:")) {
|
||||
stuff_float(&Hud_speed_multiplier);
|
||||
|
||||
if (temp < 0)
|
||||
Warning(LOCATION, "Undefined reticle style in hud_gauges.tbl!");
|
||||
else
|
||||
Hud_reticle_style = temp;
|
||||
}
|
||||
if (Hud_speed_multiplier <= 0.0f) {
|
||||
Warning(LOCATION, "\"$Speed Unit Multiplier:\" value of \"%f\" is invalid! Resetting to default.", Hud_speed_multiplier);
|
||||
Hud_speed_multiplier = 1.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Hud_speed_multiplier = Hud_unit_multiplier;
|
||||
}
|
||||
|
||||
int base_res[2];
|
||||
int ship_idx = -1;
|
||||
int ship_font = -1;
|
||||
int gauge_type = -1;
|
||||
int use_font = -1;
|
||||
color *use_clr_p = NULL;
|
||||
SCP_vector<int> ship_classes;
|
||||
bool retail_config = false;
|
||||
int n_ships = 0;
|
||||
if (optional_string("$Wireframe Targetbox:")) {
|
||||
stuff_int(&Targetbox_wire);
|
||||
if ((Targetbox_wire < 0) || (Targetbox_wire > 3)) {
|
||||
Targetbox_wire = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while(optional_string("#Gauge Config")) {
|
||||
ship_classes.clear();
|
||||
switch (optional_string_either("$Ship:", "$Ships:")) {
|
||||
if (optional_string("$Targetbox Shader Effect:")) {
|
||||
stuff_int(&Targetbox_shader_effect);
|
||||
if (Targetbox_shader_effect < 0) {
|
||||
Targetbox_shader_effect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Lock Wireframe Mode:")) {
|
||||
stuff_boolean(&Lock_targetbox_mode);
|
||||
}
|
||||
|
||||
if (optional_string("$Scale Gauges:")) {
|
||||
stuff_boolean(&scale_gauge);
|
||||
Scale_retail_gauges = scale_gauge;
|
||||
}
|
||||
|
||||
if (optional_string("$Reticle Style:")) {
|
||||
int temp = required_string_either("FS1", "FS2");
|
||||
|
||||
// using require_string_either won't advance the Mp pointer to the next token so force it instead
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
|
||||
if (temp < 0)
|
||||
Warning(LOCATION, "Undefined reticle style in hud_gauges.tbl!");
|
||||
else
|
||||
Hud_reticle_style = temp;
|
||||
}
|
||||
|
||||
int base_res[2];
|
||||
int ship_idx = -1;
|
||||
int ship_font = -1;
|
||||
int gauge_type = -1;
|
||||
int use_font = -1;
|
||||
color *use_clr_p = NULL;
|
||||
SCP_vector<int> ship_classes;
|
||||
bool retail_config = false;
|
||||
int n_ships = 0;
|
||||
|
||||
while (optional_string("#Gauge Config")) {
|
||||
ship_classes.clear();
|
||||
switch (optional_string_either("$Ship:", "$Ships:")) {
|
||||
case 0:
|
||||
mprintf(("$Ship in hud_gauges.tbl and -hdg.tbms is deprecated. Use \"$Ships: (\"Some ship class\") instead.\n"));
|
||||
|
||||
if(!ships_inited) {
|
||||
if (!ships_inited) {
|
||||
// just in case ship info has not been initialized.
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
@@ -287,15 +285,15 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
ship_idx = parse_ship_start();
|
||||
ship_classes.push_back(ship_idx);
|
||||
|
||||
if(ship_idx >= 0) {
|
||||
if (ship_idx >= 0) {
|
||||
Ship_info[ship_idx].hud_enabled = true;
|
||||
|
||||
// see if we need to load defaults for this configuration
|
||||
if(optional_string("$Load Retail Configuration:")) {
|
||||
if (optional_string("$Load Retail Configuration:")) {
|
||||
stuff_boolean(&Ship_info[ship_idx].hud_retail);
|
||||
}
|
||||
|
||||
if ( optional_string("$Color:") ) {
|
||||
if (optional_string("$Color:")) {
|
||||
stuff_int_list(colors, 3);
|
||||
|
||||
check_color(colors);
|
||||
@@ -303,10 +301,11 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
ship_clr_p = &ship_color;
|
||||
}
|
||||
|
||||
if(optional_string("$Font:")) {
|
||||
if (optional_string("$Font:")) {
|
||||
stuff_int(&ship_font);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// can't find ship class. move on.
|
||||
ship_classes.push_back(-1);
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
@@ -319,7 +318,7 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
|
||||
n_ships = stuff_int_list(shiparray, 256, SHIP_INFO_TYPE);
|
||||
|
||||
if(optional_string("$Load Retail Configuration:")) {
|
||||
if (optional_string("$Load Retail Configuration:")) {
|
||||
stuff_boolean(&retail_config);
|
||||
}
|
||||
|
||||
@@ -329,7 +328,7 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
Ship_info[shiparray[i]].hud_retail = retail_config;
|
||||
}
|
||||
|
||||
if ( optional_string("$Color:") ) {
|
||||
if (optional_string("$Color:")) {
|
||||
stuff_int_list(colors, 3);
|
||||
|
||||
check_color(colors);
|
||||
@@ -337,119 +336,131 @@ void parse_hud_gauges_tbl(const char *filename)
|
||||
ship_clr_p = &ship_color;
|
||||
}
|
||||
|
||||
if(optional_string("$Font:")) {
|
||||
if (optional_string("$Font:")) {
|
||||
stuff_int(&ship_font);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// No particular ship. -1 for default HUD configuration.
|
||||
ship_classes.push_back(-1);
|
||||
ship_font = -1;
|
||||
ship_clr_p = NULL;
|
||||
break;
|
||||
}
|
||||
// No particular ship. -1 for default HUD configuration.
|
||||
ship_classes.push_back(-1);
|
||||
ship_font = -1;
|
||||
ship_clr_p = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ship_clr_p != NULL ) {
|
||||
use_clr_p = ship_clr_p;
|
||||
} else {
|
||||
use_clr_p = hud_clr_p;
|
||||
}
|
||||
if (ship_clr_p != NULL) {
|
||||
use_clr_p = ship_clr_p;
|
||||
}
|
||||
else {
|
||||
use_clr_p = hud_clr_p;
|
||||
}
|
||||
|
||||
if(ship_font >= 0) {
|
||||
use_font = ship_font;
|
||||
} else {
|
||||
use_font = Hud_font;
|
||||
}
|
||||
if (ship_font >= 0) {
|
||||
use_font = ship_font;
|
||||
}
|
||||
else {
|
||||
use_font = Hud_font;
|
||||
}
|
||||
|
||||
// Now start going through resolution info for this HUD layout
|
||||
required_string("$Base:");
|
||||
// Now start going through resolution info for this HUD layout
|
||||
required_string("$Base:");
|
||||
|
||||
// get the base width and height describing this HUD
|
||||
stuff_int_list(base_res, 2, RAW_INTEGER_TYPE);
|
||||
// get the base width and height describing this HUD
|
||||
stuff_int_list(base_res, 2, RAW_INTEGER_TYPE);
|
||||
|
||||
// gauge scaling for this base res?
|
||||
if (optional_string("$Scale Gauges:")) {
|
||||
stuff_boolean(&scale_gauge);
|
||||
}
|
||||
// gauge scaling for this base res?
|
||||
if (optional_string("$Scale Gauges:")) {
|
||||
stuff_boolean(&scale_gauge);
|
||||
}
|
||||
|
||||
// Pruning time. Let's see if the current resolution defined by the user matches the conditions set by this entry
|
||||
if(optional_string("$Required Aspect:")) {
|
||||
// filter aspect ratio.
|
||||
if(optional_string("Full Screen")) {
|
||||
if( (float)gr_screen.max_w / (float)gr_screen.max_h > 1.5) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
//skip_to_start_of_string_either("#Gauge Config", "#End");
|
||||
continue;
|
||||
// Pruning time. Let's see if the current resolution defined by the user matches the conditions set by this entry
|
||||
if (optional_string("$Required Aspect:")) {
|
||||
// filter aspect ratio.
|
||||
if (optional_string("Full Screen")) {
|
||||
if ((float)gr_screen.max_w / (float)gr_screen.max_h > 1.5) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
//skip_to_start_of_string_either("#Gauge Config", "#End");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if(optional_string("Wide Screen")) {
|
||||
if( (float)gr_screen.max_w / (float)gr_screen.max_h <= 1.5) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
//skip_to_start_of_string_either("#Gauge Config", "#End");
|
||||
continue;
|
||||
else if (optional_string("Wide Screen")) {
|
||||
if ((float)gr_screen.max_w / (float)gr_screen.max_h <= 1.5) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
//skip_to_start_of_string_either("#Gauge Config", "#End");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check minimum resolution
|
||||
if(optional_string("$Min:")) {
|
||||
int min_res[2];
|
||||
stuff_int_list(min_res, 2, RAW_INTEGER_TYPE);
|
||||
|
||||
if(min_res[0] > gr_screen.max_w) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
} else if (min_res[0] == gr_screen.max_w) {
|
||||
if(min_res[1] > gr_screen.max_h) {
|
||||
}
|
||||
|
||||
// check minimum resolution
|
||||
if (optional_string("$Min:")) {
|
||||
int min_res[2];
|
||||
stuff_int_list(min_res, 2, RAW_INTEGER_TYPE);
|
||||
|
||||
if (min_res[0] > gr_screen.max_w) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
}
|
||||
else if (min_res[0] == gr_screen.max_w) {
|
||||
if (min_res[1] > gr_screen.max_h) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check maximum resolution
|
||||
if(optional_string("$Max:")) {
|
||||
int max_res[2];
|
||||
stuff_int_list(max_res, 2, RAW_INTEGER_TYPE);
|
||||
// check maximum resolution
|
||||
if (optional_string("$Max:")) {
|
||||
int max_res[2];
|
||||
stuff_int_list(max_res, 2, RAW_INTEGER_TYPE);
|
||||
|
||||
if(max_res[0] < gr_screen.max_w) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
} else if (max_res[0] == gr_screen.max_w) {
|
||||
if(max_res[1] < gr_screen.max_h) {
|
||||
if (max_res[0] < gr_screen.max_w) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
}
|
||||
else if (max_res[0] == gr_screen.max_w) {
|
||||
if (max_res[1] < gr_screen.max_h) {
|
||||
skip_to_start_of_string("#Gauge Config");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let's start parsing for gauges.
|
||||
required_string("$Gauges:");
|
||||
|
||||
while (!check_for_string("$Gauges:") && !check_for_string("$End Gauges")) {
|
||||
// find out what type of gauge we're parsing.
|
||||
gauge_type = parse_gauge_type();
|
||||
|
||||
// then call the specific gauge load handler function for this gauge type.
|
||||
if (optional_string("default")) {
|
||||
// sending -1 base width and height will indicate GR_640 or GR_1024 to the handlers
|
||||
load_gauge(gauge_type, -1, -1, use_font, scale_gauge, &ship_classes, use_clr_p);
|
||||
}
|
||||
else {
|
||||
load_gauge(gauge_type, base_res[0], base_res[1], use_font, scale_gauge, &ship_classes, use_clr_p);
|
||||
}
|
||||
|
||||
if (saved_Mp && (saved_Mp == Mp)) {
|
||||
Mp++;
|
||||
}
|
||||
|
||||
skip_to_start_of_string_either("$", "+");
|
||||
// stolened from AI_profiles
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
|
||||
required_string("$End Gauges");
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// let's start parsing for gauges.
|
||||
required_string("$Gauges:");
|
||||
|
||||
while (!check_for_string("$Gauges:") && !check_for_string("$End Gauges")) {
|
||||
// find out what type of gauge we're parsing.
|
||||
gauge_type = parse_gauge_type();
|
||||
|
||||
// then call the specific gauge load handler function for this gauge type.
|
||||
if(optional_string("default")) {
|
||||
// sending -1 base width and height will indicate GR_640 or GR_1024 to the handlers
|
||||
load_gauge(gauge_type, -1, -1, use_font, scale_gauge, &ship_classes, use_clr_p);
|
||||
} else {
|
||||
load_gauge(gauge_type, base_res[0], base_res[1], use_font, scale_gauge, &ship_classes, use_clr_p);
|
||||
}
|
||||
|
||||
if ( saved_Mp && (saved_Mp == Mp) ) {
|
||||
Mp++;
|
||||
}
|
||||
|
||||
skip_to_start_of_string_either("$", "+");
|
||||
// stolened from AI_profiles
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
|
||||
saved_Mp = Mp;
|
||||
}
|
||||
|
||||
required_string("$End Gauges");
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+398
-397
@@ -128,406 +128,407 @@ void iff_init()
|
||||
int i, j, k;
|
||||
int string_idx;
|
||||
|
||||
int rval;
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "iff_defs.tbl", rval));
|
||||
// Goober5000 - if table doesn't exist, use the default table
|
||||
if (cf_exists_full("iff_defs.tbl", CF_TYPE_TABLES))
|
||||
read_file_text("iff_defs.tbl", CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("iff_defs.tbl"));
|
||||
|
||||
reset_parse();
|
||||
|
||||
// parse the table --------------------------------------------------------
|
||||
|
||||
required_string("#IFFs");
|
||||
|
||||
// get the traitor
|
||||
required_string("$Traitor IFF:");
|
||||
stuff_string(traitor_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
int rgb[3];
|
||||
|
||||
// check if alternate colours are wanted to be used for these
|
||||
// Marks various stuff... like asteroids
|
||||
if ((optional_string("$Selection Color:")) || (optional_string("$Selection Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0xff);
|
||||
|
||||
// Marks the ship currently saying something
|
||||
if ((optional_string("$Message Color:")) || (optional_string("$Message Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0x7f, 0x7f, 0x7f);
|
||||
|
||||
// Marks the tagged ships
|
||||
if ((optional_string("$Tagged Color:")) || (optional_string("$Tagged Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0x00);
|
||||
|
||||
// init radar blips colour table
|
||||
int a_bright, a_dim;
|
||||
bool alternate_blip_color = false;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
radar_iff_color[i][j][k] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the bright/dim scaling is wanted to be changed
|
||||
if (optional_string("$Dimmed IFF brightness:"))
|
||||
{
|
||||
int dim_iff_brightness;
|
||||
stuff_int(&dim_iff_brightness);
|
||||
Assert(dim_iff_brightness >= 0 && dim_iff_brightness <= HUD_COLOR_ALPHA_MAX);
|
||||
*iff_color_brightness = dim_iff_brightness;
|
||||
}
|
||||
else
|
||||
*iff_color_brightness = 4;
|
||||
|
||||
// alternate = use same method as with ship blips
|
||||
// retail = use 1/2 intensities
|
||||
if (optional_string("$Use Alternate Blip Coloring:") || optional_string("$Use Alternate Blip Colouring:"))
|
||||
{
|
||||
stuff_boolean(&alternate_blip_color);
|
||||
}
|
||||
|
||||
// Parse blip colours, their order is hardcoded.
|
||||
if ((optional_string("$Missile Blip Color:")) || (optional_string("$Missile Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[0][1][i] = rgb[i];
|
||||
radar_iff_color[0][0][i] = rgb[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Navbuoy Blip Color:")) || (optional_string("$Navbuoy Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[1][1][i] = rgb[i];
|
||||
radar_iff_color[1][0][i] = rgb[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Warping Blip Color:")) || (optional_string("$Warping Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[2][1][i] = rgb[i];
|
||||
radar_iff_color[2][0][i] = rgb[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Node Blip Color:")) || (optional_string("$Node Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[3][1][i] = rgb[i];
|
||||
radar_iff_color[3][0][i] = rgb[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Tagged Blip Color:")) || (optional_string("$Tagged Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[4][1][i] = rgb[i];
|
||||
radar_iff_color[4][0][i] = rgb[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (alternate_blip_color == true)
|
||||
{
|
||||
a_bright = iff_get_alpha_value(true);
|
||||
a_dim = iff_get_alpha_value(false);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (radar_iff_color[i][0][0] >= 0)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
radar_iff_color[i][0][j] = radar_iff_color[i][1][j];
|
||||
}
|
||||
|
||||
radar_iff_color[i][1][3] = a_bright;
|
||||
radar_iff_color[i][0][3] = a_dim;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (radar_iff_color[i][0][0] >= 0)
|
||||
{
|
||||
radar_iff_color[i][0][3] = 255;
|
||||
radar_iff_color[i][1][3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Radar Target ID Flags:")) {
|
||||
parse_string_flag_list((int*)&radar_target_id_flags, rti_flags, Num_rti_flags);
|
||||
if (optional_string("+reset"))
|
||||
radar_target_id_flags = 0;
|
||||
}
|
||||
|
||||
// begin reading data
|
||||
Num_iffs = 0;
|
||||
while (required_string_either("#End", "$IFF Name:"))
|
||||
{
|
||||
iff_info *iff;
|
||||
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, 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:"))
|
||||
{
|
||||
char flag_strings[MAX_IFF_FLAGS][NAME_LENGTH];
|
||||
|
||||
int num_strings = stuff_string_list(flag_strings, MAX_IFF_FLAGS);
|
||||
for (string_idx = 0; string_idx < num_strings; string_idx++)
|
||||
{
|
||||
if (!stricmp(NOX("support allowed"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_SUPPORT_ALLOWED;
|
||||
else if (!stricmp(NOX("exempt from all teams at war"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
|
||||
else if (!stricmp(NOX("orders hidden"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_ORDERS_HIDDEN;
|
||||
else if (!stricmp(NOX("orders shown"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_ORDERS_SHOWN;
|
||||
else if (!stricmp(NOX("wing name hidden"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_WING_NAME_HIDDEN;
|
||||
else
|
||||
Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[string_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
// get default ship flags
|
||||
iff->default_parse_flags = 0;
|
||||
if (optional_string("$Default Ship Flags:"))
|
||||
{
|
||||
i = 0;
|
||||
j = 0;
|
||||
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_parse_flags |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == MAX_PARSE_OBJECT_FLAGS)
|
||||
Warning(LOCATION, "Bogus string in iff default ship flags: %s\n", flag_strings[i]);
|
||||
}
|
||||
|
||||
// again
|
||||
iff->default_parse_flags2 = 0;
|
||||
if (optional_string("$Default Ship Flags2:"))
|
||||
{
|
||||
i = 0;
|
||||
j = 0;
|
||||
char flag_strings[MAX_PARSE_OBJECT_FLAGS_2][NAME_LENGTH];
|
||||
int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS_2);
|
||||
for (i = 0; i < num_strings; i++)
|
||||
{
|
||||
for (j = 0; j < MAX_PARSE_OBJECT_FLAGS_2; j++)
|
||||
{
|
||||
if (!stricmp(flag_strings[i], Parse_object_flags_2[j]))
|
||||
{
|
||||
iff->default_parse_flags2 |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == MAX_PARSE_OBJECT_FLAGS_2)
|
||||
Warning(LOCATION, "Bogus string in iff default ship flags2: %s\n", flag_strings[i]);
|
||||
}
|
||||
|
||||
// this is cleared between each level but let's just set it here for thoroughness
|
||||
iff->ai_rearm_timestamp = timestamp(-1);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
|
||||
// now resolve the relationships ------------------------------------------
|
||||
|
||||
// first get the traitor
|
||||
Iff_traitor = iff_lookup(traitor_name);
|
||||
if (Iff_traitor < 0)
|
||||
{
|
||||
Iff_traitor = 0;
|
||||
Warning(LOCATION, "Traitor IFF %s not found in iff_defs.tbl! Defaulting to %s.\n", traitor_name, Iff_info[Iff_traitor].iff_name);
|
||||
}
|
||||
|
||||
// next get the attackees and colors
|
||||
for (int cur_iff = 0; cur_iff < Num_iffs; cur_iff++)
|
||||
{
|
||||
iff_info *iff = &Iff_info[cur_iff];
|
||||
|
||||
// clear the iffs to be attacked
|
||||
iff->attackee_bitmask = 0;
|
||||
iff->attackee_bitmask_all_teams_at_war = 0;
|
||||
|
||||
// clear the observed colors
|
||||
for (j = 0; j < MAX_IFFS; j++)
|
||||
iff->observed_color_index[j] = -1;
|
||||
|
||||
// resolve the list names
|
||||
for (int list_index = 0; list_index < MAX_IFFS; list_index++)
|
||||
{
|
||||
// are we within the number of attackees listed?
|
||||
if (list_index < num_attack_names[cur_iff])
|
||||
{
|
||||
// find out who
|
||||
int target_iff = iff_lookup(attack_names[cur_iff][list_index]);
|
||||
|
||||
// valid?
|
||||
if (target_iff >= 0)
|
||||
iff->attackee_bitmask |= iff_get_mask(target_iff);
|
||||
else
|
||||
Warning(LOCATION, "Attack target IFF %s not found for IFF %s in iff_defs.tbl!\n", attack_names[cur_iff][list_index], iff->iff_name);
|
||||
}
|
||||
|
||||
// are we within the number of colors listed?
|
||||
if (list_index < num_observed_colors[cur_iff])
|
||||
{
|
||||
// find out who
|
||||
int target_iff = iff_lookup(observed_color_table[cur_iff][list_index].iff_name);
|
||||
|
||||
// valid?
|
||||
if (target_iff >= 0)
|
||||
iff->observed_color_index[target_iff] = observed_color_table[cur_iff][list_index].color_index;
|
||||
else
|
||||
Warning(LOCATION, "Observed color IFF %s not found for IFF %s in iff_defs.tbl!\n", observed_color_table[cur_iff][list_index].iff_name, iff->iff_name);
|
||||
}
|
||||
}
|
||||
|
||||
// resolve the all teams at war relationships
|
||||
if (iff->flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
|
||||
{
|
||||
// exempt, so use standard attacks
|
||||
iff->attackee_bitmask_all_teams_at_war = iff->attackee_bitmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nonexempt, so build bitmask of all other nonexempt teams
|
||||
for (int other_iff = 0; other_iff < Num_iffs; other_iff++)
|
||||
{
|
||||
// skip myself (unless I attack myself normally)
|
||||
if ((other_iff == cur_iff) && !iff_x_attacks_y(cur_iff, cur_iff))
|
||||
continue;
|
||||
|
||||
// skip anyone exempt
|
||||
if (Iff_info[other_iff].flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
|
||||
continue;
|
||||
|
||||
// add everyone else
|
||||
iff->attackee_bitmask_all_teams_at_war |= iff_get_mask(other_iff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
fs2netd_add_table_validation("iff_defs.tbl");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "iff_defs.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Goober5000 - if table doesn't exist, use the default table
|
||||
if (cf_exists_full("iff_defs.tbl", CF_TYPE_TABLES))
|
||||
read_file_text("iff_defs.tbl", CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("iff_defs.tbl"));
|
||||
|
||||
reset_parse();
|
||||
|
||||
// parse the table --------------------------------------------------------
|
||||
|
||||
required_string("#IFFs");
|
||||
|
||||
// get the traitor
|
||||
required_string("$Traitor IFF:");
|
||||
stuff_string(traitor_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
int rgb[3];
|
||||
|
||||
// check if alternate colours are wanted to be used for these
|
||||
// Marks various stuff... like asteroids
|
||||
if ((optional_string("$Selection Color:")) || (optional_string("$Selection Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0xff);
|
||||
|
||||
// Marks the ship currently saying something
|
||||
if ((optional_string("$Message Color:")) || (optional_string("$Message Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0x7f, 0x7f, 0x7f);
|
||||
|
||||
// Marks the tagged ships
|
||||
if ((optional_string("$Tagged Color:")) || (optional_string("$Tagged Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0x00);
|
||||
|
||||
// init radar blips colour table
|
||||
int a_bright,a_dim;
|
||||
bool alternate_blip_color = false;
|
||||
for (i=0;i<5;i++)
|
||||
{
|
||||
for (j=0;j<2;j++)
|
||||
{
|
||||
for (k=0;k<3;k++)
|
||||
{
|
||||
radar_iff_color[i][j][k] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the bright/dim scaling is wanted to be changed
|
||||
if (optional_string("$Dimmed IFF brightness:"))
|
||||
{
|
||||
int dim_iff_brightness;
|
||||
stuff_int(&dim_iff_brightness);
|
||||
Assert(dim_iff_brightness >= 0 && dim_iff_brightness <= HUD_COLOR_ALPHA_MAX);
|
||||
*iff_color_brightness = dim_iff_brightness;
|
||||
}
|
||||
else
|
||||
*iff_color_brightness = 4;
|
||||
|
||||
// alternate = use same method as with ship blips
|
||||
// retail = use 1/2 intensities
|
||||
if (optional_string("$Use Alternate Blip Coloring:") || optional_string("$Use Alternate Blip Colouring:"))
|
||||
{
|
||||
stuff_boolean(&alternate_blip_color);
|
||||
}
|
||||
|
||||
// Parse blip colours, their order is hardcoded.
|
||||
if ((optional_string("$Missile Blip Color:")) || (optional_string("$Missile Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[0][1][i] = rgb[i];
|
||||
radar_iff_color[0][0][i] = rgb[i]/2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Navbuoy Blip Color:")) || (optional_string("$Navbuoy Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[1][1][i] = rgb[i];
|
||||
radar_iff_color[1][0][i] = rgb[i]/2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Warping Blip Color:")) || (optional_string("$Warping Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[2][1][i] = rgb[i];
|
||||
radar_iff_color[2][0][i] = rgb[i]/2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Node Blip Color:")) || (optional_string("$Node Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[3][1][i] = rgb[i];
|
||||
radar_iff_color[3][0][i] = rgb[i]/2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optional_string("$Tagged Blip Color:")) || (optional_string("$Tagged Blip Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
Assert(rgb[i] >= 0 && rgb[i] <= 255);
|
||||
radar_iff_color[4][1][i] = rgb[i];
|
||||
radar_iff_color[4][0][i] = rgb[i]/2;
|
||||
}
|
||||
}
|
||||
|
||||
if (alternate_blip_color == true)
|
||||
{
|
||||
a_bright = iff_get_alpha_value(true);
|
||||
a_dim = iff_get_alpha_value(false);
|
||||
for (i=0;i<5;i++)
|
||||
{
|
||||
if (radar_iff_color[i][0][0] >= 0)
|
||||
{
|
||||
for (j=0;j<3;j++)
|
||||
{
|
||||
radar_iff_color[i][0][j] = radar_iff_color[i][1][j];
|
||||
}
|
||||
|
||||
radar_iff_color[i][1][3] = a_bright;
|
||||
radar_iff_color[i][0][3] = a_dim;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0;i<5;i++)
|
||||
{
|
||||
if (radar_iff_color[i][0][0] >= 0)
|
||||
{
|
||||
radar_iff_color[i][0][3] = 255;
|
||||
radar_iff_color[i][1][3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Radar Target ID Flags:")) {
|
||||
parse_string_flag_list((int*)&radar_target_id_flags, rti_flags, Num_rti_flags);
|
||||
if (optional_string("+reset"))
|
||||
radar_target_id_flags = 0;
|
||||
}
|
||||
|
||||
// begin reading data
|
||||
Num_iffs = 0;
|
||||
while (required_string_either("#End", "$IFF Name:"))
|
||||
{
|
||||
iff_info *iff;
|
||||
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, 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:"))
|
||||
{
|
||||
char flag_strings[MAX_IFF_FLAGS][NAME_LENGTH];
|
||||
|
||||
int num_strings = stuff_string_list(flag_strings, MAX_IFF_FLAGS);
|
||||
for (string_idx = 0; string_idx < num_strings; string_idx++)
|
||||
{
|
||||
if (!stricmp(NOX("support allowed"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_SUPPORT_ALLOWED;
|
||||
else if (!stricmp(NOX("exempt from all teams at war"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
|
||||
else if (!stricmp(NOX("orders hidden"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_ORDERS_HIDDEN;
|
||||
else if (!stricmp(NOX("orders shown"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_ORDERS_SHOWN;
|
||||
else if (!stricmp(NOX("wing name hidden"), flag_strings[string_idx]))
|
||||
iff->flags |= IFFF_WING_NAME_HIDDEN;
|
||||
else
|
||||
Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[string_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
// get default ship flags
|
||||
iff->default_parse_flags = 0;
|
||||
if (optional_string("$Default Ship Flags:"))
|
||||
{
|
||||
i = 0;
|
||||
j = 0;
|
||||
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_parse_flags |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == MAX_PARSE_OBJECT_FLAGS)
|
||||
Warning(LOCATION, "Bogus string in iff default ship flags: %s\n", flag_strings[i]);
|
||||
}
|
||||
|
||||
// again
|
||||
iff->default_parse_flags2 = 0;
|
||||
if (optional_string("$Default Ship Flags2:"))
|
||||
{
|
||||
i = 0;
|
||||
j = 0;
|
||||
char flag_strings[MAX_PARSE_OBJECT_FLAGS_2][NAME_LENGTH];
|
||||
int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS_2);
|
||||
for (i = 0; i < num_strings; i++)
|
||||
{
|
||||
for (j = 0; j < MAX_PARSE_OBJECT_FLAGS_2; j++)
|
||||
{
|
||||
if (!stricmp(flag_strings[i], Parse_object_flags_2[j]))
|
||||
{
|
||||
iff->default_parse_flags2 |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == MAX_PARSE_OBJECT_FLAGS_2)
|
||||
Warning(LOCATION, "Bogus string in iff default ship flags2: %s\n", flag_strings[i]);
|
||||
}
|
||||
|
||||
// this is cleared between each level but let's just set it here for thoroughness
|
||||
iff->ai_rearm_timestamp = timestamp(-1);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
|
||||
// now resolve the relationships ------------------------------------------
|
||||
|
||||
// first get the traitor
|
||||
Iff_traitor = iff_lookup(traitor_name);
|
||||
if (Iff_traitor < 0)
|
||||
{
|
||||
Iff_traitor = 0;
|
||||
Warning(LOCATION, "Traitor IFF %s not found in iff_defs.tbl! Defaulting to %s.\n", traitor_name, Iff_info[Iff_traitor].iff_name);
|
||||
}
|
||||
|
||||
// next get the attackees and colors
|
||||
for (int cur_iff = 0; cur_iff < Num_iffs; cur_iff++)
|
||||
{
|
||||
iff_info *iff = &Iff_info[cur_iff];
|
||||
|
||||
// clear the iffs to be attacked
|
||||
iff->attackee_bitmask = 0;
|
||||
iff->attackee_bitmask_all_teams_at_war = 0;
|
||||
|
||||
// clear the observed colors
|
||||
for (j = 0; j < MAX_IFFS; j++)
|
||||
iff->observed_color_index[j] = -1;
|
||||
|
||||
// resolve the list names
|
||||
for (int list_index = 0; list_index < MAX_IFFS; list_index++)
|
||||
{
|
||||
// are we within the number of attackees listed?
|
||||
if (list_index < num_attack_names[cur_iff])
|
||||
{
|
||||
// find out who
|
||||
int target_iff = iff_lookup(attack_names[cur_iff][list_index]);
|
||||
|
||||
// valid?
|
||||
if (target_iff >= 0)
|
||||
iff->attackee_bitmask |= iff_get_mask(target_iff);
|
||||
else
|
||||
Warning(LOCATION, "Attack target IFF %s not found for IFF %s in iff_defs.tbl!\n", attack_names[cur_iff][list_index], iff->iff_name);
|
||||
}
|
||||
|
||||
// are we within the number of colors listed?
|
||||
if (list_index < num_observed_colors[cur_iff])
|
||||
{
|
||||
// find out who
|
||||
int target_iff = iff_lookup(observed_color_table[cur_iff][list_index].iff_name);
|
||||
|
||||
// valid?
|
||||
if (target_iff >= 0)
|
||||
iff->observed_color_index[target_iff] = observed_color_table[cur_iff][list_index].color_index;
|
||||
else
|
||||
Warning(LOCATION, "Observed color IFF %s not found for IFF %s in iff_defs.tbl!\n", observed_color_table[cur_iff][list_index].iff_name, iff->iff_name);
|
||||
}
|
||||
}
|
||||
|
||||
// resolve the all teams at war relationships
|
||||
if (iff->flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
|
||||
{
|
||||
// exempt, so use standard attacks
|
||||
iff->attackee_bitmask_all_teams_at_war = iff->attackee_bitmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nonexempt, so build bitmask of all other nonexempt teams
|
||||
for (int other_iff = 0; other_iff < Num_iffs; other_iff++)
|
||||
{
|
||||
// skip myself (unless I attack myself normally)
|
||||
if ((other_iff == cur_iff) && !iff_x_attacks_y(cur_iff, cur_iff))
|
||||
continue;
|
||||
|
||||
// skip anyone exempt
|
||||
if (Iff_info[other_iff].flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
|
||||
continue;
|
||||
|
||||
// add everyone else
|
||||
iff->attackee_bitmask_all_teams_at_war |= iff_get_mask(other_iff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
fs2netd_add_table_validation("iff_defs.tbl");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+20
-19
@@ -142,32 +142,33 @@ bool ScreenClassInfoEntry::Parse()
|
||||
|
||||
void GUISystem::ParseClassInfo(char* filename)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if (ClassInfoParsed) {
|
||||
Warning(LOCATION, "Class info is being parsed twice");
|
||||
DestroyClassInfo();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
ScreenClassInfo.Parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("WMCGUI: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
bool flag;
|
||||
do {
|
||||
ScreenClassInfoEntry* sciep = new ScreenClassInfoEntry;
|
||||
flag = sciep->Parse();
|
||||
if (flag) {
|
||||
list_append(&ScreenClassInfo, sciep);
|
||||
}
|
||||
} while (flag);
|
||||
|
||||
ClassInfoParsed = true;
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("WMCGUI: Unable to parse '%s'! Error code = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
ScreenClassInfo.Parse();
|
||||
|
||||
bool flag;
|
||||
do {
|
||||
ScreenClassInfoEntry* sciep = new ScreenClassInfoEntry;
|
||||
flag = sciep->Parse();
|
||||
if (flag) {
|
||||
list_append(&ScreenClassInfo, sciep);
|
||||
}
|
||||
} while(flag);
|
||||
|
||||
ClassInfoParsed = true;
|
||||
}
|
||||
|
||||
void ClassInfoEntry::Parse(char* tag, int in_type)
|
||||
|
||||
@@ -112,7 +112,6 @@ void lcl_init(int lang_init)
|
||||
char lang_string[128];
|
||||
const char *ret;
|
||||
int lang, idx, i;
|
||||
int rval;
|
||||
|
||||
// initialize encryption
|
||||
encrypt_init();
|
||||
@@ -121,12 +120,14 @@ void lcl_init(int lang_init)
|
||||
Lcl_languages.push_back(Lcl_builtin_languages[FS2_OPEN_DEFAULT_LANGUAGE]);
|
||||
|
||||
// check string.tbl to see which languages we support
|
||||
if ( (rval = setjmp(parse_abort)) != 0 ) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "strings.tbl", rval));
|
||||
}
|
||||
else {
|
||||
try
|
||||
{
|
||||
parse_stringstbl_quick("strings.tbl");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "strings.tbl", e.what()));
|
||||
}
|
||||
|
||||
parse_modular_table(NOX("*-lcl.tbm"), parse_stringstbl_quick);
|
||||
|
||||
@@ -407,7 +408,7 @@ void parse_tstringstbl(const char *filename)
|
||||
// initialize the xstr table
|
||||
void lcl_xstr_init()
|
||||
{
|
||||
int i, rval;
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < XSTR_SIZE; i++)
|
||||
@@ -417,18 +418,26 @@ void lcl_xstr_init()
|
||||
Lcl_ext_str[i] = NULL;
|
||||
|
||||
|
||||
if ( (rval = setjmp(parse_abort)) != 0 )
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "strings.tbl", rval));
|
||||
else
|
||||
try
|
||||
{
|
||||
parse_stringstbl("strings.tbl");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "strings.tbl", e.what()));
|
||||
}
|
||||
|
||||
parse_modular_table(NOX("*-lcl.tbm"), parse_stringstbl);
|
||||
|
||||
|
||||
if ( (rval = setjmp(parse_abort)) != 0 )
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "tstrings.tbl", rval));
|
||||
else
|
||||
try
|
||||
{
|
||||
parse_tstringstbl("tstrings.tbl");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "tstrings.tbl", e.what()));
|
||||
}
|
||||
|
||||
parse_modular_table(NOX("*-tlc.tbm"), parse_tstringstbl);
|
||||
|
||||
|
||||
+116
-116
@@ -279,133 +279,133 @@ int credits_screen_button_pressed(int n)
|
||||
}
|
||||
|
||||
void credits_parse_table(const char* filename)
|
||||
{
|
||||
int rval;
|
||||
{
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// any metadata?
|
||||
if (optional_string("$Music:"))
|
||||
{
|
||||
stuff_string(Credits_music_name, F_NAME, NAME_LENGTH);
|
||||
}
|
||||
if (optional_string("$Number of Images:"))
|
||||
{
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
if (temp > 0)
|
||||
Credits_num_images = temp;
|
||||
}
|
||||
if (optional_string("$Start Image Index:"))
|
||||
{
|
||||
stuff_int(&Credits_artwork_index);
|
||||
|
||||
// bounds check
|
||||
if (Credits_artwork_index < 0)
|
||||
// any metadata?
|
||||
if (optional_string("$Music:"))
|
||||
{
|
||||
Credits_artwork_index = 0;
|
||||
stuff_string(Credits_music_name, F_NAME, NAME_LENGTH);
|
||||
}
|
||||
else if (Credits_artwork_index >= Credits_num_images)
|
||||
if (optional_string("$Number of Images:"))
|
||||
{
|
||||
Credits_artwork_index = Credits_num_images - 1;
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
if (temp > 0)
|
||||
Credits_num_images = temp;
|
||||
}
|
||||
}
|
||||
if (optional_string("$Text scroll rate:"))
|
||||
{
|
||||
stuff_float(&Credits_scroll_rate);
|
||||
if (Credits_scroll_rate < 0.01f)
|
||||
Credits_scroll_rate = 0.01f;
|
||||
}
|
||||
if (optional_string("$Artworks display time:"))
|
||||
{
|
||||
stuff_float(&Credits_artwork_display_time);
|
||||
if (Credits_artwork_display_time < 0.01f)
|
||||
Credits_artwork_display_time = 0.01f;
|
||||
}
|
||||
if (optional_string("$Artworks fade time:"))
|
||||
{
|
||||
stuff_float(&Credits_artwork_fade_time);
|
||||
if (Credits_artwork_fade_time < 0.01f)
|
||||
Credits_artwork_fade_time = 0.01f;
|
||||
}
|
||||
if (optional_string("$SCP Credits position:"))
|
||||
{
|
||||
char mode[NAME_LENGTH];
|
||||
|
||||
stuff_string(mode, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (!stricmp(mode, "Start"))
|
||||
SCP_credits_position = START;
|
||||
else if (!stricmp(mode, "End"))
|
||||
SCP_credits_position = END;
|
||||
else
|
||||
Warning(LOCATION, "Unknown credits position mode \"%s\".", mode);
|
||||
}
|
||||
|
||||
ignore_white_space();
|
||||
|
||||
SCP_string credits_text;
|
||||
SCP_string line;
|
||||
|
||||
SCP_vector<int> charNum;
|
||||
SCP_vector<const char*> lines;
|
||||
int numLines = -1;
|
||||
|
||||
bool first_run = true;
|
||||
while(!check_for_string_raw("#end"))
|
||||
{
|
||||
// Read in a line of text
|
||||
stuff_string_line(line);
|
||||
|
||||
// This is a bit odd but it means if a total conversion uses different credits the
|
||||
// Volition credit won't happen
|
||||
// Also don't append the default credits anymore when there was already a parsed table
|
||||
if(first_run && !Credits_parsed && !line.compare(mod_check))
|
||||
if (optional_string("$Start Image Index:"))
|
||||
{
|
||||
credits_text.append(unmodified_credits);
|
||||
}
|
||||
stuff_int(&Credits_artwork_index);
|
||||
|
||||
first_run = false;
|
||||
|
||||
if (line.empty())
|
||||
{
|
||||
// If the line is empty then just append a newline, don't bother with splitting it first
|
||||
credits_text.append("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// split_str doesn't take care of this.
|
||||
charNum.clear();
|
||||
|
||||
// Split the string into multiple lines if it's too long
|
||||
numLines = split_str(line.c_str(), Credits_text_coords[gr_screen.res][2], charNum, lines, -1);
|
||||
|
||||
// Make sure that we have valid data
|
||||
Assertion(lines.size() == (size_t) numLines, "split_str reported %d lines but vector contains %d entries!", numLines, lines.size());
|
||||
|
||||
Assertion(lines.size() <= charNum.size(),
|
||||
"Something has gone wrong while splitting strings. Got %d lines but only %d chacter lengths.",
|
||||
lines.size(), charNum.size());
|
||||
|
||||
// Now add all splitted lines to the credit text and append a newline to the end
|
||||
for (int i = 0; i < numLines; i++)
|
||||
// bounds check
|
||||
if (Credits_artwork_index < 0)
|
||||
{
|
||||
credits_text.append(SCP_string(lines[i], charNum[i]));
|
||||
credits_text.append("\n");
|
||||
Credits_artwork_index = 0;
|
||||
}
|
||||
else if (Credits_artwork_index >= Credits_num_images)
|
||||
{
|
||||
Credits_artwork_index = Credits_num_images - 1;
|
||||
}
|
||||
}
|
||||
if (optional_string("$Text scroll rate:"))
|
||||
{
|
||||
stuff_float(&Credits_scroll_rate);
|
||||
if (Credits_scroll_rate < 0.01f)
|
||||
Credits_scroll_rate = 0.01f;
|
||||
}
|
||||
if (optional_string("$Artworks display time:"))
|
||||
{
|
||||
stuff_float(&Credits_artwork_display_time);
|
||||
if (Credits_artwork_display_time < 0.01f)
|
||||
Credits_artwork_display_time = 0.01f;
|
||||
}
|
||||
if (optional_string("$Artworks fade time:"))
|
||||
{
|
||||
stuff_float(&Credits_artwork_fade_time);
|
||||
if (Credits_artwork_fade_time < 0.01f)
|
||||
Credits_artwork_fade_time = 0.01f;
|
||||
}
|
||||
if (optional_string("$SCP Credits position:"))
|
||||
{
|
||||
char mode[NAME_LENGTH];
|
||||
|
||||
stuff_string(mode, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (!stricmp(mode, "Start"))
|
||||
SCP_credits_position = START;
|
||||
else if (!stricmp(mode, "End"))
|
||||
SCP_credits_position = END;
|
||||
else
|
||||
Warning(LOCATION, "Unknown credits position mode \"%s\".", mode);
|
||||
}
|
||||
|
||||
ignore_white_space();
|
||||
|
||||
SCP_string credits_text;
|
||||
SCP_string line;
|
||||
|
||||
SCP_vector<int> charNum;
|
||||
SCP_vector<const char*> lines;
|
||||
int numLines = -1;
|
||||
|
||||
bool first_run = true;
|
||||
while (!check_for_string_raw("#end"))
|
||||
{
|
||||
// Read in a line of text
|
||||
stuff_string_line(line);
|
||||
|
||||
// This is a bit odd but it means if a total conversion uses different credits the
|
||||
// Volition credit won't happen
|
||||
// Also don't append the default credits anymore when there was already a parsed table
|
||||
if (first_run && !Credits_parsed && !line.compare(mod_check))
|
||||
{
|
||||
credits_text.append(unmodified_credits);
|
||||
}
|
||||
|
||||
first_run = false;
|
||||
|
||||
if (line.empty())
|
||||
{
|
||||
// If the line is empty then just append a newline, don't bother with splitting it first
|
||||
credits_text.append("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// split_str doesn't take care of this.
|
||||
charNum.clear();
|
||||
|
||||
// Split the string into multiple lines if it's too long
|
||||
numLines = split_str(line.c_str(), Credits_text_coords[gr_screen.res][2], charNum, lines, -1);
|
||||
|
||||
// Make sure that we have valid data
|
||||
Assertion(lines.size() == (size_t)numLines, "split_str reported %d lines but vector contains %d entries!", numLines, lines.size());
|
||||
|
||||
Assertion(lines.size() <= charNum.size(),
|
||||
"Something has gone wrong while splitting strings. Got %d lines but only %d chacter lengths.",
|
||||
lines.size(), charNum.size());
|
||||
|
||||
// Now add all splitted lines to the credit text and append a newline to the end
|
||||
for (int i = 0; i < numLines; i++)
|
||||
{
|
||||
credits_text.append(SCP_string(lines[i], charNum[i]));
|
||||
credits_text.append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Credit_text_parts.push_back(credits_text);
|
||||
|
||||
Credits_parsed = true;
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
Credit_text_parts.push_back(credits_text);
|
||||
|
||||
Credits_parsed = true;
|
||||
}
|
||||
|
||||
void credits_parse()
|
||||
|
||||
+416
-399
@@ -2079,415 +2079,432 @@ void parse_main_hall_table(const char* filename)
|
||||
{
|
||||
SCP_vector<main_hall_defines> temp_vector;
|
||||
main_hall_defines *m, temp;
|
||||
int idx, s_idx, m_idx, rval;
|
||||
int idx, s_idx, m_idx;
|
||||
int num_resolutions = 2;
|
||||
unsigned int count;
|
||||
char temp_string[MAX_FILENAME_LEN];
|
||||
SCP_string temp_scp_string;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("$Num Resolutions:")) {
|
||||
stuff_int(&num_resolutions);
|
||||
}
|
||||
|
||||
if (num_resolutions < 1) {
|
||||
Error(LOCATION, "$Num Resolutions in %s is %d. (Must be 1 or greater)", filename, num_resolutions);
|
||||
}
|
||||
|
||||
// go for it
|
||||
count = Main_hall_defines.size();
|
||||
while (!optional_string("#end")) {
|
||||
Main_hall_defines.push_back(temp_vector);
|
||||
// read in all resolutions
|
||||
for (m_idx = 0; m_idx < num_resolutions; m_idx++) {
|
||||
Main_hall_defines.at(count).push_back(temp);
|
||||
m = &Main_hall_defines.at(count).at(m_idx);
|
||||
|
||||
// ready
|
||||
required_string("$Main Hall");
|
||||
|
||||
// Parse the entry name for the first resolution, checking for duplicates and erroring if necessary
|
||||
if (m_idx == 0) {
|
||||
if (optional_string("+Name:")) {
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
// we can't have two mainhalls with the same name
|
||||
if (main_hall_get_pointer(temp_string) == NULL) {
|
||||
m->name = temp_string;
|
||||
} else {
|
||||
Error(LOCATION, "A mainhall with the name '%s' already exists. All mainhalls must have unique names.", temp_string);
|
||||
}
|
||||
} else {
|
||||
snprintf(temp_string, MAX_FILENAME_LEN, "%d", count);
|
||||
m->name = temp_string;
|
||||
}
|
||||
} else {
|
||||
if (optional_string("+Name:")) {
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
/**
|
||||
* the reason that this is an error is that even if we were to change the names to match
|
||||
* it is very likely the user would get the wrong mainhall loaded since their campaign files
|
||||
* may still refer to the entry with the incorrect name
|
||||
*/
|
||||
if (strcmp(temp_string, Main_hall_defines.at(count).at(0).name.c_str()) != 0) {
|
||||
Error(LOCATION, "The mainhall '%s' has different names for different resolutions. All resolutions must have the same name. Either remove the hi-res entries' names entirely or set them to match the first resolution entry's name.", Main_hall_defines.at(0).at(count).name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
m->name = Main_hall_defines.at(count).at(0).name;
|
||||
}
|
||||
|
||||
// add cheats
|
||||
while (optional_string("+Cheat String:")) {
|
||||
stuff_string(temp_scp_string, F_RAW);
|
||||
m->cheat.push_back(temp_scp_string);
|
||||
|
||||
if(temp_scp_string.size() > MAIN_HALL_MAX_CHEAT_LEN) {
|
||||
// Since the value is longer than the cheat buffer it will never match.
|
||||
|
||||
Warning(LOCATION, "The value '%s' for '+Cheat String:' is too long! It can be at most %d characters long.", temp_scp_string.size(), MAIN_HALL_MAX_CHEAT_LEN);
|
||||
}
|
||||
|
||||
required_string("+Anim To Change:");
|
||||
stuff_string(temp_scp_string, F_NAME);
|
||||
m->cheat_anim_from.push_back(temp_scp_string);
|
||||
|
||||
required_string("+Anim To Change To:");
|
||||
stuff_string(temp_scp_string, F_NAME);
|
||||
m->cheat_anim_to.push_back(temp_scp_string);
|
||||
}
|
||||
|
||||
// minimum resolution
|
||||
if (optional_string("+Min Resolution:")) {
|
||||
stuff_int(&m->min_width);
|
||||
stuff_int(&m->min_height);
|
||||
} else if (m_idx == 0) {
|
||||
m->min_width = 0;
|
||||
m->min_height = 0;
|
||||
} else {
|
||||
m->min_width = GR_1024_THRESHOLD_WIDTH;
|
||||
m->min_height = GR_1024_THRESHOLD_HEIGHT;
|
||||
}
|
||||
|
||||
// minimum aspect ratio
|
||||
if (optional_string("+Min Aspect Ratio:")) {
|
||||
stuff_float(&m->min_aspect_ratio);
|
||||
} else {
|
||||
m->min_aspect_ratio = 0.0f;
|
||||
}
|
||||
|
||||
// bitmap and mask
|
||||
required_string("+Bitmap:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->bitmap = temp_string;
|
||||
|
||||
required_string("+Mask:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->mask = temp_string;
|
||||
|
||||
required_string("+Music:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->music_name = temp_string;
|
||||
|
||||
// Goober5000
|
||||
if (optional_string("+Substitute Music:")) {
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->substitute_music_name = temp_string;
|
||||
}
|
||||
|
||||
if (optional_string("+Help Overlay:")) {
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->help_overlay_name = temp_string;
|
||||
}
|
||||
|
||||
if (optional_string("+Help Overlay Resolution Index:")) {
|
||||
stuff_int(&m->help_overlay_resolution_index);
|
||||
} else {
|
||||
m->help_overlay_resolution_index = m_idx;
|
||||
}
|
||||
|
||||
// zoom area
|
||||
if (optional_string("+Zoom To:")) {
|
||||
stuff_int(&m->zoom_area_width);
|
||||
stuff_int(&m->zoom_area_height);
|
||||
} else {
|
||||
m->zoom_area_width = -1;
|
||||
m->zoom_area_height = -1;
|
||||
}
|
||||
|
||||
// intercom sounds
|
||||
required_string("+Num Intercom Sounds:");
|
||||
stuff_int(&m->num_random_intercom_sounds);
|
||||
|
||||
// initialise intercom sounds vectors
|
||||
intercom_sounds_init(*m);
|
||||
|
||||
for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
|
||||
// intercom delay
|
||||
required_string("+Intercom delay:");
|
||||
stuff_int(&m->intercom_delay.at(idx).at(0));
|
||||
stuff_int(&m->intercom_delay.at(idx).at(1));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
|
||||
// intercom sound id
|
||||
parse_sound("+Intercom sound:", &m->intercom_sounds.at(idx), "+Intercom sound:", PARSE_SOUND_INTERFACE_SOUND);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
|
||||
// intercom pan
|
||||
required_string("+Intercom pan:");
|
||||
stuff_float(&m->intercom_sound_pan.at(idx));
|
||||
}
|
||||
|
||||
// misc animations
|
||||
required_string("+Num Misc Animations:");
|
||||
stuff_int(&m->num_misc_animations);
|
||||
|
||||
// initialise the misc anim vectors
|
||||
misc_anim_init(*m);
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim names
|
||||
required_string("+Misc anim:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->misc_anim_name.at(idx) = (SCP_string)temp_string;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim groups, optionally
|
||||
if (optional_string("+Misc anim group:")) {
|
||||
stuff_int(&m->misc_anim_group.at(idx));
|
||||
} else {
|
||||
m->misc_anim_group.at(idx) = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim delay
|
||||
required_string("+Misc anim delay:");
|
||||
stuff_int(&m->misc_anim_delay.at(idx).at(0));
|
||||
stuff_int(&m->misc_anim_delay.at(idx).at(1));
|
||||
stuff_int(&m->misc_anim_delay.at(idx).at(2));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim coords
|
||||
required_string("+Misc anim coords:");
|
||||
stuff_int(&m->misc_anim_coords.at(idx).at(0));
|
||||
stuff_int(&m->misc_anim_coords.at(idx).at(1));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim mode
|
||||
required_string("+Misc anim mode:");
|
||||
stuff_int(&m->misc_anim_modes.at(idx));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim pan
|
||||
required_string("+Misc anim pan:");
|
||||
stuff_float(&m->misc_anim_sound_pan.at(idx));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound id
|
||||
parse_sound_list("+Misc anim sounds:", m->misc_anim_special_sounds.at(idx), "+Misc anim sounds:", PARSE_SOUND_INTERFACE_SOUND);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound triggers
|
||||
required_string("+Misc anim trigger:");
|
||||
int temp_int = 0;
|
||||
stuff_int(&temp_int);
|
||||
for (s_idx = 0; s_idx < temp_int; s_idx++) {
|
||||
m->misc_anim_special_trigger.at(idx).push_back(0);
|
||||
stuff_int(&m->misc_anim_special_trigger.at(idx).at(s_idx));
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound handles - deprecated, but deal with it just in case
|
||||
if (optional_string("+Misc anim handles:")) {
|
||||
advance_to_eoln(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound flags - table flag deprecated, so ignore user input
|
||||
if (optional_string("+Misc anim flags:")) {
|
||||
advance_to_eoln(NULL);
|
||||
}
|
||||
|
||||
// we need one flag for each sound
|
||||
Assert(m->misc_anim_special_sounds.at(idx).size() < INT_MAX);
|
||||
for (s_idx = 0; s_idx < (int)m->misc_anim_special_sounds.at(idx).size(); s_idx++) {
|
||||
m->misc_anim_sound_flag.at(idx).push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// render over doors - default to false
|
||||
|
||||
if (optional_string("+Misc anim over doors:")) {
|
||||
bool temp_b;
|
||||
stuff_boolean(&temp_b);
|
||||
m->misc_anim_over_doors.push_back(temp_b);
|
||||
} else {
|
||||
m->misc_anim_over_doors.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
region_info_init(*m);
|
||||
|
||||
// door animations
|
||||
required_string("+Num Door Animations:");
|
||||
stuff_int(&m->num_door_animations);
|
||||
|
||||
// initialise the door anim vectors
|
||||
door_anim_init(*m);
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door name
|
||||
required_string("+Door anim:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->door_anim_name.at(idx) = (SCP_string)temp_string;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door coords
|
||||
required_string("+Door coords:");
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(0));
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(1));
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(2));
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(3));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door open and close sounds
|
||||
parse_sound_list("+Door sounds:", m->door_sounds.at(idx), "+Door sounds:", (parse_sound_flags)(PARSE_SOUND_INTERFACE_SOUND | PARSE_SOUND_SCP_SOUND_LIST));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door pan value
|
||||
required_string("+Door pan:");
|
||||
stuff_float(&m->door_sound_pan[idx]);
|
||||
}
|
||||
|
||||
int mask;
|
||||
for (idx = 0; optional_string("+Door mask value:"); idx++) {
|
||||
// door mask
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
mask = (int) strtol(temp_string, NULL, 0);
|
||||
mask = 255 - mask;
|
||||
|
||||
if(idx >= (int) m->regions.size()) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
m->regions[idx].mask = mask;
|
||||
}
|
||||
|
||||
for (idx = 0; optional_string("+Door action:"); idx++) {
|
||||
// door action
|
||||
|
||||
if(idx >= (int) m->regions.size()) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
|
||||
if (optional_string("Script")) {
|
||||
m->regions[idx].action = SCRIPT_REGION;
|
||||
stuff_string(m->regions[idx].lua_action, F_RAW);
|
||||
} else {
|
||||
stuff_string(temp_scp_string, F_RAW);
|
||||
|
||||
int action = -1;
|
||||
for (int i = 0; Main_hall_region_map[i].name != NULL; i++) {
|
||||
if (temp_scp_string == Main_hall_region_map[i].name) {
|
||||
action = Main_hall_region_map[i].mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == -1) {
|
||||
SCP_string err_msg = "";
|
||||
for (int i = 0; Main_hall_region_map[i].name != NULL; i++) {
|
||||
if (i != 0) {
|
||||
err_msg += ", ";
|
||||
}
|
||||
err_msg += Main_hall_region_map[i].name;
|
||||
}
|
||||
|
||||
Error(LOCATION, "Unkown Door Region '%s'! Expected one of: %s", temp_scp_string.c_str(), err_msg.c_str());
|
||||
}
|
||||
|
||||
m->regions[idx].action = action;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; optional_string("+Door key:"); idx++) {
|
||||
// door key
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
if ((int) m->regions.size() <= idx) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
m->regions[idx].key = temp_string[0];
|
||||
}
|
||||
|
||||
for (idx = 0; optional_string("+Door description:"); idx++) {
|
||||
// region description (tooltip)
|
||||
stuff_string(temp_scp_string, F_MESSAGE);
|
||||
|
||||
if (temp_scp_string != "default") {
|
||||
if(idx >= (int) m->regions.size()) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
|
||||
m->regions[idx].description = temp_scp_string;
|
||||
|
||||
if (idx == 2) {
|
||||
m->default_readyroom = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// font for tooltips and other text
|
||||
if (optional_string("+Font:")) {
|
||||
stuff_int(&m->font);
|
||||
} else {
|
||||
m->font = FONT1;
|
||||
}
|
||||
|
||||
// tooltip padding
|
||||
if (optional_string("+Tooltip Padding:")) {
|
||||
stuff_int(&m->tooltip_padding);
|
||||
} else {
|
||||
m->tooltip_padding = -1; // we'll get the default value later
|
||||
}
|
||||
|
||||
// tooltip y location
|
||||
if (optional_string("+Tooltip Y:")) {
|
||||
stuff_int(&m->region_yval);
|
||||
} else {
|
||||
m->region_yval = -1;
|
||||
}
|
||||
if (optional_string("$Num Resolutions:")) {
|
||||
stuff_int(&num_resolutions);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
if (num_resolutions < 1) {
|
||||
Error(LOCATION, "$Num Resolutions in %s is %d. (Must be 1 or greater)", filename, num_resolutions);
|
||||
}
|
||||
|
||||
// free up memory from parsing the mainhall tbl
|
||||
stop_parse();
|
||||
// go for it
|
||||
count = Main_hall_defines.size();
|
||||
while (!optional_string("#end")) {
|
||||
Main_hall_defines.push_back(temp_vector);
|
||||
// read in all resolutions
|
||||
for (m_idx = 0; m_idx < num_resolutions; m_idx++) {
|
||||
Main_hall_defines.at(count).push_back(temp);
|
||||
m = &Main_hall_defines.at(count).at(m_idx);
|
||||
|
||||
// ready
|
||||
required_string("$Main Hall");
|
||||
|
||||
// Parse the entry name for the first resolution, checking for duplicates and erroring if necessary
|
||||
if (m_idx == 0) {
|
||||
if (optional_string("+Name:")) {
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
// we can't have two mainhalls with the same name
|
||||
if (main_hall_get_pointer(temp_string) == NULL) {
|
||||
m->name = temp_string;
|
||||
}
|
||||
else {
|
||||
Error(LOCATION, "A mainhall with the name '%s' already exists. All mainhalls must have unique names.", temp_string);
|
||||
}
|
||||
}
|
||||
else {
|
||||
snprintf(temp_string, MAX_FILENAME_LEN, "%d", count);
|
||||
m->name = temp_string;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (optional_string("+Name:")) {
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
/**
|
||||
* the reason that this is an error is that even if we were to change the names to match
|
||||
* it is very likely the user would get the wrong mainhall loaded since their campaign files
|
||||
* may still refer to the entry with the incorrect name
|
||||
*/
|
||||
if (strcmp(temp_string, Main_hall_defines.at(count).at(0).name.c_str()) != 0) {
|
||||
Error(LOCATION, "The mainhall '%s' has different names for different resolutions. All resolutions must have the same name. Either remove the hi-res entries' names entirely or set them to match the first resolution entry's name.", Main_hall_defines.at(0).at(count).name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
m->name = Main_hall_defines.at(count).at(0).name;
|
||||
}
|
||||
|
||||
// add cheats
|
||||
while (optional_string("+Cheat String:")) {
|
||||
stuff_string(temp_scp_string, F_RAW);
|
||||
m->cheat.push_back(temp_scp_string);
|
||||
|
||||
if (temp_scp_string.size() > MAIN_HALL_MAX_CHEAT_LEN) {
|
||||
// Since the value is longer than the cheat buffer it will never match.
|
||||
|
||||
Warning(LOCATION, "The value '%s' for '+Cheat String:' is too long! It can be at most %d characters long.", temp_scp_string.size(), MAIN_HALL_MAX_CHEAT_LEN);
|
||||
}
|
||||
|
||||
required_string("+Anim To Change:");
|
||||
stuff_string(temp_scp_string, F_NAME);
|
||||
m->cheat_anim_from.push_back(temp_scp_string);
|
||||
|
||||
required_string("+Anim To Change To:");
|
||||
stuff_string(temp_scp_string, F_NAME);
|
||||
m->cheat_anim_to.push_back(temp_scp_string);
|
||||
}
|
||||
|
||||
// minimum resolution
|
||||
if (optional_string("+Min Resolution:")) {
|
||||
stuff_int(&m->min_width);
|
||||
stuff_int(&m->min_height);
|
||||
}
|
||||
else if (m_idx == 0) {
|
||||
m->min_width = 0;
|
||||
m->min_height = 0;
|
||||
}
|
||||
else {
|
||||
m->min_width = GR_1024_THRESHOLD_WIDTH;
|
||||
m->min_height = GR_1024_THRESHOLD_HEIGHT;
|
||||
}
|
||||
|
||||
// minimum aspect ratio
|
||||
if (optional_string("+Min Aspect Ratio:")) {
|
||||
stuff_float(&m->min_aspect_ratio);
|
||||
}
|
||||
else {
|
||||
m->min_aspect_ratio = 0.0f;
|
||||
}
|
||||
|
||||
// bitmap and mask
|
||||
required_string("+Bitmap:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->bitmap = temp_string;
|
||||
|
||||
required_string("+Mask:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->mask = temp_string;
|
||||
|
||||
required_string("+Music:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->music_name = temp_string;
|
||||
|
||||
// Goober5000
|
||||
if (optional_string("+Substitute Music:")) {
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->substitute_music_name = temp_string;
|
||||
}
|
||||
|
||||
if (optional_string("+Help Overlay:")) {
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->help_overlay_name = temp_string;
|
||||
}
|
||||
|
||||
if (optional_string("+Help Overlay Resolution Index:")) {
|
||||
stuff_int(&m->help_overlay_resolution_index);
|
||||
}
|
||||
else {
|
||||
m->help_overlay_resolution_index = m_idx;
|
||||
}
|
||||
|
||||
// zoom area
|
||||
if (optional_string("+Zoom To:")) {
|
||||
stuff_int(&m->zoom_area_width);
|
||||
stuff_int(&m->zoom_area_height);
|
||||
}
|
||||
else {
|
||||
m->zoom_area_width = -1;
|
||||
m->zoom_area_height = -1;
|
||||
}
|
||||
|
||||
// intercom sounds
|
||||
required_string("+Num Intercom Sounds:");
|
||||
stuff_int(&m->num_random_intercom_sounds);
|
||||
|
||||
// initialise intercom sounds vectors
|
||||
intercom_sounds_init(*m);
|
||||
|
||||
for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
|
||||
// intercom delay
|
||||
required_string("+Intercom delay:");
|
||||
stuff_int(&m->intercom_delay.at(idx).at(0));
|
||||
stuff_int(&m->intercom_delay.at(idx).at(1));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
|
||||
// intercom sound id
|
||||
parse_sound("+Intercom sound:", &m->intercom_sounds.at(idx), "+Intercom sound:", PARSE_SOUND_INTERFACE_SOUND);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
|
||||
// intercom pan
|
||||
required_string("+Intercom pan:");
|
||||
stuff_float(&m->intercom_sound_pan.at(idx));
|
||||
}
|
||||
|
||||
// misc animations
|
||||
required_string("+Num Misc Animations:");
|
||||
stuff_int(&m->num_misc_animations);
|
||||
|
||||
// initialise the misc anim vectors
|
||||
misc_anim_init(*m);
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim names
|
||||
required_string("+Misc anim:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->misc_anim_name.at(idx) = (SCP_string)temp_string;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim groups, optionally
|
||||
if (optional_string("+Misc anim group:")) {
|
||||
stuff_int(&m->misc_anim_group.at(idx));
|
||||
}
|
||||
else {
|
||||
m->misc_anim_group.at(idx) = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim delay
|
||||
required_string("+Misc anim delay:");
|
||||
stuff_int(&m->misc_anim_delay.at(idx).at(0));
|
||||
stuff_int(&m->misc_anim_delay.at(idx).at(1));
|
||||
stuff_int(&m->misc_anim_delay.at(idx).at(2));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim coords
|
||||
required_string("+Misc anim coords:");
|
||||
stuff_int(&m->misc_anim_coords.at(idx).at(0));
|
||||
stuff_int(&m->misc_anim_coords.at(idx).at(1));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim mode
|
||||
required_string("+Misc anim mode:");
|
||||
stuff_int(&m->misc_anim_modes.at(idx));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim pan
|
||||
required_string("+Misc anim pan:");
|
||||
stuff_float(&m->misc_anim_sound_pan.at(idx));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound id
|
||||
parse_sound_list("+Misc anim sounds:", m->misc_anim_special_sounds.at(idx), "+Misc anim sounds:", PARSE_SOUND_INTERFACE_SOUND);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound triggers
|
||||
required_string("+Misc anim trigger:");
|
||||
int temp_int = 0;
|
||||
stuff_int(&temp_int);
|
||||
for (s_idx = 0; s_idx < temp_int; s_idx++) {
|
||||
m->misc_anim_special_trigger.at(idx).push_back(0);
|
||||
stuff_int(&m->misc_anim_special_trigger.at(idx).at(s_idx));
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound handles - deprecated, but deal with it just in case
|
||||
if (optional_string("+Misc anim handles:")) {
|
||||
advance_to_eoln(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// anim sound flags - table flag deprecated, so ignore user input
|
||||
if (optional_string("+Misc anim flags:")) {
|
||||
advance_to_eoln(NULL);
|
||||
}
|
||||
|
||||
// we need one flag for each sound
|
||||
Assert(m->misc_anim_special_sounds.at(idx).size() < INT_MAX);
|
||||
for (s_idx = 0; s_idx < (int)m->misc_anim_special_sounds.at(idx).size(); s_idx++) {
|
||||
m->misc_anim_sound_flag.at(idx).push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_misc_animations; idx++) {
|
||||
// render over doors - default to false
|
||||
|
||||
if (optional_string("+Misc anim over doors:")) {
|
||||
bool temp_b;
|
||||
stuff_boolean(&temp_b);
|
||||
m->misc_anim_over_doors.push_back(temp_b);
|
||||
}
|
||||
else {
|
||||
m->misc_anim_over_doors.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
region_info_init(*m);
|
||||
|
||||
// door animations
|
||||
required_string("+Num Door Animations:");
|
||||
stuff_int(&m->num_door_animations);
|
||||
|
||||
// initialise the door anim vectors
|
||||
door_anim_init(*m);
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door name
|
||||
required_string("+Door anim:");
|
||||
stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
|
||||
m->door_anim_name.at(idx) = (SCP_string)temp_string;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door coords
|
||||
required_string("+Door coords:");
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(0));
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(1));
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(2));
|
||||
stuff_int(&m->door_anim_coords.at(idx).at(3));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door open and close sounds
|
||||
parse_sound_list("+Door sounds:", m->door_sounds.at(idx), "+Door sounds:", (parse_sound_flags)(PARSE_SOUND_INTERFACE_SOUND | PARSE_SOUND_SCP_SOUND_LIST));
|
||||
}
|
||||
|
||||
for (idx = 0; idx < m->num_door_animations; idx++) {
|
||||
// door pan value
|
||||
required_string("+Door pan:");
|
||||
stuff_float(&m->door_sound_pan[idx]);
|
||||
}
|
||||
|
||||
int mask;
|
||||
for (idx = 0; optional_string("+Door mask value:"); idx++) {
|
||||
// door mask
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
mask = (int)strtol(temp_string, NULL, 0);
|
||||
mask = 255 - mask;
|
||||
|
||||
if (idx >= (int)m->regions.size()) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
m->regions[idx].mask = mask;
|
||||
}
|
||||
|
||||
for (idx = 0; optional_string("+Door action:"); idx++) {
|
||||
// door action
|
||||
|
||||
if (idx >= (int)m->regions.size()) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
|
||||
if (optional_string("Script")) {
|
||||
m->regions[idx].action = SCRIPT_REGION;
|
||||
stuff_string(m->regions[idx].lua_action, F_RAW);
|
||||
}
|
||||
else {
|
||||
stuff_string(temp_scp_string, F_RAW);
|
||||
|
||||
int action = -1;
|
||||
for (int i = 0; Main_hall_region_map[i].name != NULL; i++) {
|
||||
if (temp_scp_string == Main_hall_region_map[i].name) {
|
||||
action = Main_hall_region_map[i].mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == -1) {
|
||||
SCP_string err_msg = "";
|
||||
for (int i = 0; Main_hall_region_map[i].name != NULL; i++) {
|
||||
if (i != 0) {
|
||||
err_msg += ", ";
|
||||
}
|
||||
err_msg += Main_hall_region_map[i].name;
|
||||
}
|
||||
|
||||
Error(LOCATION, "Unkown Door Region '%s'! Expected one of: %s", temp_scp_string.c_str(), err_msg.c_str());
|
||||
}
|
||||
|
||||
m->regions[idx].action = action;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; optional_string("+Door key:"); idx++) {
|
||||
// door key
|
||||
stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
|
||||
|
||||
if ((int)m->regions.size() <= idx) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
m->regions[idx].key = temp_string[0];
|
||||
}
|
||||
|
||||
for (idx = 0; optional_string("+Door description:"); idx++) {
|
||||
// region description (tooltip)
|
||||
stuff_string(temp_scp_string, F_MESSAGE);
|
||||
|
||||
if (temp_scp_string != "default") {
|
||||
if (idx >= (int)m->regions.size()) {
|
||||
m->regions.resize(idx + 1);
|
||||
}
|
||||
|
||||
m->regions[idx].description = temp_scp_string;
|
||||
|
||||
if (idx == 2) {
|
||||
m->default_readyroom = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// font for tooltips and other text
|
||||
if (optional_string("+Font:")) {
|
||||
stuff_int(&m->font);
|
||||
}
|
||||
else {
|
||||
m->font = FONT1;
|
||||
}
|
||||
|
||||
// tooltip padding
|
||||
if (optional_string("+Tooltip Padding:")) {
|
||||
stuff_int(&m->tooltip_padding);
|
||||
}
|
||||
else {
|
||||
m->tooltip_padding = -1; // we'll get the default value later
|
||||
}
|
||||
|
||||
// tooltip y location
|
||||
if (optional_string("+Tooltip Y:")) {
|
||||
stuff_int(&m->region_yval);
|
||||
}
|
||||
else {
|
||||
m->region_yval = -1;
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// free up memory from parsing the mainhall tbl
|
||||
stop_parse();
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+16
-15
@@ -1292,25 +1292,26 @@ int Player_tips_shown = 0;
|
||||
// tooltips
|
||||
void player_tips_init()
|
||||
{
|
||||
int rval;
|
||||
|
||||
Num_player_tips = 0;
|
||||
|
||||
try
|
||||
{
|
||||
read_file_text("tips.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "tips.tbl", rval));
|
||||
return;
|
||||
}
|
||||
while (!optional_string("#end")) {
|
||||
required_string("+Tip:");
|
||||
|
||||
read_file_text("tips.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
while(!optional_string("#end")) {
|
||||
required_string("+Tip:");
|
||||
|
||||
if(Num_player_tips >= MAX_PLAYER_TIPS) {
|
||||
break;
|
||||
if (Num_player_tips >= MAX_PLAYER_TIPS) {
|
||||
break;
|
||||
}
|
||||
Player_tips[Num_player_tips++] = stuff_and_malloc_string(F_NAME, NULL);
|
||||
}
|
||||
Player_tips[Num_player_tips++] = stuff_and_malloc_string(F_NAME, NULL);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "tips.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
-38
@@ -1026,51 +1026,54 @@ int techroom_load_ani(anim **animpp, char *name)
|
||||
|
||||
void techroom_intel_init()
|
||||
{
|
||||
int rval, temp;
|
||||
int temp;
|
||||
static int inited = 0;
|
||||
|
||||
if (inited)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
read_file_text("species.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "species.tbl", rval));
|
||||
Intel_info_size = 0;
|
||||
while (optional_string("$Entry:")) {
|
||||
Assert(Intel_info_size < MAX_INTEL_ENTRIES);
|
||||
if (Intel_info_size >= MAX_INTEL_ENTRIES) {
|
||||
mprintf(("TECHMENU: Too many intel entries!\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
Intel_info[Intel_info_size].flags = IIF_DEFAULT_VALUE;
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(Intel_info[Intel_info_size].name, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string("$Anim:");
|
||||
stuff_string(Intel_info[Intel_info_size].anim_filename, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string("$AlwaysInTechRoom:");
|
||||
stuff_int(&temp);
|
||||
if (temp) {
|
||||
// set default to align with what we read - Goober5000
|
||||
Intel_info[Intel_info_size].flags |= IIF_IN_TECH_DATABASE;
|
||||
Intel_info[Intel_info_size].flags |= IIF_DEFAULT_IN_TECH_DATABASE;
|
||||
}
|
||||
|
||||
required_string("$Description:");
|
||||
stuff_string(Intel_info[Intel_info_size].desc, F_MULTITEXT, TECH_INTEL_DESC_LEN);
|
||||
|
||||
Intel_info_size++;
|
||||
}
|
||||
|
||||
inited = 1;
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "species.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("species.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
Intel_info_size = 0;
|
||||
while (optional_string("$Entry:")) {
|
||||
Assert(Intel_info_size < MAX_INTEL_ENTRIES);
|
||||
if (Intel_info_size >= MAX_INTEL_ENTRIES) {
|
||||
mprintf(("TECHMENU: Too many intel entries!\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
Intel_info[Intel_info_size].flags = IIF_DEFAULT_VALUE;
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(Intel_info[Intel_info_size].name, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string("$Anim:");
|
||||
stuff_string(Intel_info[Intel_info_size].anim_filename, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string("$AlwaysInTechRoom:");
|
||||
stuff_int(&temp);
|
||||
if (temp) {
|
||||
// set default to align with what we read - Goober5000
|
||||
Intel_info[Intel_info_size].flags |= IIF_IN_TECH_DATABASE;
|
||||
Intel_info[Intel_info_size].flags |= IIF_DEFAULT_IN_TECH_DATABASE;
|
||||
}
|
||||
|
||||
required_string("$Description:");
|
||||
stuff_string(Intel_info[Intel_info_size].desc, F_MULTITEXT, TECH_INTEL_DESC_LEN);
|
||||
|
||||
Intel_info_size++;
|
||||
}
|
||||
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
void techroom_init()
|
||||
|
||||
@@ -274,77 +274,78 @@ int brief_text_wipe_finished();
|
||||
//
|
||||
void brief_parse_icon_tbl()
|
||||
{
|
||||
int rval, icon;
|
||||
int icon;
|
||||
size_t species;
|
||||
char name[MAX_FILENAME_LEN];
|
||||
|
||||
Assert(!Species_info.empty());
|
||||
const size_t max_icons = Species_info.size() * MIN_BRIEF_ICONS;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "icons.tbl", rval));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("icons.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Start");
|
||||
|
||||
Briefing_icon_info.clear();
|
||||
while (required_string_either("#End","$Name:"))
|
||||
try
|
||||
{
|
||||
if(Briefing_icon_info.size() >= max_icons) {
|
||||
Warning(LOCATION, "Too many icons in icons.tbl; only the first %d will be used", max_icons);
|
||||
skip_to_start_of_string("#End");
|
||||
break;
|
||||
}
|
||||
read_file_text("icons.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
briefing_icon_info bii;
|
||||
required_string("#Start");
|
||||
|
||||
// parse regular frames
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
generic_anim_init(&bii.regular, name);
|
||||
|
||||
// parse fade frames
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
hud_anim_init(&bii.fade, 0, 0, name);
|
||||
|
||||
// parse highlighting frames
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
hud_anim_init(&bii.highlight, 0, 0, name);
|
||||
|
||||
// add it to the collection
|
||||
Briefing_icon_info.push_back(bii);
|
||||
}
|
||||
required_string("#End");
|
||||
|
||||
|
||||
// now assign the icons to their species
|
||||
const size_t num_species_covered = Briefing_icon_info.size() / MIN_BRIEF_ICONS;
|
||||
size_t bii_index = 0;
|
||||
for (icon = 0; icon < MIN_BRIEF_ICONS; icon++)
|
||||
{
|
||||
for (species = 0; species < num_species_covered; species++)
|
||||
Species_info[species].bii_index[icon] = bii_index++;
|
||||
}
|
||||
|
||||
// error check
|
||||
if (num_species_covered < Species_info.size())
|
||||
{
|
||||
SCP_string errormsg = "The following species are missing icon info in icons.tbl:\n";
|
||||
|
||||
for (species = num_species_covered; species < Species_info.size(); species++)
|
||||
Briefing_icon_info.clear();
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
errormsg += Species_info[species].species_name;
|
||||
errormsg += "\n";
|
||||
if (Briefing_icon_info.size() >= max_icons) {
|
||||
Warning(LOCATION, "Too many icons in icons.tbl; only the first %d will be used", max_icons);
|
||||
skip_to_start_of_string("#End");
|
||||
break;
|
||||
}
|
||||
|
||||
briefing_icon_info bii;
|
||||
|
||||
// parse regular frames
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
generic_anim_init(&bii.regular, name);
|
||||
|
||||
// parse fade frames
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
hud_anim_init(&bii.fade, 0, 0, name);
|
||||
|
||||
// parse highlighting frames
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
hud_anim_init(&bii.highlight, 0, 0, name);
|
||||
|
||||
// add it to the collection
|
||||
Briefing_icon_info.push_back(bii);
|
||||
}
|
||||
required_string("#End");
|
||||
|
||||
|
||||
// now assign the icons to their species
|
||||
const size_t num_species_covered = Briefing_icon_info.size() / MIN_BRIEF_ICONS;
|
||||
size_t bii_index = 0;
|
||||
for (icon = 0; icon < MIN_BRIEF_ICONS; icon++)
|
||||
{
|
||||
for (species = 0; species < num_species_covered; species++)
|
||||
Species_info[species].bii_index[icon] = bii_index++;
|
||||
}
|
||||
|
||||
Error(LOCATION, errormsg.c_str());
|
||||
// error check
|
||||
if (num_species_covered < Species_info.size())
|
||||
{
|
||||
SCP_string errormsg = "The following species are missing icon info in icons.tbl:\n";
|
||||
|
||||
for (species = num_species_covered; species < Species_info.size(); species++)
|
||||
{
|
||||
errormsg += Species_info[species].species_name;
|
||||
errormsg += "\n";
|
||||
}
|
||||
|
||||
Error(LOCATION, errormsg.c_str());
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "icons.tbl", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+211
-195
@@ -100,7 +100,7 @@ bool campaign_is_ignored(const char *filename);
|
||||
*/
|
||||
int mission_campaign_get_info(const char *filename, char *name, int *type, int *max_players, char **desc)
|
||||
{
|
||||
int rval, i, success = 0;
|
||||
int i, success = 0;
|
||||
char campaign_type[NAME_LENGTH], fname[MAX_FILENAME_LEN];
|
||||
|
||||
Assert( name != NULL );
|
||||
@@ -116,53 +116,57 @@ int mission_campaign_get_info(const char *filename, char *name, int *type, int *
|
||||
|
||||
*type = -1;
|
||||
do {
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error code = %i.\n", fname, rval));
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text(fname);
|
||||
reset_parse();
|
||||
|
||||
read_file_text(fname);
|
||||
reset_parse();
|
||||
required_string("$Name:");
|
||||
stuff_string(name, F_NAME, NAME_LENGTH);
|
||||
if (name == NULL) {
|
||||
nprintf(("Warning", "No name found for campaign file %s\n", filename));
|
||||
break;
|
||||
}
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string( name, F_NAME, NAME_LENGTH );
|
||||
if (name == NULL) {
|
||||
nprintf(("Warning", "No name found for campaign file %s\n", filename));
|
||||
break;
|
||||
}
|
||||
required_string("$Type:");
|
||||
stuff_string(campaign_type, F_NAME, NAME_LENGTH);
|
||||
|
||||
required_string("$Type:");
|
||||
stuff_string( campaign_type, F_NAME, NAME_LENGTH );
|
||||
for (i = 0; i < MAX_CAMPAIGN_TYPES; i++) {
|
||||
if (!stricmp(campaign_type, campaign_types[i])) {
|
||||
*type = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<MAX_CAMPAIGN_TYPES; i++) {
|
||||
if ( !stricmp(campaign_type, campaign_types[i]) ) {
|
||||
*type = i;
|
||||
if (name == NULL) {
|
||||
Warning(LOCATION, "Invalid campaign type \"%s\"\n", campaign_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (desc) {
|
||||
if (optional_string("+Description:")) {
|
||||
*desc = stuff_and_malloc_string(F_MULTITEXT, NULL);
|
||||
}
|
||||
else {
|
||||
*desc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// if this is a multiplayer campaign, get the max players
|
||||
if ((*type) != CAMPAIGN_TYPE_SINGLE) {
|
||||
skip_to_string("+Num Players:");
|
||||
stuff_int(max_players);
|
||||
}
|
||||
|
||||
// if we found a valid campaign type
|
||||
if ((*type) >= 0) {
|
||||
success = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
Warning(LOCATION, "Invalid campaign type \"%s\"\n", campaign_type);
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error message = %s.\n", fname, e.what()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (desc) {
|
||||
if (optional_string("+Description:")) {
|
||||
*desc = stuff_and_malloc_string(F_MULTITEXT, NULL);
|
||||
} else {
|
||||
*desc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// if this is a multiplayer campaign, get the max players
|
||||
if ((*type) != CAMPAIGN_TYPE_SINGLE) {
|
||||
skip_to_string("+Num Players:");
|
||||
stuff_int(max_players);
|
||||
}
|
||||
|
||||
// if we found a valid campaign type
|
||||
if ((*type) >= 0) {
|
||||
success = 1;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
Assert(success);
|
||||
@@ -176,22 +180,14 @@ int mission_campaign_get_info(const char *filename, char *name, int *type, int *
|
||||
*/
|
||||
int mission_campaign_get_mission_list(const char *filename, char **list, int max)
|
||||
{
|
||||
int rval, i, num = 0;
|
||||
int i, num = 0;
|
||||
char name[MAX_FILENAME_LEN];
|
||||
|
||||
filename = cf_add_ext(filename, FS_CAMPAIGN_FILE_EXT);
|
||||
|
||||
// read the campaign file and get the list of mission filenames
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
|
||||
// since we can't return count of allocated elements, free them instead
|
||||
for (i=0; i<num; i++)
|
||||
vm_free(list[i]);
|
||||
|
||||
num = -1;
|
||||
|
||||
} else {
|
||||
try
|
||||
{
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
|
||||
@@ -203,6 +199,16 @@ int mission_campaign_get_mission_list(const char *filename, char **list, int max
|
||||
Warning(LOCATION, "Maximum number of missions exceeded (%d)!", max);
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
|
||||
// since we can't return count of allocated elements, free them instead
|
||||
for (i = 0; i<num; i++)
|
||||
vm_free(list[i]);
|
||||
|
||||
num = -1;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
@@ -410,7 +416,7 @@ void mission_campaign_get_sw_info()
|
||||
*/
|
||||
int mission_campaign_load( char *filename, player *pl, int load_savefile, bool reset_stats )
|
||||
{
|
||||
int len, rval, i;
|
||||
int len, i;
|
||||
char name[NAME_LENGTH], type[NAME_LENGTH], temp[NAME_LENGTH];
|
||||
|
||||
if (campaign_is_ignored(filename)) {
|
||||
@@ -429,21 +435,8 @@ int mission_campaign_load( char *filename, player *pl, int load_savefile, bool r
|
||||
}
|
||||
|
||||
// read the mission file and get the list of mission filenames
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("Error parsing '%s'\r\nError code = %i.\r\n", filename, rval));
|
||||
|
||||
Campaign.filename[0] = 0;
|
||||
Campaign.num_missions = 0;
|
||||
|
||||
if ( !Fred_running && !(Game_mode & GM_MULTIPLAYER) ) {
|
||||
Campaign_file_missing = 1;
|
||||
Campaign_load_failure = CAMPAIGN_ERROR_MISSING;
|
||||
return CAMPAIGN_ERROR_MISSING;
|
||||
}
|
||||
|
||||
return CAMPAIGN_ERROR_CORRUPT;
|
||||
|
||||
} else {
|
||||
try
|
||||
{
|
||||
// be sure to remove all old malloced strings of Mission_names
|
||||
// we must also free any goal stuff that was from a previous campaign
|
||||
// this also frees sexpressions so the next call to init_sexp will be able to reclaim
|
||||
@@ -643,6 +636,21 @@ int mission_campaign_load( char *filename, player *pl, int load_savefile, bool r
|
||||
Campaign.num_missions++;
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("Error parsing '%s'\r\nError message = %s.\r\n", filename, e.what()));
|
||||
|
||||
Campaign.filename[0] = 0;
|
||||
Campaign.num_missions = 0;
|
||||
|
||||
if (!Fred_running && !(Game_mode & GM_MULTIPLAYER)) {
|
||||
Campaign_file_missing = 1;
|
||||
Campaign_load_failure = CAMPAIGN_ERROR_MISSING;
|
||||
return CAMPAIGN_ERROR_MISSING;
|
||||
}
|
||||
|
||||
return CAMPAIGN_ERROR_CORRUPT;
|
||||
}
|
||||
|
||||
// set up the other variables for the campaign stuff. After initializing, we must try and load
|
||||
// the campaign save file for this player. Since all campaign loads go through this routine, I
|
||||
@@ -1406,14 +1414,9 @@ void mission_campaign_clear()
|
||||
*/
|
||||
int mission_campaign_get_filenames(char *filename, char dest[][NAME_LENGTH], int *num)
|
||||
{
|
||||
int rval;
|
||||
|
||||
// read the mission file and get the list of mission filenames
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return rval;
|
||||
|
||||
} else {
|
||||
try
|
||||
{
|
||||
Assert( strlen(filename) < MAX_FILENAME_LEN ); // make sure no overflow
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
@@ -1431,6 +1434,11 @@ int mission_campaign_get_filenames(char *filename, char dest[][NAME_LENGTH], int
|
||||
(*num)++;
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1443,110 +1451,115 @@ void read_mission_goal_list(int num)
|
||||
{
|
||||
char *filename, notes[NOTES_LENGTH], goals[MAX_GOALS][NAME_LENGTH];
|
||||
char events[MAX_MISSION_EVENTS][NAME_LENGTH];
|
||||
int i, z, rval, event_count, count = 0;
|
||||
int i, z, event_count, count = 0;
|
||||
|
||||
filename = Campaign.missions[num].name;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
try
|
||||
{
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
init_sexp();
|
||||
|
||||
// first, read the mission notes for this mission. Used in campaign editor
|
||||
if (skip_to_string("#Mission Info")) {
|
||||
if (skip_to_string("$Notes:")) {
|
||||
stuff_string(notes, F_NOTES, NOTES_LENGTH);
|
||||
if (Campaign.missions[num].notes){
|
||||
vm_free(Campaign.missions[num].notes);
|
||||
}
|
||||
|
||||
Campaign.missions[num].notes = (char *)vm_malloc(strlen(notes) + 1);
|
||||
strcpy(Campaign.missions[num].notes, notes);
|
||||
}
|
||||
}
|
||||
|
||||
event_count = 0;
|
||||
// skip to events section in the mission file. Events come before goals, so we process them first
|
||||
if (skip_to_string("#Events")) {
|
||||
while (1) {
|
||||
if (skip_to_string("$Formula:", "#Goals") != 1){
|
||||
break;
|
||||
}
|
||||
|
||||
z = skip_to_string("+Name:", "$Formula:");
|
||||
if (!z){
|
||||
break;
|
||||
}
|
||||
|
||||
if (z == 1){
|
||||
stuff_string(events[event_count], F_NAME, NAME_LENGTH);
|
||||
}
|
||||
else {
|
||||
sprintf(events[event_count], NOX("Event #%d"), event_count + 1);
|
||||
}
|
||||
|
||||
event_count++;
|
||||
if (event_count > MAX_MISSION_EVENTS) {
|
||||
Warning(LOCATION, "Maximum number of events exceeded (%d)!", MAX_MISSION_EVENTS);
|
||||
event_count = MAX_MISSION_EVENTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = 0;
|
||||
if (skip_to_string("#Goals")) {
|
||||
while (1) {
|
||||
if (skip_to_string("$Type:", "#End") != 1){
|
||||
break;
|
||||
}
|
||||
|
||||
z = skip_to_string("+Name:", "$Type:");
|
||||
if (!z){
|
||||
break;
|
||||
}
|
||||
|
||||
if (z == 1){
|
||||
stuff_string(goals[count], F_NAME, NAME_LENGTH);
|
||||
}
|
||||
else {
|
||||
sprintf(goals[count], NOX("Goal #%d"), count + 1);
|
||||
}
|
||||
|
||||
count++;
|
||||
if (count > MAX_GOALS) {
|
||||
Warning(LOCATION, "Maximum number of goals exceeded (%d)!", MAX_GOALS);
|
||||
count = MAX_GOALS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Campaign.missions[num].num_goals = count;
|
||||
if (count) {
|
||||
Campaign.missions[num].goals = (mgoal *)vm_malloc(count * sizeof(mgoal));
|
||||
Assert(Campaign.missions[num].goals); // make sure we got the memory
|
||||
memset(Campaign.missions[num].goals, 0, count * sizeof(mgoal));
|
||||
|
||||
for (i = 0; i < count; i++){
|
||||
strcpy_s(Campaign.missions[num].goals[i].name, goals[i]);
|
||||
}
|
||||
}
|
||||
// copy the events
|
||||
Campaign.missions[num].num_events = event_count;
|
||||
if (event_count) {
|
||||
Campaign.missions[num].events = (mevent *)vm_malloc(event_count * sizeof(mevent));
|
||||
Assert(Campaign.missions[num].events);
|
||||
memset(Campaign.missions[num].events, 0, event_count * sizeof(mevent));
|
||||
|
||||
for (i = 0; i < event_count; i++){
|
||||
strcpy_s(Campaign.missions[num].events[i].name, events[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000 - variables do not need to be read here
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
init_sexp();
|
||||
|
||||
// first, read the mission notes for this mission. Used in campaign editor
|
||||
if (skip_to_string("#Mission Info")) {
|
||||
if (skip_to_string("$Notes:")) {
|
||||
stuff_string(notes, F_NOTES, NOTES_LENGTH);
|
||||
if (Campaign.missions[num].notes){
|
||||
vm_free(Campaign.missions[num].notes);
|
||||
}
|
||||
|
||||
Campaign.missions[num].notes = (char *) vm_malloc(strlen(notes) + 1);
|
||||
strcpy(Campaign.missions[num].notes, notes);
|
||||
}
|
||||
}
|
||||
|
||||
event_count = 0;
|
||||
// skip to events section in the mission file. Events come before goals, so we process them first
|
||||
if ( skip_to_string("#Events") ) {
|
||||
while (1) {
|
||||
if (skip_to_string("$Formula:", "#Goals") != 1){
|
||||
break;
|
||||
}
|
||||
|
||||
z = skip_to_string("+Name:", "$Formula:");
|
||||
if (!z){
|
||||
break;
|
||||
}
|
||||
|
||||
if (z == 1){
|
||||
stuff_string(events[event_count], F_NAME, NAME_LENGTH);
|
||||
} else {
|
||||
sprintf(events[event_count], NOX("Event #%d"), event_count + 1);
|
||||
}
|
||||
|
||||
event_count++;
|
||||
if (event_count > MAX_MISSION_EVENTS) {
|
||||
Warning(LOCATION, "Maximum number of events exceeded (%d)!", MAX_MISSION_EVENTS);
|
||||
event_count = MAX_MISSION_EVENTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = 0;
|
||||
if (skip_to_string("#Goals")) {
|
||||
while (1) {
|
||||
if (skip_to_string("$Type:", "#End") != 1){
|
||||
break;
|
||||
}
|
||||
|
||||
z = skip_to_string("+Name:", "$Type:");
|
||||
if (!z){
|
||||
break;
|
||||
}
|
||||
|
||||
if (z == 1){
|
||||
stuff_string(goals[count], F_NAME, NAME_LENGTH);
|
||||
} else {
|
||||
sprintf(goals[count], NOX("Goal #%d"), count + 1);
|
||||
}
|
||||
|
||||
count++;
|
||||
if (count > MAX_GOALS) {
|
||||
Warning(LOCATION, "Maximum number of goals exceeded (%d)!", MAX_GOALS);
|
||||
count = MAX_GOALS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Campaign.missions[num].num_goals = count;
|
||||
if (count) {
|
||||
Campaign.missions[num].goals = (mgoal *) vm_malloc(count * sizeof(mgoal));
|
||||
Assert(Campaign.missions[num].goals); // make sure we got the memory
|
||||
memset(Campaign.missions[num].goals, 0, count * sizeof(mgoal));
|
||||
|
||||
for (i=0; i<count; i++){
|
||||
strcpy_s(Campaign.missions[num].goals[i].name, goals[i]);
|
||||
}
|
||||
}
|
||||
// copy the events
|
||||
Campaign.missions[num].num_events = event_count;
|
||||
if (event_count) {
|
||||
Campaign.missions[num].events = (mevent *)vm_malloc(event_count * sizeof(mevent));
|
||||
Assert ( Campaign.missions[num].events );
|
||||
memset(Campaign.missions[num].events, 0, event_count * sizeof(mevent));
|
||||
|
||||
for (i = 0; i < event_count; i++ ){
|
||||
strcpy_s(Campaign.missions[num].events[i].name, events[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000 - variables do not need to be read here
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1622,33 +1635,36 @@ void mission_campaign_maybe_play_movie(int type)
|
||||
*/
|
||||
int mission_campaign_parse_is_multi(char *filename, char *name)
|
||||
{
|
||||
int i, rval;
|
||||
int i;
|
||||
char temp[NAME_LENGTH];
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
try
|
||||
{
|
||||
read_file_text(filename);
|
||||
reset_parse();
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(temp, F_NAME, NAME_LENGTH);
|
||||
if (name)
|
||||
strcpy(name, temp);
|
||||
|
||||
required_string("$Type:");
|
||||
stuff_string(temp, F_NAME, NAME_LENGTH);
|
||||
|
||||
for (i = 0; i < MAX_CAMPAIGN_TYPES; i++) {
|
||||
if (!stricmp(temp, campaign_types[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
Error(LOCATION, "Unknown campaign type %s", temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
read_file_text( filename );
|
||||
reset_parse();
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string( temp, F_NAME, NAME_LENGTH );
|
||||
if ( name )
|
||||
strcpy( name, temp );
|
||||
|
||||
required_string( "$Type:" );
|
||||
stuff_string( temp, F_NAME, NAME_LENGTH );
|
||||
|
||||
for (i = 0; i < MAX_CAMPAIGN_TYPES; i++ ) {
|
||||
if ( !stricmp(temp, campaign_types[i]) ) {
|
||||
return i;
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONCAMPAIGN: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
Error(LOCATION, "Unknown campaign type %s", temp );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -648,19 +648,22 @@ void parse_msgtbl()
|
||||
// this is called at the start of each level
|
||||
void messages_init()
|
||||
{
|
||||
int rval, i;
|
||||
int i;
|
||||
static int table_read = 0;
|
||||
|
||||
if ( !table_read ) {
|
||||
Default_command_persona = -1;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "messages.tbl", rval));
|
||||
|
||||
try
|
||||
{
|
||||
parse_msgtbl();
|
||||
table_read = 1;
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "messages.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
parse_msgtbl();
|
||||
table_read = 1;
|
||||
}
|
||||
|
||||
Current_mission_mood = 0;
|
||||
|
||||
@@ -5853,15 +5853,18 @@ int get_mission_info(const char *filename, mission *mission_p, bool basic)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error code = %i.\n", real_fname, rval));
|
||||
try
|
||||
{
|
||||
read_file_text(real_fname, CF_TYPE_MISSIONS);
|
||||
mission_p->Reset();
|
||||
parse_init(basic);
|
||||
parse_mission_info(mission_p, basic);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error message = %s.\n", real_fname, e.what()));
|
||||
break;
|
||||
}
|
||||
|
||||
read_file_text(real_fname, CF_TYPE_MISSIONS);
|
||||
mission_p->Reset( );
|
||||
parse_init(basic);
|
||||
parse_mission_info(mission_p, basic);
|
||||
} while (0);
|
||||
|
||||
return rval;
|
||||
@@ -5926,22 +5929,27 @@ int parse_main(const char *mission_name, int flags)
|
||||
cfclose(ftemp);
|
||||
}
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error code = %i.\n", mission_name, rval));
|
||||
try
|
||||
{
|
||||
// import?
|
||||
if (flags & MPF_IMPORT_FSM) {
|
||||
read_file_text(mission_name, CF_TYPE_ANY);
|
||||
convertFSMtoFS2();
|
||||
}
|
||||
else {
|
||||
read_file_text(mission_name, CF_TYPE_MISSIONS);
|
||||
}
|
||||
|
||||
The_mission.Reset();
|
||||
rval = parse_mission(&The_mission, flags);
|
||||
display_parse_diagnostics();
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error message = %s.\n", mission_name, e.what()));
|
||||
rval = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// import?
|
||||
if (flags & MPF_IMPORT_FSM) {
|
||||
read_file_text(mission_name, CF_TYPE_ANY);
|
||||
convertFSMtoFS2();
|
||||
} else {
|
||||
read_file_text(mission_name, CF_TYPE_MISSIONS);
|
||||
}
|
||||
|
||||
The_mission.Reset( );
|
||||
rval = parse_mission(&The_mission, flags);
|
||||
display_parse_diagnostics();
|
||||
} while (0);
|
||||
|
||||
if (!Fred_running)
|
||||
@@ -6283,7 +6291,7 @@ void mission_parse_set_up_initial_docks()
|
||||
*/
|
||||
int mission_parse_is_multi(const char *filename, char *mission_name)
|
||||
{
|
||||
int rval, game_type;
|
||||
int game_type;
|
||||
int filelength;
|
||||
CFILE *ftemp;
|
||||
|
||||
@@ -6302,25 +6310,28 @@ int mission_parse_is_multi(const char *filename, char *mission_name)
|
||||
|
||||
game_type = 0;
|
||||
do {
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_MISSIONS);
|
||||
reset_parse();
|
||||
|
||||
if (skip_to_string("$Name:") != 1) {
|
||||
nprintf(("Network", "Unable to process %s because we couldn't find $Name:", filename));
|
||||
break;
|
||||
}
|
||||
stuff_string(mission_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (skip_to_string("+Game Type Flags:") != 1) {
|
||||
nprintf(("Network", "Unable to process %s because we couldn't find +Game Type Flags:\n", filename));
|
||||
break;
|
||||
}
|
||||
stuff_int(&game_type);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("MISSIONS: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
break;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_MISSIONS);
|
||||
reset_parse();
|
||||
|
||||
if ( skip_to_string("$Name:") != 1 ) {
|
||||
nprintf(("Network", "Unable to process %s because we couldn't find $Name:", filename));
|
||||
break;
|
||||
}
|
||||
stuff_string( mission_name, F_NAME, NAME_LENGTH );
|
||||
|
||||
if ( skip_to_string("+Game Type Flags:") != 1 ) {
|
||||
nprintf(("Network", "Unable to process %s because we couldn't find +Game Type Flags:\n", filename));
|
||||
break;
|
||||
}
|
||||
stuff_int(&game_type);
|
||||
} while (0);
|
||||
|
||||
return (game_type & MISSION_TYPE_MULTI) ? game_type : 0;
|
||||
|
||||
@@ -1058,49 +1058,51 @@ void debrief_traitor_init()
|
||||
if ( !inited ) {
|
||||
debriefing *debrief;
|
||||
debrief_stage *stagep;
|
||||
int rval;
|
||||
int stage_num;
|
||||
|
||||
try
|
||||
{
|
||||
read_file_text("traitor.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "traitor.tbl", rval));
|
||||
// simplied form of the debriefing stuff.
|
||||
debrief = &Traitor_debriefing;
|
||||
required_string("#Debriefing_info");
|
||||
|
||||
required_string("$Num stages:");
|
||||
stuff_int(&debrief->num_stages);
|
||||
Assert(debrief->num_stages == 1);
|
||||
|
||||
stage_num = 0;
|
||||
stagep = &debrief->stages[stage_num++];
|
||||
required_string("$Formula:");
|
||||
stagep->formula = get_sexp_main();
|
||||
required_string("$multi text");
|
||||
stuff_string(stagep->text, F_MULTITEXT, NULL);
|
||||
required_string("$Voice:");
|
||||
char traitor_voice_file[MAX_FILENAME_LEN];
|
||||
stuff_string(traitor_voice_file, F_FILESPEC, MAX_FILENAME_LEN);
|
||||
|
||||
// DKA 9/13/99 Only 1 traitor msg for FS2
|
||||
// if ( Player->main_hall ) {
|
||||
// strcpy_s(stagep->voice, NOX("3_"));
|
||||
// } else {
|
||||
// strcpy_s(stagep->voice, NOX("1_"));
|
||||
// }
|
||||
|
||||
// Goober5000
|
||||
debrief_choose_voice(stagep->voice, traitor_voice_file, debrief_find_persona_index(), 1);
|
||||
|
||||
required_string("$Recommendation text:");
|
||||
stuff_string(stagep->recommendation_text, F_MULTITEXT, NULL);
|
||||
|
||||
inited = 1;
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "traitor.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("traitor.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// simplied form of the debriefing stuff.
|
||||
debrief = &Traitor_debriefing;
|
||||
required_string("#Debriefing_info");
|
||||
|
||||
required_string("$Num stages:");
|
||||
stuff_int(&debrief->num_stages);
|
||||
Assert(debrief->num_stages == 1);
|
||||
|
||||
stage_num = 0;
|
||||
stagep = &debrief->stages[stage_num++];
|
||||
required_string("$Formula:");
|
||||
stagep->formula = get_sexp_main();
|
||||
required_string("$multi text");
|
||||
stuff_string( stagep->text, F_MULTITEXT, NULL);
|
||||
required_string("$Voice:");
|
||||
char traitor_voice_file[MAX_FILENAME_LEN];
|
||||
stuff_string(traitor_voice_file, F_FILESPEC, MAX_FILENAME_LEN);
|
||||
|
||||
// DKA 9/13/99 Only 1 traitor msg for FS2
|
||||
// if ( Player->main_hall ) {
|
||||
// strcpy_s(stagep->voice, NOX("3_"));
|
||||
// } else {
|
||||
// strcpy_s(stagep->voice, NOX("1_"));
|
||||
// }
|
||||
|
||||
// Goober5000
|
||||
debrief_choose_voice(stagep->voice, traitor_voice_file, debrief_find_persona_index(), 1);
|
||||
|
||||
required_string("$Recommendation text:");
|
||||
stuff_string( stagep->recommendation_text, F_MULTITEXT, NULL);
|
||||
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
// disable the accept button if in single player and I am a traitor
|
||||
|
||||
+218
-211
@@ -36,240 +36,247 @@ bool Beams_use_damage_factors = false;
|
||||
|
||||
void parse_mod_table(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
// SCP_vector<SCP_string> lines;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default game_settings.tbl>", rval));
|
||||
return;
|
||||
}
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("game_settings.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("game_settings.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
reset_parse();
|
||||
// start parsing
|
||||
optional_string("#CAMPAIGN SETTINGS");
|
||||
|
||||
// start parsing
|
||||
optional_string("#CAMPAIGN SETTINGS");
|
||||
|
||||
if (optional_string("$Default Campaign File Name:")) {
|
||||
char temp[MAX_FILENAME_LEN];
|
||||
stuff_string(temp, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// remove extension?
|
||||
if (drop_extension(temp)) {
|
||||
mprintf(("Game Settings Table: Removed extension on default campaign file name %s\n", temp));
|
||||
}
|
||||
|
||||
// check length
|
||||
int maxlen = (MAX_FILENAME_LEN - 4);
|
||||
int len = strlen(temp);
|
||||
if (len > maxlen) {
|
||||
Warning(LOCATION, "Token too long: [%s]. Length = %i. Max is %i.\n", temp, len, maxlen);
|
||||
temp[maxlen] = 0;
|
||||
}
|
||||
|
||||
strcpy_s(Default_campaign_file_name, temp);
|
||||
}
|
||||
|
||||
if (optional_string("#Ignored Campaign File Names")) {
|
||||
SCP_string campaign_name;
|
||||
|
||||
while (optional_string("$Campaign File Name:")) {
|
||||
stuff_string(campaign_name, F_NAME);
|
||||
if (optional_string("$Default Campaign File Name:")) {
|
||||
char temp[MAX_FILENAME_LEN];
|
||||
stuff_string(temp, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// remove extension?
|
||||
if (drop_extension(campaign_name)) {
|
||||
mprintf(("Game Settings Table: Removed extension on ignored campaign file name %s\n", campaign_name.c_str()));
|
||||
if (drop_extension(temp)) {
|
||||
mprintf(("Game Settings Table: Removed extension on default campaign file name %s\n", temp));
|
||||
}
|
||||
|
||||
Ignored_campaigns.push_back(campaign_name);
|
||||
// check length
|
||||
int maxlen = (MAX_FILENAME_LEN - 4);
|
||||
int len = strlen(temp);
|
||||
if (len > maxlen) {
|
||||
Warning(LOCATION, "Token too long: [%s]. Length = %i. Max is %i.\n", temp, len, maxlen);
|
||||
temp[maxlen] = 0;
|
||||
}
|
||||
|
||||
strcpy_s(Default_campaign_file_name, temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Red-alert applies to delayed ships:")) {
|
||||
stuff_boolean(&Red_alert_applies_to_delayed_ships);
|
||||
if (Red_alert_applies_to_delayed_ships) {
|
||||
mprintf(("Game Settings Table: Red-alert stats will be loaded for ships that arrive later in missions\n"));
|
||||
} else {
|
||||
mprintf(("Game Settings Table: Red-alert stats will NOT be loaded for ships that arrive later in missions (this is retail behavior)\n"));
|
||||
if (optional_string("#Ignored Campaign File Names")) {
|
||||
SCP_string campaign_name;
|
||||
|
||||
while (optional_string("$Campaign File Name:")) {
|
||||
stuff_string(campaign_name, F_NAME);
|
||||
|
||||
// remove extension?
|
||||
if (drop_extension(campaign_name)) {
|
||||
mprintf(("Game Settings Table: Removed extension on ignored campaign file name %s\n", campaign_name.c_str()));
|
||||
}
|
||||
|
||||
Ignored_campaigns.push_back(campaign_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
optional_string("#HUD SETTINGS");
|
||||
|
||||
// how long should the game wait before displaying a directive?
|
||||
if (optional_string("$Directive Wait Time:")) {
|
||||
stuff_int(&Directive_wait_time);
|
||||
}
|
||||
|
||||
if (optional_string("$Cutscene camera displays HUD:")) {
|
||||
stuff_boolean(&Cutscene_camera_displays_hud);
|
||||
}
|
||||
// compatibility
|
||||
if (optional_string("$Cutscene camera disables HUD:")) {
|
||||
mprintf(("Game Settings Table: \"$$Cutscene camera disables HUD\" is deprecated in favor of \"$Cutscene camera displays HUD\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
Cutscene_camera_displays_hud = !temp;
|
||||
}
|
||||
|
||||
if (optional_string("$Full color head animations:")) {
|
||||
stuff_boolean(&Full_color_head_anis);
|
||||
}
|
||||
// compatibility
|
||||
if (optional_string("$Color head animations with hud colors:")) {
|
||||
mprintf(("Game Settings Table: \"$Color head animations with hud colors\" is deprecated in favor of \"$Full color head animations\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
Full_color_head_anis = !temp;
|
||||
}
|
||||
|
||||
optional_string("#SEXP SETTINGS");
|
||||
|
||||
if (optional_string("$Loop SEXPs Then Arguments:")) {
|
||||
stuff_boolean(&True_loop_argument_sexps);
|
||||
if (True_loop_argument_sexps) {
|
||||
mprintf(("Game Settings Table: Using Reversed Loops For SEXP Arguments\n"));
|
||||
} else {
|
||||
mprintf(("Game Settings Table: Using Standard Loops For SEXP Arguments\n"));
|
||||
if (optional_string("$Red-alert applies to delayed ships:")) {
|
||||
stuff_boolean(&Red_alert_applies_to_delayed_ships);
|
||||
if (Red_alert_applies_to_delayed_ships) {
|
||||
mprintf(("Game Settings Table: Red-alert stats will be loaded for ships that arrive later in missions\n"));
|
||||
}
|
||||
else {
|
||||
mprintf(("Game Settings Table: Red-alert stats will NOT be loaded for ships that arrive later in missions (this is retail behavior)\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Use Alternate Chaining Behavior:")) {
|
||||
stuff_boolean(&Alternate_chaining_behavior);
|
||||
if (Alternate_chaining_behavior) {
|
||||
mprintf(("Game Settings Table: Using alternate event chaining behavior\n"));
|
||||
} else {
|
||||
mprintf(("Game Settings Table: Using standard event chaining behavior\n"));
|
||||
optional_string("#HUD SETTINGS");
|
||||
|
||||
// how long should the game wait before displaying a directive?
|
||||
if (optional_string("$Directive Wait Time:")) {
|
||||
stuff_int(&Directive_wait_time);
|
||||
}
|
||||
}
|
||||
|
||||
optional_string("#GRAPHICS SETTINGS");
|
||||
|
||||
if (optional_string("$Enable External Shaders:")) {
|
||||
stuff_boolean(&Enable_external_shaders);
|
||||
if (Enable_external_shaders)
|
||||
mprintf(("Game Settings Table: External shaders are enabled\n"));
|
||||
else
|
||||
mprintf(("Game Settings Table: External shaders are DISABLED\n"));
|
||||
}
|
||||
|
||||
if (optional_string("$Default Detail Level:")) {
|
||||
int detail_level;
|
||||
|
||||
stuff_int(&detail_level);
|
||||
|
||||
mprintf(("Game Settings Table: Setting default detail level to %i of %i-%i\n", detail_level, 0, NUM_DEFAULT_DETAIL_LEVELS-1));
|
||||
|
||||
if (detail_level < 0 || detail_level > NUM_DEFAULT_DETAIL_LEVELS-1) {
|
||||
Warning(LOCATION, "Invalid detail level: %i, setting to %i\n", detail_level, Default_detail_level);
|
||||
} else {
|
||||
Default_detail_level = detail_level;
|
||||
if (optional_string("$Cutscene camera displays HUD:")) {
|
||||
stuff_boolean(&Cutscene_camera_displays_hud);
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Briefing Window FOV:")) {
|
||||
float fov;
|
||||
|
||||
stuff_float(&fov);
|
||||
|
||||
mprintf(("Game Settings Table: Setting briefing window FOV from %f to %f\n", Briefing_window_FOV, fov));
|
||||
|
||||
Briefing_window_FOV = fov;
|
||||
}
|
||||
|
||||
optional_string("#NETWORK SETTINGS");
|
||||
|
||||
if (optional_string("$FS2NetD port:")) {
|
||||
stuff_int(&FS2NetD_port);
|
||||
if (FS2NetD_port)
|
||||
mprintf(("Game Settings Table: FS2NetD connecting to port %i\n", FS2NetD_port));
|
||||
}
|
||||
|
||||
optional_string("#SOUND SETTINGS");
|
||||
|
||||
if (optional_string("$Default Sound Volume:")) {
|
||||
stuff_float(&Master_sound_volume);
|
||||
}
|
||||
|
||||
if (optional_string("$Default Music Volume:")) {
|
||||
stuff_float(&Master_event_music_volume);
|
||||
}
|
||||
|
||||
if (optional_string("$Default Voice Volume:")) {
|
||||
stuff_float(&Master_voice_volume);
|
||||
}
|
||||
|
||||
optional_string("#FRED SETTINGS");
|
||||
|
||||
if (optional_string("$Disable Hard Coded Message Head Ani Files:")) {
|
||||
stuff_boolean(&Disable_hc_message_ani);
|
||||
if (Disable_hc_message_ani) {
|
||||
mprintf(("Game Settings Table: FRED - Disabling Hard Coded Message Ani Files\n"));
|
||||
} else {
|
||||
mprintf(("Game Settings Table: FRED - Using Hard Coded Message Ani Files\n"));
|
||||
|
||||
// compatibility
|
||||
if (optional_string("$Cutscene camera disables HUD:")) {
|
||||
mprintf(("Game Settings Table: \"$$Cutscene camera disables HUD\" is deprecated in favor of \"$Cutscene camera displays HUD\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
Cutscene_camera_displays_hud = !temp;
|
||||
}
|
||||
}
|
||||
|
||||
optional_string("#OTHER SETTINGS");
|
||||
|
||||
if (optional_string("$Fixed Turret Collisions:")) {
|
||||
stuff_boolean(&Fixed_turret_collisions);
|
||||
}
|
||||
|
||||
if (optional_string("$Damage Impacted Subsystem First:")) {
|
||||
stuff_boolean(&Damage_impacted_subsystem_first);
|
||||
}
|
||||
|
||||
if (optional_string("$Default ship select effect:")) {
|
||||
char effect[NAME_LENGTH];
|
||||
stuff_string(effect, F_NAME, NAME_LENGTH);
|
||||
if (!stricmp(effect, "FS2"))
|
||||
Default_ship_select_effect = 2;
|
||||
else if (!stricmp(effect, "FS1"))
|
||||
Default_ship_select_effect = 1;
|
||||
else if (!stricmp(effect, "off"))
|
||||
Default_ship_select_effect = 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Default weapon select effect:")) {
|
||||
char effect[NAME_LENGTH];
|
||||
stuff_string(effect, F_NAME, NAME_LENGTH);
|
||||
if (!stricmp(effect, "FS2"))
|
||||
Default_weapon_select_effect = 2;
|
||||
else if (!stricmp(effect, "FS1"))
|
||||
Default_weapon_select_effect = 1;
|
||||
else if (!stricmp(effect, "off"))
|
||||
Default_weapon_select_effect = 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Weapons inherit parent collision group:")) {
|
||||
stuff_boolean(&Weapons_inherit_parent_collision_group);
|
||||
if (Weapons_inherit_parent_collision_group)
|
||||
mprintf(("Game Settings Table: Weapons inherit parent collision group\n"));
|
||||
}
|
||||
|
||||
if (optional_string("$Flight controls follow eyepoint orientation:")) {
|
||||
stuff_boolean(&Flight_controls_follow_eyepoint_orientation);
|
||||
if (Flight_controls_follow_eyepoint_orientation)
|
||||
mprintf(("Game Settings Table: Flight controls follow eyepoint orientation\n"));
|
||||
}
|
||||
|
||||
if (optional_string("$Beams Use Damage Factors:")) {
|
||||
stuff_boolean(&Beams_use_damage_factors);
|
||||
if (Beams_use_damage_factors) {
|
||||
mprintf(("Game Settings Table: Beams will use Damage Factors\n"));
|
||||
} else {
|
||||
mprintf(("Game Settings Table: Beams will ignore Damage Factors (retail behavior)\n"));
|
||||
if (optional_string("$Full color head animations:")) {
|
||||
stuff_boolean(&Full_color_head_anis);
|
||||
}
|
||||
// compatibility
|
||||
if (optional_string("$Color head animations with hud colors:")) {
|
||||
mprintf(("Game Settings Table: \"$Color head animations with hud colors\" is deprecated in favor of \"$Full color head animations\"\n"));
|
||||
bool temp;
|
||||
stuff_boolean(&temp);
|
||||
Full_color_head_anis = !temp;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#END");
|
||||
optional_string("#SEXP SETTINGS");
|
||||
|
||||
if (optional_string("$Loop SEXPs Then Arguments:")) {
|
||||
stuff_boolean(&True_loop_argument_sexps);
|
||||
if (True_loop_argument_sexps) {
|
||||
mprintf(("Game Settings Table: Using Reversed Loops For SEXP Arguments\n"));
|
||||
}
|
||||
else {
|
||||
mprintf(("Game Settings Table: Using Standard Loops For SEXP Arguments\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Use Alternate Chaining Behavior:")) {
|
||||
stuff_boolean(&Alternate_chaining_behavior);
|
||||
if (Alternate_chaining_behavior) {
|
||||
mprintf(("Game Settings Table: Using alternate event chaining behavior\n"));
|
||||
}
|
||||
else {
|
||||
mprintf(("Game Settings Table: Using standard event chaining behavior\n"));
|
||||
}
|
||||
}
|
||||
|
||||
optional_string("#GRAPHICS SETTINGS");
|
||||
|
||||
if (optional_string("$Enable External Shaders:")) {
|
||||
stuff_boolean(&Enable_external_shaders);
|
||||
if (Enable_external_shaders)
|
||||
mprintf(("Game Settings Table: External shaders are enabled\n"));
|
||||
else
|
||||
mprintf(("Game Settings Table: External shaders are DISABLED\n"));
|
||||
}
|
||||
|
||||
if (optional_string("$Default Detail Level:")) {
|
||||
int detail_level;
|
||||
|
||||
stuff_int(&detail_level);
|
||||
|
||||
mprintf(("Game Settings Table: Setting default detail level to %i of %i-%i\n", detail_level, 0, NUM_DEFAULT_DETAIL_LEVELS - 1));
|
||||
|
||||
if (detail_level < 0 || detail_level > NUM_DEFAULT_DETAIL_LEVELS - 1) {
|
||||
Warning(LOCATION, "Invalid detail level: %i, setting to %i\n", detail_level, Default_detail_level);
|
||||
}
|
||||
else {
|
||||
Default_detail_level = detail_level;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_string("$Briefing Window FOV:")) {
|
||||
float fov;
|
||||
|
||||
stuff_float(&fov);
|
||||
|
||||
mprintf(("Game Settings Table: Setting briefing window FOV from %f to %f\n", Briefing_window_FOV, fov));
|
||||
|
||||
Briefing_window_FOV = fov;
|
||||
}
|
||||
|
||||
optional_string("#NETWORK SETTINGS");
|
||||
|
||||
if (optional_string("$FS2NetD port:")) {
|
||||
stuff_int(&FS2NetD_port);
|
||||
if (FS2NetD_port)
|
||||
mprintf(("Game Settings Table: FS2NetD connecting to port %i\n", FS2NetD_port));
|
||||
}
|
||||
|
||||
optional_string("#SOUND SETTINGS");
|
||||
|
||||
if (optional_string("$Default Sound Volume:")) {
|
||||
stuff_float(&Master_sound_volume);
|
||||
}
|
||||
|
||||
if (optional_string("$Default Music Volume:")) {
|
||||
stuff_float(&Master_event_music_volume);
|
||||
}
|
||||
|
||||
if (optional_string("$Default Voice Volume:")) {
|
||||
stuff_float(&Master_voice_volume);
|
||||
}
|
||||
|
||||
optional_string("#FRED SETTINGS");
|
||||
|
||||
if (optional_string("$Disable Hard Coded Message Head Ani Files:")) {
|
||||
stuff_boolean(&Disable_hc_message_ani);
|
||||
if (Disable_hc_message_ani) {
|
||||
mprintf(("Game Settings Table: FRED - Disabling Hard Coded Message Ani Files\n"));
|
||||
}
|
||||
else {
|
||||
mprintf(("Game Settings Table: FRED - Using Hard Coded Message Ani Files\n"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
optional_string("#OTHER SETTINGS");
|
||||
|
||||
if (optional_string("$Fixed Turret Collisions:")) {
|
||||
stuff_boolean(&Fixed_turret_collisions);
|
||||
}
|
||||
|
||||
if (optional_string("$Damage Impacted Subsystem First:")) {
|
||||
stuff_boolean(&Damage_impacted_subsystem_first);
|
||||
}
|
||||
|
||||
if (optional_string("$Default ship select effect:")) {
|
||||
char effect[NAME_LENGTH];
|
||||
stuff_string(effect, F_NAME, NAME_LENGTH);
|
||||
if (!stricmp(effect, "FS2"))
|
||||
Default_ship_select_effect = 2;
|
||||
else if (!stricmp(effect, "FS1"))
|
||||
Default_ship_select_effect = 1;
|
||||
else if (!stricmp(effect, "off"))
|
||||
Default_ship_select_effect = 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Default weapon select effect:")) {
|
||||
char effect[NAME_LENGTH];
|
||||
stuff_string(effect, F_NAME, NAME_LENGTH);
|
||||
if (!stricmp(effect, "FS2"))
|
||||
Default_weapon_select_effect = 2;
|
||||
else if (!stricmp(effect, "FS1"))
|
||||
Default_weapon_select_effect = 1;
|
||||
else if (!stricmp(effect, "off"))
|
||||
Default_weapon_select_effect = 0;
|
||||
}
|
||||
|
||||
if (optional_string("$Weapons inherit parent collision group:")) {
|
||||
stuff_boolean(&Weapons_inherit_parent_collision_group);
|
||||
if (Weapons_inherit_parent_collision_group)
|
||||
mprintf(("Game Settings Table: Weapons inherit parent collision group\n"));
|
||||
}
|
||||
|
||||
if (optional_string("$Flight controls follow eyepoint orientation:")) {
|
||||
stuff_boolean(&Flight_controls_follow_eyepoint_orientation);
|
||||
if (Flight_controls_follow_eyepoint_orientation)
|
||||
mprintf(("Game Settings Table: Flight controls follow eyepoint orientation\n"));
|
||||
}
|
||||
|
||||
if (optional_string("$Beams Use Damage Factors:")) {
|
||||
stuff_boolean(&Beams_use_damage_factors);
|
||||
if (Beams_use_damage_factors) {
|
||||
mprintf(("Game Settings Table: Beams will use Damage Factors\n"));
|
||||
}
|
||||
else {
|
||||
mprintf(("Game Settings Table: Beams will ignore Damage Factors (retail behavior)\n"));
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#END");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : "<default game_settings.tbl>", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void mod_table_init()
|
||||
|
||||
+42
-38
@@ -249,48 +249,52 @@ void neb2_regen();
|
||||
// initialize neb2 stuff at game startup
|
||||
void neb2_init()
|
||||
{
|
||||
int rval;
|
||||
char name[MAX_FILENAME_LEN];
|
||||
|
||||
if ( ( rval = setjmp(parse_abort) ) != 0 ) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "nebula.tbl", rval));
|
||||
try
|
||||
{
|
||||
// read in the nebula.tbl
|
||||
read_file_text("nebula.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// background bitmaps
|
||||
Neb2_bitmap_count = 0;
|
||||
while (!optional_string("#end")) {
|
||||
// nebula
|
||||
required_string("+Nebula:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (Neb2_bitmap_count < MAX_NEB2_BITMAPS) {
|
||||
strcpy_s(Neb2_bitmap_filenames[Neb2_bitmap_count++], name);
|
||||
}
|
||||
else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebulas (%d)!\nSkipping %s.", MAX_NEB2_BITMAPS, name);
|
||||
}
|
||||
}
|
||||
|
||||
// poofs
|
||||
Neb2_poof_count = 0;
|
||||
while (!optional_string("#end")) {
|
||||
// nebula
|
||||
required_string("+Poof:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (Neb2_poof_count < MAX_NEB2_POOFS) {
|
||||
strcpy_s(Neb2_poof_filenames[Neb2_poof_count++], name);
|
||||
}
|
||||
else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebula poofs (%d)!\nSkipping %s.", MAX_NEB2_POOFS, name);
|
||||
}
|
||||
}
|
||||
|
||||
// should always have 6 neb poofs
|
||||
Assert(Neb2_poof_count == 6);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "nebula.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// read in the nebula.tbl
|
||||
read_file_text("nebula.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// background bitmaps
|
||||
Neb2_bitmap_count = 0;
|
||||
while ( !optional_string("#end") ) {
|
||||
// nebula
|
||||
required_string("+Nebula:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if ( Neb2_bitmap_count < MAX_NEB2_BITMAPS ) {
|
||||
strcpy_s(Neb2_bitmap_filenames[Neb2_bitmap_count++], name);
|
||||
} else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebulas (%d)!\nSkipping %s.", MAX_NEB2_BITMAPS, name);
|
||||
}
|
||||
}
|
||||
|
||||
// poofs
|
||||
Neb2_poof_count = 0;
|
||||
while ( !optional_string("#end") ) {
|
||||
// nebula
|
||||
required_string("+Poof:");
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if ( Neb2_poof_count < MAX_NEB2_POOFS ) {
|
||||
strcpy_s(Neb2_poof_filenames[Neb2_poof_count++], name);
|
||||
} else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebula poofs (%d)!\nSkipping %s.", MAX_NEB2_POOFS, name);
|
||||
}
|
||||
}
|
||||
|
||||
// should always have 6 neb poofs
|
||||
Assert(Neb2_poof_count == 6);
|
||||
}
|
||||
|
||||
// set detail level
|
||||
|
||||
+116
-114
@@ -155,123 +155,125 @@ DCF(lightning_intensity, "Sets lightning intensity between 0.0 and 1.0 (Default
|
||||
void nebl_init()
|
||||
{
|
||||
char name[MAX_FILENAME_LEN];
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "lightning.tbl", rval));
|
||||
try
|
||||
{
|
||||
// parse the lightning table
|
||||
read_file_text("lightning.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse the individual lightning bolt types
|
||||
required_string("#Bolts begin");
|
||||
while (!optional_string("#Bolts end")){
|
||||
bolt_type new_bolt_type;
|
||||
|
||||
// bolt title
|
||||
required_string("$Bolt:");
|
||||
stuff_string(new_bolt_type.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// b_scale
|
||||
required_string("+b_scale:");
|
||||
stuff_float(&new_bolt_type.b_scale);
|
||||
|
||||
// b_shrink
|
||||
required_string("+b_shrink:");
|
||||
stuff_float(&new_bolt_type.b_shrink);
|
||||
|
||||
// b_poly_pct
|
||||
required_string("+b_poly_pct:");
|
||||
stuff_float(&new_bolt_type.b_poly_pct);
|
||||
|
||||
// child rand
|
||||
required_string("+b_rand:");
|
||||
stuff_float(&new_bolt_type.b_rand);
|
||||
|
||||
// z add
|
||||
required_string("+b_add:");
|
||||
stuff_float(&new_bolt_type.b_add);
|
||||
|
||||
// # strikes
|
||||
required_string("+b_strikes:");
|
||||
stuff_int(&new_bolt_type.num_strikes);
|
||||
|
||||
// lifetime
|
||||
required_string("+b_lifetime:");
|
||||
stuff_int(&new_bolt_type.lifetime);
|
||||
|
||||
// noise
|
||||
required_string("+b_noise:");
|
||||
stuff_float(&new_bolt_type.noise);
|
||||
|
||||
// emp effect
|
||||
required_string("+b_emp:");
|
||||
stuff_float(&new_bolt_type.emp_intensity);
|
||||
stuff_float(&new_bolt_type.emp_time);
|
||||
|
||||
// texture
|
||||
required_string("+b_texture:");
|
||||
stuff_string(name, F_NAME, sizeof(name));
|
||||
if (!Fred_running){
|
||||
new_bolt_type.texture = bm_load(name);
|
||||
}
|
||||
|
||||
// glow
|
||||
required_string("+b_glow:");
|
||||
stuff_string(name, F_NAME, sizeof(name));
|
||||
if (!Fred_running){
|
||||
new_bolt_type.glow = bm_load(name);
|
||||
}
|
||||
|
||||
// brightness
|
||||
required_string("+b_bright:");
|
||||
stuff_float(&new_bolt_type.b_bright);
|
||||
|
||||
Bolt_types.push_back(new_bolt_type);
|
||||
}
|
||||
|
||||
// parse lightning storm types
|
||||
required_string("#Storms begin");
|
||||
while (!optional_string("#Storms end")){
|
||||
storm_type new_storm_type;
|
||||
|
||||
// bolt title
|
||||
required_string("$Storm:");
|
||||
stuff_string(new_storm_type.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// bolt types
|
||||
while (optional_string("+bolt:")){
|
||||
if (new_storm_type.num_bolt_types < MAX_BOLT_TYPES_PER_STORM){
|
||||
stuff_string(name, F_NAME, sizeof(name));
|
||||
|
||||
new_storm_type.bolt_types[new_storm_type.num_bolt_types] = nebl_get_bolt_index(name);
|
||||
Assert(new_storm_type.bolt_types[new_storm_type.num_bolt_types] != (size_t)-1);
|
||||
|
||||
new_storm_type.num_bolt_types++;
|
||||
}
|
||||
}
|
||||
|
||||
// flavor
|
||||
required_string("+flavor:");
|
||||
stuff_float(&new_storm_type.flavor.xyz.x);
|
||||
stuff_float(&new_storm_type.flavor.xyz.y);
|
||||
stuff_float(&new_storm_type.flavor.xyz.z);
|
||||
|
||||
// frequencies
|
||||
required_string("+random_freq:");
|
||||
stuff_int(&new_storm_type.min);
|
||||
stuff_int(&new_storm_type.max);
|
||||
|
||||
// counts
|
||||
required_string("+random_count:");
|
||||
stuff_int(&new_storm_type.min_count);
|
||||
stuff_int(&new_storm_type.max_count);
|
||||
|
||||
Storm_types.push_back(new_storm_type);
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "lightning.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// parse the lightning table
|
||||
read_file_text("lightning.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse the individual lightning bolt types
|
||||
required_string("#Bolts begin");
|
||||
while(!optional_string("#Bolts end")){
|
||||
bolt_type new_bolt_type;
|
||||
|
||||
// bolt title
|
||||
required_string("$Bolt:");
|
||||
stuff_string(new_bolt_type.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// b_scale
|
||||
required_string("+b_scale:");
|
||||
stuff_float(&new_bolt_type.b_scale);
|
||||
|
||||
// b_shrink
|
||||
required_string("+b_shrink:");
|
||||
stuff_float(&new_bolt_type.b_shrink);
|
||||
|
||||
// b_poly_pct
|
||||
required_string("+b_poly_pct:");
|
||||
stuff_float(&new_bolt_type.b_poly_pct);
|
||||
|
||||
// child rand
|
||||
required_string("+b_rand:");
|
||||
stuff_float(&new_bolt_type.b_rand);
|
||||
|
||||
// z add
|
||||
required_string("+b_add:");
|
||||
stuff_float(&new_bolt_type.b_add);
|
||||
|
||||
// # strikes
|
||||
required_string("+b_strikes:");
|
||||
stuff_int(&new_bolt_type.num_strikes);
|
||||
|
||||
// lifetime
|
||||
required_string("+b_lifetime:");
|
||||
stuff_int(&new_bolt_type.lifetime);
|
||||
|
||||
// noise
|
||||
required_string("+b_noise:");
|
||||
stuff_float(&new_bolt_type.noise);
|
||||
|
||||
// emp effect
|
||||
required_string("+b_emp:");
|
||||
stuff_float(&new_bolt_type.emp_intensity);
|
||||
stuff_float(&new_bolt_type.emp_time);
|
||||
|
||||
// texture
|
||||
required_string("+b_texture:");
|
||||
stuff_string(name, F_NAME, sizeof(name));
|
||||
if(!Fred_running){
|
||||
new_bolt_type.texture = bm_load(name);
|
||||
}
|
||||
|
||||
// glow
|
||||
required_string("+b_glow:");
|
||||
stuff_string(name, F_NAME, sizeof(name));
|
||||
if(!Fred_running){
|
||||
new_bolt_type.glow = bm_load(name);
|
||||
}
|
||||
|
||||
// brightness
|
||||
required_string("+b_bright:");
|
||||
stuff_float(&new_bolt_type.b_bright);
|
||||
|
||||
Bolt_types.push_back(new_bolt_type);
|
||||
}
|
||||
|
||||
// parse lightning storm types
|
||||
required_string("#Storms begin");
|
||||
while(!optional_string("#Storms end")){
|
||||
storm_type new_storm_type;
|
||||
|
||||
// bolt title
|
||||
required_string("$Storm:");
|
||||
stuff_string(new_storm_type.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// bolt types
|
||||
while(optional_string("+bolt:")){
|
||||
if(new_storm_type.num_bolt_types < MAX_BOLT_TYPES_PER_STORM){
|
||||
stuff_string(name, F_NAME, sizeof(name));
|
||||
|
||||
new_storm_type.bolt_types[new_storm_type.num_bolt_types] = nebl_get_bolt_index(name);
|
||||
Assert(new_storm_type.bolt_types[new_storm_type.num_bolt_types] != (size_t)-1);
|
||||
|
||||
new_storm_type.num_bolt_types++;
|
||||
}
|
||||
}
|
||||
|
||||
// flavor
|
||||
required_string("+flavor:");
|
||||
stuff_float(&new_storm_type.flavor.xyz.x);
|
||||
stuff_float(&new_storm_type.flavor.xyz.y);
|
||||
stuff_float(&new_storm_type.flavor.xyz.z);
|
||||
|
||||
// frequencies
|
||||
required_string("+random_freq:");
|
||||
stuff_int(&new_storm_type.min);
|
||||
stuff_int(&new_storm_type.max);
|
||||
|
||||
// counts
|
||||
required_string("+random_count:");
|
||||
stuff_int(&new_storm_type.min_count);
|
||||
stuff_int(&new_storm_type.max_count);
|
||||
|
||||
Storm_types.push_back(new_storm_type);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize lightning before entering a level
|
||||
|
||||
+22
-20
@@ -64,28 +64,30 @@ int palman_is_nondarkening(int r,int g, int b)
|
||||
|
||||
void palman_load_pixels()
|
||||
{
|
||||
int rval;
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "pixels.tbl", rval));
|
||||
try
|
||||
{
|
||||
// open pixels.tbl
|
||||
read_file_text("pixels.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse pixels
|
||||
while (!optional_string("#END")){
|
||||
// nondarkening pixel
|
||||
if (required_string("+ND")){
|
||||
stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default][0]);
|
||||
stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default][1]);
|
||||
stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default++][2]);
|
||||
}
|
||||
}
|
||||
|
||||
// set this to be the active table
|
||||
palman_set_nondarkening(Palman_non_darkening_default, Palman_num_nondarkening_default);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "pixels.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// open pixels.tbl
|
||||
read_file_text("pixels.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse pixels
|
||||
while(!optional_string("#END")){
|
||||
// nondarkening pixel
|
||||
if(required_string("+ND")){
|
||||
stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default][0]);
|
||||
stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default][1]);
|
||||
stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default++][2]);
|
||||
}
|
||||
}
|
||||
|
||||
// set this to be the active table
|
||||
palman_set_nondarkening(Palman_non_darkening_default, Palman_num_nondarkening_default);
|
||||
}
|
||||
|
||||
void palman_set_nondarkening(ubyte colors[MAX_NONDARK_COLORS][3], int size)
|
||||
|
||||
+41
-41
@@ -43,7 +43,6 @@ int Warning_count, Error_count;
|
||||
int Warning_count_save = 0, Error_count_save = 0;
|
||||
int fred_parse_flag = 0;
|
||||
int Token_found_flag;
|
||||
jmp_buf parse_abort;
|
||||
|
||||
char *Mission_text = NULL;
|
||||
char *Mission_text_raw = NULL;
|
||||
@@ -483,7 +482,7 @@ int required_string(char *pstr)
|
||||
if (count == RS_MAX_TRIES) {
|
||||
nprintf(("Error", "Error: Unable to find required token [%s]\n", pstr));
|
||||
Warning(LOCATION, "Error: Unable to find required token [%s]\n", pstr);
|
||||
longjmp(parse_abort, 1);
|
||||
throw parse::ParseException("Required string not found");
|
||||
}
|
||||
|
||||
Mp += strlen(pstr);
|
||||
@@ -691,8 +690,8 @@ int required_string_either(char *str1, char *str2)
|
||||
|
||||
if (count == RS_MAX_TRIES) {
|
||||
nprintf(("Error", "Error: Unable to find either required token [%s] or [%s]\n", str1, str2));
|
||||
Warning(LOCATION, "Error: Unable to find either required token [%s] or [%s]\n", str1, str2);
|
||||
longjmp(parse_abort, 2);
|
||||
Warning(LOCATION, "Error: Unable to find either required token [%s] or [%s]\n", str1, str2);
|
||||
throw parse::ParseException("Required string not found");
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -887,8 +886,8 @@ char* alloc_text_until(char* instr, char* endstr)
|
||||
|
||||
if(foundstr == NULL)
|
||||
{
|
||||
Error(LOCATION, "Missing [%s] in file");
|
||||
longjmp(parse_abort, 3);
|
||||
Error(LOCATION, "Missing [%s] in file", endstr);
|
||||
throw parse::ParseException("End string not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -922,8 +921,8 @@ void copy_text_until(char *outstr, char *instr, char *endstr, int max_chars)
|
||||
foundstr = stristr(instr, endstr);
|
||||
|
||||
if (foundstr == NULL) {
|
||||
nprintf(("Error", "Error. Looking for [%s], but never found it.\n", endstr));
|
||||
longjmp(parse_abort, 3);
|
||||
nprintf(("Error", "Error. Looking for [%s], but never found it.\n", endstr));
|
||||
throw parse::ParseException("End string not found");
|
||||
}
|
||||
|
||||
if (foundstr - instr + strlen(endstr) < (uint) max_chars) {
|
||||
@@ -934,7 +933,7 @@ void copy_text_until(char *outstr, char *instr, char *endstr, int max_chars)
|
||||
nprintf(("Error", "Error. Too much text (%i chars, %i allowed) before %s\n",
|
||||
foundstr - instr - strlen(endstr), max_chars, endstr));
|
||||
|
||||
longjmp(parse_abort, 4);
|
||||
throw parse::ParseException("Too much text found");
|
||||
}
|
||||
|
||||
diag_printf("Here's the partial wad of text:\n%.30s\n", outstr);
|
||||
@@ -949,8 +948,8 @@ void copy_text_until(SCP_string &outstr, char *instr, char *endstr)
|
||||
foundstr = stristr(instr, endstr);
|
||||
|
||||
if (foundstr == NULL) {
|
||||
nprintf(("Error", "Error. Looking for [%s], but never found it.\n", endstr));
|
||||
longjmp(parse_abort, 3);
|
||||
nprintf(("Error", "Error. Looking for [%s], but never found it.\n", endstr));
|
||||
throw parse::ParseException("End string not found");
|
||||
}
|
||||
|
||||
outstr.assign(instr, foundstr - instr);
|
||||
@@ -1046,8 +1045,8 @@ char* alloc_block(char* startstr, char* endstr, int extra_chars)
|
||||
//Check that we left the file
|
||||
if(level > 0)
|
||||
{
|
||||
Error(LOCATION, "Unclosed pair of \"%s\" and \"%s\" on line %d in file", startstr, endstr, get_line_num());
|
||||
longjmp(parse_abort, 3);
|
||||
Error(LOCATION, "Unclosed pair of \"%s\" and \"%s\" on line %d in file", startstr, endstr, get_line_num());
|
||||
throw parse::ParseException("End string not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1967,8 +1966,9 @@ int parse_get_line(char *lineout, int max_line_len, char *start, int max_size, c
|
||||
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
|
||||
{
|
||||
// copy the filename
|
||||
if (!filename)
|
||||
longjmp(parse_abort, 10);
|
||||
if (!filename)
|
||||
throw parse::ParseException("Invalid filename");
|
||||
|
||||
strcpy_s(Current_filename_sub, filename);
|
||||
|
||||
// if we are paused then processed_text and raw_text must not be NULL!!
|
||||
@@ -2106,16 +2106,16 @@ void read_raw_file_text(const char *filename, int mode, char *raw_text)
|
||||
mf = cfopen(filename, "rb", CFILE_NORMAL, mode);
|
||||
if (mf == NULL)
|
||||
{
|
||||
nprintf(("Error", "Wokka! Error opening file (%s)!\n", filename));
|
||||
longjmp(parse_abort, 5);
|
||||
nprintf(("Error", "Wokka! Error opening file (%s)!\n", filename));
|
||||
throw parse::ParseException("Failed to open file");
|
||||
}
|
||||
|
||||
// read the entire file in
|
||||
int file_len = cfilelength(mf);
|
||||
|
||||
if(!file_len) {
|
||||
nprintf(("Error", "Oh noes!! File is empty! (%s)!\n", filename));
|
||||
longjmp(parse_abort, 5);
|
||||
nprintf(("Error", "Oh noes!! File is empty! (%s)!\n", filename));
|
||||
throw parse::ParseException("Failed to open file");
|
||||
}
|
||||
|
||||
// allocate, or reallocate, memory for Mission_text and Mission_text_raw based on size we need now
|
||||
@@ -2567,8 +2567,8 @@ int stuff_bool_list(bool *blp, int max_bools)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading boolean list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading boolean list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -2665,8 +2665,8 @@ int stuff_string_list(SCP_vector<SCP_string>& slp)
|
||||
ignore_white_space();
|
||||
|
||||
if ( *Mp != '(' ) {
|
||||
error_display(1, "Reading string list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 100);
|
||||
error_display(1, "Reading string list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -2699,8 +2699,8 @@ int stuff_string_list(char slp[][NAME_LENGTH], int max_strings)
|
||||
ignore_white_space();
|
||||
|
||||
if ( *Mp != '(' ) {
|
||||
error_display(1, "Reading string list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 100);
|
||||
error_display(1, "Reading string list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -2756,8 +2756,8 @@ int stuff_int_list(int *ilp, int max_ints, int lookup_type)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading integer list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading integer list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -2858,8 +2858,8 @@ int stuff_loadout_list (int *ilp, int max_ints, int lookup_type)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading loadout list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading loadout list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -2962,8 +2962,8 @@ int stuff_float_list(float* flp, int max_floats)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading float list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading float list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -2995,8 +2995,8 @@ void mark_int_list(int *ilp, int max_ints, int lookup_type)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Marking integer list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Marking integer list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -3062,15 +3062,15 @@ void stuff_parenthesized_vec3d(vec3d *vp)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading parenthesized vec3d. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 11);
|
||||
error_display(1, "Reading parenthesized vec3d. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
} else {
|
||||
Mp++;
|
||||
stuff_vec3d(vp);
|
||||
ignore_white_space();
|
||||
if (*Mp != ')') {
|
||||
error_display(1, "Reading parenthesized vec3d. Found [%c]. Expecting ')'.\n", *Mp);
|
||||
longjmp(parse_abort, 12);
|
||||
error_display(1, "Reading parenthesized vec3d. Found [%c]. Expecting ')'.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
Mp++;
|
||||
}
|
||||
@@ -3089,8 +3089,8 @@ int stuff_vec3d_list(vec3d *vlp, int max_vecs)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading vec3d list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading vec3d list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
@@ -3120,8 +3120,8 @@ int stuff_vec3d_list(SCP_vector<vec3d> &vec_list)
|
||||
ignore_white_space();
|
||||
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading vec3d list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading vec3d list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
|
||||
+11
-4
@@ -14,9 +14,7 @@
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include <csetjmp>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
// NOTE: although the main game doesn't need this anymore, FRED2 still does
|
||||
#define MISSION_TEXT_SIZE 1000000
|
||||
@@ -27,7 +25,6 @@ extern char *Mp;
|
||||
extern char *token_found;
|
||||
extern int fred_parse_flag;
|
||||
extern int Token_found_flag;
|
||||
extern jmp_buf parse_abort;
|
||||
|
||||
|
||||
#define COMMENT_CHAR (char)';'
|
||||
@@ -257,4 +254,14 @@ int get_string_or_variable (SCP_string &str);
|
||||
#define PARSING_FOUND_STRING 0
|
||||
#define PARSING_FOUND_VARIABLE 1
|
||||
|
||||
namespace parse
|
||||
{
|
||||
class ParseException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
ParseException(const std::string& msg) : std::runtime_error(msg) {}
|
||||
~ParseException() throw() {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+54
-52
@@ -109,46 +109,42 @@ bool script_hook_valid(script_hook *hook)
|
||||
void script_parse_table(const char *filename)
|
||||
{
|
||||
script_state *st = &Script_system;
|
||||
int rval;
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
if (optional_string("#Global Hooks"))
|
||||
{
|
||||
//int num = 42;
|
||||
//Script_system.SetHookVar("Version", 'i', &num);
|
||||
if (optional_string("$Global:")) {
|
||||
st->ParseChunk(&Script_globalhook, "Global");
|
||||
}
|
||||
|
||||
if(optional_string("#Global Hooks"))
|
||||
{
|
||||
//int num = 42;
|
||||
//Script_system.SetHookVar("Version", 'i', &num);
|
||||
if(optional_string("$Global:")) {
|
||||
st->ParseChunk(&Script_globalhook, "Global");
|
||||
if (optional_string("$Splash:")) {
|
||||
st->ParseChunk(&Script_splashhook, "Splash");
|
||||
}
|
||||
|
||||
if (optional_string("$GameInit:")) {
|
||||
st->ParseChunk(&Script_gameinithook, "GameInit");
|
||||
}
|
||||
|
||||
if (optional_string("$Simulation:")) {
|
||||
st->ParseChunk(&Script_simulationhook, "Simulation");
|
||||
}
|
||||
|
||||
if (optional_string("$HUD:")) {
|
||||
st->ParseChunk(&Script_hudhook, "HUD");
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if(optional_string("$Splash:")) {
|
||||
st->ParseChunk(&Script_splashhook, "Splash");
|
||||
}
|
||||
|
||||
if(optional_string("$GameInit:")) {
|
||||
st->ParseChunk(&Script_gameinithook, "GameInit");
|
||||
}
|
||||
|
||||
if(optional_string("$Simulation:")) {
|
||||
st->ParseChunk(&Script_simulationhook, "Simulation");
|
||||
}
|
||||
|
||||
if(optional_string("$HUD:")) {
|
||||
st->ParseChunk(&Script_hudhook, "HUD");
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
/*
|
||||
if(optional_string("#State Hooks"))
|
||||
{
|
||||
while(optional_string("$State:")) {
|
||||
/*
|
||||
if(optional_string("#State Hooks"))
|
||||
{
|
||||
while(optional_string("$State:")) {
|
||||
char buf[NAME_LENGTH];
|
||||
int idx;
|
||||
stuff_string(buf, F_NAME, sizeof(buf));
|
||||
@@ -157,25 +153,31 @@ void script_parse_table(const char *filename)
|
||||
|
||||
if(optional_string("$Hook:"))
|
||||
{
|
||||
if(idx > -1) {
|
||||
GS_state_hooks[idx] = st->ParseChunk(buf);
|
||||
} else {
|
||||
st->ParseChunk(buf);
|
||||
}
|
||||
if(idx > -1) {
|
||||
GS_state_hooks[idx] = st->ParseChunk(buf);
|
||||
} else {
|
||||
st->ParseChunk(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
*/
|
||||
if (optional_string("#Conditional Hooks"))
|
||||
{
|
||||
while (st->ParseCondition(filename));
|
||||
required_string("#End");
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
*/
|
||||
if(optional_string("#Conditional Hooks"))
|
||||
{
|
||||
while(st->ParseCondition(filename));
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
fs2netd_add_table_validation(filename);
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Initializes the (global) scripting system, as well as any subsystems.
|
||||
|
||||
+2
-2
@@ -3576,8 +3576,8 @@ int stuff_sexp_variable_list()
|
||||
|
||||
// check for start of list
|
||||
if (*Mp != '(') {
|
||||
error_display(1, "Reading sexp variable list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
longjmp(parse_abort, 6);
|
||||
error_display(1, "Reading sexp variable list. Found [%c]. Expecting '('.\n", *Mp);
|
||||
throw parse::ParseException("Syntax error");
|
||||
}
|
||||
|
||||
Mp++;
|
||||
|
||||
+103
-101
@@ -3934,46 +3934,47 @@ void parse_ship_type()
|
||||
|
||||
void parse_shiptype_tbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
try
|
||||
{
|
||||
if (filename != NULL)
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("objecttypes.tbl"));
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("#Target Priorities"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
parse_ai_target_priorities();
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Weapon Targeting Priorities"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
parse_weapon_targeting_priorities();
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Ship Types"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
parse_ship_type();
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename != NULL)
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
else
|
||||
read_file_text_from_array(defaults_get_file("objecttypes.tbl"));
|
||||
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("#Target Priorities"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
parse_ai_target_priorities();
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Weapon Targeting Priorities"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
parse_weapon_targeting_priorities();
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Ship Types"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
parse_ship_type();
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
|
||||
// The E - Simple lookup function for FRED.
|
||||
@@ -4029,56 +4030,56 @@ void ship_set_default_player_ship()
|
||||
|
||||
void parse_shiptbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse default ship
|
||||
//Override default player ship
|
||||
if (optional_string("#Default Player Ship"))
|
||||
{
|
||||
required_string("$Name:");
|
||||
stuff_string(default_player_ship, F_NAME, sizeof(default_player_ship));
|
||||
required_string("#End");
|
||||
}
|
||||
//Add engine washes
|
||||
//This will override if they already exist
|
||||
if (optional_string("#Engine Wash Info"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
parse_engine_wash(Parsing_modular_table);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
//Add ship classes
|
||||
if (optional_string("#Ship Classes"))
|
||||
{
|
||||
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
if (parse_ship(filename, Parsing_modular_table)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
//Set default player ship
|
||||
ship_set_default_player_ship();
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse default ship
|
||||
//Override default player ship
|
||||
if(optional_string("#Default Player Ship"))
|
||||
{
|
||||
required_string("$Name:");
|
||||
stuff_string(default_player_ship, F_NAME, sizeof(default_player_ship));
|
||||
required_string("#End");
|
||||
}
|
||||
//Add engine washes
|
||||
//This will override if they already exist
|
||||
if(optional_string("#Engine Wash Info"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
parse_engine_wash(Parsing_modular_table);
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
//Add ship classes
|
||||
if(optional_string("#Ship Classes"))
|
||||
{
|
||||
|
||||
while (required_string_either("#End","$Name:"))
|
||||
{
|
||||
if ( parse_ship(filename, Parsing_modular_table) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
//Set default player ship
|
||||
ship_set_default_player_ship();
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
|
||||
int ship_show_velocity_dot = 0;
|
||||
@@ -17481,28 +17482,29 @@ void parse_armor_type()
|
||||
|
||||
void armor_parse_table(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
//Enumerate through all the armor types and add them.
|
||||
while (optional_string("#Armor Type")) {
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
parse_armor_type();
|
||||
continue;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
//Enumerate through all the armor types and add them.
|
||||
while ( optional_string("#Armor Type") ) {
|
||||
while ( required_string_either("#End", "$Name:") ) {
|
||||
parse_armor_type();
|
||||
continue;
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
|
||||
void armor_init()
|
||||
|
||||
+194
-192
@@ -153,203 +153,205 @@ void parse_thrust_glows(species_info *species, bool no_create)
|
||||
|
||||
void parse_species_tbl(const char *filename)
|
||||
{
|
||||
int i, rval;
|
||||
int i;
|
||||
char species_name[NAME_LENGTH];
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : NOX("<default species_defs.tbl>"), rval));
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("species_defs.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
required_string("#SPECIES DEFS");
|
||||
|
||||
// no longer required: counted automatically
|
||||
if (optional_string("$NumSpecies:"))
|
||||
{
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
}
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#END", "$Species_Name:"))
|
||||
{
|
||||
bool no_create = false;
|
||||
species_info *species, new_species;
|
||||
|
||||
species = &new_species;
|
||||
|
||||
// Start Species - Get its name
|
||||
required_string("$Species_Name:");
|
||||
stuff_string(species_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
no_create = true;
|
||||
|
||||
for (i = 0; i < (int)Species_info.size(); i++)
|
||||
{
|
||||
if (!stricmp(Species_info[i].species_name, species_name))
|
||||
{
|
||||
species = &Species_info[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy_s(species->species_name, species_name);
|
||||
}
|
||||
|
||||
// Goober5000 - IFF
|
||||
if (optional_string("$Default IFF:"))
|
||||
{
|
||||
bool iff_found = false;
|
||||
char temp_name[NAME_LENGTH];
|
||||
stuff_string(temp_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// search for it in iffs
|
||||
for (int iLoop = 0; iLoop < Num_iffs; iLoop++)
|
||||
{
|
||||
if (!stricmp(Iff_info[iLoop].iff_name, temp_name))
|
||||
{
|
||||
species->default_iff = iLoop;
|
||||
iff_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!iff_found)
|
||||
{
|
||||
species->default_iff = 0;
|
||||
Warning(LOCATION, "Species %s default IFF %s not found in iff_defs.tbl! Defaulting to %s.\n", species->species_name, temp_name, Iff_info[species->default_iff].iff_name);
|
||||
}
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
// we have no idea which it could be, so default to 0
|
||||
species->default_iff = 0;
|
||||
|
||||
// let them know
|
||||
Warning(LOCATION, "$Default IFF not specified for species %s in species_defs.tbl! Defaulting to %s.\n", species->species_name, Iff_info[species->default_iff].iff_name);
|
||||
}
|
||||
|
||||
// Goober5000 - FRED color
|
||||
if (optional_string("$FRED Color:") || optional_string("$FRED Colour:"))
|
||||
{
|
||||
stuff_int_list(species->fred_color.a1d, 3, RAW_INTEGER_TYPE);
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
// set defaults to Volition's originals
|
||||
if (!stricmp(species->species_name, "Terran"))
|
||||
{
|
||||
species->fred_color.rgb.r = 0;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 192;
|
||||
}
|
||||
else if (!stricmp(species->species_name, "Vasudan"))
|
||||
{
|
||||
species->fred_color.rgb.r = 0;
|
||||
species->fred_color.rgb.g = 128;
|
||||
species->fred_color.rgb.b = 0;
|
||||
}
|
||||
else if (!stricmp(species->species_name, "Shivan"))
|
||||
{
|
||||
species->fred_color.rgb.r = 192;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 0;
|
||||
}
|
||||
else if (!stricmp(species->species_name, "Ancients") || !stricmp(species->species_name, "Ancient"))
|
||||
{
|
||||
species->fred_color.rgb.r = 192;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 192;
|
||||
}
|
||||
else
|
||||
{
|
||||
species->fred_color.rgb.r = 0;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 0;
|
||||
}
|
||||
|
||||
// let them know
|
||||
Warning(LOCATION, "$FRED Color not specified for species %s in species_defs.tbl! Defaulting to (%d, %d, %d).\n", species->species_name, species->fred_color.rgb.r, species->fred_color.rgb.g, species->fred_color.rgb.b);
|
||||
}
|
||||
|
||||
// stuff
|
||||
optional_string("$MiscAnims:");
|
||||
|
||||
// Get its Debris Texture
|
||||
if ((!no_create && required_string("+Debris_Texture:")) || optional_string("+Debris_Texture:"))
|
||||
{
|
||||
generic_bitmap_init(&species->debris_texture, NULL);
|
||||
stuff_string(species->debris_texture.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
|
||||
|
||||
// Shield Hit Animation
|
||||
if (optional_string("+Shield_Hit_ani:")) // Shouldn't be required -- LPine
|
||||
{
|
||||
generic_anim_init(&species->shield_anim, NULL);
|
||||
stuff_string(species->shield_anim.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
species->shield_anim.filename[0] = '\0';
|
||||
species->shield_anim.first_frame = -1; // Landmine to trip up anyone who does end up using this
|
||||
}
|
||||
|
||||
|
||||
// Thruster Anims
|
||||
parse_thrust_anims(species, no_create);
|
||||
|
||||
// Thruster Glow Anims
|
||||
parse_thrust_glows(species, no_create);
|
||||
|
||||
|
||||
// Goober5000 - AWACS multiplier
|
||||
if (optional_string("$AwacsMultiplier:"))
|
||||
{
|
||||
stuff_float(&species->awacs_multiplier);
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
// set defaults to Volition's originals
|
||||
if (!stricmp(species->species_name, "Vasudan"))
|
||||
species->awacs_multiplier = 1.25f;
|
||||
else if (!stricmp(species->species_name, "Shivan"))
|
||||
species->awacs_multiplier = 1.50f;
|
||||
else
|
||||
species->awacs_multiplier = 1.0f;
|
||||
|
||||
// let them know
|
||||
Warning(LOCATION, "$AwacsMultiplier not specified for species %s in species_defs.tbl! Defaulting to %.2d.\n", species->species_name, species->awacs_multiplier);
|
||||
}
|
||||
|
||||
// Goober5000 - countermeasure type
|
||||
// (we won't be able to resolve it until after we've parsed the weapons table)
|
||||
if (optional_string("$Countermeasure type:"))
|
||||
stuff_string(species->cmeasure_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// don't add new entry if this is just a modified one
|
||||
if (!no_create)
|
||||
Species_info.push_back(new_species);
|
||||
}
|
||||
|
||||
required_string("#END");
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", (filename) ? filename : NOX("<default species_defs.tbl>"), e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
read_file_text_from_array(defaults_get_file("species_defs.tbl"));
|
||||
else
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
|
||||
reset_parse();
|
||||
|
||||
|
||||
// start parsing
|
||||
required_string("#SPECIES DEFS");
|
||||
|
||||
// no longer required: counted automatically
|
||||
if (optional_string("$NumSpecies:"))
|
||||
{
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
}
|
||||
|
||||
// begin reading data
|
||||
while (required_string_either("#END","$Species_Name:"))
|
||||
{
|
||||
bool no_create = false;
|
||||
species_info *species, new_species;
|
||||
|
||||
species = &new_species;
|
||||
|
||||
// Start Species - Get its name
|
||||
required_string("$Species_Name:");
|
||||
stuff_string(species_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (optional_string("+nocreate"))
|
||||
{
|
||||
no_create = true;
|
||||
|
||||
for (i = 0; i < (int)Species_info.size(); i++)
|
||||
{
|
||||
if (!stricmp(Species_info[i].species_name, species_name))
|
||||
{
|
||||
species = &Species_info[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy_s(species->species_name, species_name);
|
||||
}
|
||||
|
||||
// Goober5000 - IFF
|
||||
if (optional_string("$Default IFF:"))
|
||||
{
|
||||
bool iff_found = false;
|
||||
char temp_name[NAME_LENGTH];
|
||||
stuff_string(temp_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// search for it in iffs
|
||||
for (int iLoop = 0; iLoop < Num_iffs; iLoop++)
|
||||
{
|
||||
if (!stricmp(Iff_info[iLoop].iff_name, temp_name))
|
||||
{
|
||||
species->default_iff = iLoop;
|
||||
iff_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!iff_found)
|
||||
{
|
||||
species->default_iff = 0;
|
||||
Warning(LOCATION, "Species %s default IFF %s not found in iff_defs.tbl! Defaulting to %s.\n", species->species_name, temp_name, Iff_info[species->default_iff].iff_name);
|
||||
}
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
// we have no idea which it could be, so default to 0
|
||||
species->default_iff = 0;
|
||||
|
||||
// let them know
|
||||
Warning(LOCATION, "$Default IFF not specified for species %s in species_defs.tbl! Defaulting to %s.\n", species->species_name, Iff_info[species->default_iff].iff_name);
|
||||
}
|
||||
|
||||
// Goober5000 - FRED color
|
||||
if (optional_string("$FRED Color:") || optional_string("$FRED Colour:"))
|
||||
{
|
||||
stuff_int_list(species->fred_color.a1d, 3, RAW_INTEGER_TYPE);
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
// set defaults to Volition's originals
|
||||
if (!stricmp(species->species_name, "Terran"))
|
||||
{
|
||||
species->fred_color.rgb.r = 0;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 192;
|
||||
}
|
||||
else if (!stricmp(species->species_name, "Vasudan"))
|
||||
{
|
||||
species->fred_color.rgb.r = 0;
|
||||
species->fred_color.rgb.g = 128;
|
||||
species->fred_color.rgb.b = 0;
|
||||
}
|
||||
else if (!stricmp(species->species_name, "Shivan"))
|
||||
{
|
||||
species->fred_color.rgb.r = 192;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 0;
|
||||
}
|
||||
else if (!stricmp(species->species_name, "Ancients") || !stricmp(species->species_name, "Ancient"))
|
||||
{
|
||||
species->fred_color.rgb.r = 192;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 192;
|
||||
}
|
||||
else
|
||||
{
|
||||
species->fred_color.rgb.r = 0;
|
||||
species->fred_color.rgb.g = 0;
|
||||
species->fred_color.rgb.b = 0;
|
||||
}
|
||||
|
||||
// let them know
|
||||
Warning(LOCATION, "$FRED Color not specified for species %s in species_defs.tbl! Defaulting to (%d, %d, %d).\n", species->species_name, species->fred_color.rgb.r, species->fred_color.rgb.g, species->fred_color.rgb.b);
|
||||
}
|
||||
|
||||
// stuff
|
||||
optional_string("$MiscAnims:");
|
||||
|
||||
// Get its Debris Texture
|
||||
if ((!no_create && required_string("+Debris_Texture:")) || optional_string("+Debris_Texture:"))
|
||||
{
|
||||
generic_bitmap_init(&species->debris_texture, NULL);
|
||||
stuff_string(species->debris_texture.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
|
||||
|
||||
// Shield Hit Animation
|
||||
if (optional_string("+Shield_Hit_ani:")) // Shouldn't be required -- LPine
|
||||
{
|
||||
generic_anim_init(&species->shield_anim, NULL);
|
||||
stuff_string(species->shield_anim.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
species->shield_anim.filename[0] = '\0';
|
||||
species->shield_anim.first_frame = -1; // Landmine to trip up anyone who does end up using this
|
||||
}
|
||||
|
||||
|
||||
// Thruster Anims
|
||||
parse_thrust_anims(species, no_create);
|
||||
|
||||
// Thruster Glow Anims
|
||||
parse_thrust_glows(species, no_create);
|
||||
|
||||
|
||||
// Goober5000 - AWACS multiplier
|
||||
if (optional_string("$AwacsMultiplier:"))
|
||||
{
|
||||
stuff_float(&species->awacs_multiplier);
|
||||
}
|
||||
else if (!no_create)
|
||||
{
|
||||
// set defaults to Volition's originals
|
||||
if (!stricmp(species->species_name, "Vasudan"))
|
||||
species->awacs_multiplier = 1.25f;
|
||||
else if (!stricmp(species->species_name, "Shivan"))
|
||||
species->awacs_multiplier = 1.50f;
|
||||
else
|
||||
species->awacs_multiplier = 1.0f;
|
||||
|
||||
// let them know
|
||||
Warning(LOCATION, "$AwacsMultiplier not specified for species %s in species_defs.tbl! Defaulting to %.2d.\n", species->species_name, species->awacs_multiplier);
|
||||
}
|
||||
|
||||
// Goober5000 - countermeasure type
|
||||
// (we won't be able to resolve it until after we've parsed the weapons table)
|
||||
if (optional_string("$Countermeasure type:"))
|
||||
stuff_string(species->cmeasure_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
// don't add new entry if this is just a modified one
|
||||
if ( !no_create )
|
||||
Species_info.push_back( new_species );
|
||||
}
|
||||
|
||||
required_string("#END");
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
extern void fs2netd_add_table_validation(const char *tblname);
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
|
||||
int Species_initted = 0;
|
||||
|
||||
+181
-172
@@ -404,183 +404,192 @@ void parse_startbl(const char *filename)
|
||||
{
|
||||
char name[MAX_FILENAME_LEN], tempf[16];
|
||||
starfield_bitmap sbm;
|
||||
int idx, rval;
|
||||
int idx;
|
||||
bool in_check = false;
|
||||
int rc = -1;
|
||||
int run_count = 0;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// freaky! ;)
|
||||
while (!check_for_eof()) {
|
||||
while ((rc = optional_string_either("$Bitmap:", "$BitmapX:")) != -1) {
|
||||
in_check = true;
|
||||
|
||||
starfield_bitmap_entry_init(&sbm);
|
||||
|
||||
stuff_string(sbm.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
sbm.xparent = rc; // 0 == intensity alpha bitmap, 1 == green xparency bitmap
|
||||
|
||||
if ((idx = stars_find_bitmap(sbm.filename)) >= 0) {
|
||||
if (sbm.xparent == Starfield_bitmaps[idx].xparent) {
|
||||
if (!Parsing_modular_table)
|
||||
Warning(LOCATION, "Starfield bitmap '%s' listed more than once!! Only using the first entry!", sbm.filename);
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Starfield bitmap '%s' already listed as a %sxparent bitmap!! Only using the xparent version!",
|
||||
(rc) ? "xparent" : "non-xparent", (rc) ? "xparent" : "non-xparent", sbm.filename);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Starfield_bitmaps.push_back(sbm);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
while (optional_string("$Sun:")) {
|
||||
in_check = true;
|
||||
|
||||
starfield_bitmap_entry_init(&sbm);
|
||||
|
||||
stuff_string(sbm.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// associated glow
|
||||
required_string("$Sunglow:");
|
||||
stuff_string(sbm.glow_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// associated lighting values
|
||||
required_string("$SunRGBI:");
|
||||
stuff_float(&sbm.r);
|
||||
stuff_float(&sbm.g);
|
||||
stuff_float(&sbm.b);
|
||||
stuff_float(&sbm.i);
|
||||
|
||||
if (optional_string("$SunSpecularRGB:")) {
|
||||
stuff_float(&sbm.spec_r);
|
||||
stuff_float(&sbm.spec_g);
|
||||
stuff_float(&sbm.spec_b);
|
||||
}
|
||||
else {
|
||||
sbm.spec_r = sbm.r;
|
||||
sbm.spec_g = sbm.g;
|
||||
sbm.spec_b = sbm.b;
|
||||
}
|
||||
|
||||
// lens flare stuff
|
||||
if (optional_string("$Flare:")) {
|
||||
sbm.flare = 1;
|
||||
|
||||
required_string("+FlareCount:");
|
||||
stuff_int(&sbm.n_flares);
|
||||
|
||||
// if there's a flare, it has to have at least one texture
|
||||
required_string("$FlareTexture1:");
|
||||
stuff_string(sbm.flare_bitmaps[0].filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
sbm.n_flare_bitmaps = 1;
|
||||
|
||||
for (idx = 1; idx < MAX_FLARE_BMP; idx++) {
|
||||
// allow 9999 textures (theoretically speaking, that is)
|
||||
sprintf(tempf, "$FlareTexture%d:", idx + 1);
|
||||
|
||||
if (optional_string(tempf)) {
|
||||
sbm.n_flare_bitmaps++;
|
||||
stuff_string(sbm.flare_bitmaps[idx].filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
// else break; //don't allow flaretexture1 and then 3, etc.
|
||||
}
|
||||
|
||||
required_string("$FlareGlow1:");
|
||||
|
||||
required_string("+FlareTexture:");
|
||||
stuff_int(&sbm.flare_infos[0].tex_num);
|
||||
|
||||
required_string("+FlarePos:");
|
||||
stuff_float(&sbm.flare_infos[0].pos);
|
||||
|
||||
required_string("+FlareScale:");
|
||||
stuff_float(&sbm.flare_infos[0].scale);
|
||||
|
||||
sbm.n_flares = 1;
|
||||
|
||||
for (idx = 1; idx < MAX_FLARE_COUNT; idx++) {
|
||||
// allow a lot of glows
|
||||
sprintf(tempf, "$FlareGlow%d:", idx + 1);
|
||||
|
||||
if (optional_string(tempf)) {
|
||||
sbm.n_flares++;
|
||||
|
||||
required_string("+FlareTexture:");
|
||||
stuff_int(&sbm.flare_infos[idx].tex_num);
|
||||
|
||||
required_string("+FlarePos:");
|
||||
stuff_float(&sbm.flare_infos[idx].pos);
|
||||
|
||||
required_string("+FlareScale:");
|
||||
stuff_float(&sbm.flare_infos[idx].scale);
|
||||
}
|
||||
// else break; //don't allow "flare 1" and then "flare 3"
|
||||
}
|
||||
}
|
||||
|
||||
sbm.glare = !optional_string("$NoGlare:");
|
||||
|
||||
sbm.xparent = 1;
|
||||
|
||||
if ((idx = stars_find_sun(sbm.filename)) >= 0) {
|
||||
if (Parsing_modular_table)
|
||||
Sun_bitmaps[idx] = sbm;
|
||||
else
|
||||
Warning(LOCATION, "Sun bitmap '%s' listed more than once!! Only using the first entry!", sbm.filename);
|
||||
}
|
||||
else {
|
||||
Sun_bitmaps.push_back(sbm);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
// normal debris pieces
|
||||
while (optional_string("$Debris:")) {
|
||||
in_check = true;
|
||||
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (Num_debris_normal < MAX_DEBRIS_VCLIPS) {
|
||||
strcpy_s(Debris_vclips_normal[Num_debris_normal++].name, name);
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Could not load normal motion debris '%s'; maximum of %d exceeded.", name, MAX_DEBRIS_VCLIPS);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
// nebula debris pieces
|
||||
while (optional_string("$DebrisNeb:")) {
|
||||
in_check = true;
|
||||
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (Num_debris_nebula < MAX_DEBRIS_VCLIPS) {
|
||||
strcpy_s(Debris_vclips_nebula[Num_debris_nebula++].name, name);
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Could not load nebula motion debris '%s'; maximum of %d exceeded.", name, MAX_DEBRIS_VCLIPS);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
// since it's possible for some idiot to have a tbl screwed up enough
|
||||
// that this ends up in an endless loop, give an opportunity to advance
|
||||
// through the file no matter what, because even the retail tbl has an
|
||||
// extra "#end" line in it.
|
||||
if (optional_string("#end") || (run_count++ > 5)) {
|
||||
run_count = 0;
|
||||
advance_to_eoln(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// freaky! ;)
|
||||
while ( !check_for_eof() ) {
|
||||
while ( (rc = optional_string_either("$Bitmap:", "$BitmapX:")) != -1 ) {
|
||||
in_check = true;
|
||||
|
||||
starfield_bitmap_entry_init( &sbm );
|
||||
|
||||
stuff_string(sbm.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
sbm.xparent = rc; // 0 == intensity alpha bitmap, 1 == green xparency bitmap
|
||||
|
||||
if ( (idx = stars_find_bitmap(sbm.filename)) >= 0 ) {
|
||||
if (sbm.xparent == Starfield_bitmaps[idx].xparent) {
|
||||
if ( !Parsing_modular_table )
|
||||
Warning(LOCATION, "Starfield bitmap '%s' listed more than once!! Only using the first entry!", sbm.filename);
|
||||
} else {
|
||||
Warning(LOCATION, "Starfield bitmap '%s' already listed as a %sxparent bitmap!! Only using the xparent version!",
|
||||
(rc) ? "xparent" : "non-xparent", (rc) ? "xparent" : "non-xparent", sbm.filename);
|
||||
}
|
||||
} else {
|
||||
Starfield_bitmaps.push_back(sbm);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
while ( optional_string("$Sun:") ) {
|
||||
in_check = true;
|
||||
|
||||
starfield_bitmap_entry_init( &sbm );
|
||||
|
||||
stuff_string(sbm.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// associated glow
|
||||
required_string("$Sunglow:");
|
||||
stuff_string(sbm.glow_filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
// associated lighting values
|
||||
required_string("$SunRGBI:");
|
||||
stuff_float(&sbm.r);
|
||||
stuff_float(&sbm.g);
|
||||
stuff_float(&sbm.b);
|
||||
stuff_float(&sbm.i);
|
||||
|
||||
if ( optional_string("$SunSpecularRGB:") ) {
|
||||
stuff_float(&sbm.spec_r);
|
||||
stuff_float(&sbm.spec_g);
|
||||
stuff_float(&sbm.spec_b);
|
||||
} else {
|
||||
sbm.spec_r = sbm.r;
|
||||
sbm.spec_g = sbm.g;
|
||||
sbm.spec_b = sbm.b;
|
||||
}
|
||||
|
||||
// lens flare stuff
|
||||
if ( optional_string("$Flare:") ) {
|
||||
sbm.flare = 1;
|
||||
|
||||
required_string("+FlareCount:");
|
||||
stuff_int(&sbm.n_flares);
|
||||
|
||||
// if there's a flare, it has to have at least one texture
|
||||
required_string("$FlareTexture1:");
|
||||
stuff_string(sbm.flare_bitmaps[0].filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
sbm.n_flare_bitmaps = 1;
|
||||
|
||||
for (idx = 1; idx < MAX_FLARE_BMP; idx++) {
|
||||
// allow 9999 textures (theoretically speaking, that is)
|
||||
sprintf(tempf, "$FlareTexture%d:", idx+1);
|
||||
|
||||
if (optional_string(tempf)) {
|
||||
sbm.n_flare_bitmaps++;
|
||||
stuff_string(sbm.flare_bitmaps[idx].filename, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
// else break; //don't allow flaretexture1 and then 3, etc.
|
||||
}
|
||||
|
||||
required_string("$FlareGlow1:");
|
||||
|
||||
required_string("+FlareTexture:");
|
||||
stuff_int(&sbm.flare_infos[0].tex_num);
|
||||
|
||||
required_string("+FlarePos:");
|
||||
stuff_float(&sbm.flare_infos[0].pos);
|
||||
|
||||
required_string("+FlareScale:");
|
||||
stuff_float(&sbm.flare_infos[0].scale);
|
||||
|
||||
sbm.n_flares = 1;
|
||||
|
||||
for (idx = 1; idx < MAX_FLARE_COUNT; idx++) {
|
||||
// allow a lot of glows
|
||||
sprintf(tempf, "$FlareGlow%d:", idx+1);
|
||||
|
||||
if (optional_string(tempf)) {
|
||||
sbm.n_flares++;
|
||||
|
||||
required_string("+FlareTexture:");
|
||||
stuff_int(&sbm.flare_infos[idx].tex_num);
|
||||
|
||||
required_string("+FlarePos:");
|
||||
stuff_float(&sbm.flare_infos[idx].pos);
|
||||
|
||||
required_string("+FlareScale:");
|
||||
stuff_float(&sbm.flare_infos[idx].scale);
|
||||
}
|
||||
// else break; //don't allow "flare 1" and then "flare 3"
|
||||
}
|
||||
}
|
||||
|
||||
sbm.glare = !optional_string("$NoGlare:");
|
||||
|
||||
sbm.xparent = 1;
|
||||
|
||||
if ( (idx = stars_find_sun(sbm.filename)) >= 0 ) {
|
||||
if (Parsing_modular_table)
|
||||
Sun_bitmaps[idx] = sbm;
|
||||
else
|
||||
Warning(LOCATION, "Sun bitmap '%s' listed more than once!! Only using the first entry!", sbm.filename);
|
||||
} else {
|
||||
Sun_bitmaps.push_back(sbm);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
// normal debris pieces
|
||||
while ( optional_string("$Debris:") ) {
|
||||
in_check = true;
|
||||
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (Num_debris_normal < MAX_DEBRIS_VCLIPS) {
|
||||
strcpy_s(Debris_vclips_normal[Num_debris_normal++].name, name);
|
||||
} else {
|
||||
Warning(LOCATION, "Could not load normal motion debris '%s'; maximum of %d exceeded.", name, MAX_DEBRIS_VCLIPS);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
// nebula debris pieces
|
||||
while ( optional_string("$DebrisNeb:") ) {
|
||||
in_check = true;
|
||||
|
||||
stuff_string(name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (Num_debris_nebula < MAX_DEBRIS_VCLIPS) {
|
||||
strcpy_s(Debris_vclips_nebula[Num_debris_nebula++].name, name);
|
||||
} else {
|
||||
Warning(LOCATION, "Could not load nebula motion debris '%s'; maximum of %d exceeded.", name, MAX_DEBRIS_VCLIPS);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_END();
|
||||
|
||||
// since it's possible for some idiot to have a tbl screwed up enough
|
||||
// that this ends up in an endless loop, give an opportunity to advance
|
||||
// through the file no matter what, because even the retail tbl has an
|
||||
// extra "#end" line in it.
|
||||
if ( optional_string("#end") || (run_count++ > 5) ) {
|
||||
run_count = 0;
|
||||
advance_to_eoln(NULL);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+175
-160
@@ -245,190 +245,205 @@ const medal_stuff &medal_stuff::operator=(const medal_stuff &m)
|
||||
|
||||
void parse_medal_tbl()
|
||||
{
|
||||
int rval, i;
|
||||
int i;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "medals.tbl", rval));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text("medals.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Medals");
|
||||
|
||||
// special background information
|
||||
if (optional_string("+Background Bitmap:")) {
|
||||
stuff_string(Medals_background_filename, F_NAME, NAME_LENGTH);
|
||||
} else {
|
||||
strcpy_s(Medals_background_filename, Default_medals_background_filename);
|
||||
}
|
||||
|
||||
// special mask information
|
||||
if (optional_string("+Mask Bitmap:")) {
|
||||
stuff_string(Medals_mask_filename, F_NAME, NAME_LENGTH);
|
||||
} else {
|
||||
strcpy_s(Medals_mask_filename, Default_medals_mask_filename);
|
||||
}
|
||||
|
||||
// special positioning for player callsign
|
||||
if (optional_string("+Callsign Position 640:")) {
|
||||
stuff_int(&Medals_callsign_coords[GR_640].x);
|
||||
stuff_int(&Medals_callsign_coords[GR_640].y);
|
||||
} else {
|
||||
Medals_callsign_coords[GR_640].x = Default_medals_callsign_coords[GR_640][0];
|
||||
Medals_callsign_coords[GR_640].y = Default_medals_callsign_coords[GR_640][1];
|
||||
}
|
||||
if (optional_string("+Callsign Position 1024:")) {
|
||||
stuff_int(&Medals_callsign_coords[GR_1024].x);
|
||||
stuff_int(&Medals_callsign_coords[GR_1024].y);
|
||||
} else {
|
||||
Medals_callsign_coords[GR_1024].x = Default_medals_callsign_coords[GR_1024][0];
|
||||
Medals_callsign_coords[GR_1024].y = Default_medals_callsign_coords[GR_1024][1];
|
||||
}
|
||||
|
||||
// special positioning for medal label
|
||||
if (optional_string("+Label Position 640:")) {
|
||||
stuff_int(&Medals_label_coords[GR_640].x);
|
||||
stuff_int(&Medals_label_coords[GR_640].y);
|
||||
stuff_int(&Medals_label_coords[GR_640].w);
|
||||
} else {
|
||||
Medals_label_coords[GR_640].x = Default_medals_label_coords[GR_640][0];
|
||||
Medals_label_coords[GR_640].y = Default_medals_label_coords[GR_640][1];
|
||||
Medals_label_coords[GR_640].w = Default_medals_label_coords[GR_640][2];
|
||||
}
|
||||
if (optional_string("+Label Position 1024:")) {
|
||||
stuff_int(&Medals_label_coords[GR_1024].x);
|
||||
stuff_int(&Medals_label_coords[GR_1024].y);
|
||||
stuff_int(&Medals_label_coords[GR_1024].w);
|
||||
} else {
|
||||
Medals_label_coords[GR_1024].x = Default_medals_label_coords[GR_1024][0];
|
||||
Medals_label_coords[GR_1024].y = Default_medals_label_coords[GR_1024][1];
|
||||
Medals_label_coords[GR_1024].w = Default_medals_label_coords[GR_1024][2];
|
||||
}
|
||||
|
||||
// parse in all the medal names
|
||||
Num_medals = 0;
|
||||
while ( required_string_either("#End", "$Name:") )
|
||||
try
|
||||
{
|
||||
medal_stuff temp_medal;
|
||||
medal_display_info temp_display;
|
||||
read_file_text("medals.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string( temp_medal.name, F_NAME, NAME_LENGTH );
|
||||
required_string("#Medals");
|
||||
|
||||
// is this rank? if so, save it
|
||||
if (!stricmp(temp_medal.name, "Rank"))
|
||||
Rank_medal_index = Num_medals;
|
||||
|
||||
required_string("$Bitmap:");
|
||||
stuff_string( temp_medal.bitmap, F_NAME, MAX_FILENAME_LEN );
|
||||
|
||||
if (optional_string("+Position 640:")) {
|
||||
stuff_int(&temp_display.coords[GR_640].x);
|
||||
stuff_int(&temp_display.coords[GR_640].y);
|
||||
} else if (Num_medals < NUM_MEDALS_FS2) {
|
||||
temp_display.coords[GR_640].x = Default_medal_coords[GR_640][Num_medals][0];
|
||||
temp_display.coords[GR_640].y = Default_medal_coords[GR_640][Num_medals][1];
|
||||
} else {
|
||||
Warning(LOCATION, "No default GR_640 position for medal '%s'!", temp_medal.name);
|
||||
temp_display.coords[GR_640].x = 0;
|
||||
temp_display.coords[GR_640].y = 0;
|
||||
// special background information
|
||||
if (optional_string("+Background Bitmap:")) {
|
||||
stuff_string(Medals_background_filename, F_NAME, NAME_LENGTH);
|
||||
}
|
||||
if (optional_string("+Position 1024:")) {
|
||||
stuff_int(&temp_display.coords[GR_1024].x);
|
||||
stuff_int(&temp_display.coords[GR_1024].y);
|
||||
} else if (Num_medals < NUM_MEDALS_FS2) {
|
||||
temp_display.coords[GR_1024].x = Default_medal_coords[GR_1024][Num_medals][0];
|
||||
temp_display.coords[GR_1024].y = Default_medal_coords[GR_1024][Num_medals][1];
|
||||
} else {
|
||||
Warning(LOCATION, "No default GR_1024 position for medal '%s'!", temp_medal.name);
|
||||
temp_display.coords[GR_1024].x = 0;
|
||||
temp_display.coords[GR_1024].y = 0;
|
||||
else {
|
||||
strcpy_s(Medals_background_filename, Default_medals_background_filename);
|
||||
}
|
||||
|
||||
if (optional_string("+Debriefing Bitmap:")) {
|
||||
stuff_string( temp_medal.debrief_bitmap, F_NAME, MAX_FILENAME_LEN );
|
||||
} else if (Num_medals < NUM_MEDALS_FS2) {
|
||||
strcpy_s(temp_medal.debrief_bitmap, Default_debriefing_bitmaps[Num_medals]);
|
||||
} else {
|
||||
Warning(LOCATION, "No default debriefing bitmap for medal '%s'!", temp_medal.name);
|
||||
strcpy_s(temp_medal.debrief_bitmap, "");
|
||||
// special mask information
|
||||
if (optional_string("+Mask Bitmap:")) {
|
||||
stuff_string(Medals_mask_filename, F_NAME, NAME_LENGTH);
|
||||
}
|
||||
else {
|
||||
strcpy_s(Medals_mask_filename, Default_medals_mask_filename);
|
||||
}
|
||||
|
||||
required_string("$Num mods:");
|
||||
stuff_int( &temp_medal.num_versions );
|
||||
|
||||
// this is dumb
|
||||
temp_medal.version_starts_at_1 = (Num_medals == Rank_medal_index);
|
||||
if (optional_string("+Version starts at 1:")) {
|
||||
stuff_boolean( &temp_medal.version_starts_at_1 );
|
||||
// special positioning for player callsign
|
||||
if (optional_string("+Callsign Position 640:")) {
|
||||
stuff_int(&Medals_callsign_coords[GR_640].x);
|
||||
stuff_int(&Medals_callsign_coords[GR_640].y);
|
||||
}
|
||||
else {
|
||||
Medals_callsign_coords[GR_640].x = Default_medals_callsign_coords[GR_640][0];
|
||||
Medals_callsign_coords[GR_640].y = Default_medals_callsign_coords[GR_640][1];
|
||||
}
|
||||
if (optional_string("+Callsign Position 1024:")) {
|
||||
stuff_int(&Medals_callsign_coords[GR_1024].x);
|
||||
stuff_int(&Medals_callsign_coords[GR_1024].y);
|
||||
}
|
||||
else {
|
||||
Medals_callsign_coords[GR_1024].x = Default_medals_callsign_coords[GR_1024][0];
|
||||
Medals_callsign_coords[GR_1024].y = Default_medals_callsign_coords[GR_1024][1];
|
||||
}
|
||||
|
||||
if (optional_string("+Available From Start:")) {
|
||||
stuff_boolean( &temp_medal.available_from_start );
|
||||
// special positioning for medal label
|
||||
if (optional_string("+Label Position 640:")) {
|
||||
stuff_int(&Medals_label_coords[GR_640].x);
|
||||
stuff_int(&Medals_label_coords[GR_640].y);
|
||||
stuff_int(&Medals_label_coords[GR_640].w);
|
||||
}
|
||||
else {
|
||||
Medals_label_coords[GR_640].x = Default_medals_label_coords[GR_640][0];
|
||||
Medals_label_coords[GR_640].y = Default_medals_label_coords[GR_640][1];
|
||||
Medals_label_coords[GR_640].w = Default_medals_label_coords[GR_640][2];
|
||||
}
|
||||
if (optional_string("+Label Position 1024:")) {
|
||||
stuff_int(&Medals_label_coords[GR_1024].x);
|
||||
stuff_int(&Medals_label_coords[GR_1024].y);
|
||||
stuff_int(&Medals_label_coords[GR_1024].w);
|
||||
}
|
||||
else {
|
||||
Medals_label_coords[GR_1024].x = Default_medals_label_coords[GR_1024][0];
|
||||
Medals_label_coords[GR_1024].y = Default_medals_label_coords[GR_1024][1];
|
||||
Medals_label_coords[GR_1024].w = Default_medals_label_coords[GR_1024][2];
|
||||
}
|
||||
|
||||
// some medals are based on kill counts. When string +Num Kills: is present, we know that
|
||||
// this medal is a badge and should be treated specially
|
||||
if ( optional_string("+Num Kills:") ) {
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
int persona;
|
||||
stuff_int( &temp_medal.kills_needed );
|
||||
// parse in all the medal names
|
||||
Num_medals = 0;
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
medal_stuff temp_medal;
|
||||
medal_display_info temp_display;
|
||||
|
||||
if (optional_string("$Wavefile 1:"))
|
||||
stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
required_string("$Name:");
|
||||
stuff_string(temp_medal.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
if (optional_string("$Wavefile 2:"))
|
||||
stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
// is this rank? if so, save it
|
||||
if (!stricmp(temp_medal.name, "Rank"))
|
||||
Rank_medal_index = Num_medals;
|
||||
|
||||
if (optional_string("$Wavefile Base:"))
|
||||
stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
required_string("$Bitmap:");
|
||||
stuff_string(temp_medal.bitmap, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
while (check_for_string("$Promotion Text:")) {
|
||||
required_string("$Promotion Text:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
persona = -1;
|
||||
if (optional_string("+Persona:")) {
|
||||
stuff_int(&persona);
|
||||
if (persona < 0) {
|
||||
Warning(LOCATION, "Debriefing text for %s is assigned to an invalid persona: %i (must be 0 or greater).\n", temp_medal.name, persona);
|
||||
continue;
|
||||
if (optional_string("+Position 640:")) {
|
||||
stuff_int(&temp_display.coords[GR_640].x);
|
||||
stuff_int(&temp_display.coords[GR_640].y);
|
||||
}
|
||||
else if (Num_medals < NUM_MEDALS_FS2) {
|
||||
temp_display.coords[GR_640].x = Default_medal_coords[GR_640][Num_medals][0];
|
||||
temp_display.coords[GR_640].y = Default_medal_coords[GR_640][Num_medals][1];
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "No default GR_640 position for medal '%s'!", temp_medal.name);
|
||||
temp_display.coords[GR_640].x = 0;
|
||||
temp_display.coords[GR_640].y = 0;
|
||||
}
|
||||
if (optional_string("+Position 1024:")) {
|
||||
stuff_int(&temp_display.coords[GR_1024].x);
|
||||
stuff_int(&temp_display.coords[GR_1024].y);
|
||||
}
|
||||
else if (Num_medals < NUM_MEDALS_FS2) {
|
||||
temp_display.coords[GR_1024].x = Default_medal_coords[GR_1024][Num_medals][0];
|
||||
temp_display.coords[GR_1024].y = Default_medal_coords[GR_1024][Num_medals][1];
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "No default GR_1024 position for medal '%s'!", temp_medal.name);
|
||||
temp_display.coords[GR_1024].x = 0;
|
||||
temp_display.coords[GR_1024].y = 0;
|
||||
}
|
||||
|
||||
if (optional_string("+Debriefing Bitmap:")) {
|
||||
stuff_string(temp_medal.debrief_bitmap, F_NAME, MAX_FILENAME_LEN);
|
||||
}
|
||||
else if (Num_medals < NUM_MEDALS_FS2) {
|
||||
strcpy_s(temp_medal.debrief_bitmap, Default_debriefing_bitmaps[Num_medals]);
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "No default debriefing bitmap for medal '%s'!", temp_medal.name);
|
||||
strcpy_s(temp_medal.debrief_bitmap, "");
|
||||
}
|
||||
|
||||
required_string("$Num mods:");
|
||||
stuff_int(&temp_medal.num_versions);
|
||||
|
||||
// this is dumb
|
||||
temp_medal.version_starts_at_1 = (Num_medals == Rank_medal_index);
|
||||
if (optional_string("+Version starts at 1:")) {
|
||||
stuff_boolean(&temp_medal.version_starts_at_1);
|
||||
}
|
||||
|
||||
if (optional_string("+Available From Start:")) {
|
||||
stuff_boolean(&temp_medal.available_from_start);
|
||||
}
|
||||
|
||||
// some medals are based on kill counts. When string +Num Kills: is present, we know that
|
||||
// this medal is a badge and should be treated specially
|
||||
if (optional_string("+Num Kills:")) {
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
int persona;
|
||||
stuff_int(&temp_medal.kills_needed);
|
||||
|
||||
if (optional_string("$Wavefile 1:"))
|
||||
stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (optional_string("$Wavefile 2:"))
|
||||
stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (optional_string("$Wavefile Base:"))
|
||||
stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
while (check_for_string("$Promotion Text:")) {
|
||||
required_string("$Promotion Text:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
persona = -1;
|
||||
if (optional_string("+Persona:")) {
|
||||
stuff_int(&persona);
|
||||
if (persona < 0) {
|
||||
Warning(LOCATION, "Debriefing text for %s is assigned to an invalid persona: %i (must be 0 or greater).\n", temp_medal.name, persona);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
temp_medal.promotion_text[persona] = vm_strdup(buf);
|
||||
}
|
||||
if (temp_medal.promotion_text.find(-1) == temp_medal.promotion_text.end()) {
|
||||
Warning(LOCATION, "%s medal is missing default debriefing text.\n", temp_medal.name);
|
||||
temp_medal.promotion_text[-1] = "";
|
||||
}
|
||||
temp_medal.promotion_text[persona] = vm_strdup(buf);
|
||||
}
|
||||
if (temp_medal.promotion_text.find(-1) == temp_medal.promotion_text.end()) {
|
||||
Warning(LOCATION, "%s medal is missing default debriefing text.\n", temp_medal.name);
|
||||
temp_medal.promotion_text[-1] = "";
|
||||
}
|
||||
|
||||
Medals.push_back(temp_medal);
|
||||
Medal_display_info.push_back(temp_display);
|
||||
Num_medals++;
|
||||
}
|
||||
|
||||
Medals.push_back(temp_medal);
|
||||
Medal_display_info.push_back(temp_display);
|
||||
Num_medals++;
|
||||
required_string("#End");
|
||||
|
||||
// be sure that we know where the rank is
|
||||
if (Rank_medal_index < 0)
|
||||
{
|
||||
Warning(LOCATION, "Could not find the 'Rank' medal!");
|
||||
Rank_medal_index = 0;
|
||||
}
|
||||
|
||||
// be sure that the badges kill numbers show up in order
|
||||
//WMC - I don't think this is needed anymore due to my changes to post-mission functions
|
||||
//but I'm keeping it here to be sure.
|
||||
int prev_badge_kills = 0;
|
||||
for (i = 0; i < Num_medals; i++)
|
||||
{
|
||||
if (Medals[i].kills_needed < prev_badge_kills && Medals[i].kills_needed != 0)
|
||||
Error(LOCATION, "Badges must appear sorted by lowest kill # first in medals.tbl\nFind Allender for most information.");
|
||||
|
||||
if (Medals[i].kills_needed > 0)
|
||||
prev_badge_kills = Medals[i].kills_needed;
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
|
||||
// be sure that we know where the rank is
|
||||
if (Rank_medal_index < 0)
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
Warning(LOCATION, "Could not find the 'Rank' medal!");
|
||||
Rank_medal_index = 0;
|
||||
}
|
||||
|
||||
// be sure that the badges kill numbers show up in order
|
||||
//WMC - I don't think this is needed anymore due to my changes to post-mission functions
|
||||
//but I'm keeping it here to be sure.
|
||||
int prev_badge_kills = 0;
|
||||
for (i = 0; i < Num_medals; i++ )
|
||||
{
|
||||
if ( Medals[i].kills_needed < prev_badge_kills && Medals[i].kills_needed != 0)
|
||||
Error(LOCATION, "Badges must appear sorted by lowest kill # first in medals.tbl\nFind Allender for most information.");
|
||||
|
||||
if (Medals[i].kills_needed > 0)
|
||||
prev_badge_kills = Medals[i].kills_needed;
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "medals.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
-46
@@ -59,61 +59,64 @@ void parse_rank_tbl()
|
||||
{
|
||||
atexit(scoreing_close);
|
||||
char buf[MULTITEXT_LENGTH];
|
||||
int rval, idx, persona;
|
||||
int idx, persona;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "rank.tbl", rval));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
read_file_text("rank.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
read_file_text("rank.tbl", CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// parse in all the rank names
|
||||
idx = 0;
|
||||
skip_to_string("[RANK NAMES]");
|
||||
ignore_white_space();
|
||||
while ( required_string_either("#End", "$Name:") ) {
|
||||
Assert ( idx < NUM_RANKS );
|
||||
required_string("$Name:");
|
||||
stuff_string( Ranks[idx].name, F_NAME, NAME_LENGTH );
|
||||
required_string("$Points:");
|
||||
stuff_int( &Ranks[idx].points );
|
||||
required_string("$Bitmap:");
|
||||
stuff_string( Ranks[idx].bitmap, F_NAME, MAX_FILENAME_LEN );
|
||||
required_string("$Promotion Voice Base:");
|
||||
stuff_string( Ranks[idx].promotion_voice_base, F_NAME, MAX_FILENAME_LEN );
|
||||
while (check_for_string("$Promotion Text:")) {
|
||||
required_string("$Promotion Text:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
persona = -1;
|
||||
if (optional_string("+Persona:")) {
|
||||
stuff_int(&persona);
|
||||
if (persona < 0) {
|
||||
Warning(LOCATION, "Debriefing text for %s rank is assigned to an invalid persona: %i (must be 0 or greater).\n", Ranks[idx].name, persona);
|
||||
continue;
|
||||
// parse in all the rank names
|
||||
idx = 0;
|
||||
skip_to_string("[RANK NAMES]");
|
||||
ignore_white_space();
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
Assert(idx < NUM_RANKS);
|
||||
required_string("$Name:");
|
||||
stuff_string(Ranks[idx].name, F_NAME, NAME_LENGTH);
|
||||
required_string("$Points:");
|
||||
stuff_int(&Ranks[idx].points);
|
||||
required_string("$Bitmap:");
|
||||
stuff_string(Ranks[idx].bitmap, F_NAME, MAX_FILENAME_LEN);
|
||||
required_string("$Promotion Voice Base:");
|
||||
stuff_string(Ranks[idx].promotion_voice_base, F_NAME, MAX_FILENAME_LEN);
|
||||
while (check_for_string("$Promotion Text:")) {
|
||||
required_string("$Promotion Text:");
|
||||
stuff_string(buf, F_MULTITEXT, sizeof(buf));
|
||||
drop_white_space(buf);
|
||||
compact_multitext_string(buf);
|
||||
persona = -1;
|
||||
if (optional_string("+Persona:")) {
|
||||
stuff_int(&persona);
|
||||
if (persona < 0) {
|
||||
Warning(LOCATION, "Debriefing text for %s rank is assigned to an invalid persona: %i (must be 0 or greater).\n", Ranks[idx].name, persona);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ranks[idx].promotion_text[persona] = vm_strdup(buf);
|
||||
}
|
||||
Ranks[idx].promotion_text[persona] = vm_strdup(buf);
|
||||
if (Ranks[idx].promotion_text.find(-1) == Ranks[idx].promotion_text.end()) {
|
||||
Warning(LOCATION, "%s rank is missing default debriefing text.\n", Ranks[idx].name);
|
||||
Ranks[idx].promotion_text[-1] = "";
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if (Ranks[idx].promotion_text.find(-1) == Ranks[idx].promotion_text.end()) {
|
||||
Warning(LOCATION, "%s rank is missing default debriefing text.\n", Ranks[idx].name);
|
||||
Ranks[idx].promotion_text[-1] = "";
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
required_string("#End");
|
||||
|
||||
// be sure that all rank points are in order
|
||||
// be sure that all rank points are in order
|
||||
#ifndef NDEBUG
|
||||
for ( idx = 0; idx < NUM_RANKS-1; idx++ ) {
|
||||
if ( Ranks[idx].points >= Ranks[idx+1].points )
|
||||
Int3();
|
||||
}
|
||||
for (idx = 0; idx < NUM_RANKS - 1; idx++) {
|
||||
if (Ranks[idx].points >= Ranks[idx + 1].points)
|
||||
Int3();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "rank.tbl", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize a nice blank scoring element
|
||||
|
||||
+60
-58
@@ -87,68 +87,70 @@ SCP_vector<mflash_info> Mflash_info;
|
||||
|
||||
void parse_mflash_tbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
uint i;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
try
|
||||
{
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// header
|
||||
required_string("#Muzzle flash types");
|
||||
|
||||
while (optional_string("$Mflash:")) {
|
||||
mflash_info mflash;
|
||||
bool override_mflash = false;
|
||||
|
||||
required_string("+name:");
|
||||
stuff_string(mflash.name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (optional_string("+override"))
|
||||
override_mflash = true;
|
||||
|
||||
// read in all blobs
|
||||
while (optional_string("+blob_name:")) {
|
||||
mflash_blob_info mblob;
|
||||
|
||||
stuff_string(mblob.name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
required_string("+blob_offset:");
|
||||
stuff_float(&mblob.offset);
|
||||
|
||||
required_string("+blob_radius:");
|
||||
stuff_float(&mblob.radius);
|
||||
|
||||
mflash.blobs.push_back(mblob);
|
||||
}
|
||||
|
||||
for (i = 0; i < Mflash_info.size(); i++) {
|
||||
if (!stricmp(mflash.name, Mflash_info[i].name)) {
|
||||
if (override_mflash) {
|
||||
Mflash_info[i] = mflash;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// no matching name exists so add as new
|
||||
if (i == Mflash_info.size()) {
|
||||
Mflash_info.push_back(mflash);
|
||||
}
|
||||
// a mflash of the same name exists, don't add it again
|
||||
else {
|
||||
if (!override_mflash) {
|
||||
Warning(LOCATION, "Muzzle flash \"%s\" already exists! Using existing entry instead.", mflash.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close
|
||||
required_string("#end");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// header
|
||||
required_string("#Muzzle flash types");
|
||||
|
||||
while ( optional_string("$Mflash:") ) {
|
||||
mflash_info mflash;
|
||||
bool override_mflash = false;
|
||||
|
||||
required_string("+name:");
|
||||
stuff_string(mflash.name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
if (optional_string("+override"))
|
||||
override_mflash = true;
|
||||
|
||||
// read in all blobs
|
||||
while ( optional_string("+blob_name:") ) {
|
||||
mflash_blob_info mblob;
|
||||
|
||||
stuff_string(mblob.name, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
required_string("+blob_offset:");
|
||||
stuff_float(&mblob.offset);
|
||||
|
||||
required_string("+blob_radius:");
|
||||
stuff_float(&mblob.radius);
|
||||
|
||||
mflash.blobs.push_back(mblob);
|
||||
}
|
||||
|
||||
for (i = 0; i < Mflash_info.size(); i++) {
|
||||
if ( !stricmp(mflash.name, Mflash_info[i].name) ) {
|
||||
if (override_mflash) {
|
||||
Mflash_info[i] = mflash;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// no matching name exists so add as new
|
||||
if (i == Mflash_info.size()) {
|
||||
Mflash_info.push_back(mflash);
|
||||
}
|
||||
// a mflash of the same name exists, don't add it again
|
||||
else {
|
||||
if (!override_mflash) {
|
||||
Warning(LOCATION, "Muzzle flash \"%s\" already exists! Using existing entry instead.", mflash.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close
|
||||
required_string("#end");
|
||||
}
|
||||
|
||||
// initialize muzzle flash stuff for the whole game
|
||||
|
||||
+110
-108
@@ -320,50 +320,52 @@ int weapon_explosions::GetAnim(int weapon_expl_index, vec3d *pos, float size)
|
||||
|
||||
void parse_weapon_expl_tbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
uint i;
|
||||
lod_checker lod_check;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0) {
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
required_string("#Start");
|
||||
while (required_string_either("#End","$Name:"))
|
||||
|
||||
try
|
||||
{
|
||||
memset( &lod_check, 0, sizeof(lod_checker) );
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
// base filename
|
||||
required_string("$Name:");
|
||||
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
//Do we have an LOD num
|
||||
if (optional_string("$LOD:"))
|
||||
required_string("#Start");
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
stuff_int(&lod_check.num_lods);
|
||||
}
|
||||
memset(&lod_check, 0, sizeof(lod_checker));
|
||||
|
||||
// only bother with this if we have 1 or more lods and less than max lods,
|
||||
// otherwise the stardard level loading will take care of the different effects
|
||||
if ( (lod_check.num_lods > 0) || (lod_check.num_lods < MAX_WEAPON_EXPL_LOD) ) {
|
||||
// name check, update lod count if it already exists
|
||||
for (i = 0; i < LOD_checker.size(); i++) {
|
||||
if ( !stricmp(LOD_checker[i].filename, lod_check.filename) ) {
|
||||
LOD_checker[i].num_lods = lod_check.num_lods;
|
||||
// base filename
|
||||
required_string("$Name:");
|
||||
stuff_string(lod_check.filename, F_NAME, MAX_FILENAME_LEN);
|
||||
|
||||
//Do we have an LOD num
|
||||
if (optional_string("$LOD:"))
|
||||
{
|
||||
stuff_int(&lod_check.num_lods);
|
||||
}
|
||||
|
||||
// only bother with this if we have 1 or more lods and less than max lods,
|
||||
// otherwise the stardard level loading will take care of the different effects
|
||||
if ((lod_check.num_lods > 0) || (lod_check.num_lods < MAX_WEAPON_EXPL_LOD)) {
|
||||
// name check, update lod count if it already exists
|
||||
for (i = 0; i < LOD_checker.size(); i++) {
|
||||
if (!stricmp(LOD_checker[i].filename, lod_check.filename)) {
|
||||
LOD_checker[i].num_lods = lod_check.num_lods;
|
||||
}
|
||||
}
|
||||
|
||||
// old entry not found, add new entry
|
||||
if (i == LOD_checker.size()) {
|
||||
LOD_checker.push_back(lod_check);
|
||||
}
|
||||
}
|
||||
|
||||
// old entry not found, add new entry
|
||||
if ( i == LOD_checker.size() ) {
|
||||
LOD_checker.push_back(lod_check);
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2794,83 +2796,83 @@ static char Default_cmeasure_name[NAME_LENGTH] = "";
|
||||
|
||||
void parse_weaponstbl(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if ((rval = setjmp(parse_abort)) != 0)
|
||||
try
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("#Primary Weapons"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
// AL 28-3-98: If parse_weapon() fails, try next .tbl weapon
|
||||
if (parse_weapon(WP_LASER, Parsing_modular_table) < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Secondary Weapons"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
// AL 28-3-98: If parse_weapon() fails, try next .tbl weapon
|
||||
if (parse_weapon(WP_MISSILE, Parsing_modular_table) < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Beam Weapons"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
// AL 28-3-98: If parse_weapon() fails, try next .tbl weapon
|
||||
if (parse_weapon(WP_BEAM, Parsing_modular_table) < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if (optional_string("#Countermeasures"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
int idx = parse_weapon(WP_MISSILE, Parsing_modular_table);
|
||||
|
||||
if (idx < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Make sure cmeasure flag is set
|
||||
Weapon_info[idx].wi_flags |= WIF_CMEASURE;
|
||||
|
||||
//Set cmeasure index
|
||||
if (!strlen(Default_cmeasure_name)) {
|
||||
//We can't be sure that index will be the same after sorting, so save the name
|
||||
strcpy_s(Default_cmeasure_name, Weapon_info[idx].name);
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Read in a list of weapon_info indicies that are an ordering of the player weapon precedence.
|
||||
// This list is used to select an alternate weapon when a particular weapon is not available
|
||||
// during weapon selection.
|
||||
if ((!Parsing_modular_table && required_string("$Player Weapon Precedence:")) || optional_string("$Player Weapon Precedence:"))
|
||||
{
|
||||
Num_player_weapon_precedence = stuff_int_list(Player_weapon_precedence, MAX_WEAPON_TYPES, WEAPON_LIST_TYPE);
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
{
|
||||
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
reset_parse();
|
||||
|
||||
if(optional_string("#Primary Weapons"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
// AL 28-3-98: If parse_weapon() fails, try next .tbl weapon
|
||||
if ( parse_weapon(WP_LASER, Parsing_modular_table) < 0 ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if(optional_string("#Secondary Weapons"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
// AL 28-3-98: If parse_weapon() fails, try next .tbl weapon
|
||||
if ( parse_weapon(WP_MISSILE, Parsing_modular_table) < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if(optional_string("#Beam Weapons"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:")) {
|
||||
// AL 28-3-98: If parse_weapon() fails, try next .tbl weapon
|
||||
if ( parse_weapon(WP_BEAM, Parsing_modular_table) < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
if(optional_string("#Countermeasures"))
|
||||
{
|
||||
while (required_string_either("#End", "$Name:"))
|
||||
{
|
||||
int idx = parse_weapon(WP_MISSILE, Parsing_modular_table);
|
||||
|
||||
if(idx < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Make sure cmeasure flag is set
|
||||
Weapon_info[idx].wi_flags |= WIF_CMEASURE;
|
||||
|
||||
//Set cmeasure index
|
||||
if(!strlen(Default_cmeasure_name)) {
|
||||
//We can't be sure that index will be the same after sorting, so save the name
|
||||
strcpy_s(Default_cmeasure_name, Weapon_info[idx].name);
|
||||
}
|
||||
}
|
||||
|
||||
required_string("#End");
|
||||
}
|
||||
|
||||
// Read in a list of weapon_info indicies that are an ordering of the player weapon precedence.
|
||||
// This list is used to select an alternate weapon when a particular weapon is not available
|
||||
// during weapon selection.
|
||||
if ( (!Parsing_modular_table && required_string("$Player Weapon Precedence:")) || optional_string("$Player Weapon Precedence:") )
|
||||
{
|
||||
Num_player_weapon_precedence = stuff_int_list(Player_weapon_precedence, MAX_WEAPON_TYPES, WEAPON_LIST_TYPE);
|
||||
}
|
||||
|
||||
// add tbl/tbm to multiplayer validation list
|
||||
fs2netd_add_table_validation(filename);
|
||||
}
|
||||
|
||||
//uses a simple bucket sort to sort weapons, order of importance is:
|
||||
|
||||
Reference in new issue
Block a user