//projects a point void g3_project_point(g3s_point *p) { #ifndef __powerc fix tx,ty; if (p->p3_flags & PF_PROJECTED || p->p3_codes & CC_BEHIND) return; if (checkmuldiv(&tx,p->p3_x,Canv_w2,p->p3_z) && checkmuldiv(&ty,p->p3_y,Canv_h2,p->p3_z)) { p->p3_sx = Canv_w2 + tx; p->p3_sy = Canv_h2 - ty; p->p3_flags |= PF_PROJECTED; } else p->p3_flags |= PF_OVERFLOW; #else double fz; if ((p->p3_flags & PF_PROJECTED) || (p->p3_codes & CC_BEHIND)) return; if ( p->p3_z <= 0 ) { p->p3_flags |= PF_OVERFLOW; return; } fz = f2fl(p->p3_z); p->p3_sx = fl2f(fCanv_w2 + (f2fl(p->p3_x)*fCanv_w2 / fz)); p->p3_sy = fl2f(fCanv_h2 - (f2fl(p->p3_y)*fCanv_h2 / fz)); p->p3_flags |= PF_PROJECTED; #endif }
void do_object_window() { object *obj=&Objects[Cur_object_index]; if ( MattWindow == NULL ) return; //------------------------------------------------------------ // Call the ui code.. //------------------------------------------------------------ ui_button_any_drawn = 0; ui_window_do_gadgets(MattWindow); if ( QuitButton->pressed || (last_keypress==KEY_ESC)) { if (InitialMode[0]->flag) obj->movement_type = MT_NONE; if (InitialMode[1]->flag) obj->movement_type = MT_SPINNING; obj->mtype.spin_rate.x = fl2f(atof(Xtext->text)); obj->mtype.spin_rate.y = fl2f(atof(Ytext->text)); obj->mtype.spin_rate.z = fl2f(atof(Ztext->text)); object_close_window(); return; } old_object = Cur_object_index; }
//draws a bitmap with the specified 3d width & height //returns 1 if off screen, 0 if drew void g3_draw_bitmap(const vms_vector &pos,fix width,fix height,grs_bitmap &bm) { g3s_point pnt; fix w,h; if (g3_rotate_point(pnt,pos) & CC_BEHIND) return; g3_project_point(pnt); if (pnt.p3_flags & PF_OVERFLOW) return; #ifndef __powerc fix t; if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z)) w = fixmul(t,Matrix_scale.x); else return; if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z)) h = fixmul(t,Matrix_scale.y); else return; #else if (pnt.p3_z == 0) return; double fz = f2fl(pnt.p3_z); w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x); h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y); #endif const fix blob0y = pnt.p3_sy - h, blob1x = pnt.p3_sx + w; const array<grs_point, 3> blob_vertices{{ {pnt.p3_sx - w, blob0y}, {blob1x, blob0y}, {blob1x, pnt.p3_sy + h}, }}; scale_bitmap(bm, blob_vertices, 0); }
int medlisp_scale_segment(void) { vms_matrix rotmat; vms_vector scale; scale.x = fl2f((float) func_get_param(0)); scale.y = fl2f((float) func_get_param(1)); scale.z = fl2f((float) func_get_param(2)); med_create_new_segment(&scale); med_rotate_segment(Cursegp,vm_angles_2_matrix(&rotmat,&Seg_orientation)); Update_flags |= UF_WORLD_CHANGED; mine_changed = 1; return 1; }
void state_callback(int nitems, newmenu_item *items, int *last_key, int citem) { fix x = fl2f((grd_curcanv->cv_bitmap.bm_w - THUMBNAIL_W * f2fl(Scale_x)) / 2); fix y = fl2f(items[0].y - 5 * f2fl(Scale_factor)); grs_point scale_pts[] = { {x, y}, {x + i2f(THUMBNAIL_W), y + i2f(THUMBNAIL_H)}, {x + THUMBNAIL_W * Scale_factor, y + THUMBNAIL_H * Scale_factor} }; if (citem > 0) { if (sc_bmp[citem - 1]) { scale_bitmap(sc_bmp[citem - 1], scale_pts); } } }
// set netgame defaults // NOTE : should be used when creating a newpilot void multi_options_set_netgame_defaults(multi_server_options *options) { // any player can do squadmate messaging options->squad_set = MSO_SQUAD_ANY; // only the host can end the game options->endgame_set = MSO_END_HOST; // allow ingame file xfer and custom pilot pix options->flags = (MSO_FLAG_INGAME_XFER | MSO_FLAG_ACCEPT_PIX); // set the default time limit to be -1 (no limit) options->mission_time_limit = fl2f(-1.0f); // set the default max kills for a mission options->kill_limit = 9999; // set the default # of respawns options->respawn = 2; // set the default # of max observers options->max_observers = 2; // set the default netgame qos options->voice_qos = 10; // set the default token timeout options->voice_token_wait = 2000; // he must wait 2 seconds between voice gets // set the default max voice record time options->voice_record_time = 5000; // Set default skill level to medium options->skill_level = NUM_SKILL_LEVELS / 2; }
int object_dialog_handler(UI_DIALOG *, d_event *event, object_dialog *o) { dxxobject *obj=&Objects[Cur_object_index]; int keypress = 0; int rval = 0; if (event->type == EVENT_KEY_COMMAND) keypress = event_key_get(event); Assert(MattWindow != NULL); //------------------------------------------------------------ // Call the ui code.. //------------------------------------------------------------ ui_button_any_drawn = 0; if (event->type == EVENT_WINDOW_CLOSE) { d_free(o); MattWindow = NULL; return 0; } else if (event->type == EVENT_UI_DIALOG_DRAW) { ui_dprintf_at( MattWindow, 10, 132,"&X:" ); ui_dprintf_at( MattWindow, 10, 162,"&Y:" ); ui_dprintf_at( MattWindow, 10, 192,"&Z:" ); } if ( GADGET_PRESSED(o->quitButton) || (keypress==KEY_ESC)) { if (o->initialMode[0]->flag) obj->movement_type = MT_NONE; if (o->initialMode[1]->flag) obj->movement_type = MT_SPINNING; obj->mtype.spin_rate.x = fl2f(atof(o->xtext->text)); obj->mtype.spin_rate.y = fl2f(atof(o->ytext->text)); obj->mtype.spin_rate.z = fl2f(atof(o->ztext->text)); object_close_window(); return 1; } return rval; }
void garage_tweak_ship() { int r; newmenu_item m[20]; char mass[10],drag[10]; char low_thrust[10],high_thrust[10],reverse_thrust[10]; char rot_speed[10]; //arbitary units sprintf( mass, "%.1f", f2fl(Player_ship->mass) ); sprintf( drag, "%.1f", f2fl(Player_ship->drag) ); sprintf( low_thrust, "%.1f", f2fl(Player_ship->low_thrust) ); sprintf( high_thrust, "%.1f", f2fl(Player_ship->high_thrust) ); sprintf( reverse_thrust, "%.1f", f2fl(Player_ship->reverse_thrust) ); sprintf( rot_speed, "%d", Player_ship->rot_speed ); m[0].type=NM_TYPE_TEXT; m[0].text = "Mass (Default:4.0)"; m[1].type=NM_TYPE_INPUT; m[1].text = mass; m[1].text_len = 10; m[2].type=NM_TYPE_TEXT; m[2].text = "Drag (Default:2.0)"; m[3].type=NM_TYPE_INPUT; m[3].text = drag; m[3].text_len = 10; m[4].type=NM_TYPE_TEXT; m[4].text = "Low thrust (Default:200.0)"; m[5].type=NM_TYPE_INPUT; m[5].text = low_thrust; m[5].text_len = 10; m[6].type=NM_TYPE_TEXT; m[6].text = "High thrust (Default:500.0)"; m[7].type=NM_TYPE_INPUT; m[7].text = high_thrust; m[7].text_len = 10; m[8].type=NM_TYPE_TEXT; m[8].text = "Reverse thrust (Default:300.0)"; m[9].type=NM_TYPE_INPUT; m[9].text = reverse_thrust; m[9].text_len = 10; m[10].type=NM_TYPE_TEXT; m[10].text = "Rotation speed (Default:20)"; m[11].type=NM_TYPE_INPUT; m[11].text = rot_speed; m[11].text_len = 10; r = newmenu_do( "Garage", NULL, 12, m, NULL ); if ( r < 0 ) return; Player_ship->mass = fl2f(atof(mass)); Player_ship->drag = fl2f(atof(drag)); Player_ship->low_thrust = fl2f(atof(low_thrust)); Player_ship->high_thrust = fl2f(atof(high_thrust)); Player_ship->reverse_thrust = fl2f(atof(reverse_thrust)); Player_ship->rot_speed = (int)atof(rot_speed); }
fix timer_get_fixed_seconds() { LARGE_INTEGER end_time, elapsed_time; float seconds; QueryPerformanceCounter(&end_time); elapsed_time.QuadPart = end_time.QuadPart - start.QuadPart; seconds = (float)elapsed_time.QuadPart / (float)frequency.QuadPart; return fl2f(seconds); }
// build the stats value strings for this player void multi_pinfo_build_stats() { scoring_struct *sc = &Multi_pinfo_popup_player->m_player->stats; // build alltime fighter and non-fighter kills sprintf(Multi_pinfo_stats_vals[MPI_FIGHTER_KILLS], "%d", sc->kill_count); // missions flown sprintf(Multi_pinfo_stats_vals[MPI_MISSIONS_FLOWN],"%d",(int)sc->missions_flown); // flight time game_format_time(fl2f((float)sc->flight_time),Multi_pinfo_stats_vals[MPI_FLIGHT_TIME]); // last flown if(sc->last_flown == 0){ strcpy_s(Multi_pinfo_stats_vals[MPI_LAST_FLOWN],XSTR("No missions flown",693)); } else { time_t last_flown_tmp = sc->last_flown; tm *tmr = gmtime(&last_flown_tmp); if(tmr != NULL){ strftime(Multi_pinfo_stats_vals[MPI_LAST_FLOWN],MAX_LABEL_TEXT,"%m/%d/%y %H:%M",tmr); } else { strcpy_s(Multi_pinfo_stats_vals[MPI_LAST_FLOWN], ""); } } // rank strcpy_s(Multi_pinfo_stats_vals[MPI_RANK],Ranks[sc->rank].name); // primary shots fired sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_FIRED],"%u",sc->p_shots_fired); // primary hit pct if (sc->p_shots_fired > 0) { sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_PCT], "%d%%", (int)(100.0f * ((float)sc->p_shots_hit / (float)sc->p_shots_fired))); } else { sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_PCT], "%d%%", 0); } // primary shots fired sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_FIRED],"%u",sc->s_shots_fired); // primary hit pct if (sc->s_shots_fired > 0) { sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_PCT], "%d%%", (int)(100.0f * ((float)sc->s_shots_hit / (float)sc->s_shots_fired))); } else { sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_PCT], "%d%%", 0); } }
void DoReactorSmoke (tObject *objP) { int h = -1, i, nShields = 0, nParts; vmsVector vDir, vPos; i = OBJ_IDX (objP); if (!(SHOW_SMOKE && gameOpts->render.smoke.bRobots)) { if (gameData.smoke.objects [i] >= 0) KillObjectSmoke (i); return; } if ((objP->shields < 0) || (objP->flags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))) nParts = 0; else { nShields = f2ir (gameData.bots.info [gameStates.app.bD1Mission][objP->id].strength); h = nShields ? f2ir (objP->shields) * 100 / nShields : 0; } if (h < 0) h = 0; nParts = 10 - h / 10; if (nParts > 0) { nParts = REACTOR_MAX_PARTS; if (gameData.smoke.objects [i] < 0) { //PrintLog ("creating robot %d smoke\n", i); SetSmokeObject (i, CreateSmoke (&objP->position.vPos, NULL, NULL, objP->nSegment, 1, nParts, fl2f (-4.0), -1, 1, BOT_PART_LIFE * 2, BOT_PART_SPEED, 0, i, NULL, 1, -1)); } else { SetSmokePartScale (gameData.smoke.objects [i], fl2f (-4.0)); SetSmokeDensity (gameData.smoke.objects [i], nParts, -1); vDir.p.x = d_rand () - F1_0 / 4; vDir.p.y = d_rand () - F1_0 / 4; vDir.p.z = d_rand () - F1_0 / 4; VmVecNormalize (&vDir); VmVecScaleAdd (&vPos, &objP->position.vPos, &vDir, -objP->size / 2); SetSmokePos (gameData.smoke.objects [i], &vPos, NULL, objP->nSegment); } } else KillObjectSmoke (i); }
//draw a sortof sphere - i.e., the 2d radius is proportional to the 3d //radius, but not to the distance from the eye int G3DrawSphere (g3sPoint *pnt, fix rad) { if (! (pnt->p3_codes & CC_BEHIND)) { if (! (pnt->p3Flags & PF_PROJECTED)) G3ProjectPoint (pnt); if (! (pnt->p3_codes & PF_OVERFLOW)) { fix r2, t; r2 = FixMul (rad, viewInfo.scale.x); #ifndef __powerc if (CheckMulDiv (&t, r2, xCanvW2, pnt->p3_z)) return gr_disk (pnt->p3_sx, pnt->p3_sy, t); #else if (pnt->p3_z == 0) return 0; return gr_disk (pnt->p3_sx, pnt->p3_sy, fl2f (( (f2fl (r2) * fxCanvW2) / f2fl (pnt->p3_z))); #endif } }
//process this powerup for this frame void do_powerup_frame(object *obj) { vclip_info *vci = &obj->rtype.vclip_info; vclip *vc = &Vclip[vci->vclip_num]; vci->frametime -= FrameTime; while (vci->frametime < 0 ) { vci->frametime += vc->frame_time; vci->framenum++; if (vci->framenum >= vc->num_frames) vci->framenum=0; } if (obj->lifeleft <= 0) { object_create_explosion(obj->segnum, &obj->pos, fl2f(3.5), VCLIP_POWERUP_DISAPPEARANCE ); if ( Vclip[VCLIP_POWERUP_DISAPPEARANCE].sound_num > -1 ) digi_link_sound_to_object( Vclip[VCLIP_POWERUP_DISAPPEARANCE].sound_num, obj-Objects, 0, F1_0); } }
//draw a sortof sphere - i.e., the 2d radius is proportional to the 3d //radius, but not to the distance from the eye int g3_draw_sphere(g3s_point *pnt,fix rad) { if (! (pnt->p3_codes & CC_BEHIND)) { if (! (pnt->p3_flags & PF_PROJECTED)) g3_project_point(pnt); if (! (pnt->p3_codes & PF_OVERFLOW)) { fix r2,t; r2 = fixmul(rad,Matrix_scale.x); #ifndef __powerc if (checkmuldiv(&t,r2,Canv_w2,pnt->p3_z)) return gr_disk(pnt->p3_sx,pnt->p3_sy,t); #else if (pnt->p3_z == 0) return 0; return gr_disk(pnt->p3_sx, pnt->p3_sy, fl2f(((f2fl(r2) * fCanv_w2) / f2fl(pnt->p3_z)))); #endif } } return 0; }
void parse_ai_profiles_tbl(const char *filename) { int i; char profile_name[NAME_LENGTH]; ai_profile_t dummy_profile; char *saved_Mp = NULL; char buf[NAME_LENGTH]; try { if (filename == NULL) read_file_text_from_default(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; } else { // don't create multiple profiles with the same name if (previous_profile != NULL) { 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, "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; } 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]) { 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 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++) { //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); set_flag(profile, "$aspect bomb invulnerability fix:", AIPF2_ASPECT_INVULNERABILITY_FIX, AIP_FLAG2); set_flag(profile, "$glide decay requires thrust:", AIPF2_GLIDE_DECAY_REQUIRES_THRUST, AIP_FLAG2); set_flag(profile, "$ai can slow down when attacking big ships:", AIPF2_AI_CAN_SLOW_DOWN_ATTACKING_BIG_SHIPS, AIP_FLAG2); profile->bay_arrive_speed_mult = 1.0f; profile->bay_depart_speed_mult = 1.0f; if (optional_string("$bay arrive speed multiplier:")) { stuff_float(&profile->bay_arrive_speed_mult); } if (optional_string("$bay depart speed multiplier:")) { stuff_float(&profile->bay_depart_speed_mult); } // ---------- // 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; } } 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; } // add tbl/tbm to multiplayer validation list extern void fs2netd_add_table_validation(const char *tblname); fs2netd_add_table_validation(filename); }
//draws a bitmap with the specified 3d width & height //returns 1 if off screen, 0 if drew bool G3DrawBitMap (vmsVector *pos, fix width, fix height, grsBitmap *bm, int orientation) { #ifndef __powerc g3sPoint pnt; fix t, w, h; if (G3TransformAndEncodePoint (&pnt, pos) & CC_BEHIND) return 1; G3ProjectPoint (&pnt); if (pnt.p3Flags & PF_OVERFLOW) return 1; if (CheckMulDiv (&t, width, xCanvW2, pnt.p3_z)) w = FixMul (t, viewInfo.scale.x); else return 1; if (CheckMulDiv (&t, height, xCanvH2, pnt.p3_z)) h = FixMul (t, viewInfo.scale.y); else return 1; blob_vertices[0].x = pnt.p3_sx - w; blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h; blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w; blob_vertices[2].y = pnt.p3_sy + h; scale_bitmap (bm, blob_vertices, 0); return 0; #else g3sPoint pnt; fix w, h; double fz; if (G3TransformAndEncodePoint (&pnt, pos) & CC_BEHIND) return 1; G3ProjectPoint (&pnt); if (pnt.p3Flags & PF_OVERFLOW) return 1; if (pnt.p3_z == 0) return 1; fz = f2fl (pnt.p3_z); w = FixMul (fl2f (( (f2fl (width)*fxCanvW2) / fz)), viewInfo.scale.x); h = FixMul (fl2f (( (f2fl (height)*fxCanvH2) / fz)), viewInfo.scale.y); blob_vertices[0].x = pnt.p3_sx - w; blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h; blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w; blob_vertices[2].y = pnt.p3_sy + h; scale_bitmap (bm, blob_vertices); return 0; #endif }
void HudGaugeDirectives::render(float frametime) { char buf[256], *second_line; int i, t, x, y, z, end, offset, bx, by, y_count; color *c; if (!Training_obj_num_lines){ return; } offset = 0; end = Training_obj_num_lines; if (end > Max_directives) { end = Max_directives; offset = Training_obj_num_lines - end; } // draw top of objective display setGaugeColor(); renderBitmap(directives_top.first_frame, position[0], position[1]); // print out title renderPrintf(position[0] + header_offsets[0], position[1] + header_offsets[1], EG_OBJ_TITLE, XSTR( "directives", 422)); bx = position[0]; by = position[1] + middle_frame_offset_y; y_count = 0; for (i=0; i<end; i++) { x = position[0] + text_start_offsets[0]; y = position[1] + text_start_offsets[1] + y_count * text_h; z = TRAINING_OBJ_LINES_MASK(i + offset); c = &Color_normal; if (Training_obj_lines[i + offset] & TRAINING_OBJ_LINES_KEY) { message_translate_tokens(buf, Mission_events[z].objective_key_text); // remap keys c = &Color_bright_green; } else { strcpy_s(buf, Mission_events[z].objective_text); if (Mission_events[z].count){ sprintf(buf + strlen(buf), NOX(" [%d]"), Mission_events[z].count); } // if this is a multiplayer tvt game, and this is event is not for my team, don't display it if((MULTI_TEAM) && (Net_player != NULL)){ if((Mission_events[z].team != -1) && (Net_player->p_info.team != Mission_events[z].team)){ continue; } } switch (mission_get_event_status(z)) { case EVENT_CURRENT: c = &Color_bright_white; break; case EVENT_FAILED: c = &Color_bright_red; break; case EVENT_SATISFIED: t = Mission_events[z].satisfied_time; if (t + i2f(2) > Missiontime) { if (Missiontime % fl2f(.4f) < fl2f(.2f)){ c = &Color_bright_blue; } else { c = &Color_bright_white; } } else { c = &Color_bright_blue; } break; } } // maybe split the directives line second_line = split_str_once(buf, max_line_width); Assert( second_line != buf ); // blit the background frames setGaugeColor(); renderBitmap(directives_middle.first_frame, bx, by); by += text_h; if ( second_line ) { renderBitmap(directives_middle.first_frame, bx, by); by += text_h; } // blit the text gr_set_color_fast(c); renderString(x, y, EG_OBJ1 + i, buf); y_count++; if ( second_line ) { y = position[1] + text_start_offsets[1] + y_count * text_h; renderString(x+12, y, EG_OBJ1 + i + 1, second_line); y_count++; } } // draw the bottom of objective display setGaugeColor(); renderBitmap(directives_bottom.first_frame, bx, by + bottom_bg_offset); }
// displays (renders) the training objectives list void training_obj_display() { char buf[256], *second_line; int i, t, x, y, z, height, end, offset, bx, by, y_count; color *c; if (!Training_obj_num_lines){ return; } if ( !hud_gauge_active(HUD_DIRECTIVES_VIEW) ) { // Always draw the directives display if this is a training mission if ( !(The_mission.game_type & MISSION_TYPE_TRAINING) ) { return; } } // don't ever display directives display in multiplayer missions // if ( Game_mode & GM_MULTIPLAYER ){ // return; // } height = gr_get_font_height(); offset = 0; end = Training_obj_num_lines; if (end > TRAINING_OBJ_DISPLAY_LINES) { end = TRAINING_OBJ_DISPLAY_LINES; offset = Training_obj_num_lines - end; } // draw top of objective display // hud_set_default_color(); hud_set_gauge_color(HUD_DIRECTIVES_VIEW); GR_AABITMAP(Directive_gauge[0].first_frame, Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TOP][0]+fl2i(HUD_offset_x), Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TOP][1]+fl2i(HUD_offset_y)); // gr_set_bitmap(Directive_gauge[0].first_frame); // gr_aabitmap(Directive_coords[DIRECTIVE_COORDS_TOP][0]+fl2i(HUD_offset_x), Directive_coords[DIRECTIVE_COORDS_TOP][1]+fl2i(HUD_offset_y)); // print out title emp_hud_printf(Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TITLE][0]+fl2i(HUD_offset_x), Directive_coords[gr_screen.res][DIRECTIVE_COORDS_TITLE][1]+fl2i(HUD_offset_y), EG_OBJ_TITLE, XSTR( "Directives", 422)); // gr_printf(Directive_coords[DIRECTIVE_COORDS_TITLE][0]+fl2i(HUD_offset_x), Directive_coords[DIRECTIVE_COORDS_TITLE][1]+fl2i(HUD_offset_y), XSTR( "directives", 422)); bx = DIRECTIVE_X+fl2i(HUD_offset_x); by = Directive_coords[gr_screen.res][DIRECTIVE_COORDS_MIDDLE][1]+fl2i(HUD_offset_y); y_count = 0; for (i=0; i<end; i++) { x = DIRECTIVE_X + 5 + fl2i(HUD_offset_x); y = Training_obj_window_coords[gr_screen.res][1] + fl2i(HUD_offset_y) + y_count * height + height / 2 + 1; z = TRAINING_OBJ_LINES_MASK(i + offset); c = &Color_normal; if (Training_obj_lines[i + offset] & TRAINING_OBJ_LINES_KEY) { message_translate_tokens(buf, Mission_events[z].objective_key_text); // remap keys // gr_set_color_fast(&Color_normal); c = &Color_bright_green; } else { strcpy(buf, Mission_events[z].objective_text); if (Mission_events[z].count){ sprintf(buf + strlen(buf), NOX(" [%d]"), Mission_events[z].count); } #ifndef NO_NETWORK // if this is a multiplayer tvt game, and this is event is not for my team, don't display it if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_TEAM) && (Net_player != NULL)){ if((Mission_events[z].team != -1) && (Net_player->p_info.team != Mission_events[z].team)){ continue; } } #endif switch (mission_get_event_status(z)) { case EVENT_CURRENT: // gr_set_color_fast(&Color_bright_white); c = &Color_bright_white; break; case EVENT_FAILED: // gr_set_color_fast(&Color_bright_red); c = &Color_bright_red; break; case EVENT_SATISFIED: // gr_set_color_fast(&Color_bright_blue); t = Mission_events[z].satisfied_time; if (t + i2f(2) > Missiontime) { if (Missiontime % fl2f(.4f) < fl2f(.2f)){ c = &Color_bright_blue; } else { c = &Color_bright_white; } } else { c = &Color_bright_blue; } break; } } // maybe split the directives line second_line = split_str_once(buf, 167); // blit the background frames // hud_set_default_color(); hud_set_gauge_color(HUD_DIRECTIVES_VIEW); GR_AABITMAP(Directive_gauge[1].first_frame, bx, by); // gr_set_bitmap(Directive_gauge[1].first_frame); // gr_aabitmap(bx, by); by += DIRECTIVE_H; if ( second_line ) { GR_AABITMAP(Directive_gauge[1].first_frame, bx, by); // gr_set_bitmap(Directive_gauge[1].first_frame); // gr_aabitmap(bx, by); by += DIRECTIVE_H; } // blit the text gr_set_color_fast(c); emp_hud_string(x, y, EG_OBJ1 + i, buf); // gr_printf(x, y, buf); y_count++; if ( second_line ) { y = Training_obj_window_coords[gr_screen.res][1] + fl2i(HUD_offset_y) + y_count * height + height / 2 + 1; emp_hud_string(x+12, y, EG_OBJ1 + i + 1, second_line); // gr_printf(x+12, y, second_line); y_count++; } } // draw the bottom of objective display // hud_set_default_color(); hud_set_gauge_color(HUD_DIRECTIVES_VIEW); GR_AABITMAP(Directive_gauge[2].first_frame, bx, by); // gr_set_bitmap(Directive_gauge[2].first_frame); // gr_aabitmap(bx, by); }
// Scales bitmap, bp, into vertbuf[0] to vertbuf[1] void scale_bitmap(grs_bitmap *bp, grs_point *vertbuf, int orientation ) { grs_bitmap * dbp = &grd_curcanv->cv_bitmap; fix x0, y0, x1, y1; fix u0, v0, u1, v1; fix clipped_x0, clipped_y0, clipped_x1, clipped_y1; fix clipped_u0, clipped_v0, clipped_u1, clipped_v1; fix xmin, xmax, ymin, ymax; int dx0, dy0, dx1, dy1; int dtemp; // Set initial variables.... x0 = vertbuf[0].x; y0 = vertbuf[0].y; x1 = vertbuf[2].x; y1 = vertbuf[2].y; xmin = 0; ymin = 0; xmax = i2f(dbp->bm_w)-fl2f(.5); ymax = i2f(dbp->bm_h)-fl2f(.5); u0 = i2f(0); v0 = i2f(0); u1 = i2f(bp->bm_w-1); v1 = i2f(bp->bm_h-1); // Check for obviously offscreen bitmaps... if ( (y1<=y0) || (x1<=x0) ) return; if ( (x1<0 ) || (x0>=xmax) ) return; if ( (y1<0 ) || (y0>=ymax) ) return; clipped_u0 = u0; clipped_v0 = v0; clipped_u1 = u1; clipped_v1 = v1; clipped_x0 = x0; clipped_y0 = y0; clipped_x1 = x1; clipped_y1 = y1; // Clip the left, moving u0 right as necessary if ( x0 < xmin ) { clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1); clipped_x0 = xmin; } // Clip the right, moving u1 left as necessary if ( x1 > xmax ) { clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1); clipped_x1 = xmax; } // Clip the top, moving v0 down as necessary if ( y0 < ymin ) { clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1); clipped_y0 = ymin; } // Clip the bottom, moving v1 up as necessary if ( y1 > ymax ) { clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1); clipped_y1 = ymax; } dx0 = f2i(clipped_x0); dx1 = f2i(clipped_x1); dy0 = f2i(clipped_y0); dy1 = f2i(clipped_y1); if (dx1<=dx0) return; if (dy1<=dy0) return; dtemp = f2i(clipped_u1)-f2i(clipped_u0); if ( bp->bm_flags & BM_FLAG_RLE ) { if ( (dtemp < (f2i(clipped_x1)-f2i(clipped_x0))) && (dtemp>0) ) scale_up_bitmap_rle(bp, dbp, dx0, dy0, dx1, dy1, clipped_u0, clipped_v0, clipped_u1, clipped_v1, orientation ); else scale_bitmap_c_rle(bp, dbp, dx0, dy0, dx1, dy1, clipped_u0, clipped_v0, clipped_u1, clipped_v1, orientation ); } else { if ( (dtemp < (f2i(clipped_x1)-f2i(clipped_x0))) && (dtemp>0) ) scale_up_bitmap(bp, dbp, dx0, dy0, dx1, dy1, clipped_u0, clipped_v0, clipped_u1, clipped_v1, orientation ); else scale_bitmap_c(bp, dbp, dx0, dy0, dx1, dy1, clipped_u0, clipped_v0, clipped_u1, clipped_v1, orientation ); } }
if ((tm=seg->sides[sidenum].tmap_num2) != 0) if ((ec=TmapInfo[tm&0x3fff].eclip_num)!=-1) if ((sn=Effects[ec].sound_num)!=-1) { vms_vector pnt; compute_center_point_on_side(&pnt,seg,sidenum); digi_link_sound_to_pos(sn,segnum,sidenum,&pnt,1, F1_0/2); } } } //fix flash_dist=i2f(1); fix flash_dist=fl2f(.9); //create flash for player appearance void create_player_appearance_effect(object *player_obj) { vms_vector pos; object *effect_obj; #ifndef NDEBUG { int objnum = player_obj-Objects; if ( (objnum < 0) || (objnum > Highest_object_index) ) Int3(); // See Rob, trying to track down weird network bug } #endif
// build the stats value strings for this player void multi_pinfo_build_stats() { // int idx; // int fighter_kills,other_kills; scoring_struct* sc = &Multi_pinfo_popup_player->m_player->stats; // build alltime fighter and non-fighter kills /* fighter_kills = 0; other_kills = 0; for(idx=0;idx<MAX_SHIP_CLASSES;idx++){ if(sc->kills[idx] > 0){ if(Ship_info[idx].flags & SIF_FIGHTER){ fighter_kills += sc->kills[idx]; } else { other_kills += sc->kills[idx]; } } } */ sprintf(Multi_pinfo_stats_vals[MPI_FIGHTER_KILLS], "%d", sc->kill_count); // sprintf(Multi_pinfo_stats_vals[MPI_OTHER_KILLS],"%d",other_kills); // missions flown sprintf(Multi_pinfo_stats_vals[MPI_MISSIONS_FLOWN], "%d", (int)sc->missions_flown); // flight time game_format_time(fl2f((float)sc->flight_time), Multi_pinfo_stats_vals[MPI_FLIGHT_TIME]); // last flown if (sc->last_flown == 0) { strcpy_s(Multi_pinfo_stats_vals[MPI_LAST_FLOWN], XSTR("No missions flown", 693)); } else { time_t last_flown_tmp = sc->last_flown; tm* tmr = gmtime(&last_flown_tmp); if (tmr != NULL) { strftime(Multi_pinfo_stats_vals[MPI_LAST_FLOWN], MAX_LABEL_TEXT, "%m/%d/%y %H:%M", tmr); } else { strcpy_s(Multi_pinfo_stats_vals[MPI_LAST_FLOWN], ""); } } // rank strcpy_s(Multi_pinfo_stats_vals[MPI_RANK], Ranks[sc->rank].name); // primary shots fired sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_FIRED], "%d", sc->p_shots_fired); // primary shots hit // sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_HIT],"%d",sc->p_shots_hit); // primary hit pct if (sc->p_shots_fired > 0) { sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_PCT], "%d%%", (int)(100.0f * ((float)sc->p_shots_hit / (float)sc-> p_shots_fired))); } else { sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_PCT], "%d%%", 0); } // primary shots fired sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_FIRED], "%d", sc->s_shots_fired); // primary shots hit // sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_HIT],"%d",sc->s_shots_hit); // primary hit pct if (sc->s_shots_fired > 0) { sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_PCT], "%d%%", (int)(100.0f * ((float)sc->s_shots_hit / (float)sc-> s_shots_fired))); } else { sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_PCT], "%d%%", 0); } }
void do_countdown_frame() { fix old_time; int fc, div_scale; if (!Control_center_destroyed) return; // Control center destroyed, rock the player's ship. fc = Countdown_seconds_left; if (fc > 16) fc = 16; // At Trainee, decrease rocking of ship by 4x. div_scale = 1; if (Difficulty_level == 0) div_scale = 4; if (FixedStep & EPS20) { ConsoleObject->mtype.phys_info.rotvel.x += (fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32))/div_scale; ConsoleObject->mtype.phys_info.rotvel.z += (fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32))/div_scale; } // Hook in the rumble sound effect here. old_time = Countdown_timer; Countdown_timer -= FrameTime; Countdown_seconds_left = f2i(Countdown_timer + F1_0*7/8); if ( (old_time > COUNTDOWN_VOICE_TIME ) && (Countdown_timer <= COUNTDOWN_VOICE_TIME) ) { digi_play_sample( SOUND_COUNTDOWN_13_SECS, F3_0 ); } if ( f2i(old_time + F1_0*7/8) != Countdown_seconds_left ) { if ( (Countdown_seconds_left>=0) && (Countdown_seconds_left<10) ) digi_play_sample( SOUND_COUNTDOWN_0_SECS+Countdown_seconds_left, F3_0 ); if ( Countdown_seconds_left==Total_countdown_time-1) digi_play_sample( SOUND_COUNTDOWN_29_SECS, F3_0 ); } if (Countdown_timer > 0) { fix size,old_size; size = (i2f(Total_countdown_time)-Countdown_timer) / fl2f(0.65); old_size = (i2f(Total_countdown_time)-old_time) / fl2f(0.65); if (size != old_size && (Countdown_seconds_left < (Total_countdown_time-5) )) { // Every 2 seconds! //@@if (Dead_controlcen_object_num != -1) { //@@ vms_vector vp; //,v,c; //@@ compute_segment_center(&vp, &Segments[Objects[Dead_controlcen_object_num].segnum]); //@@ object_create_explosion( Objects[Dead_controlcen_object_num].segnum, &vp, size*10, VCLIP_SMALL_EXPLOSION); //@@} digi_play_sample( SOUND_CONTROL_CENTER_WARNING_SIREN, F3_0 ); } } else { int flash_value; if (old_time > 0) digi_play_sample( SOUND_MINE_BLEW_UP, F1_0 ); flash_value = f2i(-Countdown_timer * (64 / 4)); // 4 seconds to total whiteness PALETTE_FLASH_SET(flash_value,flash_value,flash_value); if (PaletteBlueAdd > 64 ) { gr_set_current_canvas( NULL ); gr_clear_canvas(BM_XRGB(31,31,31)); //make screen all white to match palette effect reset_palette_add(); //restore palette for death message //controlcen->MaxCapacity = Fuelcen_max_amount; //gauge_message( "Control Center Reset" ); DoPlayerDead(); //kill_player(); } } }
void GetCameraUVL (tCamera *pc, tUVL *uvlP, tTexCoord2f *texCoordP, fVector3 *vertexP) { #ifndef _DEBUG if (pc->bHaveUVL) { if (uvlP) memcpy (uvlP, pc->uvlList, sizeof (pc->uvlList)); } else #endif { fix i; float duImage, dvImage, duFace, dvFace, du, dv,aFace, aImage; int xFlip, yFlip, rotLeft, rotRight; #if RENDER2TEXTURE int bCamBufAvail = OglCamBufAvail (pc, 1) == 1; int bFitToWall = pc->bTeleport || gameOpts->render.cameras.bFitToWall; #endif if (uvlP) { rotLeft = (uvlP [1].u > uvlP [0].u); rotRight = (uvlP [1].u < uvlP [0].u); if (rotLeft) { yFlip = (uvlP [1].u < uvlP [2].u); xFlip = (uvlP [3].v > uvlP [1].v); } else if (rotRight) { yFlip = (uvlP [3].u < uvlP [0].u); xFlip = (uvlP [1].v > uvlP [3].v); } else { xFlip = (uvlP [2].u < uvlP [0].u); yFlip = (uvlP [1].v > uvlP [0].v); } dvFace = f2fl (uvlP [1].v - uvlP [0].v); duFace = f2fl (uvlP [2].u - uvlP [0].u); } else { rotLeft = (texCoordP [1].v.u < texCoordP [0].v.u); rotRight = (texCoordP [1].v.u > texCoordP [0].v.u); if (rotLeft) { yFlip = (texCoordP [1].v.u > texCoordP [2].v.u); xFlip = (texCoordP [3].v.v < texCoordP [1].v.v); } else if (rotRight) { yFlip = (texCoordP [3].v.u > texCoordP [0].v.u); xFlip = (texCoordP [1].v.v < texCoordP [3].v.v); } else { xFlip = (texCoordP [2].v.u < texCoordP [0].v.u); yFlip = (texCoordP [1].v.v > texCoordP [0].v.v); } dvFace = (float) fabs (texCoordP [1].v.v - texCoordP [0].v.v); duFace = (float) fabs (texCoordP [2].v.u - texCoordP [0].v.u); } du = dv = 0; if (bCamBufAvail) { duImage = (float) grdCurCanv->cvBitmap.bmProps.w / (float) pc->texBuf.bmProps.w; dvImage = (float) grdCurCanv->cvBitmap.bmProps.h / (float) pc->texBuf.bmProps.h; if (!bFitToWall && gameOpts->render.nPath) { aImage = (float) grdCurCanv->cvBitmap.bmProps.h / (float) grdCurCanv->cvBitmap.bmProps.w; if (vertexP) aFace = VmVecDistf ((fVector *) vertexP, (fVector *) (vertexP + 1)) / VmVecDistf ((fVector *) (vertexP + 1), (fVector *) (vertexP + 2)); else aFace = dvFace / duFace; dv = (aImage - aFace) / 2.0f; duImage -= du / 2; dvImage -= dv; } } else { duImage = duFace; dvImage = dvFace; } if (uvlP) { uvlP [0].v = uvlP [3].v = fl2f (yFlip ? dvImage : dv / 2); uvlP [1].v = uvlP [2].v = fl2f (yFlip ? dv / 2 : dvImage); uvlP [0].u = uvlP [1].u = fl2f (xFlip ? duImage : du / 2); uvlP [2].u = uvlP [3].u = fl2f (xFlip ? du / 2 : duImage); for (i = 0; i < 4; i++) uvlP [i].l = F1_0; if (rotRight) { for (i = 1; i < 5; i++) { pc->uvlList [i - 1] = uvlP [i % 4]; } } else if (rotRight) { for (i = 0; i < 4; i++) { pc->uvlList [i] = uvlP [(i + 1) % 4]; } } else memcpy (pc->uvlList, uvlP, sizeof (pc->uvlList)); } else { tTexCoord2f texCoord [4]; texCoord [0].v.v = texCoord [3].v.v = yFlip ? dvImage : dv; texCoord [1].v.v = texCoord [2].v.v = yFlip ? dv : dvImage; texCoord [0].v.u = texCoord [1].v.u = xFlip ? duImage : du / 2; texCoord [2].v.u = texCoord [3].v.u = xFlip ? du / 2 : duImage; if (rotLeft) { for (i = 1; i < 5; i++) { pc->texCoord [i - 1] = texCoord [i % 4]; } } else if (rotRight) { for (i = 0; i < 4; i++) { pc->texCoord [i] = texCoord [(i + 1) % 4]; } } else memcpy (pc->texCoord, texCoord, sizeof (pc->texCoord)); } pc->bHaveUVL = 1; } }
/** * Render a shield mesh in the global array ::Shield_hits[] */ void render_shield(int shield_num) { int i; vec3d *centerp; matrix *orient; object *objp; ship *shipp; ship_info *si; if (Shield_hits[shield_num].type == SH_UNUSED) { return; } Assert(Shield_hits[shield_num].objnum >= 0); objp = &Objects[Shield_hits[shield_num].objnum]; if (objp->flags & OF_NO_SHIELDS) { return; } // If this object didn't get rendered, don't render its shields. In fact, make the shield hit go away. if (!(objp->flags & OF_WAS_RENDERED)) { Shield_hits[shield_num].type = SH_UNUSED; return; } // At detail levels 1, 3, animations play at double speed to reduce load. if ( (Detail.shield_effects == 1) || (Detail.shield_effects == 3) ) { Shield_hits[shield_num].start_time -= Frametime; } MONITOR_INC(NumShieldRend,1); shipp = &Ships[objp->instance]; si = &Ship_info[shipp->ship_info_index]; // objp, shipp, and si are now setup correctly // If this ship is in its deathroll, make the shield hit effects go away faster. if (shipp->flags & SF_DYING) { Shield_hits[shield_num].start_time -= fl2f(2*flFrametime); } // Detail level stuff. When lots of shield hits, maybe make them go away faster. if (Poly_count > 50) { if (Shield_hits[shield_num].start_time + (SHIELD_HIT_DURATION*50)/Poly_count < Missiontime) { Shield_hits[shield_num].type = SH_UNUSED; free_global_tri_records(shield_num); return; } } else if ((Shield_hits[shield_num].start_time + SHIELD_HIT_DURATION) < Missiontime) { Shield_hits[shield_num].type = SH_UNUSED; free_global_tri_records(shield_num); return; } orient = &objp->orient; centerp = &objp->pos; int bitmap_id, frame_num; // Do some sanity checking Assert( (si->species >= 0) && (si->species < (int)Species_info.size()) ); generic_anim *sa = &Species_info[si->species].shield_anim; // don't try to draw if we don't have an ani if ( sa->first_frame >= 0 ) { frame_num = fl2i( f2fl(Missiontime - Shield_hits[shield_num].start_time) * sa->num_frames ); if ( frame_num >= sa->num_frames ) { frame_num = sa->num_frames - 1; } else if ( frame_num < 0 ) { mprintf(( "HEY! Missiontime went backwards! (Shield.cpp)\n" )); frame_num = 0; } bitmap_id = sa->first_frame + frame_num; float alpha = 0.9999f; if(The_mission.flags & MISSION_FLAG_FULLNEB) { alpha *= 0.85f; } gr_set_bitmap(bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha ); if ( (Detail.shield_effects == 1) || (Detail.shield_effects == 2) ) { if ( bitmap_id != - 1 ) { render_low_detail_shield_bitmap(&Global_tris[Shield_hits[shield_num].tri_list[0]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]); } } else { if ( bitmap_id != - 1 ) { for (i=0; i<Shield_hits[shield_num].num_tris; i++) { render_shield_triangle(&Global_tris[Shield_hits[shield_num].tri_list[i]], orient, centerp, Shield_hits[shield_num].rgb[0], Shield_hits[shield_num].rgb[1], Shield_hits[shield_num].rgb[2]); } } } } }
void DrawMarkerNumber (automap *am, int num) { int i; g3s_point BasePoint,FromPoint,ToPoint; float ArrayX[10][20]={ {-.25, 0.0, 0.0, 0.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0}, {-1.0, -1.0, -1.0, 1.0, 1.0, 1.0}, {-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0}, {-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0} }; float ArrayY[10][20]={ {.75, 1.0, 1.0, -1.0, -1.0, -1.0}, {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0}, {1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 1.0, -1.0}, {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0}, {1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0}, {1.0, 1.0, 1.0, -1.0}, {1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 0.0, 0.0}, {1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0} }; int NumOfPoints[]={6,10,8,6,10,10,4,10,8}; for (i=0;i<NumOfPoints[num];i++) { ArrayX[num][i]*=MarkerScale; ArrayY[num][i]*=MarkerScale; } if (num==HighlightMarker) gr_setcolor (am->white_63); else gr_setcolor (am->blue_48); g3_rotate_point(&BasePoint,&Objects[MarkerObject[(Player_num*2)+num]].pos); for (i=0;i<NumOfPoints[num];i+=2) { FromPoint=BasePoint; ToPoint=BasePoint; FromPoint.p3_x+=fixmul ((fl2f (ArrayX[num][i])),Matrix_scale.x); FromPoint.p3_y+=fixmul ((fl2f (ArrayY[num][i])),Matrix_scale.y); g3_code_point (&FromPoint); g3_project_point (&FromPoint); ToPoint.p3_x+=fixmul ((fl2f (ArrayX[num][i+1])),Matrix_scale.x); ToPoint.p3_y+=fixmul ((fl2f (ArrayY[num][i+1])),Matrix_scale.y); g3_code_point (&ToPoint); g3_project_point (&ToPoint); automap_draw_line(&FromPoint, &ToPoint); } }
int G3GetOOFModelItems (int nModel, tOOFObject *po, tG3Model *pm, float fScale) { tOOF_subObject *pso; tOOF_face *pof; tOOF_faceVert *pfv; tG3SubModel *psm; fVector3 *pvn = pm->pVertNorms, vNormal; tG3ModelVertex *pmv = pm->pFaceVerts; tG3ModelFace *pmf = pm->pFaces; int h, i, j, n, nIndex = 0; for (i = po->nSubObjects, pso = po->pSubObjects, psm = pm->pSubModels; i; i--, pso++, psm++) { psm->nParent = pso->nParent; if (psm->nParent < 0) pm->iSubModel = (short) (psm - pm->pSubModels); psm->vOffset.p.x = fl2f (pso->vOffset.x * fScale); psm->vOffset.p.y = fl2f (pso->vOffset.y * fScale); psm->vOffset.p.z = fl2f (pso->vOffset.z * fScale); psm->nAngles = 0; psm->nBomb = -1; psm->nMissile = -1; psm->nGun = -1; psm->nGunPoint = -1; psm->bBullets = 0; psm->bThruster = 0; psm->bGlow = 0; psm->bRender = 1; j = pso->faces.nFaces; psm->nIndex = nIndex; psm->nFaces = j; psm->pFaces = pmf; G3InitSubModelMinMax (psm); for (pof = pso->faces.pFaces; j; j--, pof++, pmf++) { pmf->nIndex = nIndex; pmf->bThruster = 0; pmf->bGlow = 0; n = pof->nVerts; pmf->nVerts = n; if (pof->bTextured) pmf->nBitmap = pof->texProps.nTexId; else pmf->nBitmap = -1; pfv = pof->pVerts; h = pfv->nIndex; if (nModel > 200) { VmVecNormal ((fVector *) &vNormal, (fVector *) (pso->pvVerts + pfv [0].nIndex), (fVector *) (pso->pvVerts + pfv [1].nIndex), (fVector *) (pso->pvVerts + pfv [2].nIndex)); } else memcpy (&vNormal, &pof->vNormal, sizeof (fVector3)); for (; n; n--, pfv++, pmv++, pvn++) { h = pfv->nIndex; pmv->nIndex = h; pmv->texCoord.v.u = pfv->fu; pmv->texCoord.v.v = pfv->fv; pmv->normal = vNormal; VmVecScale ((fVector *) (pm->pVerts + h), (fVector *) (pso->pvVerts + h), fScale); pmv->vertex = pm->pVerts [h]; G3SetSubModelMinMax (psm, &pmv->vertex); *pvn = vNormal; if ((pmv->bTextured = pof->bTextured)) pmv->baseColor.red = pmv->baseColor.green = pmv->baseColor.blue = 1.0f; else { pmv->baseColor.red = (float) pof->texProps.color.r / 255.0f; pmv->baseColor.green = (float) pof->texProps.color.g / 255.0f; pmv->baseColor.blue = (float) pof->texProps.color.b / 255.0f; } pmv->baseColor.alpha = 1.0f; nIndex++; } } } return 1; }
int iglasses_read_headset( fix *yaw, fix *pitch, fix *roll ) { static unsigned char buff[16]; float radPitch,radRoll,sinPitch,sinRoll,cosPitch,cosRoll; float rotx,roty,rotz; float fx,fy,fz; long x,y,z,p,r; unsigned char checksum; long i,count; ReadBufferTimed(Iport, buff, 12, 10 ); // Wait 1/100 second for timeout. checksum = 0; count = Iport->count; ClearRXBuffer(Iport); WriteChar( Iport, 'S' ); for (i=0; i < 11; i++) checksum += buff[i]; if ( (count < 12) || (checksum != buff[11]) ) { *yaw = i_yaw; *pitch = i_pitch; *roll = i_roll; return 0; } x = (short)(buff[1] << 8) | buff[2]; y = (short)(buff[3] << 8) | buff[4]; z = (short)(buff[5] << 8) | buff[6]; p = (short)(buff[7] << 8) | buff[8]; r = (short)(buff[9] << 8) | buff[10]; fx = (float)x/FBITS; fy = (float)y/FBITS; fz = (float)z/FBITS; radPitch = (float)p*TO_RADIANS; radRoll = (float)r*TO_RADIANS; sinPitch = sin(radPitch); cosPitch = cos(radPitch); sinRoll = sin(radRoll); cosRoll = cos(radRoll); roty = cosPitch*fy - sinPitch*fz; rotz = sinPitch*fy + cosPitch*fz; rotx = cosRoll*fx - sinRoll*roty; #ifdef USE_FILTERS *yaw = filterFIR( &X_filter,fl2f(-atan2(rotz,rotx)*M_PI/2.0)); *pitch = filterFIR( &Y_filter,fl2f(-radPitch*M_PI/2.0)); *roll = filterFIR( &Z_filter,fl2f(radRoll*M_PI/2.0)); if ( Num_readings < 30 ) { Num_readings++; BasisYaw = *yaw; BasisPitch = *pitch; BasisBank = *roll; } *yaw -= BasisYaw; *pitch -= BasisPitch; *roll -= BasisBank; #else *yaw = fl2f(-atan2(rotz,rotx)*M_PI/2.0); *pitch = fl2f(-radPitch*M_PI/2.0); *roll = fl2f(radRoll*M_PI/2.0); #endif i_yaw = *yaw; i_pitch = *pitch; i_roll = *roll; return 1; }
void parse_ai_profiles_tbl(const char *filename) { int i; char profile_name[NAME_LENGTH]; ai_profile_t dummy_profile; char *saved_Mp = NULL; char buf[NAME_LENGTH]; try { if (filename == NULL) read_file_text_from_default(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; } else { // don't create multiple profiles with the same name if (previous_profile != NULL) { 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, "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; } 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]) { profile->reset(); } // brand new profile, so set it to the base defaults else { *profile = Ai_profiles[0]; } } // 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++) { //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, MAX_DETAIL_LEVEL + 1); set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AI::Profile_Flags::Big_ships_can_attack_beam_turrets_on_untargeted_ships); set_flag(profile, "$smart primary weapon selection:", AI::Profile_Flags::Smart_primary_weapon_selection); set_flag(profile, "$smart secondary weapon selection:", AI::Profile_Flags::Smart_secondary_weapon_selection); set_flag(profile, "$smart shield management:", AI::Profile_Flags::Smart_shield_management); set_flag(profile, "$smart afterburner management:", AI::Profile_Flags::Smart_afterburner_management); set_flag(profile, "$free afterburner use:", AI::Profile_Flags::Free_afterburner_use); set_flag(profile, "$allow rapid secondary dumbfire:", AI::Profile_Flags::Allow_rapid_secondary_dumbfire); set_flag(profile, "$huge turret weapons ignore bombs:", AI::Profile_Flags::Huge_turret_weapons_ignore_bombs); set_flag(profile, "$don't insert random turret fire delay:", AI::Profile_Flags::Dont_insert_random_turret_fire_delay); set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AI::Profile_Flags::Hack_improve_non_homing_swarm_turret_fire_accuracy); set_flag(profile, "$shockwaves damage small ship subsystems:", AI::Profile_Flags::Shockwaves_damage_small_ship_subsystems); set_flag(profile, "$navigation subsystem governs warpout capability:", AI::Profile_Flags::Navigation_subsys_governs_warp); set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AI::Profile_Flags::No_min_dock_speed_cap); set_flag(profile, "$disable linked fire penalty:", AI::Profile_Flags::Disable_linked_fire_penalty); set_flag(profile, "$disable weapon damage scaling:", AI::Profile_Flags::Disable_weapon_damage_scaling); set_flag(profile, "$use additive weapon velocity:", AI::Profile_Flags::Use_additive_weapon_velocity); set_flag(profile, "$use newtonian dampening:", AI::Profile_Flags::Use_newtonian_dampening); set_flag(profile, "$include beams for kills and assists:", AI::Profile_Flags::Include_beams_in_stat_calcs); set_flag(profile, "$score kills based on damage caused:", AI::Profile_Flags::Kill_scoring_scales_with_damage); set_flag(profile, "$score assists based on damage caused:", AI::Profile_Flags::Assist_scoring_scales_with_damage); set_flag(profile, "$allow event and goal scoring in multiplayer:", AI::Profile_Flags::Allow_multi_event_scoring); set_flag(profile, "$fix linked primary weapon decision bug:", AI::Profile_Flags::Fix_linked_primary_bug); set_flag(profile, "$prevent turrets targeting too distant bombs:", AI::Profile_Flags::Prevent_targeting_bombs_beyond_range); set_flag(profile, "$smart subsystem targeting for turrets:", AI::Profile_Flags::Smart_subsystem_targeting_for_turrets); set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AI::Profile_Flags::Fix_heat_seeker_stealth_bug); set_flag(profile, "$multi allow empty primaries:", AI::Profile_Flags::Multi_allow_empty_primaries); set_flag(profile, "$multi allow empty secondaries:", AI::Profile_Flags::Multi_allow_empty_secondaries); set_flag(profile, "$allow turrets target weapons freely:", AI::Profile_Flags::Allow_turrets_target_weapons_freely); set_flag(profile, "$use only single fov for turrets:", AI::Profile_Flags::Use_only_single_fov_for_turrets); set_flag(profile, "$allow vertical dodge:", AI::Profile_Flags::Allow_vertical_dodge); set_flag(profile, "$force beam turrets to use normal fov:", AI::Profile_Flags::Force_beam_turret_fov); set_flag(profile, "$fix ai class bug:", AI::Profile_Flags::Fix_ai_class_bug); set_flag(profile, "$turrets ignore targets radius in range checks:", AI::Profile_Flags::Turrets_ignore_target_radius); set_flag(profile, "$no extra collision avoidance vs player:", AI::Profile_Flags::No_special_player_avoid); set_flag(profile, "$perform fewer checks for death screams:", AI::Profile_Flags::Perform_fewer_scream_checks); set_flag(profile, "$advanced turret fov edge checks:", AI::Profile_Flags::Advanced_turret_fov_edge_checks); set_flag(profile, "$require turrets to have target in fov:", AI::Profile_Flags::Require_turret_to_have_target_in_fov); set_flag(profile, "$all ships manage shields:", AI::Profile_Flags::All_ships_manage_shields); set_flag(profile, "$ai aims from ship center:", AI::Profile_Flags::Ai_aims_from_ship_center); set_flag(profile, "$allow primary link at mission start:", AI::Profile_Flags::Allow_primary_link_at_start); set_flag(profile, "$allow beams to damage bombs:", AI::Profile_Flags::Beams_damage_weapons); set_flag(profile, "$disable weapon damage scaling for player:", AI::Profile_Flags::Player_weapon_scale_fix); set_flag(profile, "$countermeasures affect aspect seekers:", AI::Profile_Flags::Aspect_lock_countermeasure); set_flag(profile, "$ai guards specific ship in wing:", AI::Profile_Flags::Ai_guards_specific_ship_in_wing); 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:", AI::Profile_Flags::No_warp_camera); set_flag(profile, "$fix ai path order bug:", AI::Profile_Flags::Fix_ai_path_order_bug); set_flag(profile, "$strict turret-tagged-only targeting:", AI::Profile_Flags::Strict_turred_tagged_only_targeting); set_flag(profile, "$aspect bomb invulnerability fix:", AI::Profile_Flags::Aspect_invulnerability_fix); set_flag(profile, "$glide decay requires thrust:", AI::Profile_Flags::Glide_decay_requires_thrust); set_flag(profile, "$ai can slow down when attacking big ships:", AI::Profile_Flags::Ai_can_slow_down_attacking_big_ships); set_flag(profile, "$use actual primary range:", AI::Profile_Flags::Use_actual_primary_range); profile->bay_arrive_speed_mult = 1.0f; profile->bay_depart_speed_mult = 1.0f; if (optional_string("$bay arrive speed multiplier:")) { stuff_float(&profile->bay_arrive_speed_mult); } if (optional_string("$bay depart speed multiplier:")) { stuff_float(&profile->bay_depart_speed_mult); } // ---------- // 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); profile->flags.set(AI::Profile_Flags::Perform_fewer_scream_checks, temp); } 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); profile->flags.set(AI::Profile_Flags::Allow_primary_link_at_start, !temp); } // 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 if (!skip_to_start_of_string_either("$", "#")) break; 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; } // add tbl/tbm to multiplayer validation list extern void fs2netd_add_table_validation(const char *tblname); fs2netd_add_table_validation(filename); }
void DoCountdownFrame () { fix oldTime; int fc, h, div_scale; static fix cdtFrameTime; if (!gameData.reactor.bDestroyed) { cdtFrameTime = 0; return; } cdtFrameTime += gameData.time.xRealFrame; if (gameStates.limitFPS.bCountDown && !gameStates.app.tick40fps.bTick) return; if (!IS_D2_OEM && !IS_MAC_SHARE && !IS_SHAREWARE) { // get countdown in OEM and SHAREWARE only // On last level, we don't want a countdown. if ((gameData.missions.nCurrentMission == gameData.missions.nBuiltinMission) && (gameData.missions.nCurrentLevel == gameData.missions.nLastLevel)) { if (!(gameData.app.nGameMode & GM_MULTI)) return; if (gameData.app.nGameMode & GM_MULTI_ROBOTS) return; } } // Control center destroyed, rock the tPlayer's ship. fc = gameData.reactor.countdown.nSecsLeft; if (fc > 16) fc = 16; // At Trainee, decrease rocking of ship by 4x. div_scale = 1; if (gameStates.app.nDifficultyLevel == 0) div_scale = 4; h = 3 * F1_0 / 16 + (F1_0 * (16 - fc)) / 32; gameData.objs.console->mType.physInfo.rotVel.p.x += (FixMul (d_rand () - 16384, h)) / div_scale; gameData.objs.console->mType.physInfo.rotVel.p.z += (FixMul (d_rand () - 16384, h)) / div_scale; // Hook in the rumble sound effect here. oldTime = gameData.reactor.countdown.nTimer; if (!TimeStopped ()) gameData.reactor.countdown.nTimer -= cdtFrameTime; cdtFrameTime = 0; gameData.reactor.countdown.nSecsLeft = f2i (gameData.reactor.countdown.nTimer + F1_0 * 7 / 8); if ((oldTime > COUNTDOWN_VOICE_TIME) && (gameData.reactor.countdown.nTimer <= COUNTDOWN_VOICE_TIME)) { DigiPlaySample (SOUND_COUNTDOWN_13_SECS, F3_0); } if (f2i (oldTime + F1_0*7/8) != gameData.reactor.countdown.nSecsLeft) { if ((gameData.reactor.countdown.nSecsLeft >= 0) && (gameData.reactor.countdown.nSecsLeft < 10)) DigiPlaySample ((short) (SOUND_COUNTDOWN_0_SECS + gameData.reactor.countdown.nSecsLeft), F3_0); if (gameData.reactor.countdown.nSecsLeft == gameData.reactor.countdown.nTotalTime - 1) DigiPlaySample (SOUND_COUNTDOWN_29_SECS, F3_0); } if (gameData.reactor.countdown.nTimer > 0) { fix size,old_size; size = (i2f (gameData.reactor.countdown.nTotalTime) - gameData.reactor.countdown.nTimer) / fl2f (0.65); old_size = (i2f (gameData.reactor.countdown.nTotalTime) - oldTime) / fl2f (0.65); if (size != old_size && (gameData.reactor.countdown.nSecsLeft < (gameData.reactor.countdown.nTotalTime-5))) // Every 2 seconds! DigiPlaySample (SOUND_CONTROL_CENTER_WARNING_SIREN, F3_0); } else { int flashValue = f2i (-gameData.reactor.countdown.nTimer * (64 / 4)); // 4 seconds to total whiteness if (oldTime > 0) DigiPlaySample (SOUND_MINE_BLEW_UP, F1_0); PALETTE_FLASH_SET (flashValue, flashValue, flashValue); if (gameStates.ogl.palAdd.blue > 64) { WINDOS ( DDGrSetCurrentCanvas (NULL), GrSetCurrentCanvas (NULL) ); WINDOS ( dd_gr_clear_canvas (RGBA_PAL2 (31,31,31)), GrClearCanvas (RGBA_PAL2 (31,31,31)) ); //make screen all white to match palette effect ResetCockpit (); //force cockpit redraw next time ResetPaletteAdd (); //restore palette for death message //controlcen->MaxCapacity = gameData.matCens.xFuelMaxAmount; //gauge_message ("Control Center Reset"); DoPlayerDead (); //kill_player (); } } }
//draws a bitmap with the specified 3d width & height //returns 1 if off screen, 0 if drew bool g3_draw_bitmap(vms_vector *pos,fix width,fix height,grs_bitmap *bm) { #ifndef __powerc g3s_point pnt; fix t,w,h; if (g3_rotate_point(&pnt,pos) & CC_BEHIND) return 1; g3_project_point(&pnt); if (pnt.p3_flags & PF_OVERFLOW) return 1; if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z)) w = fixmul(t,Matrix_scale.x); else return 1; if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z)) h = fixmul(t,Matrix_scale.y); else return 1; blob_vertices[0].x = pnt.p3_sx - w; blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h; blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w; blob_vertices[2].y = pnt.p3_sy + h; scale_bitmap(bm,blob_vertices,0); return 0; #else g3s_point pnt; fix w,h; double fz; if (g3_rotate_point(&pnt,pos) & CC_BEHIND) return 1; g3_project_point(&pnt); if (pnt.p3_flags & PF_OVERFLOW) return 1; if (pnt.p3_z == 0) return 1; fz = f2fl(pnt.p3_z); w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x); h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y); blob_vertices[0].x = pnt.p3_sx - w; blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h; blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w; blob_vertices[2].y = pnt.p3_sy + h; scale_bitmap(bm, blob_vertices, 0); return 0; #endif }