diff --git a/code/ai/ai.h b/code/ai/ai.h index cf74bf8697..295bf723b7 100644 --- a/code/ai/ai.h +++ b/code/ai/ai.h @@ -9,11 +9,14 @@ /* * $Logfile: /Freespace2/code/Ship/ai.h $ - * $Revision: 1.15 $ - * $Date: 2007-01-07 01:00:18 $ - * $Author: Goober5000 $ + * $Revision: 1.16 $ + * $Date: 2007-01-14 14:03:31 $ + * $Author: bobboau $ * * $Log: not supported by cvs2svn $ + * Revision 1.15 2007/01/07 01:00:18 Goober5000 + * convert a mission variable to a mission flag + * * Revision 1.14 2006/12/28 00:59:18 wmcoolmon * WMC codebase commit. See pre-commit build thread for details on changes. * @@ -419,6 +422,8 @@ typedef struct ai_goal { int index; } dockee; + int dock_animation_done_time; + } ai_goal; #define MAX_GOAL_SHIP_NAMES 100 diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index 343e18c8d4..fea7a311f5 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -9,13 +9,17 @@ /* * $Logfile: /Freespace2/code/Ship/AiCode.cpp $ - * $Revision: 1.94 $ - * $Date: 2007-01-08 00:50:58 $ - * $Author: Goober5000 $ + * $Revision: 1.95 $ + * $Date: 2007-01-14 14:03:31 $ + * $Author: bobboau $ * * AI code that does interesting stuff * * $Log: not supported by cvs2svn $ + * Revision 1.94 2007/01/08 00:50:58 Goober5000 + * remove WMC's limbo code, per our discussion a few months ago + * this will later be handled by copying ship stats using sexps or scripts + * * Revision 1.93 2007/01/07 01:00:18 Goober5000 * convert a mission variable to a mission flag * @@ -11327,8 +11331,12 @@ void ai_dock() dist = ai_path(); //nprintf(("AI", "Time = %7.3f, submode = %i\n", f2fl(Missiontime), aip->submode)); //nprintf(("AI", "Dock 1: Frame: %i, goal point = %i, dist = %7.3f\n", Framecount, aip->path_cur-aip->path_start, dist)); + + aigp->dock_animation_done_time = Missiontime; if (aip->path_cur-aip->path_start >= aip->path_length-1) { // If got this far, advance no matter what. + model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING, dockee_index, 1); + aigp->dock_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_DOCKING, dockee_index); aip->submode = AIS_DOCK_2; aip->submode_start_time = Missiontime; aip->path_cur--; @@ -11337,7 +11345,8 @@ void ai_dock() if (Pl_objp->phys_info.speed > goal_objp->phys_info.speed + 1.5f) { set_accel_for_target_speed(Pl_objp, goal_objp->phys_info.speed); } else { - // model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING, aip->dock_index, 1); + model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING, dockee_index, 1); + aigp->dock_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_DOCKING, dockee_index); aip->submode = AIS_DOCK_2; aip->submode_start_time = Missiontime; } @@ -11352,6 +11361,7 @@ void ai_dock() { float dist; int r; + if(!timestamp_elapsed(aigp->dock_animation_done_time))break;//wait untill the animation is done before docking if ((r = maybe_dock_obstructed(Pl_objp, goal_objp,0)) != -1) { nprintf(("AI", "Dock 2: Obstructed by %s\n", Ships[Objects[r].instance].ship_name)); @@ -11423,6 +11433,7 @@ void ai_dock() tolerance += 4*flFrametime * (rdinfo.submodel_r * rdinfo.submodel_w); } + aigp->dock_animation_done_time = Missiontime; if (dist < tolerance) { // - Removed by MK on 11/7/97, causes errors for ships docked at mission start: maybe_recreate_path(Pl_objp, aip, 1); @@ -11434,7 +11445,8 @@ void ai_dock() ai_do_objects_docked_stuff( Pl_objp, docker_index, goal_objp, dockee_index ); if (aip->submode == AIS_DOCK_3) { - // model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, aip->dockee_index, 1); + model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, dockee_index, 1); + aigp->dock_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_DOCKED, dockee_index); // model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, 1); snd_play_3d( &Snds[SND_DOCK_ATTACH], &Pl_objp->pos, &View_position ); hud_maybe_flash_docking_text(Pl_objp); @@ -11534,6 +11546,8 @@ void ai_dock() // Play a ship docking detach sound snd_play_3d( &Snds[SND_DOCK_DETACH], &Pl_objp->pos, &View_position ); + model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, dockee_index, -1); + aigp->dock_animation_done_time = model_anim_get_time_type(shipp, TRIGGER_TYPE_DOCKED, dockee_index); aip->submode = AIS_UNDOCK_1; aip->submode_start_time = Missiontime; @@ -11549,16 +11563,18 @@ void ai_dock() //nprintf(("AI", "Undock 1: time in this mode = %7.3f\n", f2fl(Missiontime - aip->submode_start_time))); - if (Missiontime - aip->submode_start_time < REARM_BREAKOFF_DELAY) + if (Missiontime - aip->submode_start_time < REARM_BREAKOFF_DELAY) { break; // Waiting for one second to elapse to let detach sound effect play out. } + if(!timestamp_elapsed(aigp->dock_animation_done_time)){ + break; + } else if ( !(aigp->flags & AIGF_DOCK_SOUND_PLAYED)) { snd_play_3d( &Snds[SND_DOCK_DEPART], &Pl_objp->pos, &View_position ); aigp->flags |= AIGF_DOCK_SOUND_PLAYED; - // model_anim_start_type(shipp, TRIGGER_TYPE_DOCKED, aip->dockee_index, -1); } dist = dock_orient_and_approach(Pl_objp, docker_index, goal_objp, dockee_index, DOA_UNDOCK_1, &rdinfo); @@ -11633,7 +11649,7 @@ void ai_dock() Assert(dist != UNINITIALIZED_VALUE); if (dist < Pl_objp->radius/2 + 5.0f) { - // model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING, aip->dockee_index, -1); + model_anim_start_type(shipp, TRIGGER_TYPE_DOCKING, dockee_index, -1); aip->submode = AIS_UNDOCK_4; aip->submode_start_time = Missiontime; } @@ -11776,7 +11792,7 @@ void ai_debug_render_stuff() parent_objnum = AI_debug_render_stuff[i].parent_objnum; - ship_get_global_turret_info(&Objects[parent_objnum], tp, &gpos, &gvec); + ship_get_global_turret_info(&Objects[parent_objnum], ss->system_info, &gpos, &gvec); g3_rotate_vertex(&vert1, &gpos); vm_vec_scale_add(&gpos2, &gpos, &gvec, 20.0f); g3_rotate_vertex(&vert2, &gpos2); @@ -11900,6 +11916,7 @@ void process_subobjects(int objnum) // do solar/radar/gas/activator rotation here ship_do_submodel_rotation(shipp, psub, pss); + submodel_scripted_rotate(objp, pss); } // Deal with a ship with blown out engines. diff --git a/code/ai/aiturret.cpp b/code/ai/aiturret.cpp index c99feb64b3..d84a089dff 100644 --- a/code/ai/aiturret.cpp +++ b/code/ai/aiturret.cpp @@ -1,12 +1,16 @@ /* * $Logfile: /Freespace2/code/ai/aiturret.cpp $ - * $Revision: 1.51 $ - * $Date: 2007-01-08 00:50:58 $ - * $Author: Goober5000 $ + * $Revision: 1.52 $ + * $Date: 2007-01-14 14:03:31 $ + * $Author: bobboau $ * * Functions for AI control of turrets * * $Log: not supported by cvs2svn $ + * Revision 1.51 2007/01/08 00:50:58 Goober5000 + * remove WMC's limbo code, per our discussion a few months ago + * this will later be handled by copying ship stats using sexps or scripts + * * Revision 1.50 2007/01/07 12:36:51 taylor * make fire-on-normal return value a little more obvious * fix the "infinite genius" move I made by breaking turret movements ;) @@ -227,6 +231,7 @@ typedef struct eval_enemy_obj_struct { bool beam_flag; // turret is a beam vec3d *tpos; vec3d *tvec; + matrix *tmat; ship_subsys *turret_subsys; int current_enemy; @@ -246,17 +251,47 @@ typedef struct eval_enemy_obj_struct { // return 1 if objp is in fov of the specified turret, tp. Otherwise return 0. // dist = distance from turret to center point of object -int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist) +int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist, matrix *tmat) { vec3d v2e; float dot; vm_vec_normalized_dir(&v2e, &objp->pos, tpos); - dot = vm_vec_dot(&v2e, tvec); - dot += objp->radius / (dist + objp->radius); + if(tp->turret_y_fov < -1 || !tmat || IS_MAT_NULL(tmat)){ + dot = vm_vec_dot(&v2e, tvec); + dot += objp->radius / (dist + objp->radius); - if ( dot >= tp->turret_fov ) { - return 1; + if ( dot >= tp->turret_fov ) { + return 1; + } + }else{ + vec3d x,tx; + + /* + vm_project_point_onto_plane(&x,&v2e,&tmat->vec.uvec,&vmd_zero_vector); + vm_project_point_onto_plane(&y,&v2e,&tmat->vec.rvec,&vmd_zero_vector); + vm_vec_normalize(&x); + vm_vec_normalize(&y); + float dx = vm_vec_dot(&tmat->vec.fvec, &x); + float dy = vm_vec_dot(&tmat->vec.uvec, &v2e); + + if(dy >= tp->turret_y_fov && dx >= tp->turret_fov) + return 1; + */ + + vm_project_point_onto_plane(&x,&v2e,&tmat->vec.uvec,&vmd_zero_vector); + vm_project_point_onto_plane(&tx,&v2e,tvec,&vmd_zero_vector); + vm_vec_normalize(&x); + vm_vec_normalize(&tx); + float dx = vm_vec_dot(&tx, &x); + + float dy = vm_vec_dot(&tmat->vec.uvec, &v2e); + float dn = vm_vec_dot(&tp->turret_norm, &tmat->vec.uvec); + float na = acos(dn); + + if(dy <= cos(na - tp->turret_y_fov) && dy >= cos(na + tp->turret_y_fov) && dx >= tp->turret_fov) + return 1; + } return 0; @@ -672,7 +707,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo) // maybe update nearest attacker if ( dist < eeo->nearest_attacker_dist ) { - if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, tp, eeo->tvec, eeo->tpos, dist + objp->radius) ) { + if ( (eeo->current_enemy == -1) || object_in_turret_fov(objp, tp, eeo->tvec, eeo->tpos, dist + objp->radius, eeo->tmat) ) { // nprintf(("AI", "Nearest enemy = %s, dist = %7.3f, dot = %6.3f, fov = %6.3f\n", Ships[objp->instance].ship_name, dist, vm_vec_dot(&v2e, tvec), tp->turret_fov)); eeo->nearest_attacker_dist = dist; eeo->nearest_attacker_objnum = OBJ_INDEX(objp); @@ -724,7 +759,7 @@ int is_target_beam_valid(ship_weapon *swp, object *objp) // tpos => position of turret (world coords) // tvec => forward vector of turret (world coords) // current_enemy => objnum of current turret target -int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag) +int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subsys, int enemy_team_mask, vec3d *tpos, vec3d *tvec, matrix*tmat, int current_enemy, bool big_only_flag, bool small_only_flag, bool tagged_only_flag, bool beam_flag) { //float weapon_travel_dist; int weapon_system_ok; @@ -760,6 +795,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs eeo.current_enemy = current_enemy; eeo.tpos = tpos; eeo.tvec = tvec; + eeo.tmat = tmat; eeo.turret_subsys = turret_subsys; eeo.nearest_attacker_dist = 99999.0f; @@ -865,7 +901,7 @@ DCF_BOOL(use_parent_target, Use_parent_target) // tpos => position of turret (world coords) // tvec => forward vector of turret (world coords) // current_enemy => objnum of current turret target -int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, int current_enemy, float fov) +int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d *tvec, matrix*tmat, int current_enemy, float fov) { int enemy_team_mask, enemy_objnum; model_subsystem *tp; @@ -921,10 +957,11 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d vec3d v2e; float dot, dist; dist = vm_vec_normalized_dir(&v2e, &Objects[aip->target_objnum].pos, tpos); - dot = vm_vec_dot(&v2e, tvec); + // dot = vm_vec_dot(&v2e, tvec); // MODIFY FOR ATTACKING BIG SHIP // dot += (0.5f * Objects[aip->target_objnum].radius / dist); - if (dot > fov) { +// if (dot > fov) { + if (object_in_turret_fov(&Objects[aip->target_objnum], tp, tvec, tpos, dist, tmat) ){ return aip->target_objnum; } } @@ -934,7 +971,7 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d } } - enemy_objnum = get_nearest_turret_objnum(objnum, turret_subsys, enemy_team_mask, tpos, tvec, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag); + enemy_objnum = get_nearest_turret_objnum(objnum, turret_subsys, enemy_team_mask, tpos, tvec, tmat, current_enemy, big_only_flag, small_only_flag, tagged_only_flag, beam_flag); if ( enemy_objnum >= 0 ) { Assert( !((Objects[enemy_objnum].flags & OF_BEAM_PROTECTED) && beam_flag) ); if ( Objects[enemy_objnum].flags & OF_PROTECTED ) { @@ -951,13 +988,68 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d // of the turret. The gun normal is the unrotated gun normal, (the center of the FOV cone), not // the actual gun normal given using the current turret heading. But it _is_ rotated into the model's orientation // in global space. -void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos, vec3d *gvec) +void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos, vec3d *gvec, matrix *tmat) { // vm_vec_unrotate(gpos, &tp->turret_avg_firing_point, &objp->orient); vm_vec_unrotate(gpos, &tp->pnt, &objp->orient); vm_vec_add2(gpos, &objp->pos); vm_vec_unrotate(gvec, &tp->turret_norm, &objp->orient); + + matrix *o = &model_get(tp->model_num)->submodel[tp->subobj_num].orientation; + if(tmat && !IS_MAT_NULL(o)){ + vm_matrix_x_matrix(tmat, &objp->orient, o); + } } +/*void ship_get_global_turret_info(object *objp, ship_subsys *tp, vec3d *gpos, vec3d *gvec, matrix *tmat) +{ +// vm_vec_unrotate(gpos, &tp->turret_avg_firing_point, &objp->orient); + *gvec = tp->system_info->turret_norm; + *gpos = tp->system_info->pnt; + polymodel* pm = model_get(tp->system_info->model_num); + int mn; + vec3d tpnt; + for ( ship_subsys*ss = tp->parent; ss; ss = ss->parent ){ + + int smn=ss->system_info->subobj_num; + if(smn <0)break; + + matrix *so = &pm->submodel[smn].orientation; + matrix m; + vm_angles_2_matrix(&m,&ss->submodel_info_1.angs ); + + if(!IS_MAT_NULL(&pm->submodel[smn].orientation)){ + matrix inv, f; + vm_matrix_inverse(&inv, &pm->submodel[smn].orientation); + vm_matrix_x_matrix(&f, &m, &inv); + vm_matrix_x_matrix(&m, &pm->submodel[smn].orientation, &f); + } + + + vm_vec_unrotate(&tpnt,gpos,&m); + + vm_vec_add(gpos,&tpnt,&pm->submodel[smn].offset ); + vm_vec_unrotate(&tpnt, gvec, &m); + + *gvec = tpnt; + mn = smn; + } + //if they are not a subsystem then we can assume they have no rotation, unless someone tries to put a turret on a look at object. + if(mn > 0) + for(mn = pm->submodel[mn].parent; mn > -1; mn = pm->submodel[mn].parent){ + vm_vec_add2(gpos,&pm->submodel[mn].offset); + } + + vm_vec_unrotate(&tpnt, gpos, &objp->orient); + vm_vec_add(gpos, &tpnt, &objp->pos); + vm_vec_unrotate(&tpnt, gvec, &objp->orient); + *gvec=tpnt; + + matrix *o = &pm->submodel[tp->system_info->subobj_num].orientation; + if(tmat && !IS_MAT_NULL(o)){ + vm_matrix_x_matrix(tmat, &objp->orient, o); + } +} +*/ // Given an object and a turret on that object, return the actual firing point of the gun // and its normal. This uses the current turret angles. We are keeping track of which @@ -1000,6 +1092,8 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object { int ret_val = 0; + matrix tmat; + if (ss->turret_enemy_objnum != -1) { model_subsystem *tp = ss->system_info; vec3d gun_pos, gun_vec; @@ -1019,7 +1113,7 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object // weapon_system_strength scales time enemy in range in 0..1. So, the lower this is, the worse the aiming will be. weapon_system_strength = ship_get_subsystem_strength(shipp, SUBSYSTEM_WEAPONS); - ship_get_global_turret_info(&Objects[parent_objnum], tp, &gun_pos, &gun_vec); + ship_get_global_turret_info(&Objects[parent_objnum], tp, &gun_pos, &gun_vec, &tmat); //Figure out what point on the ship we want to point the gun at, and store the global location //in enemy_point. @@ -1054,7 +1148,10 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object vec3d v2e; vm_vec_normalized_dir(&v2e, predicted_enemy_pos, &gun_pos); - if (vm_vec_dot(&v2e, gvec) > tp->turret_fov) { + float dist = vm_vec_normalized_dir(&v2e, predicted_enemy_pos, &gun_pos); + + if(object_in_turret_fov(lep, ss->system_info, &gun_vec, &gun_pos, dist ,&tmat)){ +// if (vm_vec_dot(&v2e, gvec) > tp->turret_fov) { ret_val = model_rotate_gun(shipp->modelnum, ss->system_info, &Objects[parent_objnum].orient, &ss->submodel_info_1.angs, &ss->submodel_info_2.angs, &Objects[parent_objnum].pos, predicted_enemy_pos); @@ -1556,6 +1653,39 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) return; } + Assert((parent_objnum >= 0) && (parent_objnum < MAX_OBJECTS)); + objp = &Objects[parent_objnum]; + Assert(objp->type == OBJ_SHIP); + Assert( shipp->objnum == parent_objnum ); + + // Monitor number of calls to ai_fire_from_turret + Num_ai_firing++; + + if ( (ss->turret_enemy_objnum < 0 || ss->turret_enemy_objnum >= MAX_OBJECTS) || (ss->turret_enemy_sig != Objects[ss->turret_enemy_objnum].signature)) + { + ss->turret_enemy_objnum = -1; + lep = NULL; + } + else + { + lep = &Objects[ss->turret_enemy_objnum]; + } + + + //aip = &Ai_info[Ships[objp->instance].ai_index]; + + // Use the turret info for all guns, not one gun in particular. + vec3d gvec, gpos; + matrix tmat; + ship_get_global_turret_info(&Objects[parent_objnum], tp, &gpos, &gvec, &tmat); + + // Rotate the turret even if time hasn't elapsed, since it needs to turn to face its target. + int use_angles = aifft_rotate_turret(shipp, parent_objnum, ss, objp, lep, &predicted_enemy_pos, &gvec); + + if ( !timestamp_elapsed(ss->turret_next_fire_stamp) ) { + return; + } + // check if there is any available weapon to fire int weap_check; bool valid_weap = false; @@ -1622,11 +1752,11 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) //aip = &Ai_info[Ships[objp->instance].ai_index]; // Use the turret info for all guns, not one gun in particular. - vec3d gvec, gpos; +// vec3d gvec, gpos; ship_get_global_turret_info(&Objects[parent_objnum], tp, &gpos, &gvec); // Rotate the turret even if time hasn't elapsed, since it needs to turn to face its target. - int use_angles = aifft_rotate_turret(shipp, parent_objnum, ss, objp, lep, &predicted_enemy_pos, &gvec); + use_angles = aifft_rotate_turret(shipp, parent_objnum, ss, objp, lep, &predicted_enemy_pos, &gvec); if ( !timestamp_elapsed(ss->turret_next_fire_stamp) ) { return; @@ -1773,7 +1903,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) // Maybe pick a new enemy. if ( turret_should_pick_new_target(ss) ) { Num_find_turret_enemy++; - int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum, tp->turret_fov); + int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, &tmat, ss->turret_enemy_objnum, tp->turret_fov); //Assert(objnum < 0 || is_target_beam_valid(tp, objnum)); if (objnum >= 0 && is_target_beam_valid(&ss->weapons, &Objects[objnum])) { @@ -1842,24 +1972,28 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) //This can't happen. See above code //Assert(ss->turret_enemy_objnum != -1); - float dot = vm_vec_dot(&v2e, &gvec); // Ok, the turret is lined up... now line up a particular gun. bool ok_to_fire = false; bool something_was_ok_to_fire=false; vec3d tv2e; //so flak can get their jitter without screwing up other guns - if (dot > tp->turret_fov ) { - // We're ready to fire... now get down to specifics, like where is the - // actual gun point and normal, not just the one for whole turret. - ship_get_global_turret_gun_info(&Objects[parent_objnum], ss, &gpos, &gvec, use_angles, &predicted_enemy_pos); + // We're ready to fire... now get down to specifics, like where is the + // actual gun point and normal, not just the one for whole turret. + //WMC - use_angles was always 0 + vec3d gp = gpos; + vec3d gd = gvec; + ship_get_global_turret_gun_info(&Objects[parent_objnum], ss, &gpos, &gvec, use_angles, &predicted_enemy_pos); + + // Fire in the direction the turret is facing, not right at the target regardless of turret dir. + vm_vec_sub(&v2e, &predicted_enemy_pos, &gpos); + dist_to_enemy = vm_vec_normalize(&v2e); + ss->turret_next_fire_pos++; + + float dot = vm_vec_dot(&v2e, &gvec); + if ( object_in_turret_fov(&Objects[ss->turret_enemy_objnum], ss->system_info, &gd, &gp, dist_to_enemy, &tmat) ) { + ss->turret_next_fire_pos++; - - // Fire in the direction the turret is facing, not right at the target regardless of turret dir. - vm_vec_sub(&v2e, &predicted_enemy_pos, &gpos); - dist_to_enemy = vm_vec_normalize(&v2e); - dot = vm_vec_dot(&v2e, &gvec); - for(i = 0; i < num_valid; i++) { wip = get_turret_weapon_wip(&ss->weapons, valid_weapons[i]); @@ -1907,6 +2041,43 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) } } + //start testing if your going to hit yourself-Bobboau + if(tp->flags & MSS_FLAG_TURRET_HULL_CHECK){ + polymodel *pm = model_get(shipp->modelnum); + mc_info test_collide; + matrix or; + vm_vector_2_matrix(&or, &v2e, NULL, NULL); + vec3d start, end; + + float r; + //push the initial vector along the normal by some amount that is roughly + //eqivelent to how wide the weapon is going to be + //this reduces false positives + if(wip->model_num != -1) + r = model_get_radius(wip->model_num)*4; + else if(wip->wi_flags & WIF_BEAM) + r = wip->b_info.beam_muzzle_radius; + else + r = wip->laser_head_radius*4; + + + vm_vec_scale_add(&start,&gpos, &gvec, r); + vm_vec_scale_add(&end,&gpos, &gvec, model_get_radius(shipp->modelnum)); + + test_collide.model_num = shipp->modelnum; + test_collide.submodel_num = pm->detail[0]; + test_collide.orient = &objp->orient; + test_collide.pos = &objp->pos; + test_collide.p0 = &gpos; + test_collide.p1 = &end; + test_collide.flags = MC_CHECK_MODEL | MC_CHECK_RAY; + + if(model_collide(&test_collide)){ + ok_to_fire = 0; + } + } + //end testing if your going to hit yourself + if ( ok_to_fire ) { something_was_ok_to_fire = true; diff --git a/code/bmpman/bmpman.cpp b/code/bmpman/bmpman.cpp index bdc739ee03..668560da42 100644 --- a/code/bmpman/bmpman.cpp +++ b/code/bmpman/bmpman.cpp @@ -10,13 +10,19 @@ /* * $Logfile: /Freespace2/code/Bmpman/BmpMan.cpp $ * - * $Revision: 2.94 $ - * $Date: 2007-01-10 01:40:06 $ - * $Author: taylor $ + * $Revision: 2.95 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * Code to load and manage all bitmaps for the game * * $Log: not supported by cvs2svn $ + * Revision 2.94 2007/01/10 01:40:06 taylor + * remove the non-dark stuff, it only works on PCX files and stuff to use it has already been ripped out + * per earlier discussions: remove -jpgtga and -pcx32, set image load order to DDS->TGA->JPG->PCX + * some debug log cleanup + * remove bitmap data from system memory once it's in API memory + * * Revision 2.93 2007/01/07 12:32:06 taylor * fix bm_page_in_texture() so that it will load all frames of an animation (caused slowdowns in-game with it) * @@ -2524,8 +2530,8 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags ) // read the file data if ( gr_bm_lock( be->filename, handle, bitmapnum, bpp, flags ) == -1 ) { // oops, this isn't good - reset and return NULL - bm_unlock( bitmapnum ); - bm_unload( bitmapnum ); + bm_unlock( handle ); + bm_unload( handle ); return NULL; } diff --git a/code/fred2/management.cpp b/code/fred2/management.cpp index 852a36c384..2ac81a96fa 100644 --- a/code/fred2/management.cpp +++ b/code/fred2/management.cpp @@ -9,9 +9,9 @@ /* * $Logfile: /Freespace2/code/Fred2/Management.cpp $ - * $Revision: 1.28 $ - * $Date: 2007-01-10 01:41:27 $ - * $Author: taylor $ + * $Revision: 1.29 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * This file handles the management of Objects, Ships, Wings, etc. Basically * all the little structures we have that usually inter-relate that need to @@ -19,6 +19,9 @@ * function. * * $Log: not supported by cvs2svn $ + * Revision 1.28 2007/01/10 01:41:27 taylor + * remove -jpgtga, set 32-bit mode as default (the OGL code will automatically fallback to 16-bit is needed) + * * Revision 1.27 2007/01/07 00:01:28 Goober5000 * add a feature for specifying the source of Command messages * @@ -1441,6 +1444,7 @@ void clear_mission() for(i=0; i= 0) return; @@ -5125,7 +5130,7 @@ void setup_environment_mapping(vec3d *eye_pos, matrix *eye_orient) return; } - ENVMAP = (Game_subspace_effect) ? gr_screen.dynamic_environment_map : gr_screen.static_environment_map; + ENVMAP = (Game_subspace_effect || The_mission.flags & MISSION_FLAG_DYNAMIC_ENVIRONMENT_MAP) ? gr_screen.dynamic_environment_map : gr_screen.static_environment_map; /* Envmap matrix setup -- left-handed @@ -5514,8 +5519,10 @@ void game_render_frame( vec3d *eye_pos, matrix *eye_orient ) shield_point_multi_setup(); } + void stars_add_lights(); + stars_add_lights(); // this needs to happen after g3_start_frame() and before the primary projection and view matrix is setup - if ( Cmdline_env && (!cube_map_drawen || Game_subspace_effect) ) { + if ( Cmdline_env && (!cube_map_drawen || Game_subspace_effect || The_mission.flags & MISSION_FLAG_DYNAMIC_ENVIRONMENT_MAP) ) { setup_environment_mapping(eye_pos, eye_orient); cube_map_drawen = true; } diff --git a/code/globalincs/pstypes.h b/code/globalincs/pstypes.h index dda42169ec..cc16b2c16f 100644 --- a/code/globalincs/pstypes.h +++ b/code/globalincs/pstypes.h @@ -9,16 +9,19 @@ /* * $Logfile: /Freespace2/code/GlobalIncs/PsTypes.h $ - * $Revision: 2.49 $ - * $Date: 2006-12-28 22:47:02 $ - * $Author: Goober5000 $ - * $Revision: 2.49 $ - * $Date: 2006-12-28 22:47:02 $ - * $Author: Goober5000 $ + * $Revision: 2.50 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ + * $Revision: 2.50 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * Header file containg global typedefs, constants and macros * * $Log: not supported by cvs2svn $ + * Revision 2.49 2006/12/28 22:47:02 Goober5000 + * fix spelling... *twitch* + * * Revision 2.48 2006/10/06 09:31:27 taylor * re-fix this crap that I managed to break last time (was Mantis bug 1066 I think) * @@ -530,7 +533,7 @@ typedef struct vert2df { */ typedef struct angles { - float p, b, h; + float p, b, h; } angles_t; typedef struct matrix { diff --git a/code/graphics/grbatch.cpp b/code/graphics/grbatch.cpp index a5abd46cab..12055943fd 100644 --- a/code/graphics/grbatch.cpp +++ b/code/graphics/grbatch.cpp @@ -157,6 +157,7 @@ const geometry_batcher &geometry_batcher::operator=(const geometry_batcher &geo) void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float depth) { + Assert(n_allocated > n_to_render + 2); vec3d*cam_position; matrix*cam_matrix; if(space == LOCAL_SPACE){ @@ -271,6 +272,7 @@ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float dep void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float angle, float depth) { + Assert(n_allocated > n_to_render + 2); vec3d*cam_position; matrix*cam_matrix; @@ -392,6 +394,7 @@ void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float ang void geometry_batcher::draw_tri(vertex* verts) { + Assert(n_allocated > n_to_render + 1); vertex *P = &vert[n_to_render *3 ]; for (int i = 0; i < 3; i++) @@ -402,6 +405,7 @@ void geometry_batcher::draw_tri(vertex* verts) void geometry_batcher::draw_quad(vertex* verts) { + Assert(n_allocated > n_to_render + 2); vertex *P = &vert[n_to_render * 3]; P[0] = verts[0]; @@ -418,6 +422,7 @@ void geometry_batcher::draw_quad(vertex* verts) void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity) { + Assert(n_allocated > n_to_render + 2); vec3d*cam_position; matrix*cam_matrix; @@ -489,6 +494,7 @@ void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float in float geometry_batcher::draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b) { + Assert(n_allocated > n_to_render + 2); width1 *= 0.5f; width2 *= 0.5f; @@ -593,13 +599,11 @@ void geometry_batcher::render(int flags) // laser batcher struct batch_item : public geometry_batcher { - batch_item(): texture(-1), tmap_flags(0), alpha(1.0f), laser(false) {}; + batch_item(): texture(-1), tmap_flags(0), alpha(1.0f) {}; int texture; int tmap_flags; float alpha; - - bool laser; }; static std::vector geometry_map; @@ -607,7 +611,7 @@ static std::vector geometry_map; int find_good_batch_item(int texture, int flags) { for (uint i = 0; i < geometry_map.size(); i++) { - if (geometry_map[i].texture == texture) + if (geometry_map[i].texture == texture && geometry_map[i].tmap_flags == flags) return i; } @@ -631,10 +635,9 @@ float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float wid } geometry_batcher *item = NULL; - int index = find_good_batch_item(texture); + int index = find_good_batch_item(texture, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT); Assert( index >= 0 ); - geometry_map[index].laser = true; item = &geometry_map[index]; item->add_allocate(1); @@ -653,8 +656,6 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float int index = find_good_batch_item(texture); Assert( index >= 0 ); - Assert( geometry_map[index].laser == false ); - geometry_map[index].tmap_flags = tmap_flags; geometry_map[index].alpha = alpha; @@ -694,24 +695,15 @@ void batch_set_flag(int geo, int flag){ void batch_render_lasers() { - for (uint i = 0; i < geometry_map.size(); i++) { - if ( !geometry_map[i].laser ) - continue; - - if ( !geometry_map[i].need_to_render() ) - continue; - - Assert( geometry_map[i].texture >= 0 ); - gr_set_bitmap(geometry_map[i].texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f); - geometry_map[i].render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT); - } } void batch_render_bitmaps() +{ +} + +void batch_render_all() { for (uint i = 0; i < geometry_map.size(); i++) { - if ( geometry_map[i].laser ) - continue; if ( !geometry_map[i].need_to_render() ) continue; @@ -722,12 +714,6 @@ void batch_render_bitmaps() } } -void batch_render_all() -{ - batch_render_lasers(); - batch_render_bitmaps(); -} - void batch_reset() { geometry_map.clear(); diff --git a/code/hud/hudets.cpp b/code/hud/hudets.cpp index f126c37c9a..886c72680b 100644 --- a/code/hud/hudets.cpp +++ b/code/hud/hudets.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Hud/HUDets.cpp $ - * $Revision: 2.20 $ - * $Date: 2006-02-25 21:47:00 $ - * $Author: Goober5000 $ + * $Revision: 2.21 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * C file that contains code to manage and display the Energy Transfer System (ETS) * * $Log: not supported by cvs2svn $ + * Revision 2.20 2006/02/25 21:47:00 Goober5000 + * spelling + * * Revision 2.19 2006/01/09 04:54:51 phreak * Remove tertiary weapons in their current form, I want something more flexable instead of what I had there. * @@ -383,7 +386,7 @@ void update_ets(object* objp, float fl_frametime) // new_energy = fl_frametime * sinfo_p->power_output; // update weapon energy - max_new_weapon_energy = fl_frametime * MAX_WEAPON_REGEN_PER_SECOND * max_g; + max_new_weapon_energy = sinfo_p->power_output * fl_frametime * MAX_WEAPON_REGEN_PER_SECOND * max_g; if ( objp->flags & OF_PLAYER_SHIP ) { ship_p->weapon_energy += Energy_levels[ship_p->weapon_recharge_index] * max_new_weapon_energy * The_mission.ai_profile->weapon_energy_scale[Game_skill_level]; } else { @@ -395,7 +398,7 @@ void update_ets(object* objp, float fl_frametime) } float shield_delta; - max_new_shield_energy = fl_frametime * MAX_SHIELD_REGEN_PER_SECOND * max_s; + max_new_shield_energy = sinfo_p->power_output * fl_frametime * MAX_SHIELD_REGEN_PER_SECOND * max_s; if ( objp->flags & OF_PLAYER_SHIP ) { shield_delta = Energy_levels[ship_p->shield_recharge_index] * max_new_shield_energy * The_mission.ai_profile->shield_energy_scale[Game_skill_level]; } else { diff --git a/code/hud/hudshield.cpp b/code/hud/hudshield.cpp index 0fd8e2b2c6..43d5a34b49 100644 --- a/code/hud/hudshield.cpp +++ b/code/hud/hudshield.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Hud/HUDshield.cpp $ - * $Revision: 2.39 $ - * $Date: 2006-05-18 14:56:02 $ - * $Author: taylor $ + * $Revision: 2.40 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * C file for the display and management of the HUD shield * * $Log: not supported by cvs2svn $ + * Revision 2.39 2006/05/18 14:56:02 taylor + * fix bool compiler warning for MSVC + * * Revision 2.38 2006/05/13 07:09:24 taylor * minor cleanup and a couple extra error checks * get rid of some wasteful math from the gr_set_proj_matrix() calls @@ -588,7 +591,10 @@ void hud_shield_show(object *objp) else { bool g3_yourself = !g3_in_frame(); - angles rot_angles = {-1.570796327f,0.0f,0.0f}; + angles rot_angles; + rot_angles.b = -1.570796327f; + rot_angles.p =0.0f; + rot_angles.h =0.0f; matrix object_orient; vm_angles_2_matrix(&object_orient, &rot_angles); diff --git a/code/lighting/lighting.cpp b/code/lighting/lighting.cpp index a9b8752e9d..21b84155a1 100644 --- a/code/lighting/lighting.cpp +++ b/code/lighting/lighting.cpp @@ -9,13 +9,22 @@ /* * $Logfile: /Freespace2/code/Lighting/Lighting.cpp $ - * $Revision: 2.21 $ - * $Date: 2006-07-24 07:36:50 $ - * $Author: taylor $ + * $Revision: 2.22 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * Code to calculate dynamic lighting on a vertex. * * $Log: not supported by cvs2svn $ + * Revision 2.21 2006/07/24 07:36:50 taylor + * minor cleanup/optimization to beam warmup glow rendering function + * various lighting code cleanups + * - try to always make sure beam origin lights occur outside of model + * - make Static_lights[] dynamic + * - be sure to reset to first 8 lights when moving on to render spec related texture passes + * - add ambient color to point lights (helps warp effects) + * - sort lights to try and get more important and/or visible lights to always happen in initial render pass + * * Revision 2.20 2006/02/19 23:14:22 Goober5000 * reduce confusion in naming * --Goober5000 @@ -750,6 +759,7 @@ int light_filter_push( int objnum, vec3d *pos, float rad ) Assert( Num_light_levels < MAX_LIGHT_LEVELS ); Num_relevent_lights[n2] = 0; + if(objnum < 0)return 0; for (i=0; i 0 ); } diff --git a/code/math/vecmat.cpp b/code/math/vecmat.cpp index 1d7a2b7f09..c48b4b3b03 100644 --- a/code/math/vecmat.cpp +++ b/code/math/vecmat.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Math/VecMat.cpp $ - * $Revision: 2.32 $ - * $Date: 2006-09-13 03:18:15 $ - * $Author: taylor $ + * $Revision: 2.33 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * C module containg functions for manipulating vectors and matricies * * $Log: not supported by cvs2svn $ + * Revision 2.32 2006/09/13 03:18:15 taylor + * might as well add this, just to be on the safe side (I haven't hit it anywhere, but it could be made into a warning if it starts getting hit) + * * Revision 2.31 2006/08/20 00:51:06 taylor * maybe optimize the (PI/2), (PI*2) and (RAND_MAX/2) stuff a little bit * @@ -1062,6 +1065,31 @@ float vm_vec_delta_ang_norm(vec3d *v0,vec3d *v1,vec3d *fvec) return a; } +matrix* vm_matrix_inverse(matrix*dest, matrix*src){ +/* float d = -src->a2d[0][0]*src->a2d[1][2]*src->a2d[2][1] + -src->a2d[0][1]*src->a2d[1][0]*src->a2d[2][2] + -src->a2d[0][2]*src->a2d[1][1]*src->a2d[2][0] + +src->a2d[0][0]*src->a2d[1][1]*src->a2d[2][2]; + +src->a2d[0][1]*src->a2d[1][2]*src->a2d[2][1] + +src->a2d[0][2]*src->a2d[1][0]*src->a2d[2][1] + */ + + dest->a2d[0][0] = (-src->a2d[1][2]*src->a2d[2][1]+src->a2d[1][1]*src->a2d[2][2]); + dest->a2d[0][1] = ( src->a2d[0][2]*src->a2d[2][1]-src->a2d[0][1]*src->a2d[2][2]); + dest->a2d[0][2] = (-src->a2d[0][2]*src->a2d[1][1]+src->a2d[0][1]*src->a2d[1][2]); + + dest->a2d[1][0] = ( src->a2d[1][2]*src->a2d[2][0]-src->a2d[1][0]*src->a2d[2][2]); + dest->a2d[1][1] = (-src->a2d[0][2]*src->a2d[2][0]+src->a2d[0][0]*src->a2d[2][2]); + dest->a2d[1][2] = ( src->a2d[0][2]*src->a2d[1][0]-src->a2d[0][0]*src->a2d[1][2]); + + dest->a2d[2][0] = (-src->a2d[1][1]*src->a2d[2][0]+src->a2d[1][0]*src->a2d[2][1]); + dest->a2d[2][1] = ( src->a2d[0][1]*src->a2d[2][0]-src->a2d[0][0]*src->a2d[2][1]); + dest->a2d[2][2] = (-src->a2d[0][1]*src->a2d[1][0]+src->a2d[0][0]*src->a2d[1][1]); + + return dest; +} + + matrix *sincos_2_matrix(matrix *m,float sinp,float cosp,float sinb,float cosb,float sinh,float cosh) { float sbsh,cbch,cbsh,sbch; diff --git a/code/math/vecmat.h b/code/math/vecmat.h index ff21b1462e..b6562d2429 100644 --- a/code/math/vecmat.h +++ b/code/math/vecmat.h @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Math/VecMat.h $ - * $Revision: 2.15 $ - * $Date: 2006-04-12 22:23:41 $ - * $Author: taylor $ + * $Revision: 2.16 $ + * $Date: 2007-01-14 14:03:32 $ + * $Author: bobboau $ * * Header file for functions that manipulate vectors and matricies * * $Log: not supported by cvs2svn $ + * Revision 2.15 2006/04/12 22:23:41 taylor + * compiler warning fixes to make GCC 4.1 shut the hell up + * * Revision 2.14 2006/02/25 21:47:00 Goober5000 * spelling * @@ -241,6 +244,8 @@ //macro to check if vector is zero #define IS_VEC_NULL(v) (((v)->xyz.x == 0.0f) && ((v)->xyz.y == 0.0f) && ((v)->xyz.z == 0.0f)) +#define IS_MAT_NULL(v) (IS_VEC_NULL(&(v)->vec.fvec) && IS_VEC_NULL(&(v)->vec.uvec) && IS_VEC_NULL(&(v)->vec.rvec)) + //macro to set a vector to zero. we could do this with an in-line assembly //macro, but it's probably better to let the compiler optimize it. //Note: NO RETURN VALUE @@ -545,6 +550,9 @@ matrix *vm_vector_2_matrix_norm(matrix *m,vec3d *fvec,vec3d *uvec,vec3d *rvec); //dest CANNOT equal either source vec3d *vm_vec_rotate(vec3d *dest,vec3d *src,matrix *m); +//makes an inverse of the src matrix +matrix* vm_matrix_inverse(matrix*dest, matrix*src); + //rotates a vector through the transpose of the given matrix. //returns ptr to dest vector //dest CANNOT equal source diff --git a/code/mission/missionparse.cpp b/code/mission/missionparse.cpp index 1df1ccc938..d4be623bf9 100644 --- a/code/mission/missionparse.cpp +++ b/code/mission/missionparse.cpp @@ -9,13 +9,17 @@ /* * $Logfile: /Freespace2/code/Mission/MissionParse.cpp $ - * $Revision: 2.208 $ - * $Date: 2007-01-07 21:28:10 $ - * $Author: Goober5000 $ + * $Revision: 2.209 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * main upper level code for parsing stuff * * $Log: not supported by cvs2svn $ + * Revision 2.208 2007/01/07 21:28:10 Goober5000 + * yet more tweaks to the WCS death scream stuff + * added a ship flag to force screaming + * * Revision 2.207 2007/01/07 12:55:57 taylor * safety check to make sure that we don't end up with non-player-usable weapons in the weaponselect pool (Mantis bug #1196) * @@ -5610,6 +5614,8 @@ void parse_reinforcements(mission *pm) while (required_string_either("#Background bitmaps", "$Name:")) parse_reinforcement(pm); + + } void parse_bitmap(mission *pm) @@ -5848,6 +5854,16 @@ void parse_bitmaps(mission *pm) stuff_string(pm->envmap_name, F_NAME, MAX_FILENAME_LEN); } + if (optional_string("+skybox_flags:")){ + pm->skybox_flags = 0; + parse_string_flag_list(&pm->skybox_flags, model_render_flags, model_render_flags_size); + }else{ + pm->skybox_flags = DEFALT_NMODEL_FLAGS; + } + if (optional_string("+dynamic_skybox")){ + pm->flags |= MISSION_FLAG_DYNAMIC_ENVIRONMENT_MAP; + } + // bypass spurious stuff from e.g. FS1 missions skip_to_start_of_string("#"); } diff --git a/code/mission/missionparse.h b/code/mission/missionparse.h index 0d1e6c76b3..f089ad27f3 100644 --- a/code/mission/missionparse.h +++ b/code/mission/missionparse.h @@ -9,13 +9,17 @@ /* * $Source: /cvs/cvsroot/fs2open/fs2_open/code/mission/missionparse.h,v $ - * $Revision: 2.94 $ - * $Author: Goober5000 $ - * $Date: 2007-01-07 21:28:11 $ + * $Revision: 2.95 $ + * $Author: bobboau $ + * $Date: 2007-01-14 14:03:33 $ * * main header file for parsing code * * $Log: not supported by cvs2svn $ + * Revision 2.94 2007/01/07 21:28:11 Goober5000 + * yet more tweaks to the WCS death scream stuff + * added a ship flag to force screaming + * * Revision 2.93 2007/01/07 01:00:18 Goober5000 * convert a mission variable to a mission flag * @@ -630,7 +634,8 @@ struct p_dock_instance; #define MISSION_FLAG_SCRAMBLE (1<<17) // a scramble mission - Goober5000 #define MISSION_FLAG_NO_BUILTIN_COMMAND (1<<18) // turns off Command without turning off pilots - Karajorma #define MISSION_FLAG_PLAYER_START_AI (1<<19) // Player Starts mission under AI Control (NOT MULTI COMPATABLE) - Kazan -#define MISSION_FLAG_ALL_ATTACK (1<<20) // all teams at war - Goober5000 +#define MISSION_FLAG_DYNAMIC_ENVIRONMENT_MAP (1<<20) // mission uses dynamic environment map +#define MISSION_FLAG_ALL_ATTACK (1<<21) // all teams at war - Goober5000 // some mice macros for mission type #define IS_MISSION_MULTI_COOP (The_mission.game_type & MISSION_TYPE_MULTI_COOP) @@ -668,7 +673,10 @@ typedef struct mission { char squad_filename[MAX_FILENAME_LEN]; // if the player has been reassigned to a squadron, this is the filename of the logo, otherwise empty string char squad_name[NAME_LENGTH]; // if the player has been reassigned to a squadron, this is the name of the squadron, otherwise empty string char loading_screen[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN]; + char skybox_model[MAX_FILENAME_LEN]; + int skybox_flags; + char envmap_name[MAX_FILENAME_LEN]; int contrail_threshold; int ambient_light_level; diff --git a/code/missionui/missionscreencommon.cpp b/code/missionui/missionscreencommon.cpp index 3e9f325312..5c9b7cb73a 100644 --- a/code/missionui/missionscreencommon.cpp +++ b/code/missionui/missionscreencommon.cpp @@ -9,11 +9,14 @@ /* * $Logfile: /Freespace2/code/MissionUI/MissionScreenCommon.cpp $ - * $Revision: 2.36 $ - * $Date: 2006-12-28 00:59:32 $ - * $Author: wmcoolmon $ + * $Revision: 2.37 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * $Log: not supported by cvs2svn $ + * Revision 2.36 2006/12/28 00:59:32 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.35 2006/11/06 05:43:36 taylor * fix a memory leak that Valgrind was complaining about (happens mainly when you have a mission without a briefing) * @@ -1830,7 +1833,10 @@ void draw_model_icon(int model_id, int flags, float closeup_zoom, int x, int y, return; matrix object_orient = IDENTITY_MATRIX; - angles rot_angles = {0.0f,0.0f,0.0f}; + angles rot_angles; + rot_angles.p =0.0f; + rot_angles.b =0.0f; + rot_angles.h =0.0f; float zoom = closeup_zoom * 2.5f; if(sip == NULL) diff --git a/code/model/model.h b/code/model/model.h index 0ca8e728fb..036e3b930c 100644 --- a/code/model/model.h +++ b/code/model/model.h @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Model/MODEL.H $ - * $Revision: 2.97 $ - * $Date: 2007-01-10 01:44:39 $ - * $Author: taylor $ + * $Revision: 2.98 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * header file for information about polygon models * * $Log: not supported by cvs2svn $ + * Revision 2.97 2007/01/10 01:44:39 taylor + * add support for new IBX format which can support up to UINT_MAX worth of verts (NOTE: D3D code still needs to be made compatible with this!!) + * * Revision 2.96 2006/12/28 22:47:03 Goober5000 * fix spelling... *twitch* * @@ -692,6 +695,8 @@ struct object; +extern flag_def_list model_render_flags[]; +extern int model_render_flags_size; #define MAX_DEBRIS_OBJECTS 32 #define MAX_MODEL_DETAIL_LEVELS 8 @@ -699,11 +704,12 @@ struct object; #define MAX_NAME_LEN 32 #define MAX_ARC_EFFECTS 8 -#define MOVEMENT_TYPE_NONE -1 -#define MOVEMENT_TYPE_POS 0 -#define MOVEMENT_TYPE_ROT 1 +#define MOVEMENT_TYPE_NONE -1 +#define MOVEMENT_TYPE_POS 0 +#define MOVEMENT_TYPE_ROT 1 #define MOVEMENT_TYPE_ROT_SPECIAL 2 // for turrets only -#define MOVEMENT_TYPE_TRIGGERED 3 //triggered rotation +#define MOVEMENT_TYPE_TRIGGERED 3 //triggered rotation +#define MOVEMENT_TYPE_LOOK_AT 4 // the subobject is always looking at a 'look at' subobject, as best it can - Bobboau // DA 11/13/98 Reordered to account for difference between max and game @@ -766,7 +772,10 @@ typedef struct submodel_instance_info { #define MSS_FLAG_UNTARGETABLE (1 << 8) // Goober5000 #define MSS_FLAG_CARRY_NO_DAMAGE (1 << 9) // WMC #define MSS_FLAG_USE_MULTIPLE_GUNS (1 << 10) // WMC -#define MSS_FLAG_FIRE_ON_NORMAL (1 << 11) // forces a turret to fire down its normal vecs +#define MSS_FLAG_FIRE_ON_NORMAL (1 << 11) // forces a turret to fire down it's normal vecs +#define MSS_FLAG_TURRET_HULL_CHECK (1 << 12) // makes the turret check to see if it's going to shoot through it's own hull before fireing - Bobboau +#define MSS_FLAG_DUM_ROTATES (1 << 13) // rotates in a similar fashion (from the end user's point of view anyway) as rotateing subobjects + // haha! dumb is suposed to have a b at the end, but this doesn't! this must be REALLY dumb! hahahahahaha lolololol omgftw! // definition of stepped rotation struct typedef struct stepped_rotation { @@ -808,6 +817,7 @@ typedef struct model_subsystem { /* contains rotation rate info */ vec3d turret_norm; // direction this turret faces matrix turret_matrix; // turret_norm converted to a matrix. float turret_fov; // dot of turret_norm:vec_to_enemy > this means can see + float turret_y_fov; // y_component int turret_num_firing_points; // number of firing points on this turret vec3d turret_firing_point[MAX_TFP]; // in parent object's reference frame, point from which to fire. int turret_gun_sobj; // Which subobject in this model the firing points are linked to. @@ -843,6 +853,8 @@ typedef struct model_subsystem { /* contains rotation rate info */ int n_triggers; queued_animation *triggers; //all the triggered animations assosiated with this object + script_hook scripted_rotation; + } model_subsystem; typedef struct model_special { @@ -853,6 +865,38 @@ typedef struct model_special { vec3d norm; // normal for the special submodel thingy } model_special; +struct glow_point{ + vec3d pnt; + vec3d norm; + float radius; +}; + +typedef struct thruster_bank { + std::vector points; + + // Engine wash info + struct engine_wash_info *wash_info_pointer; // index into Engine_wash_info + + int obj_num; // what subsystem number this thruster is on + int sub_model; +} thruster_bank; + +typedef struct glow_point_bank { // glow bank structure -Bobboau + int type; + int glow_timestamp; + int on_time; + int off_time; + int disp_time; + int is_on; + int is_active; + int submodel_parent; + int LOD; + int num_points; + glow_point *points; + int glow_bitmap; + int glow_neb_bitmap; +} glow_point_bank; + // model arc types #define MARC_TYPE_NORMAL 0 // standard freespace 1 blue lightning arcs #define MARC_TYPE_EMP 1 // EMP blast type arcs @@ -892,6 +936,7 @@ typedef struct IBX { typedef struct bsp_info { + int sub_object_number; // who am I again? char name[MAX_NAME_LEN]; // name of the subsystem. Probably displayed on HUD int movement_type; // -1 if no movement, otherwise rotational or positional movement -- subobjects only int movement_axis; // which axis this subobject moves or rotates on. @@ -913,6 +958,8 @@ typedef struct bsp_info { int my_replacement; // If not -1 this subobject is what should get rendered instead of this one int i_replace; // If this is not -1, then this subobject will replace i_replace when it is damaged angles angs; // The angles from parent. Stuffed by model_set_instance + angles ang_vel; // rate of change of above + angles ang_acl; // rate of change of above int is_live_debris; // whether current submodel is a live debris model int num_live_debris; // num live debris models assocaiated with a submodel @@ -947,8 +994,18 @@ typedef struct bsp_info { vec3d render_box_min; vec3d render_box_max; int use_render_box; //0==do nothing, 1==only render this object if you are inside the box, -1==only if your out + + float render_sphere; + int use_render_sphere; + bool gun_rotation;//for animated weapon models + matrix orientation; + int look_at; + + float dumb_turn_rate; // The turning rate of this subobject, if MSS_FLAG_ROTATES is set. + + std::vector submodel_thruster; } bsp_info; void parse_triggersint(int &n_trig, queued_animation **triggers, char *props); @@ -994,37 +1051,6 @@ typedef struct w_bank { float radius[MAX_SLOTS]; } w_bank; -struct glow_point{ - vec3d pnt; - vec3d norm; - float radius; -}; - -typedef struct thruster_bank { - int num_points; - glow_point *points; - - // Engine wash info - struct engine_wash_info *wash_info_pointer; // index into Engine_wash_info - - int obj_num; // what subsystem number this thruster is on -} thruster_bank; - -typedef struct glow_point_bank { // glow bank structure -Bobboau - int type; - int glow_timestamp; - int on_time; - int off_time; - int disp_time; - int is_on; - int is_active; - int submodel_parent; - int LOD; - int num_points; - glow_point *points; - int glow_bitmap; - int glow_neb_bitmap; -} glow_point_bank; // defines for docking bay things. The types are essentially flags since docking bays can probably // be used for multiple things in some cases (i.e. rearming and general docking) @@ -1074,7 +1100,8 @@ typedef struct shield_tri { // The verts array in the shield_tri structure points to one of these members typedef struct shield_vertex { vec3d pos; - float u,v; + vec3d norm; + float u,v,i; } shield_vertex; // the high level shield structure. A ship without any shield has nverts and ntris set to 0. @@ -1213,11 +1240,11 @@ typedef struct polymodel { int n_guns; // number of primary gun points (not counting turrets) int n_missiles; // number of secondary missile points (not counting turrets) int n_docks; // number of docking points - int n_thrusters; // number of thrusters on this ship. +// int n_thrusters; // number of thrusters on this ship. w_bank *gun_banks; // array of gun banks w_bank *missile_banks; // array of missile banks dock_bay *docking_bays; // array of docking point pairs - thruster_bank *thrusters; // array of thruster objects -- likely to change in the future +// thruster_bank *thrusters; // array of thruster objects -- likely to change in the future ship_bay_t *ship_bay; // contains path indexes for ship bay approach/depart paths shield_info shield; // new shield information @@ -1718,4 +1745,11 @@ int decal_make_model(polymodel * pm); void model_setup_cloak(vec3d *shift, int full_cloak, int alpha); void model_finish_cloak(int full_cloak); +void model_do_look_at(int model_num); + +struct ship_subsys; +void model_2_submodel(polymodel *pm, int sn, vec3d*v, matrix*m); +void submodel_scripted_rotate(object* obj, ship_subsys *pss); +void model_do_dumb_rotation(int modelnum); + #endif // _MODEL_H diff --git a/code/model/modelanim.h b/code/model/modelanim.h index dc8a8a7e3e..e9fbb4d3fa 100644 --- a/code/model/modelanim.h +++ b/code/model/modelanim.h @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/model/modelanim.h $ - * $Revision: 1.2 $ - * $Date: 2006-11-06 06:50:59 $ - * $Author: taylor $ + * $Revision: 1.3 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * header file for information about polygon models * * $Log: not supported by cvs2svn $ + * Revision 1.2 2006/11/06 06:50:59 taylor + * updated/fixed modelanim code + * * * $NoKeywords: $ */ @@ -42,7 +45,7 @@ #define TRIGGER_TYPE_DOCK_BAY_DOOR 5 //fighter bays #define TRIGGER_TYPE_AFTERBURNER 6 //Afterburner -C #define TRIGGER_TYPE_TURRET_FIRING 7 //Turret shooting -C -#define TRIGGER_TYPE_SCRIPTEDturret_animation_position 8 //Triggered exclusively by scripting...maybe SEXPs? -C +#define TRIGGER_TYPE_SCRIPTED 8 //Triggered exclusively by scripting...maybe SEXPs? -C #define MAX_TRIGGER_ANIMATION_TYPES 9 diff --git a/code/model/modelcollide.cpp b/code/model/modelcollide.cpp index 75e0416c69..96be60bbd0 100644 --- a/code/model/modelcollide.cpp +++ b/code/model/modelcollide.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Model/ModelCollide.cpp $ - * $Revision: 2.17 $ - * $Date: 2006-09-11 06:45:40 $ - * $Author: taylor $ + * $Revision: 2.18 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * Routines for detecting collisions of models. * * $Log: not supported by cvs2svn $ + * Revision 2.17 2006/09/11 06:45:40 taylor + * various small compiler warning and strict compiling fixes + * * Revision 2.16 2006/07/06 04:06:04 Goober5000 * 1) complete (almost) changeover to reorganized texture mapping system * 2) finally fix texture animation; textures now animate at the correct speed @@ -1031,6 +1034,14 @@ NoHit: vm_vec_add2(&Mc_base, &saved_base ); vm_angles_2_matrix(&tm, &csm->angs); + + if(!IS_MAT_NULL(&csm->orientation)){ + matrix inv, f; + vm_matrix_inverse(&inv, &csm->orientation); + vm_matrix_x_matrix(&f, &tm, &inv); + vm_matrix_x_matrix(&tm, &csm->orientation, &f); + } + vm_matrix_x_matrix(&Mc_orient, &saved_orient, &tm); mc_check_subobj( i ); diff --git a/code/model/modelinterp.cpp b/code/model/modelinterp.cpp index c404fae83c..fc42965945 100644 --- a/code/model/modelinterp.cpp +++ b/code/model/modelinterp.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Model/ModelInterp.cpp $ - * $Revision: 2.179 $ - * $Date: 2007-01-14 10:26:38 $ - * $Author: wmcoolmon $ + * $Revision: 2.180 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * Rendering models, I think. * * $Log: not supported by cvs2svn $ + * Revision 2.179 2007/01/14 10:26:38 wmcoolmon + * Attempt to remove various warnings under MSVC 2003, mostly related to casting, but also some instances of inaccessible code. + * * Revision 2.178 2007/01/13 16:38:22 bobboau * made a last second change of mind on something, made it a bit safer * @@ -4062,9 +4065,9 @@ void model_render_thrusters(bsp_info*model, ship *shipp) geometry_batcher* pri_geo, *sec_geo, *tri_geo; - pri_geo = batch_get_geometry(find_good_batch_item(Interp_thrust_glow_bitmap)); - sec_geo = batch_get_geometry(find_good_batch_item(Interp_secondary_thrust_glow_bitmap)); - tri_geo = batch_get_geometry(find_good_batch_item(Interp_tertiary_thrust_glow_rad_factor)); + pri_geo = batch_get_geometry(find_good_batch_item(Interp_thrust_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT)); + sec_geo = batch_get_geometry(find_good_batch_item(Interp_secondary_thrust_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT)); + tri_geo = batch_get_geometry(find_good_batch_item(Interp_tertiary_thrust_glow_rad_factor, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT)); pri_geo->space=WORLD_SPACE; sec_geo->space=WORLD_SPACE; tri_geo->space=WORLD_SPACE; @@ -4087,6 +4090,10 @@ void model_render_thrusters(bsp_info*model, ship *shipp) if ( !model_should_render_engine_glow(model->sub_object_number, bank->obj_num) ) continue; + pri_geo->add_allocate(bank->points.size()); + sec_geo->add_allocate(bank->points.size()); + tri_geo->add_allocate(bank->points.size()); + for (j = 0; j < bank->points.size(); j++) { float d, D; diff --git a/code/model/modelread.cpp b/code/model/modelread.cpp index c52df56ae1..7202c8c173 100644 --- a/code/model/modelread.cpp +++ b/code/model/modelread.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Model/ModelRead.cpp $ - * $Revision: 2.122 $ - * $Date: 2007-01-10 01:44:39 $ - * $Author: taylor $ + * $Revision: 2.123 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * file which reads and deciphers POF information * * $Log: not supported by cvs2svn $ + * Revision 2.122 2007/01/10 01:44:39 taylor + * add support for new IBX format which can support up to UINT_MAX worth of verts (NOTE: D3D code still needs to be made compatible with this!!) + * * Revision 2.121 2006/12/28 22:47:03 Goober5000 * fix spelling... *twitch* * @@ -1227,10 +1230,22 @@ #include "cfile/cfile.h" #include "parse/parselo.h" #include "cmdline/cmdline.h" +#include "parse/scripting.h" +#include "parse/lua.h" #include "gamesnd/gamesnd.h" +flag_def_list model_render_flags[] = +{ + {"no lighting", MR_NO_LIGHTING}, + {"transparent", MR_ALL_XPARENT}, + {"no Zbuffer", MR_NO_ZBUFFER}, + {"no cull", MR_NO_CULL}, + {"no glowmaps", MR_NO_GLOWMAPS} +}; + +int model_render_flags_size = sizeof(model_render_flags)/sizeof(flag_def_list); #define MAX_SUBMODEL_COLLISION_ROT_ANGLE (PI / 6.0f) // max 30 degrees per frame @@ -1356,15 +1371,15 @@ void model_unload(int modelnum, int force) vm_free(pm->docking_bays); } - - if ( pm->thrusters ) { +//thrusters are vectors now, and they are on a per submodel basis now too +/* if ( pm->thrusters ) { for (i = 0; i < pm->n_thrusters; i++) { if (pm->thrusters[i].points) vm_free(pm->thrusters[i].points); } vm_free(pm->thrusters); - } + }*/ if ( pm->glow_point_banks ) { // free the glows!!! -Bobboau for (i = 0; i < pm->n_glow_point_banks; i++) { @@ -1556,6 +1571,7 @@ void model_copy_subsystems( int n_subsystems, model_subsystem *d_sp, model_subsy int nfp; dest->turret_fov = source->turret_fov; + dest->turret_y_fov = source->turret_y_fov; dest->turret_num_firing_points = source->turret_num_firing_points; dest->turret_norm = source->turret_norm; dest->turret_matrix = source->turret_matrix; @@ -1605,6 +1621,16 @@ static void set_subsystem_info( model_subsystem *subsystemp, char *props, char * strcpy(buf,"180"); angle = ANG_TO_RAD(atoi(buf))/2.0f; subsystemp->turret_fov = (float)cos(angle); + + if ( (p = strstr(props, "$y_fov")) != NULL ){ + get_user_prop_value(p+6, buf); // get the value of the fov + angle = ANG_TO_RAD(atoi(buf))/2.0f; + subsystemp->turret_y_fov = (float)(angle); + }else{ + subsystemp->turret_y_fov = -2.0f; + } + + subsystemp->turret_num_firing_points = 0; if ( (p = strstr(props, "$crewspot")) != NULL) { @@ -1636,6 +1662,11 @@ static void set_subsystem_info( model_subsystem *subsystemp, char *props, char * subsystemp->flags |= MSS_FLAG_TRIGGERED; } +//unnesisary additional formatting +// if ( (p = strstr(props, "$orient:")) != NULL ) { +// p+=8; + + // Rotating subsystem if ( (p = strstr(props, "$rotate")) != NULL) { subsystemp->flags |= MSS_FLAG_ROTATES; @@ -2192,7 +2223,7 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs //mprintf(0,"Got chunk SOBJ, len=%d\n",len); - n = cfread_int(fp); + pm->submodel[n].sub_object_number = n = cfread_int(fp); //mprintf(("SOBJ IDed itself as %d", n)); Assert(n < pm->n_models ); @@ -2245,6 +2276,19 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs } } + if(( p = strstr(props, "$look_at:"))!= NULL ){ + pm->submodel[n].movement_type = MOVEMENT_TYPE_LOOK_AT; + pm->submodel[n].look_at = atoi(p+9); + }else{ + pm->submodel[n].look_at = -1; + } + if(( p = strstr(props, "$dumb_rotate:"))!= NULL ){ + pm->submodel[n].movement_type = MSS_FLAG_DUM_ROTATES; + pm->submodel[n].dumb_turn_rate = atof(p+13); + }else{ + pm->submodel[n].dumb_turn_rate = 0.0f; + } + if ( pm->submodel[n].name[0] == '\0' ) { strcpy(pm->submodel[n].name, "unknown object name"); } @@ -2283,6 +2327,14 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs else pm->submodel[n].gun_rotation = false; + if ( (p = strstr(props, "$detail_sphere:")) != NULL ) { + p += 15; + pm->submodel[n].use_render_sphere = atoi(p); + p=strstr(p, ","); + pm->submodel[n].render_sphere = (float)strtod(++p, (char **)NULL); + pm->submodel[n].render_sphere*=pm->submodel[n].render_sphere; + } + if ( (p = strstr(props, "$detail_box:")) != NULL ) { p += 13; pm->submodel[n].use_render_box = atoi(p); @@ -2310,6 +2362,70 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs } } + matrix *o = &pm->submodel[n].orientation; + if((p = strstr(props, "$uvec:")) != NULL ){ + p+=6; + + char*c = p; + while(*c==' ')c++;//skip spaces + o->vec.uvec.xyz.x = atof(c); + c = strchr(c,',');//find end of number + c++; + while(*c==' ')c++;//skip spaces + o->vec.uvec.xyz.y = atof(c); + c = strchr(c,',');//find end of number + c++; + while(*c==' ')c++;//skip spaces + o->vec.uvec.xyz.z = atof(c); + if((p = strstr(props, "$fvec:")) != NULL ){ + c = p+6; + + while(*c==' ')c++;//skip spaces + o->vec.fvec.xyz.x = atof(c); + c = strchr(c,',');//find end of number + c++; + while(*c==' ')c++;//skip spaces + o->vec.fvec.xyz.y = atof(c); + c = strchr(c,',');//find end of number + c++; + while(*c==' ')c++;//skip spaces + o->vec.fvec.xyz.z = atof(c); + + vm_vec_crossprod(&o->vec.rvec, &o->vec.uvec, &o->vec.fvec); + vm_vec_crossprod(&o->vec.fvec, &o->vec.rvec, &o->vec.uvec); + vm_vec_normalize(&o->vec.uvec); + vm_vec_normalize(&o->vec.fvec); + vm_vec_normalize(&o->vec.rvec); + + }else{ + int p = pm->submodel[n].parent; + if(p >-1){ + matrix *O = &pm->submodel[p].orientation; + memcpy(o,O,sizeof(matrix)); + }else{ + memset(o,0,sizeof(matrix)); + } + Error( LOCATION, "improper custum orientation matrix, you must define a up vector, then a forward vector"); + } + }else{ + int p = pm->submodel[n].parent; + if(p >-1){ + matrix *O = &pm->submodel[p].orientation; + memcpy(o,O,sizeof(matrix)); + }else{ + memset(o,0,sizeof(matrix)); + } + if(strstr(props, "$fvec:") != NULL )Error( LOCATION, "improper custum orientation matrix, you must define a up vector, then a forward vector"); + } + + pm->submodel[n].ang_vel.p = 0.0f; + pm->submodel[n].ang_vel.b = 0.0f; + pm->submodel[n].ang_vel.h = 0.0f; + + pm->submodel[n].ang_acl.p = 1.0f; + pm->submodel[n].ang_acl.b = 1.0f; + pm->submodel[n].ang_acl.h = 1.0f; + if ( !rotating_submodel_has_subsystem ) { nprintf(("Model", "Model %s: Rotating Submodel without subsystem: %s\n", pm->filename, pm->submodel[n].name)); @@ -2396,6 +2512,21 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs pm->shield.tris[i].neighbors[j] = cfread_int( fp ); // read in the neighbor indices -- indexes into tri list } } + for(i = 0; ishield.nverts; i++){ + vec3d*norm = &pm->shield.verts[i].norm; + vm_vec_zero(norm); + int n = 0; + for(j = 0; jshield.ntris; j++){ + for (int k = 0; k<3; k++){ + if(pm->shield.tris[j].verts[k] == i){ + n++; + vm_vec_add2(norm, &pm->shield.tris[j].norm); + } + } + } + if(n) + vm_vec_scale(norm, 1.0f/float(n)); + } } break; @@ -2576,26 +2707,22 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs } case ID_FUEL: + {//go ahead remove this bracket, see what it's for, I dare you char props[MAX_PROP_LEN]; - pm->n_thrusters = cfread_int(fp); + int n_thrusters = cfread_int(fp); - if (pm->n_thrusters > 0) { - pm->thrusters = (thruster_bank *)vm_malloc(sizeof(thruster_bank) * pm->n_thrusters); - Assert( pm->thrusters != NULL ); + if (n_thrusters > 0) { - for (i = 0; i < pm->n_thrusters; i++ ) { - thruster_bank *bank = &pm->thrusters[i]; + thruster_bank bank; + for (i = 0; i < n_thrusters; i++ ) { - bank->num_points = cfread_int(fp); - bank->points = NULL; + int num_points = cfread_int(fp); - if (bank->num_points > 0) - bank->points = (glow_point *) vm_malloc(sizeof(glow_point) * bank->num_points); - - bank ->obj_num = -1; + bank.obj_num = -1; + bank.sub_model = -1; if (pm->version < 2117) { - bank->wash_info_pointer = NULL; + bank.wash_info_pointer = NULL; } else { cfread_string_len( props, MAX_PROP_LEN, fp ); // look for $engine_subsystem=xxx @@ -2613,23 +2740,25 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs // set wash_info_index to invalid int table_error = 1; - bank->wash_info_pointer = NULL; + bank.wash_info_pointer = NULL; + bank.sub_model = -1; for (int k=0; kwash_info_pointer = subsystems[k].engine_wash_pointer; - if (bank->wash_info_pointer != NULL) { + bank.wash_info_pointer = subsystems[k].engine_wash_pointer; + if (bank.wash_info_pointer != NULL) { table_error = 0; } // also set what subsystem this is attached to but not if we only have one thruster bank // do this so that original :V: models still work like they used to - if (pm->n_thrusters > 1) { - bank->obj_num = k; + if (n_thrusters > 1) { + bank.obj_num = k; } + bank.sub_model = subsystems[k].subobj_num; break; } } - if ( (bank->wash_info_pointer == NULL) && (n_subsystems > 0) ) { + if ( (bank.wash_info_pointer == NULL) && (n_subsystems > 0) ) { if (table_error) { // Warning(LOCATION, "No engine wash table entry in ships.tbl for ship model %s", filename); } else { @@ -2637,26 +2766,42 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs } } } else { - bank->wash_info_pointer = NULL; + bank.wash_info_pointer = NULL; } } - for (j = 0; j < bank->num_points; j++) { - glow_point *p = &bank->points[j]; + glow_point p; + vec3d os; + if(bank.sub_model > -1){ + model_find_submodel_offset(&os, pm->id, bank.sub_model); + } + for (j = 0; j < num_points; j++) { - cfread_vector( &(p->pnt), fp ); - cfread_vector( &(p->norm), fp ); + cfread_vector( &(p.pnt), fp ); + cfread_vector( &(p.norm), fp ); if ( pm->version > 2004 ) { - p->radius = cfread_float( fp ); + p.radius = cfread_float( fp ); //mprintf(( "Rad = %.2f\n", rad )); } else { - p->radius = 1.0f; + p.radius = 1.0f; } + if(bank.sub_model > -1){ + vm_vec_sub2(&p.pnt, &os); + } + + bank.points.push_back(p); } //mprintf(( "Num slots = %d\n", bank->num_slots )); + if(bank.sub_model < 0){ + pm->submodel[pm->detail[0]].submodel_thruster.push_back(bank); + }else{ + pm->submodel[bank.sub_model].submodel_thruster.push_back(bank); + } + bank.points.clear(); } } + } break; case ID_TGUN: @@ -4121,6 +4266,157 @@ void submodel_rotate(model_subsystem *psub, submodel_instance_info *sii) break; } } + +/*void submodel_scripted_rotate(object* ship_obj, ship_subsys *pss) +{ + + if ( pss->system_info->subobj_num < 0 ) return; + if(!pss->system_info->scripted_rotation.IsValid())return; + + pss->submodel_info_1.prev_angs = pss->submodel_info_1.angs; + + script_lua_odata lua_ship_obj = l_Ship.Set(object_h(ship_obj)); + script_lua_odata lua_subsys = l_Subsystem.Set(ship_subsys_h(ship_obj,pss)); + + Script_system.SetGlobal("Self", 'o', &lua_ship_obj); + Script_system.SetGlobal(pss->system_info->name, 'o', &lua_subsys); + + Script_system.RunBytecode(pss->system_info->scripted_rotation); + + Script_system.GetGlobal(pss->system_info->name, 'o', lua_subsys); + + Script_system.RemGlobal(pss->system_info->name); + Script_system.RemGlobal("Self"); + +} +*/ +void submodel_scripted_rotate(object* ship_obj, ship_subsys *pss) +{ + model_subsystem *psub = pss->system_info; + submodel_instance_info *sii = &pss->submodel_info_1; + + if ( psub->subobj_num < 0 ) return; + if(!psub->scripted_rotation.IsValid())return; + + sii->prev_angs = sii->angs; + +// ade_odata ade_ship_obj = l_Ship.Set(object_h(ship_obj)); + ade_odata ade_sys = l_Subsystem.Set(ship_subsys_h(ship_obj, pss)); + + Script_system.SetHookObject("Self", OBJ_INDEX(ship_obj)); + Script_system.SetHookVar(pss->system_info->name, 'o', &ade_sys); + + Script_system.RunBytecode(psub->scripted_rotation); + + Script_system.RemHookVar("Self"); + Script_system.RemHookVar(pss->system_info->name); + +} + +void world_find_real_model_point(vec3d *out, vec3d *world_pt, polymodel *pm, int submodel_num, matrix *orient, vec3d *pos); + +void submodel_look_at(polymodel *pm, int mn) +{ + bsp_info * sm; + + if ( mn < 0 ) return; + + sm = &pm->submodel[mn]; + angles *angs = &pm->submodel[mn].angs; + + if ( sm->movement_type != MOVEMENT_TYPE_LOOK_AT ) return; + + // save last angles +// sii->prev_angs = sii->angs; + + // probably send in a calculated desired turn rate +/* float diff = sii->desired_turn_rate - sii->cur_turn_rate; + + float final_turn_rate; + if (diff > 0) { + final_turn_rate = sii->cur_turn_rate + sii->turn_accel * flFrametime; + if (final_turn_rate > sii->desired_turn_rate) { + final_turn_rate = sii->desired_turn_rate; + } + } else if (diff < 0) { + final_turn_rate = sii->cur_turn_rate - sii->turn_accel * flFrametime; + if (final_turn_rate < sii->desired_turn_rate) { + final_turn_rate = sii->desired_turn_rate; + } + } else { + final_turn_rate = sii->desired_turn_rate; + } + + float delta = (sii->cur_turn_rate + final_turn_rate) * 0.5f * flFrametime; + sii->cur_turn_rate = final_turn_rate; +*/ + + vec3d other, mp; + + int pmn = pm->id; + + model_find_world_point(&mp, &vmd_zero_vector, pmn, sm->look_at, &vmd_identity_matrix, &vmd_zero_vector); + world_find_real_model_point(&other, &mp, pm, mn, &vmd_identity_matrix, &vmd_zero_vector); + if(!IS_MAT_NULL(&pm->submodel[mn].orientation))vm_vec_rotate(&mp, &other, &pm->submodel[mn].orientation); + else mp = other; + +// vm_vec_sub2(&mp, &other); + + + vec3d d, l; + model_find_submodel_offset(&d, pmn, mn); + model_find_submodel_offset(&l, pmn, sm->look_at); + vm_vec_sub(&other, &l, &d); + if(!IS_MAT_NULL(&pm->submodel[mn].orientation))vm_vec_rotate(&l, &other, &pm->submodel[mn].orientation); + else l = other; + + + + float *a; + int axis; + + switch( sm->movement_axis ) { + case MOVEMENT_AXIS_X: + l.xyz.x = 0; + mp.xyz.x = 0; + a = &angs->p; + axis = 0; + break; + case MOVEMENT_AXIS_Y: + l.xyz.y = 0; + mp.xyz.y = 0; + a = &angs->h; + axis = 1; + break; + case MOVEMENT_AXIS_Z: + l.xyz.z = 0; + mp.xyz.z = 0; + a = &angs->b; + axis = 2; + break; + } + + vm_vec_normalize(&mp); + vm_vec_normalize(&l); + + vec3d c; + vm_vec_crossprod(&c, &l, &mp); + float dot=vm_vec_dotprod(&l,&mp); + if(dot>=0.0f){ + *a = asin(c.a1d[axis]); + }else{ + *a = PI-asin(c.a1d[axis]); + } + if (*a > PI2 ) + *a -= PI2; + else if (*a < 0.0f ) + *a += PI2; + + for (int k=0; knum_details; k++ ) { + pm->submodel[sm->details[k]].angs = *angs; + } + +} /* void submodel_ai_rotate(model_subsystem *psub, submodel_instance_info *sii) { @@ -4205,35 +4501,39 @@ void submodel_ai_rotate(model_subsystem *psub, submodel_instance_info *sii) // right handed or left handed. void model_make_turret_matrix(int model_num, model_subsystem * turret ) { + + polymodel * pm; vec3d fvec, uvec, rvec; pm = model_get(model_num); bsp_info * gun = &pm->submodel[turret->turret_gun_sobj]; bsp_info * base = &pm->submodel[turret->subobj_num]; - float offset_base_h = 0.0f; - float offset_barrel_h = 0.0f; -#ifdef WMC_SIDE_TURRETS - offset_base_h = -PI_2; - offset_barrel_h = -PI_2; -#endif model_clear_instance(model_num); - base->angs.h = offset_base_h; - gun->angs.h = offset_barrel_h; model_find_world_dir(&fvec, &turret->turret_norm, model_num, turret->turret_gun_sobj, &vmd_identity_matrix, NULL ); - base->angs.h = -PI_2 + offset_base_h; - gun->angs.p = -PI_2; - gun->angs.h = offset_barrel_h; + base->angs.h = -PI/2.0f; + gun->angs.p = -PI/2.0f; model_find_world_dir(&rvec, &turret->turret_norm, model_num, turret->turret_gun_sobj, &vmd_identity_matrix, NULL ); - base->angs.h = 0.0f + offset_base_h; - gun->angs.p = -PI_2; - gun->angs.h = offset_barrel_h; + base->angs.h = 0.0f; + gun->angs.p = -PI/2.0f; model_find_world_dir(&uvec, &turret->turret_norm, model_num, turret->turret_gun_sobj, &vmd_identity_matrix, NULL ); - + +/* fvec = turret->turret_norm; + uvec = vmd_zero_vector; + if(fvec.xyz.x == 0.0f && fvec.xyz.z == 0.0f){ + uvec = base->offset; + if(IS_VEC_NULL(&uvec))uvec.xyz.y = 1; + }else{ + uvec.xyz.y = fvec.xyz.y; + if(IS_VEC_NULL(&uvec))uvec.xyz.y = 1; + }*/ + vm_vec_normalize(&fvec); +// vm_vec_crossprod(&rvec, &uvec, &fvec); +// vm_vec_crossprod(&uvec, &fvec, &rvec); vm_vec_normalize(&rvec); vm_vec_normalize(&uvec); @@ -4260,6 +4560,8 @@ void model_make_turret_matrix(int model_num, model_subsystem * turret ) // Returns 1 if rotated gun, 0 if no gun to rotate (rotation handled by AI) int model_rotate_gun(int model_num, model_subsystem *turret, matrix *orient, angles *base_angles, angles *gun_angles, vec3d *pos, vec3d *dst) { + matrix *o = &model_get(turret->model_num)->submodel[turret->subobj_num].orientation; + polymodel * pm; pm = model_get(model_num); @@ -4279,50 +4581,139 @@ int model_rotate_gun(int model_num, model_subsystem *turret, matrix *orient, ang model_make_turret_matrix(model_num, turret ); Assert( turret->flags & MSS_FLAG_TURRET_MATRIX); -// Assert( gun->movement_axis == MOVEMENT_AXIS_X ); // Gun must be able to change pitch -// Assert( base->movement_axis == MOVEMENT_AXIS_Z ); // Parent must be able to change heading //------------ // rotate the dest point into the turret gun normal's frame of // reference, but not using the turret's angles. - // Call this vector of_dst + // Call this vector of_dst + // Object Frame Destination vec3d of_dst; - matrix world_to_turret_matrix; // converts world coordinates to turret's FOR - vec3d world_to_turret_translate; // converts world coordinates to turret's FOR vec3d tempv; - vm_vec_unrotate( &tempv, &base->offset, orient); - vm_vec_add( &world_to_turret_translate, pos, &tempv ); + + vm_vec_sub(&of_dst, dst, pos); + vm_vec_rotate(&tempv, &of_dst, orient); + model_2_submodel(pm, turret->subobj_num, &tempv, NULL); + - vm_matrix_x_matrix( &world_to_turret_matrix, orient, &turret->turret_matrix ); - vm_vec_sub( &tempv, dst, &world_to_turret_translate ); - vm_vec_rotate( &of_dst, &tempv, &world_to_turret_matrix ); - - vm_vec_normalize(&of_dst); - - //------------ - // Find the heading and pitch that the gun needs to turn to - // by extracting them from the of_dst vector. - // Call this the desired_angles angles desired_angles; -// vm_extract_angles_vector(&desired_angles, &of_dst); + angles old1, old2; + old1 = *base_angles; + old2 = *gun_angles; - desired_angles.p = (float)acos(of_dst.xyz.z); - desired_angles.h = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y); - desired_angles.b = 0.0f; + //figure out what angles we are going to need + if(IS_MAT_NULL(o)){ + //the old turret code + vm_vec_rotate(&of_dst, &tempv, &turret->turret_matrix); + vm_vec_normalize(&of_dst); + + desired_angles.p = acosf(of_dst.xyz.z); + desired_angles.h = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y); + desired_angles.b = 0.0f; - // mprintf(( "Z = %.1f, atan= %.1f\n", of_dst.xyz.z, desired_angles.p )); + }else{ + //the new turret code, only active when someone has defined it's orientation - //------------ - // Gradually turn the turret towards the desired angles + //put of_dst into the proper frame + tempv = of_dst; + vm_vec_rotate( &of_dst, &tempv, o ); + + vm_vec_normalize(&of_dst); + + //need to take the gun's exsisting pitch, + //subtract the angle that would give the gun it's current pitch + + float n; //y component of the turret normal is all we need +// vm_vec_rotate( &n, &turret->turret_norm, o ); + //we only need the y component so let's not waste math + n = (turret->turret_norm.xyz.x*o->vec.uvec.xyz.x)+(turret->turret_norm.xyz.y*o->vec.uvec.xyz.y)+(turret->turret_norm.xyz.z*o->vec.uvec.xyz.z); + + + //makeing sure normalise worked + //sometimes it's off by a tiny bit, and we don't want acos bitching + if(n > 1)n = 1; + if(n < -1)n = -1; + if(of_dst.xyz.y > 1)of_dst.xyz.y = 1; + if(of_dst.xyz.y < -1)of_dst.xyz.y = -1; + + + desired_angles.p = acosf(of_dst.xyz.y)-acosf(n); + desired_angles.h = PI/2.0f-atan2_safe(of_dst.xyz.z, of_dst.xyz.x); + desired_angles.b = 0.0f; + + + //this allows turrets that can rotate 360 to track 360, + //rather than stopping and going the other way when the turret has rotated 180 + if((turret->turret_y_fov >0.0f && fabs(turret->turret_fov) < -.9999f || fabs(turret->turret_fov) >= 0.0f)// if we have a turret that can turn all the way around + && (base_angles->h < 0 && desired_angles.h > 0 || base_angles->h > 0 && desired_angles.h < 0 )// and the current and desired coords are on opposite sides of zero + && fabs((base_angles->h) - (desired_angles.h)) > PI){//and the absolute diference between them is more than half a rotation + //then go the other direction + if(desired_angles.h > base_angles->h)desired_angles.h -= 2.0f* PI; + else desired_angles.h += 2.0f* PI; + } + + } + + //move the turret +/* angles t; + angles ap; + + ap.h = fabs(fabs(desired_angles.h) - fabs(base_angles->h)); + ap.p = fabs(fabs(desired_angles.p) - fabs(gun_angles->p)); + + //how far it will move this frame float step_size = turret->turret_turning_rate * flFrametime; + + if(base_angles->h < desired_angles.h)base_angles->h+=step_size*(ap.h/PI); + else if(base_angles->h > desired_angles.h) base_angles->h-=step_size*(ap.h/PI); + + if((old1.h < base_angles->h && base_angles->h > desired_angles.h) || (old1.h > base_angles->h && base_angles->h < desired_angles.h)) + base_angles->h = desired_angles.h; + + if(gun_angles->p < desired_angles.p)gun_angles->p+=step_size*(ap.p/PI); + else if(gun_angles->p > desired_angles.p)gun_angles->p-=step_size*(ap.p/PI); + + if((old2.p < gun_angles->p && gun_angles->p > desired_angles.p) || (old2.p > gun_angles->p && gun_angles->p < desired_angles.p)) + gun_angles->p = desired_angles.p; +*/ + angles t; + angles ap; + + ap.h = fabs(desired_angles.h - base_angles->h); + ap.p = fabs(desired_angles.p - gun_angles->p); + + //how far it will move this frame +// float step_size = turret->turret_turning_rate * flFrametime; + + if(base->ang_vel.h < turret->turret_turning_rate*(ap.h/PI))base->ang_vel.h+=flFrametime*turret->turret_turning_rate; + else if(base->ang_vel.h > turret->turret_turning_rate*(ap.h/PI)) base->ang_vel.h-=flFrametime*turret->turret_turning_rate/(ap.h/PI_2+.1); + if(base->ang_vel.h > turret->turret_turning_rate)base->ang_vel.h = turret->turret_turning_rate; + if(base->ang_vel.h < 0.0f)base->ang_vel.h = 0.0f; + + if(base_angles->h < desired_angles.h)base_angles->h+=base->ang_vel.h*flFrametime; + else if(base_angles->h > desired_angles.h) base_angles->h-=base->ang_vel.h*flFrametime; + +// if((old1.h < base_angles->h && base_angles->h > desired_angles.h) || (old1.h > base_angles->h && base_angles->h < desired_angles.h)) +// base_angles->h = desired_angles.h; + + if(base->ang_vel.p < turret->turret_turning_rate*(ap.p/PI))base->ang_vel.p+=flFrametime*turret->turret_turning_rate; + else if(base->ang_vel.p > turret->turret_turning_rate*(ap.p/PI)) base->ang_vel.p-=flFrametime*turret->turret_turning_rate/(ap.p/PI_2+.1); + if(base->ang_vel.p > turret->turret_turning_rate)base->ang_vel.p = turret->turret_turning_rate; + if(base->ang_vel.p < 0.0f)base->ang_vel.p = 0.0f; + + if(gun_angles->p < desired_angles.p)gun_angles->p+=base->ang_vel.p*flFrametime; + else if(gun_angles->p > desired_angles.p)gun_angles->p-=base->ang_vel.p*flFrametime; + +// if((old2.p < gun_angles->p && gun_angles->p > desired_angles.p) || (old2.p > gun_angles->p && gun_angles->p < desired_angles.p)) +// gun_angles->p = desired_angles.p; + + +// if(step_size && base_angles->h == desired_angles.h)Assert(fabs(old1.h) - fabs(base_angles->h) <= step_size+.0001f); +// if(step_size && gun_angles->p == desired_angles.p)Assert(fabs(old2.p) - fabs(gun_angles->p) <= step_size+.0001f); + - vm_interp_angle(&base_angles->h, desired_angles.h, step_size); - vm_interp_angle(&gun_angles->p, desired_angles.p, step_size); -// base_angles->h -= step_size*(key_down_timef(KEY_1)-key_down_timef(KEY_2) ); -// gun_angles->p += step_size*(key_down_timef(KEY_3)-key_down_timef(KEY_4) ); return 1; @@ -4365,9 +4756,20 @@ void model_find_world_point(vec3d * outpnt, vec3d *mpnt,int model_num,int sub_mo //instance up the tree for this point while ((mn >= 0) && (pm->submodel[mn].parent >= 0)) { + matrix *o = &pm->submodel[mn].orientation; + matrix inv, f; + vm_angles_2_matrix(&m,&pm->submodel[mn].angs ); + + if(!IS_MAT_NULL(&pm->submodel[mn].orientation)){ + vm_matrix_inverse(&inv, &pm->submodel[mn].orientation); + vm_matrix_x_matrix(&f, &m, &inv); + vm_matrix_x_matrix(&m, &pm->submodel[mn].orientation, &f); + } + vm_vec_unrotate(&tpnt,&pnt,&m); + vm_vec_add(&pnt,&tpnt,&pm->submodel[mn].offset ); mn = pm->submodel[mn].parent; @@ -4378,6 +4780,78 @@ void model_find_world_point(vec3d * outpnt, vec3d *mpnt,int model_num,int sub_mo vm_vec_add2(outpnt,objpos); } +//will transform the given offset and orientation matrix from model space +//into the given submodel's frame of reference, +//pass this coords already transformed into object space in most situations to get usefull stuff +//NOTE: this will not apply prop defined orientations to the last object, +//but it will take it into account +void model_2_submodel(polymodel *pm, int sn, vec3d*v, matrix*m){ + + if (pm->submodel[sn].parent != -1)//this will recursively build the proper path through the tree + model_2_submodel(pm,pm->submodel[sn].parent,v, m); + + vm_vec_sub2(v, &pm->submodel[sn].offset); + vec3d t = *v; + + matrix a; + vm_angles_2_matrix(&a, &pm->submodel[sn].angs); + if(!IS_MAT_NULL(&pm->submodel[sn].orientation)){ + matrix inv, f; + vm_matrix_inverse(&inv, &pm->submodel[sn].orientation); + vm_matrix_x_matrix(&f, &a, &inv); + vm_matrix_x_matrix(&a, &pm->submodel[sn].orientation, &f); + } + vm_vec_rotate(v, &t, &a); + + if(m){ + //if you want to know the ending transformation as well, here it is + matrix M = *m; + vm_matrix_x_matrix(m, &M, &a); + } + +} + +void make_submodel_world_matrix(polymodel *pm, int sn, vec3d*v){ + if (pm->submodel[sn].parent != -1) + make_submodel_world_matrix(pm,pm->submodel[sn].parent,v); + vm_vec_sub2(v, &pm->submodel[sn].offset); + vec3d t = *v; + + matrix a; + vm_angles_2_matrix(&a, &pm->submodel[sn].angs); + if(!IS_MAT_NULL(&pm->submodel[sn].orientation)){ + matrix inv, f; + vm_matrix_inverse(&inv, &pm->submodel[sn].orientation); + vm_matrix_x_matrix(&f, &a, &inv); + vm_matrix_x_matrix(&a, &pm->submodel[sn].orientation, &f); + } + vm_vec_rotate(v, &t, &a); + +} + +//just like below, exept it actualy does what it says it does +void world_find_real_model_point(vec3d *out, vec3d *world_pt, polymodel *pm, int submodel_num, matrix *orient, vec3d *pos) +{ + + + vec3d tempv1, tempv2; + + // get into ship RF + vm_vec_sub(&tempv1, world_pt, pos); + vm_vec_rotate(&tempv2, &tempv1, orient); + + if (pm->submodel[submodel_num].parent == -1) { + *out = tempv2; + return; + } + + vec3d os = ZERO_VECTOR; + // put into submodel RF + make_submodel_world_matrix(pm,submodel_num, &tempv2); + *out = tempv2; +} + + // Given a point in the world RF, find the corresponding point in the model RF. // This is special purpose code, specific for model collision. // NOTE - this code ASSUMES submodel is 1 level down from hull (detail[0]) @@ -4510,7 +4984,20 @@ void model_find_world_dir(vec3d * out_dir, vec3d *in_dir,int model_num, int sub_ //instance up the tree for this point while ((mn >= 0) && (pm->submodel[mn].parent >= 0)) { + matrix *o = &pm->submodel[mn].orientation; + matrix inv, f; + vm_angles_2_matrix(&m,&pm->submodel[mn].angs ); + + if(!IS_MAT_NULL(&pm->submodel[mn].orientation)){ + vm_matrix_inverse(&inv, &pm->submodel[mn].orientation); + vm_matrix_x_matrix(&f, &m, &inv); + vm_matrix_x_matrix(&m, &pm->submodel[mn].orientation, &f); + } +/* if(!IS_MAT_NULL(o)){ + vm_vec_unrotate(&tpnt,&pnt,o); + }*/ + vm_vec_unrotate(&tpnt,&pnt,&m); pnt = tpnt; @@ -4521,7 +5008,6 @@ void model_find_world_dir(vec3d * out_dir, vec3d *in_dir,int model_num, int sub_ vm_vec_unrotate(out_dir,&pnt,objorient); } - // Clears all the submodel instances stored in a model to their defaults. void model_clear_instance(int model_num) { @@ -4651,6 +5137,68 @@ void model_set_instance(int model_num, int sub_model_num, submodel_instance_info } } +void model_do_childeren_dumb_rotation(polymodel * pm, int mn){ + while ( mn >= 0 ) { + + bsp_info * sm = &pm->submodel[mn]; + + if ( sm->movement_type == MSS_FLAG_DUM_ROTATES ){ + float *ang; + int axis = sm->movement_axis; + switch(axis){ + case MOVEMENT_AXIS_X: + ang = &sm->angs.p; + break; + case MOVEMENT_AXIS_Z: + ang = &sm->angs.b; + break; + default: + case MOVEMENT_AXIS_Y: + ang = &sm->angs.h; + break; + } + *ang = sm->dumb_turn_rate * float(timestamp())/1000.0f; + *ang = ((*ang/(PI*2.0f))-float(int(*ang/(PI*2.0f))))*(PI*2.0f); + //this keeps ang from getting bigger than 2PI + } + + if(pm->submodel[mn].first_child >-1)model_do_childeren_dumb_rotation(pm, pm->submodel[mn].first_child); + + mn = pm->submodel[mn].next_sibling; + } + + +} + +void model_do_dumb_rotation(int pn){ + polymodel * pm; + + pm = model_get(pn); + int mn = pm->detail[0]; + + model_do_childeren_dumb_rotation(pm,mn); +} + +void model_do_childeren_look_at(polymodel * pm, int mn){ + while ( mn >= 0 ) { + + submodel_look_at(pm, mn); + if(pm->submodel[mn].first_child >-1)model_do_childeren_look_at(pm, pm->submodel[mn].first_child); + + mn = pm->submodel[mn].next_sibling; + } + + +} + +void model_do_look_at(int pn){ + polymodel * pm; + + pm = model_get(pn); + int mn = pm->detail[0]; + + model_do_childeren_look_at(pm,mn); +} // Finds a point on the rotation axis of a submodel, used in collision, generally find rotational velocity void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int submodel_num) diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index 97ce709878..278da355f6 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Network/MultiMsgs.cpp $ - * $Revision: 2.63 $ - * $Date: 2006-12-28 00:59:39 $ - * $Author: wmcoolmon $ + * $Revision: 2.64 $ + * $Date: 2007-01-14 14:03:33 $ + * $Author: bobboau $ * * C file that holds functions for the building and processing of multiplayer packets * * $Log: not supported by cvs2svn $ + * Revision 2.63 2006/12/28 00:59:39 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.62 2006/08/04 11:45:21 karajorma * Fix bug where end-mission SEXP only resulting in the mission ending for the server * @@ -6865,7 +6868,7 @@ void send_shield_explosion_packet( int objnum, int tri_num, vec3d hit_pos ) } } -void add_shield_point_multi(int objnum, int tri_num, vec3d *hit_pos); +void add_shield_point_multi(int objnum, int tri_num, vec3d *hit_pos, float rad); void process_shield_explosion_packet( ubyte *data, header *hinfo) { @@ -6907,7 +6910,7 @@ void process_shield_explosion_packet( ubyte *data, header *hinfo) vm_vec_add2( &hit_pos, &(shieldp->verts[stri.verts[i]].pos) ); } vm_vec_scale( &hit_pos, 1.0f/3.0f ); - add_shield_point_multi( OBJ_INDEX(objp), utri_num, &hit_pos ); + add_shield_point_multi( OBJ_INDEX(objp), utri_num, &hit_pos, 10.0f ); } } diff --git a/code/object/collideshipweapon.cpp b/code/object/collideshipweapon.cpp index 2534083ae0..53906722eb 100644 --- a/code/object/collideshipweapon.cpp +++ b/code/object/collideshipweapon.cpp @@ -9,13 +9,17 @@ /* * $Logfile: /Freespace2/code/Object/CollideShipWeapon.cpp $ - * $Revision: 2.34 $ - * $Date: 2007-01-08 00:50:58 $ - * $Author: Goober5000 $ + * $Revision: 2.35 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Routines to detect collisions and do physics, damage, etc for weapons and ships * * $Log: not supported by cvs2svn $ + * Revision 2.34 2007/01/08 00:50:58 Goober5000 + * remove WMC's limbo code, per our discussion a few months ago + * this will later be handled by copying ship stats using sexps or scripts + * * Revision 2.33 2006/12/28 00:59:39 wmcoolmon * WMC codebase commit. See pre-commit build thread for details on changes. * @@ -431,6 +435,16 @@ int ship_weapon_check_collision(object * ship_obj, object * weapon_obj, float ti // Return information for AI to detect incoming fire. // Could perhaps be done elsewhere at lower cost --MK, 11/7/97 float dist = vm_vec_dist_quick(&ship_obj->pos, &weapon_obj->pos); + if(wip->wi_flags2 & WIF2_MINE){ + object *pobj = &Objects[weapon_obj->parent]; + if( !( + ( (wip->arm_time) && ((Missiontime - wp->creation_time) < wip->arm_time) ) + || ( (wip->arm_dist) && (pobj != NULL && pobj->type != OBJ_NONE && (vm_vec_dist(&weapon_obj->pos, &pobj->pos) < wip->arm_dist) ) ) + || (wip->arm_radius < dist) + ) ) + //if all that this, _ugly_ if statement + wp->lifeleft = 0.001f; + } if (dist < weapon_obj->phys_info.speed) { update_danger_weapon(ship_obj, weapon_obj); } @@ -480,11 +494,11 @@ int ship_weapon_check_collision(object * ship_obj, object * weapon_obj, float ti // If this weapon punctures the shield, then do // the hit effect, but act like a shield collision never occurred. quadrant_num = -1; // ignore shield hit - add_shield_point(OBJ_INDEX(ship_obj), mc.shield_hit_tri, &mc.hit_point); + add_shield_point(OBJ_INDEX(ship_obj), mc.shield_hit_tri, &mc.hit_point, wip->shield_hit_radius); } else { valid_hit_occured = 1; // shield effect - add_shield_point(OBJ_INDEX(ship_obj), mc.shield_hit_tri, &mc.hit_point); + add_shield_point(OBJ_INDEX(ship_obj), mc.shield_hit_tri, &mc.hit_point, wip->shield_hit_radius); do_model_check = 0; // since we hit the shield, no need to check the model } } else { diff --git a/code/object/collideweaponweapon.cpp b/code/object/collideweaponweapon.cpp index fc49945b38..2852fdf5e5 100644 --- a/code/object/collideweaponweapon.cpp +++ b/code/object/collideweaponweapon.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Object/CollideWeaponWeapon.cpp $ - * $Revision: 2.13 $ - * $Date: 2006-12-28 00:59:39 $ - * $Author: wmcoolmon $ + * $Revision: 2.14 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Routines to detect collisions and do physics, damage, etc for weapons and weapons * * $Log: not supported by cvs2svn $ + * Revision 2.13 2006/12/28 00:59:39 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.12 2006/09/11 05:36:43 taylor * compiler warning fixes * @@ -133,16 +136,6 @@ int collide_weapon_weapon( obj_pair * pair ) Assert( A->type == OBJ_WEAPON ); Assert( B->type == OBJ_WEAPON ); - // Don't allow ship to shoot down its own missile. - if (A->parent_sig == B->parent_sig) - return 1; - - // Only shoot down teammate's missile if not traveling in nearly same direction. - if (Weapons[A->instance].team == Weapons[B->instance].team) - if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f) - return 1; - - // Ignore collisions involving a bomb if the bomb is not yet armed. weapon *wpA, *wpB; weapon_info *wipA, *wipB; @@ -154,18 +147,38 @@ int collide_weapon_weapon( obj_pair * pair ) A_radius = A->radius; B_radius = B->radius; + // never shoot down teammates mine with a mine + if(wipA->wi_flags2 & WIF2_MINE && wipB->wi_flags2 & WIF2_MINE){ + if (Weapons[A->instance].team == Weapons[B->instance].team) + return 1; + } + + //you can shoot your own mine, and your team can too + if (!(wipA->wi_flags2 & WIF2_MINE || wipB->wi_flags2 & WIF2_MINE )){ + // Don't allow ship to shoot down its own missile. + if (A->parent_sig == B->parent_sig) + return 1; + + // Only shoot down teammate's missile if not traveling in nearly same direction. + if (Weapons[A->instance].team == Weapons[B->instance].team) + if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f) + return 1; + } + + // Ignore collisions involving a bomb if the bomb is not yet armed. + // UnknownPlayer : Should we even be bothering with collision detection is neither one of these is a bomb? //WMC - Here's a reason why...scripting now! if (wipA->wi_flags & WIF_BOMB) { - A_radius *= 2; // Makes bombs easier to hit + if(!(wipA->wi_flags2 & WIF2_MINE))A_radius *= 2; // Makes bombs easier to hit if (wipA->lifetime - wpA->lifeleft < BOMB_ARM_TIME) return 0; } if (wipB->wi_flags & WIF_BOMB) { - B_radius *= 2; // Makes bombs easier to hit + if(!(wipB->wi_flags2 & WIF2_MINE))B_radius *= 2; // Makes bombs easier to hit if (wipB->lifetime - wpB->lifeleft < BOMB_ARM_TIME) return 0; } diff --git a/code/object/objectsort.cpp b/code/object/objectsort.cpp index d7bb53754a..88a867e8c3 100644 --- a/code/object/objectsort.cpp +++ b/code/object/objectsort.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Object/ObjectSort.cpp $ - * $Revision: 2.14 $ - * $Date: 2006-05-27 16:59:05 $ - * $Author: taylor $ + * $Revision: 2.15 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Sorting code for objects. * * $Log: not supported by cvs2svn $ + * Revision 2.14 2006/05/27 16:59:05 taylor + * comment out some code which used only if neither D3D nor OGL + * * Revision 2.13 2006/05/13 07:09:25 taylor * minor cleanup and a couple extra error checks * get rid of some wasteful math from the gr_set_proj_matrix() calls @@ -436,7 +439,7 @@ void obj_render_all(void (*render_function)(object *objp), bool *draw_viewer_las // if(!Cmdline_nohtl)gr_set_lighting(false,false); // lasers have to be drawn without fog! - taylor - batch_render_lasers(); + batch_render_all(); /* Show spheres where wingmen should be flying { diff --git a/code/osapi/outwnd.cpp b/code/osapi/outwnd.cpp index 8f5c98f1d4..73de444115 100644 --- a/code/osapi/outwnd.cpp +++ b/code/osapi/outwnd.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/OsApi/OutWnd.cpp $ - * $Revision: 2.18 $ - * $Date: 2006-12-28 00:59:39 $ - * $Author: wmcoolmon $ + * $Revision: 2.19 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Routines for debugging output * * $Log: not supported by cvs2svn $ + * Revision 2.18 2006/12/28 00:59:39 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.17 2006/11/16 00:56:16 taylor * updated outwnd code for both Windows and non-Windows: * - make print filters dynamic @@ -1345,7 +1348,7 @@ void close_mono() void outwnd_init_debug_window(int display_under_freespace_window) { - static debug_window_inited = false; + static bool debug_window_inited = false; if ( !Cmdline_debug_window || !outwnd_inited || debug_window_inited ) return; diff --git a/code/parse/lua.cpp b/code/parse/lua.cpp index ca0e53d715..cec9207467 100644 --- a/code/parse/lua.cpp +++ b/code/parse/lua.cpp @@ -31,7 +31,7 @@ #include "object/waypoint/waypoint.h" #include "globalincs/linklist.h" #include "io/timer.h" - + //*************************Lua globals************************* std::vector Ade_table_entries; @@ -212,15 +212,18 @@ int ade_get_operator(char *tablename) int ade_set_object_with_breed(lua_State *L, int obj_idx); //**********Handles -/*ade_obj l_Camera("camera", "Camera handle"); +//I had to uncomment this stuff to get Fred to link for some reason, +//I also commented out the ones you had further down, as they are here now +//-Bobboau +ade_obj l_Camera("camera", "Camera handle"); ade_obj l_Cmission("cmission", "Campaign mission handle"); //WMC - We can get away with a pointer right now, but if it ever goes dynamic, it'd be a prob -ade_obj l_Enum("enumeration", "Enumeration object"); +//ade_obj l_Enum("enumeration", "Enumeration object"); ade_obj l_Event("event", "Mission event handle"); ade_obj l_Font("font", "font handle"); -ade_obj l_Matrix("orientation", "Orientation matrix object"); +//ade_obj l_Matrix("orientation", "Orientation matrix object"); ade_obj l_Model("model", "3D Model (POF) handle"); ade_obj l_Object("object", "Object handle"); -ade_obj l_Physics("physics", "Physics handle"); +//ade_obj l_Physics("physics", "Physics handle"); ade_obj l_Player("player", "Player handle"); ade_obj l_Shields("shields", "Shields handle"); ade_obj l_Ship("ship", "Ship handle", &l_Object); @@ -234,10 +237,10 @@ ade_obj l_Texture("texture", "Texture handle"); ade_obj l_Wing("wing", "Wing handle"); ade_obj l_Vector("vector", "Vector object"); ade_obj l_Weapon("weapon", "Weapon handle", &l_Object); -ade_obj l_WeaponBank("weaponbank", "Ship/subystem weapons bank handle"); -ade_obj l_WeaponBankType("weaponbanktype", "Ship/subsystem weapons bank type handle"); +//ade_obj l_WeaponBank("weaponbank", "Ship/subystem weapons bank handle"); +//ade_obj l_WeaponBankType("weaponbanktype", "Ship/subsystem weapons bank type handle"); ade_obj l_Weaponclass("weaponclass", "Weapon class handle"); -*/ + //########################################################### //################################################ //########################################################### @@ -248,7 +251,7 @@ ade_obj l_Weaponclass("weaponclass", "Weapon class handle"); //########################################################### //**********HANDLE: cmission -ade_obj l_Cmission("cmission", "Campaign mission handle"); +//ade_obj l_Cmission("cmission", "Campaign mission handle"); //WMC - We can get away with a pointer right now, but if it ever goes dynamic, it'd be a prob int lua_cmission_helper(lua_State *L, int *idx) @@ -649,7 +652,7 @@ ADE_FUNC(__tostring, l_Enum, NULL, "string", "Returns enumeration name") } //**********HANDLE: event -ade_obj l_Event("event", "Mission event handle"); +//ade_obj l_Event("event", "Mission event handle"); ADE_VIRTVAR(Name, l_Event, "string", "Mission event name") { @@ -1110,7 +1113,7 @@ ADE_FUNC(write, l_File, "string or number, ...", "Number of items successfully w } //**********HANDLE: Font -ade_obj l_Font("font", "font handle"); +//ade_obj l_Font("font", "font handle"); ADE_FUNC(__tostring, l_Font, NULL, "string", "Filename of font") { @@ -1171,7 +1174,7 @@ ADE_FUNC(isValid, l_Font, NULL, "True if valid, false or nil if not", "Detects } //**********HANDLE: model -ade_obj l_Model("model", "3D Model (POF) handle"); +//ade_obj l_Model("model", "3D Model (POF) handle"); ADE_VIRTVAR(Filename, l_Model, "string", "Model filename") { @@ -1246,7 +1249,7 @@ ADE_FUNC(isValid, l_Model, NULL, "True if valid, false or nil if not", "Detects //**********OBJECT: orientation matrix //WMC - So matrix can use vector, I define it up here. -ade_obj l_Vector("vector", "Vector object"); +//ade_obj l_Vector("vector", "Vector object"); //WMC - Due to the exorbitant times required to store matrix data, //I initially store the matrix in this struct. #define MH_FINE 0 @@ -1910,7 +1913,7 @@ ADE_FUNC(delete, l_SEXPVariable, NULL, "False or nil if variable couldn't be fou } //**********HANDLE: Shields -ade_obj l_Shields("shields", "Shields handle"); +//ade_obj l_Shields("shields", "Shields handle"); ADE_INDEXER(l_Shields, "SHIELD_* enumeration, NONE, or 1-4", "number", "Gets or sets shield quadrant strength") { @@ -1997,7 +2000,7 @@ ADE_FUNC(isValid, l_Shields, NULL, "True if valid, false or nil if not", "Detec } //**********HANDLE: Shiptype -ade_obj l_Shiptype("shiptype", "Ship type handle"); +//ade_obj l_Shiptype("shiptype", "Ship type handle"); extern int Species_initted; ADE_VIRTVAR(Name, l_Shiptype, "string", "Ship type name") @@ -2033,7 +2036,7 @@ ADE_FUNC(isValid, l_Shiptype, NULL, "True if valid, false or nil if not", "Dete } //**********HANDLE: Species -ade_obj l_Species("species", "Species handle"); +//ade_obj l_Species("species", "Species handle"); extern int Species_initted; ADE_VIRTVAR(Name, l_Species, "string", "Species name") @@ -2069,7 +2072,7 @@ ADE_FUNC(isValid, l_Species, NULL, "True if valid, false or nil if not", "Detec } //**********HANDLE: Team -ade_obj l_Team("team", "Team handle"); +//ade_obj l_Team("team", "Team handle"); ADE_FUNC(__eq, l_Team, "team, team", "true if equal", "Checks whether two teams are the same team") { @@ -2110,7 +2113,7 @@ ADE_FUNC(isValid, l_Team, NULL, "True if valid, false or nil if not", "Detects } //**********HANDLE: Texture -ade_obj l_Texture("texture", "Texture handle"); +//ade_obj l_Texture("texture", "Texture handle"); //WMC - int should NEVER EVER be an invalid handle. Return Nil instead. Nil FTW. static float lua_Opacity = 1.0f; @@ -2481,9 +2484,82 @@ ADE_INDEXER(l_Directives, "Directive number", "directive handle", NULL) */ //**********HANDLE: Weaponclass -ade_obj l_Weaponclass("weaponclass", "Weapon class handle"); +//ade_obj l_Weaponclass("weaponclass", "Weapon class handle"); + +ADE_VIRTVAR(DesiredVelocity, l_Object, "Local vector", "Object local desired velocity") +{ + object_h *objh; + vec3d *v3=NULL; + if(!ade_get_args(L, "o|o", l_Object.GetPtr(&objh), l_Vector.GetPtr(&v3))) + return ADE_RETURN_NIL; + + if(!objh->IsValid()) + return ADE_RETURN_NIL; + + if(ADE_SETTING_VAR && v3 != NULL) { + objh->objp->phys_info.desired_vel = *v3; + } + + return ade_set_args(L, "o", l_Vector.Set(objh->objp->phys_info.desired_vel)); +} + + +ADE_VIRTVAR(RotationalVelocity, l_Object, "Local vector", "Object local rotational velocity") +{ + object_h *objh; + vec3d *v3=NULL; + if(!ade_get_args(L, "o|o", l_Object.GetPtr(&objh), l_Vector.GetPtr(&v3))) + return ADE_RETURN_NIL; + + if(!objh->IsValid()) + return ADE_RETURN_NIL; + + if(ADE_SETTING_VAR && v3 != NULL) { + objh->objp->phys_info.rotvel = *v3; + } + + return ade_set_args(L, "o", l_Vector.Set(objh->objp->phys_info.rotvel)); +} + +ADE_VIRTVAR(DesiredRotationalVelocity, l_Object, "Local vector", "Object local desired rotational velocity") +{ + object_h *objh; + vec3d *v3=NULL; + if(!ade_get_args(L, "o|o", l_Object.GetPtr(&objh), l_Vector.GetPtr(&v3))) + return ADE_RETURN_NIL; + + if(!objh->IsValid()) + return ADE_RETURN_NIL; + + if(ADE_SETTING_VAR && v3 != NULL) { + objh->objp->phys_info.desired_rotvel = *v3; + } + + return ade_set_args(L, "o", l_Vector.Set(objh->objp->phys_info.desired_rotvel)); +} + +ADE_VIRTVAR(RotDamp, l_Object, "Number", "rotational damp") +{ + object_h *objh = NULL; + float f = 0.0f; + if(!ade_get_args(L, "o|f", l_Object.GetPtr(&objh), &f)) + return ADE_RETURN_NIL; + + if(!objh->IsValid()) + return ADE_RETURN_NIL; + + //Set hull strength. + if(ADE_SETTING_VAR && f >= 0.0f) { + objh->objp->phys_info.rotdamp = f; + } + + return ade_set_args(L, "f", objh->objp->phys_info.rotdamp); +} + + ADE_VIRTVAR(Name, l_Weaponclass, "string", "Weapon class name") + { int idx; char *s = NULL; @@ -2814,7 +2890,7 @@ ADE_VIRTVAR(Position, l_Eyepoint, "vector", "Eyepoint location") } //**********HANDLE: Object -ade_obj l_Object("object", "Object handle"); +//ade_obj l_Object("object", "Object handle"); //Helper function //Returns 1 if object sig stored in idx exists, and stores Objects[] index in idx //Returns 0 if object sig does not exist, and does not change idx @@ -2946,6 +3022,7 @@ ADE_FUNC(getBreedName, l_Object, NULL, "Object type name", "Gets object type") return ade_set_args(L, "s", Object_type_names[objh->objp->type]); } +//ade_obj l_Subsystem("subsystem", "Ship subsystem handle"); //**********HANDLE: Asteroid ade_obj l_Asteroid("asteroid", "Asteroid handle", &l_Object); @@ -2976,7 +3053,7 @@ ADE_VIRTVAR(Target, l_Asteroid, "Boolean", "Whether or not debris is a piece of } //**********HANDLE: Camera -ade_obj l_Camera("camera", "Camera handle"); +//ade_obj l_Camera("camera", "Camera handle"); ADE_FUNC(isValid, l_Camera, NULL, "True if valid, false or nil if not", "Detects whether handle is valid") { @@ -3064,7 +3141,7 @@ ADE_VIRTVAR(IsHull, l_Debris, "Boolean", "Whether or not debris is a piece of hu } //**********HANDLE: Shipclass -ade_obj l_Shipclass("shipclass", "Ship class handle"); +//ade_obj l_Shipclass("shipclass", "Ship class handle"); extern int ships_inited; ADE_VIRTVAR(Name, l_Shipclass, "string", "Ship class name") @@ -3535,7 +3612,7 @@ ADE_FUNC(__len, l_WaypointList_Waypoints, NULL, "Number of waypoints in the miss }*/ //**********HANDLE: Weapon -ade_obj l_Weapon("weapon", "Weapon handle", &l_Object); +//ade_obj l_Weapon("weapon", "Weapon handle", &l_Object); ADE_VIRTVAR(Class, l_Weapon, "weaponclass", "Weapon's class") { @@ -3926,21 +4003,6 @@ ADE_FUNC(__len, l_WeaponBankType, NULL, "Number of weapons mounted in bank", "Ge } } -//**********HANDLE: Subsystem -struct ship_subsys_h : public object_h -{ - ship_subsys *ss; //Pointer to subsystem, or NULL for the hull - - bool IsValid(){return objp->signature == sig;} - ship_subsys_h() : object_h() { - ss = NULL; - } - ship_subsys_h(object *objp, ship_subsys *sub) : object_h(objp) { - ss = sub; - } -}; -ade_obj l_Subsystem("subsystem", "Ship subsystem handle"); - ADE_VIRTVAR(AWACSIntensity, l_Subsystem, "number", "Subsystem AWACS intensity") { ship_subsys_h *sso; @@ -4228,7 +4290,7 @@ ADE_FUNC(getName, l_Subsystem, NULL, "Subsystem name", "Subsystem name")\ //**********HANDLE: shiptextures -ade_obj l_ShipTextures("shiptextures", "Ship textures handle"); +//ade_obj l_ShipTextures("shiptextures", "Ship textures handle"); ADE_FUNC(__len, l_ShipTextures, NULL, NULL, NULL) { @@ -4331,7 +4393,7 @@ ADE_FUNC(isValid, l_ShipTextures, NULL, "True if valid, false or nil if not", " } //**********HANDLE: Ship -ade_obj l_Ship("ship", "Ship handle", &l_Object); +//ade_obj l_Ship("ship", "Ship handle", &l_Object); ADE_INDEXER(l_Ship, "Subsystem name or index", "Subsystem", "Returns subsystem based on name or index passed") { @@ -4828,7 +4890,7 @@ ADE_FUNC(warpOut, l_Ship, "[boolean Departing]", "True", "Warps ship out") } //**********HANDLE: Wing -ade_obj l_Wing("wing", "Wing handle"); +//ade_obj l_Wing("wing", "Wing handle"); ADE_INDEXER(l_Wing, "Index", "Ship", "Ship via number in wing") { @@ -4849,7 +4911,7 @@ ADE_INDEXER(l_Wing, "Index", "Ship", "Ship via number in wing") return ade_set_args(L, "o", l_Ship.Set(object_h(&Objects[Ships[Wings[wdx].ship_index[sdx]].objnum]))); } //**********HANDLE: Player -ade_obj l_Player("player", "Player handle"); +//ade_obj l_Player("player", "Player handle"); int player_helper(lua_State *L, int *idx) { diff --git a/code/parse/lua.h b/code/parse/lua.h index e3ffa4eacb..3d2de77136 100644 --- a/code/parse/lua.h +++ b/code/parse/lua.h @@ -264,7 +264,24 @@ struct object_h { object_h(){objp=NULL;sig=-1;} }; +struct ship_subsys; +//**********HANDLE: Subsystem +struct ship_subsys_h : public object_h +{ + ship_subsys *ss; //Pointer to subsystem, or NULL for the hull + + bool IsValid(){return objp->signature == sig;} + ship_subsys_h() : object_h() { + ss = NULL; + } + ship_subsys_h(object *objp, ship_subsys *sub) : object_h(objp) { + ss = sub; + } +}; + //*************************Lua globals************************* +extern ade_obj l_Vector; +extern ade_obj l_Subsystem; extern ade_obj l_Object; extern ade_obj l_Weapon; extern ade_obj l_Ship; diff --git a/code/parse/scripting.cpp b/code/parse/scripting.cpp index bf3a246bc1..f3fa96c581 100644 --- a/code/parse/scripting.cpp +++ b/code/parse/scripting.cpp @@ -307,7 +307,7 @@ bool ConditionedHook::IsOverride(script_state *sys, int action) #ifndef USE_PYTHON #pragma message("NOTE: Python is not compiled in") #endif - + //WMC - defined in parse/lua.h int ade_set_object_with_breed(lua_State *L, int obj_idx); void script_state::SetHookObject(char *name, int obj_idx) diff --git a/code/parse/sexp.cpp b/code/parse/sexp.cpp index 10e92842d1..c14fcf1b4e 100644 --- a/code/parse/sexp.cpp +++ b/code/parse/sexp.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/parse/SEXP.CPP $ - * $Revision: 2.294 $ - * $Date: 2007-01-14 12:06:56 $ - * $Author: wmcoolmon $ + * $Revision: 2.295 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * main sexpression generator * * $Log: not supported by cvs2svn $ + * Revision 2.294 2007/01/14 12:06:56 wmcoolmon + * Fix +Override, attempted fix for code adjacent to [] causing crash in scripting.tbl (Unreproducable), and (Untested) fix for script-eval. + * * Revision 2.293 2006/12/28 02:07:49 Goober5000 * assume ships-with-bays which haven't yet entered the mission are valid for syntax checking * @@ -1631,6 +1634,7 @@ sexp_oper Operators[] = { { "set-object-position", OP_SET_OBJECT_POSITION, 4, 4 }, // WMC { "set-object-facing", OP_SET_OBJECT_FACING, 4, 6 }, // Goober5000 { "set-object-facing-object", OP_SET_OBJECT_FACING_OBJECT, 2, 4 }, // Goober5000 + { "is-object-facing", OP_FACING_OBJ, 3, 3, }, // Bobboau { "time-elapsed-last-order", OP_LAST_ORDER_TIME, 2, 2, /*INT_MAX*/ }, { "skill-level-at-least", OP_SKILL_LEVEL_AT_LEAST, 1, 1, }, @@ -11547,6 +11551,42 @@ int sexp_secondaries_depleted(int node) return (num_depleted_banks == num_banks); } +int sexp_facing_obj(int node) +{ + int looker, looke; + float a1, a2; + vec3d v1, v2; + + if (ship_query_state(CTEXT(node)) < 0){ + return SEXP_KNOWN_FALSE; + } + + looker = ship_name_lookup(CTEXT(node)); + if ((looker < 0)) return SEXP_FALSE; + + looke = ship_name_lookup(CTEXT(CDR(node))); + if ((looke < 0)) return SEXP_FALSE; + + + if(looke == looker) return SEXP_FALSE; + + + looker = Ships[looker].objnum; + looke = Ships[looke].objnum; + v1 = Objects[looker].orient.vec.fvec; + vm_vec_normalize(&v1); + vm_vec_sub(&v2, &Objects[looke].pos, &Objects[looker].pos); + vm_vec_normalize(&v2); + a1 = vm_vec_dotprod(&v1, &v2); + a2 = (float) cos(ANG_TO_RAD(atof(CTEXT(CDR(CDR(node)))))); + if (a1 >= a2){ + return SEXP_TRUE; + } + + return SEXP_FALSE; +} + + int sexp_facing(int node) { int obj, sh; @@ -15716,6 +15756,10 @@ int eval_sexp(int cur_node, int referenced_node) sexp_val = sexp_secondaries_depleted(node); break; + case OP_FACING_OBJ: + sexp_val = sexp_facing_obj(node); + break; + case OP_FACING: sexp_val = sexp_facing(node); break; @@ -16401,6 +16445,7 @@ int query_operator_return_type(int op) case OP_KEY_PRESSED: case OP_TARGETED: case OP_SPEED: + case OP_FACING_OBJ: case OP_FACING: case OP_FACING2: case OP_ORDER: @@ -16931,6 +16976,12 @@ int query_operator_argument_type(int op, int argnum) case OP_SHIP_UNTAG: return OPF_SHIP; + case OP_FACING_OBJ: + if (argnum <= 1) + return OPF_SHIP; + else + return OPF_POSITIVE; + case OP_FACING: if (argnum == 0) return OPF_SHIP; @@ -20153,6 +20204,15 @@ sexp_help_struct Sexp_help[] = { "Returns a boolean value. Takes 1 argument...\r\n" "\t1:\tTime in seconds." }, + { OP_FACING_OBJ, "Object Facing\r\n" + "\tIs true as long as the second object is within the first object's specified " + "forward cone. A forward cone is defined with the third and final parameter as" + "an angle.\r\n\r\n" + "Returns a boolean value. Takes 3 argument...\r\n" + "\t1:\tShip that is doing the faceing.\r\n" + "\t1:\tShip that is being faced.\r\n" + "\t2:\tAngle in degrees of the forward cone." }, + { OP_FACING, "Facing (Boolean training operator)\r\n" "\tIs true as long as the specified ship is within the player's specified " "forward cone. A forward cone is defined as any point that the angle between the " diff --git a/code/parse/sexp.h b/code/parse/sexp.h index 6c41e5e1b3..26f7e10aa6 100644 --- a/code/parse/sexp.h +++ b/code/parse/sexp.h @@ -9,13 +9,16 @@ /* * $Source: /cvs/cvsroot/fs2open/fs2_open/code/parse/sexp.h,v $ - * $Revision: 2.127 $ - * $Author: wmcoolmon $ - * $Date: 2006-12-28 00:59:39 $ + * $Revision: 2.128 $ + * $Author: bobboau $ + * $Date: 2007-01-14 14:03:36 $ * * header for sexpression parsing * * $Log: not supported by cvs2svn $ + * Revision 2.127 2006/12/28 00:59:39 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.126 2006/10/25 01:01:51 Goober5000 * moved some stuff around in the sexp menus * @@ -1094,6 +1097,7 @@ struct ship_subsys; #define OP_GET_PRIMARY_AMMO (0x002c | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Karajorma #define OP_GET_SECONDARY_AMMO (0x002d | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Karajorma #define OP_NUM_ASSISTS (0x002e | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Karajorma +#define OP_FACING_OBJ (0x002f | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Bobboau // conditional sexpressions #define OP_WHEN (0x0000 | OP_CATEGORY_CONDITIONAL) diff --git a/code/render/3d.h b/code/render/3d.h index 629a425016..c4d26bc950 100644 --- a/code/render/3d.h +++ b/code/render/3d.h @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Render/3D.H $ - * $Revision: 2.23 $ - * $Date: 2006-12-28 00:59:48 $ - * $Author: wmcoolmon $ + * $Revision: 2.24 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Include file for 3d rendering functions * * $Log: not supported by cvs2svn $ + * Revision 2.23 2006/12/28 00:59:48 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.22 2006/05/27 16:47:12 taylor * remove some of the old batcher functions, nothing is using them now anyway * minor cleanup @@ -314,6 +317,16 @@ ubyte g3_project_vector(vec3d *p, float *sx, float *sy ); //rotates a point. returns codes. ubyte g3_rotate_vector(vec3d *dest,vec3d *src); +//just like above, but ignores offsets +ubyte g3_rotate_normal(vec3d *dest,vec3d *src); +ubyte g3_unrotate_vector(vec3d *dest,vec3d *src); +ubyte g3_unrotate_normal(vec3d *dest,vec3d *src); + +ubyte g3_local_2_world(vec3d *dest,vec3d *src); +ubyte g3_local_2_world_normal(vec3d *dest,vec3d *src); +ubyte g3_world_2_local(vec3d *dest,vec3d *src); +ubyte g3_world_2_local_normal(vec3d *dest,vec3d *src); + //Codes a vector. Returns the codes of a point. ubyte g3_code_vector(vec3d * p); diff --git a/code/render/3dmath.cpp b/code/render/3dmath.cpp index 88e50c112c..83ff981038 100644 --- a/code/render/3dmath.cpp +++ b/code/render/3dmath.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Render/3dMath.cpp $ - * $Revision: 2.9 $ - * $Date: 2006-09-11 06:45:40 $ - * $Author: taylor $ + * $Revision: 2.10 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * 3d Math routines used by the Renderer lib * * $Log: not supported by cvs2svn $ + * Revision 2.9 2006/09/11 06:45:40 taylor + * various small compiler warning and strict compiling fixes + * * Revision 2.8 2005/04/05 05:53:24 taylor * s/vector/vec3d/g, better support for different compilers (Jens Granseuer) * @@ -296,6 +299,89 @@ ubyte g3_rotate_vector(vec3d *dest,vec3d *src) vm_vec_rotate(dest,&tempv,&View_matrix); return g3_code_vector(dest); } + +ubyte g3_rotate_normal(vec3d *dest,vec3d *src) +{ + vec3d tempv; + + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_rotate(dest,&tempv,&View_matrix); + return g3_code_vector(dest); +} + +ubyte g3_unrotate_vector(vec3d *dest,vec3d *src) +{ + vec3d tempv; + + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_unrotate(dest,&tempv,&View_matrix); + vm_vec_add(&tempv,src,&View_position); + return g3_code_vector(dest); +} + +ubyte g3_unrotate_normal(vec3d *dest,vec3d *src) +{ + vec3d tempv; + + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_unrotate(dest,&tempv,&View_matrix); + return g3_code_vector(dest); +} + +ubyte g3_local_2_world(vec3d *dest,vec3d *src) +{ + vec3d tempv; + + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_unrotate(&tempv,src,&Object_matrix); + vm_vec_add(dest,&tempv,&Object_position); + return g3_code_vector(dest); +} + +ubyte g3_local_2_world_normal(vec3d *dest,vec3d *src) +{ + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_unrotate(dest,src,&Object_matrix); + return g3_code_vector(dest); +} + +ubyte g3_world_2_local(vec3d *dest,vec3d *src) +{ + vec3d tempv; + + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_sub(&tempv,src,&Object_position); + vm_vec_rotate(dest,&tempv,&Object_matrix); + return g3_code_vector(dest); +} + +ubyte g3_world_2_local_normal(vec3d *dest,vec3d *src) +{ + Assert( G3_count == 1 ); + + MONITOR_INC( NumRotations, 1 ); + + vm_vec_rotate(dest,src,&Object_matrix); + return g3_code_vector(dest); +} ubyte g3_project_vector(vec3d *p, float *sx, float *sy ) { diff --git a/code/render/3dsetup.cpp b/code/render/3dsetup.cpp index 589da6f201..4e873513af 100644 --- a/code/render/3dsetup.cpp +++ b/code/render/3dsetup.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Render/3dSetup.cpp $ - * $Revision: 2.24 $ - * $Date: 2006-12-28 00:59:48 $ - * $Author: wmcoolmon $ + * $Revision: 2.25 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Code to setup matrix instancing and viewers * * $Log: not supported by cvs2svn $ + * Revision 2.24 2006/12/28 00:59:48 wmcoolmon + * WMC codebase commit. See pre-commit build thread for details on changes. + * * Revision 2.23 2006/10/06 09:34:19 taylor * meant to do this before but forgot about it (just replaced "(4.0/9.0) * PI" with it's result) * @@ -452,7 +455,7 @@ void g3_start_instance_matrix(vec3d *pos,matrix *orient, bool set_api) vm_matrix_x_matrix(&tempm,&tempm2,&View_matrix); View_matrix = tempm; - vm_matrix_x_matrix(&Object_matrix,orient,&instance_stack[instance_depth-1].om); + vm_matrix_x_matrix(&Object_matrix,&instance_stack[instance_depth-1].om,orient); // Object_matrix = tempm; // Update the lighting matrix diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 5f895a50d9..2aab16f8bf 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -10,13 +10,17 @@ /* * $Logfile: /Freespace2/code/Ship/Ship.cpp $ - * $Revision: 2.394 $ - * $Date: 2007-01-08 00:50:59 $ - * $Author: Goober5000 $ + * $Revision: 2.395 $ + * $Date: 2007-01-14 14:03:36 $ + * $Author: bobboau $ * * Ship (and other object) handling functions * * $Log: not supported by cvs2svn $ + * Revision 2.394 2007/01/08 00:50:59 Goober5000 + * remove WMC's limbo code, per our discussion a few months ago + * this will later be handled by copying ship stats using sexps or scripts + * * Revision 2.393 2007/01/07 21:28:11 Goober5000 * yet more tweaks to the WCS death scream stuff * added a ship flag to force screaming @@ -2385,7 +2389,8 @@ flag_def_list Subsystem_flags[] = { "untargetable", MSS_FLAG_UNTARGETABLE }, { "carry no damage", MSS_FLAG_CARRY_NO_DAMAGE }, { "use multiple guns", MSS_FLAG_USE_MULTIPLE_GUNS }, - { "fire down normals", MSS_FLAG_FIRE_ON_NORMAL } + { "fire down normals", MSS_FLAG_FIRE_ON_NORMAL }, + { "check hull", MSS_FLAG_TURRET_HULL_CHECK } }; int Num_subsystem_flags = sizeof(Subsystem_flags)/sizeof(flag_def_list); @@ -3625,7 +3630,11 @@ strcpy(parse_error_text, temp_error); } // The next three fields are used for the ETS - if(optional_string("$Power Output:")) + if(optional_string("$Power Output:")){ + stuff_float(&sip->power_output);//need to stuff it some were, why not there? + if(sip->power_output!=0.0f)sip->power_output = 1.0f; + } + if(optional_string("$Power_Output:")) stuff_float(&sip->power_output); if(optional_string("$Max Oclk Speed:")) @@ -3785,6 +3794,8 @@ strcpy(parse_error_text, temp_error); sip->flags2 |= SIF2_DISABLE_WEAP_DAMAGE_SCALING; else if( !stricmp( NOX("gun convergence"), ship_strings[i])) sip->flags2 |= SIF2_GUN_CONVERGENCE; + else if( !stricmp( NOX("projected shields"), ship_strings[i])) + sip->flags2 |= SIF2_PROJECTED_SHIELDS; else if (ship_type_index < 0) Warning(LOCATION, "Bogus string in ship flags: %s\n", ship_strings[i]); } @@ -4390,6 +4401,11 @@ strcpy(parse_error_text, temp_error); old_flags = true; } + if (optional_string("+check-hull")) { + sp->flags |= MSS_FLAG_TURRET_HULL_CHECK; + old_flags = true; + } + if (old_flags) { Warning(LOCATION, "Use of deprecated subsystem syntax. Please use the $Flags: field for subsystem flags.\n\n" \ "At least one of the following tags was used on ship %s, subsystem %s:\n" \ @@ -4532,8 +4548,9 @@ strcpy(parse_error_text, temp_error); //make sure that the amount of time it takes to accelerate up and down doesn't make it go farther than the angle current_trigger->correct(); } - else if(!stricmp(name_tmp, "linked")) + else if(!stricmp(name_tmp, "script")) { + sp->scripted_rotation = Script_system.ParseChunk(""); } } } @@ -5842,6 +5859,7 @@ void subsys_set(int objnum, int ignore_subsys_info) list_remove( ship_subsys_free_list, ship_system ); // remove the element from the array list_append( &shipp->subsys_list, ship_system ); // link the element into the ship + ship_system->system_info = model_system; // set the system_info pointer to point to the data read in from the model // zero flags @@ -5949,6 +5967,26 @@ void subsys_set(int objnum, int ignore_subsys_info) model_clear_instance_info( &ship_system->submodel_info_2 ); } +/* + for ( ship_system = GET_FIRST( &shipp->subsys_list); ship_system != END_OF_LIST(&shipp->subsys_list); ship_system = GET_NEXT(ship_system) ){ + ship_system->parent = NULL; + if(ship_system->system_info->model_num < 0)continue; + if(ship_system->system_info->subobj_num < 0)continue; + int pn = model_get(ship_system->system_info->model_num)->submodel[ship_system->system_info->subobj_num].parent; + if(pn<0)continue; + if(model_system->subobj_num> -1){ + for ( ship_subsys*ss = GET_FIRST( &shipp->subsys_list); ss != END_OF_LIST(&shipp->subsys_list); ss = GET_NEXT(ss) ){ + if(ship_system==ss)continue; + if(ss->system_info->model_num < 0)continue; + if(ss->system_info->subobj_num < 0)continue; + if(pn == ss->system_info->subobj_num){ + ship_system->parent = ss; + break; + } + } + } + }*/ + if ( !ignore_subsys_info ) { ship_recalc_subsys_strength( shipp ); } @@ -7918,7 +7956,7 @@ void ship_auto_repair_frame(int shipnum, float frametime) real_repair_rate = sip->subsys_repair_rate; // AL 3-14-98: only allow auto-repair if power output not zero - if (sip->power_output <= 0) + if (sip->power_output == 0) return; // iterate through subsystems, repair as needed based on elapsed frametime @@ -8945,11 +8983,11 @@ int ship_create(matrix *orient, vec3d *pos, int ship_type, char *ship_name) shipp->ab_count = 0; if(sip->flags & SIF_AFTERBURNER) { - for(i = 0; i < pm_orig->n_thrusters; i++) + for(i = 0; i < pm_orig->submodel[pm_orig->detail[0]].submodel_thruster.size(); i++) { - thruster_bank *bank = &pm_orig->thrusters[i]; + thruster_bank *bank = &pm_orig->submodel[pm_orig->detail[0]].submodel_thruster[i]; - for(j = 0; j < bank->num_points; j++) + for(j = 0; j < bank->points.size(); j++) { // this means you've reached the max # of AB trails for a ship Assert(sip->ct_count <= MAX_SHIP_CONTRAILS); @@ -9270,9 +9308,9 @@ void change_ship_type(int n, int ship_type, int by_sexp) polymodel * pm_orig; pm_orig = model_get(sp->modelnum); trail_info *ci; - for(int h = 0; h < pm_orig->n_thrusters; h++) + for(int h = 0; h < pm_orig->submodel[pm_orig->detail[0]].submodel_thruster.size(); h++) { - for(int j = 0; j < pm_orig->thrusters->num_points; j++) + for(int j = 0; j < pm_orig->submodel[pm_orig->detail[0]].submodel_thruster[h].points.size(); j++) { // this means you've reached the max # of AB trails for a ship Assert(sip->ct_count <= MAX_SHIP_CONTRAILS); @@ -9281,10 +9319,10 @@ void change_ship_type(int n, int ship_type, int by_sexp) // ci = &sip->ct_info[sip->ct_count++]; - if(pm_orig->thrusters[h].points[j].norm.xyz.z > -0.5)continue;// only make ab trails for thrusters that are pointing backwards + if(pm_orig->submodel[pm_orig->detail[0]].submodel_thruster[h].points[j].norm.xyz.z > -0.5)continue;// only make ab trails for thrusters that are pointing backwards - ci->pt = pm_orig->thrusters[h].points[j].pnt;//offset - ci->w_start = pm_orig->thrusters[h].points[j].radius * sip->ABwidth_factor;//width * table loaded width factor + ci->pt = pm_orig->submodel[pm_orig->detail[0]].submodel_thruster[h].points[j].pnt;//offset + ci->w_start = pm_orig->submodel[pm_orig->detail[0]].submodel_thruster[h].points[j].radius * sip->ABwidth_factor;//width * table loaded width factor ci->w_end = 0.05f;//end width @@ -9446,7 +9484,7 @@ int ship_launch_countermeasure(object *objp, int rand_val) cobjnum = weapon_create(&pos, &objp->orient, shipp->current_cmeasure, OBJ_INDEX(objp)); if(cobjnum > -1) { - cmeasure_set_ship_launch_vel(&Objects[cobjnum], objp, arand); + if(Weapon_info[shipp->current_cmeasure].max_speed > 0.0f)cmeasure_set_ship_launch_vel(&Objects[cobjnum], objp, arand); nprintf(("Network", "Cmeasure created by %s\n", shipp->ship_name)); // Play sound effect for counter measure launch @@ -11614,6 +11652,9 @@ void ship_model_start(object *objp) } } +// model_do_dumb_rotation(shipp->modelnum); + +// model_do_look_at(shipp->modelnum); } //========================================================== diff --git a/code/ship/ship.h b/code/ship/ship.h index 8f1be8482f..68cf03b250 100644 --- a/code/ship/ship.h +++ b/code/ship/ship.h @@ -9,13 +9,17 @@ /* * $Logfile: /Freespace2/code/Ship/Ship.h $ - * $Revision: 2.174 $ - * $Date: 2007-01-08 00:50:59 $ - * $Author: Goober5000 $ + * $Revision: 2.175 $ + * $Date: 2007-01-14 14:03:37 $ + * $Author: bobboau $ * * all sorts of cool stuff about ships * * $Log: not supported by cvs2svn $ + * Revision 2.174 2007/01/08 00:50:59 Goober5000 + * remove WMC's limbo code, per our discussion a few months ago + * this will later be handled by copying ship stats using sexps or scripts + * * Revision 2.173 2007/01/07 21:28:11 Goober5000 * yet more tweaks to the WCS death scream stuff * added a ship flag to force screaming @@ -927,6 +931,7 @@ #include "weapon/shockwave.h" #include "species_defs/species_defs.h" #include "globalincs/pstypes.h" +#include "parse/scripting.h" #include "particle/particle.h" #include @@ -1145,6 +1150,7 @@ typedef struct ship_subsys { // Things like radar dishes would only use one. submodel_instance_info submodel_info_1; // Instance data for main turret or main object submodel_instance_info submodel_info_2; // Instance data for turret guns, if there is one +// ship_subsys*parent; //if there is a subsystem that owns this this will be something other than NULL int disruption_timestamp; // time at which subsystem isn't disrupted @@ -1619,6 +1625,7 @@ extern int ship_find_exited_ship_by_signature( int signature); #define SIF2_GENERATE_HUD_ICON (1 << 5) // Enable generation of a HUD shield icon #define SIF2_DISABLE_WEAP_DAMAGE_SCALING (1 << 6) // WMC - Disable weapon scaling based on flags #define SIF2_GUN_CONVERGENCE (1 << 7) // WMC - Gun convergence based on model weapon norms. +#define SIF2_PROJECTED_SHIELDS (1 << 8) // Bobboau - new projected shield rendering #define MAX_SHIP_FLAGS 8 // Number of flags for flags field in ship_info struct #define SIF_DEFAULT_VALUE (SIF_DO_COLLISION_CHECK) @@ -2184,8 +2191,8 @@ extern void create_shield_explosion(int objnum, int model_num, matrix *orient, v extern void shield_hit_init(); extern void create_shield_explosion_all(object *objp); extern void shield_frame_init(); -extern void add_shield_point(int objnum, int tri_num, vec3d *hit_pos); -extern void add_shield_point_multi(int objnum, int tri_num, vec3d *hit_pos); +extern void add_shield_point(int objnum, int tri_num, vec3d *hit_pos, float rad); +extern void add_shield_point_multi(int objnum, int tri_num, vec3d *hit_pos, float rad); extern void shield_point_multi_setup(); extern void shield_hit_close(); @@ -2340,11 +2347,11 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos // of the turret. The gun normal is the unrotated gun normal, (the center of the FOV cone), not // the actual gun normal given using the current turret heading. But it _is_ rotated into the model's orientation // in global space. -void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos, vec3d *gvec); +void ship_get_global_turret_info(object *objp, model_subsystem *tp, vec3d *gpos, vec3d *gvec, matrix *tmat = NULL); // return 1 if objp is in fov of the specified turret, tp. Otherwise return 0. // dist = distance from turret to center point of object -int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist); +int object_in_turret_fov(object *objp, model_subsystem *tp, vec3d *tvec, vec3d *tpos, float dist, matrix *tmat = NULL); // forcible jettison cargo from a ship void object_jettison_cargo(object *objp, object *cargo_objp); diff --git a/code/ship/shipfx.cpp b/code/ship/shipfx.cpp index a466e808d4..e95088da3f 100644 --- a/code/ship/shipfx.cpp +++ b/code/ship/shipfx.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Ship/ShipFX.cpp $ - * $Revision: 2.80 $ - * $Date: 2007-01-14 10:26:39 $ - * $Author: wmcoolmon $ + * $Revision: 2.81 $ + * $Date: 2007-01-14 14:03:37 $ + * $Author: bobboau $ * * Routines for ship effects (as in special) * * $Log: not supported by cvs2svn $ + * Revision 2.80 2007/01/14 10:26:39 wmcoolmon + * Attempt to remove various warnings under MSVC 2003, mostly related to casting, but also some instances of inaccessible code. + * * Revision 2.79 2007/01/08 00:50:59 Goober5000 * remove WMC's limbo code, per our discussion a few months ago * this will later be handled by copying ship stats using sexps or scripts @@ -3422,8 +3425,8 @@ void engine_wash_ship_process(ship *shipp) else speed_scale = ship_objp->phys_info.speed/20.0f; - for (idx = 0; idx < pm->n_thrusters; idx++) { - thruster_bank *bank = &pm->thrusters[idx]; + for (idx = 0; idx < pm->submodel[pm->detail[0]].submodel_thruster.size(); idx++) { + thruster_bank *bank = &pm->submodel[pm->detail[0]].submodel_thruster[idx]; // make sure this engine is functional before we try to process a wash from it if ( !model_should_render_engine_glow(OBJ_INDEX(ship_objp), bank->obj_num) ) { @@ -3445,7 +3448,7 @@ void engine_wash_ship_process(ship *shipp) half_angle = ewp->angle; radius_mult = ewp->radius_mult; - for (j=0; jnum_points; j++) { + for (j=0; jpoints.size(); j++) { // get world pos of thruster vm_vec_unrotate(&world_thruster_pos, &bank->points[j].pnt, &ship_objp->orient); vm_vec_add2(&world_thruster_pos, &ship_objp->pos); diff --git a/code/starfield/starfield.cpp b/code/starfield/starfield.cpp index eb406eecc2..1015afe7a0 100644 --- a/code/starfield/starfield.cpp +++ b/code/starfield/starfield.cpp @@ -9,14 +9,17 @@ /* * $Logfile: /Freespace2/code/Starfield/StarField.cpp $ - * $Revision: 2.91 $ - * $Date: 2007-01-14 10:26:39 $ - * $Author: wmcoolmon $ + * $Revision: 2.92 $ + * $Date: 2007-01-14 14:03:40 $ + * $Author: bobboau $ * * Code to handle and draw starfields, background space image bitmaps, floating * debris, etc. * * $Log: not supported by cvs2svn $ + * Revision 2.91 2007/01/14 10:26:39 wmcoolmon + * Attempt to remove various warnings under MSVC 2003, mostly related to casting, but also some instances of inaccessible code. + * * Revision 2.90 2007/01/10 01:45:06 taylor * compiler warning fixage * @@ -729,7 +732,9 @@ int stars_debris_loaded = 0; // 0 = not loaded, 1 = normal vclips, 2 = nebula vc // background data int Stars_background_inited = 0; // if we're inited + int Nmodel_num = -1; // model num +int Nmodel_flags = DEFALT_NMODEL_FLAGS; // model flags int Nmodel_bitmap = -1; // model texture int Num_debris_normal = 0; @@ -1467,8 +1472,15 @@ void stars_post_level_init() float dist, dist_max; ubyte red,green,blue,alpha; + // reset to -1 so we reload it each mission (if we need to) + Nmodel_num = -1; + Nmodel_flags = DEFALT_NMODEL_FLAGS; + if(Nmodel_bitmap != -1){ + bm_release(Nmodel_bitmap); + Nmodel_bitmap = -1; + } - stars_set_background_model(The_mission.skybox_model, NULL); + stars_set_background_model(The_mission.skybox_model, "", The_mission.skybox_flags); stars_load_debris( ((The_mission.flags & MISSION_FLAG_FULLNEB) || Nebula_sexp_used) ); @@ -1701,6 +1713,43 @@ void stars_get_sun_pos(int sun_n, vec3d *pos) vm_vec_rotate(pos, &temp, &rot); } +void stars_add_lights(){ + int idx; + vec3d sun_pos; + vec3d sun_dir; + vertex sun_vex; + starfield_bitmap *bm; + float local_scale = 1.0f; + + // draw all suns + for (idx = 0; idx < (int)Suns.size(); idx++) { + // get the instance + if (Suns[idx].star_bitmap_index < 0) + return; + + bm = &Sun_bitmaps[Suns[idx].star_bitmap_index]; + + // if no bitmap then bail... + if (bm->bitmap_id < 0) + continue; + + memset( &sun_vex, 0, sizeof(vertex) ); + + // get sun pos + sun_pos = vmd_zero_vector; + sun_pos.xyz.y = 1.0f; + stars_get_sun_pos(idx, &sun_pos); + + // get the direction + sun_dir = sun_pos; + vm_vec_normalize(&sun_dir); + + // add the light source corresponding to the sun, except when rendering to an envmap +// if ( !Rendering_to_env ) + light_add_directional(&sun_dir, bm->i, bm->r, bm->g, bm->b, bm->spec_r, bm->spec_g, bm->spec_b, true); + + } +} // draw sun void stars_draw_sun(int show_sun) { @@ -1742,8 +1791,8 @@ void stars_draw_sun(int show_sun) vm_vec_normalize(&sun_dir); // add the light source corresponding to the sun, except when rendering to an envmap - if ( !Rendering_to_env ) - light_add_directional(&sun_dir, bm->i, bm->r, bm->g, bm->b, bm->spec_r, bm->spec_g, bm->spec_b, true); +// if ( !Rendering_to_env ) +// light_add_directional(&sun_dir, bm->i, bm->r, bm->g, bm->b, bm->spec_r, bm->spec_g, bm->spec_b, true); // if supernova if ( supernova_active() ) @@ -2610,6 +2659,8 @@ void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspa Rendering_to_env = env; +// stars_add_lights(); + if (show_subspace) subspace_render(); @@ -2621,6 +2672,10 @@ void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspa xt1 = timer_get_fixed_seconds(); #endif + if ( !env && show_stars && ( Game_detail_flags & DETAIL_FLAG_STARS) && !(The_mission.flags & MISSION_FLAG_FULLNEB) && (supernova_active() < 3) ) { + stars_draw_stars(); + } + if ( show_nebulas && (Game_detail_flags & DETAIL_FLAG_NEBULAS) && (Neb2_render_mode != NEB2_RENDER_POF) && (Neb2_render_mode != NEB2_RENDER_LAME)) { nebula_render(); } @@ -2638,9 +2693,6 @@ void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspa stars_draw_background(); } - if ( !env && show_stars && ( Game_detail_flags & DETAIL_FLAG_STARS) && !(The_mission.flags & MISSION_FLAG_FULLNEB) && (supernova_active() < 3) ) { - stars_draw_stars(); - } last_stars_filled = 1; @@ -2947,27 +2999,36 @@ void stars_page_in() // background nebula models and planets void stars_draw_background() { - int flags = MR_NO_ZBUFFER | MR_NO_CULL | MR_ALL_XPARENT | MR_NO_LIGHTING; if (Nmodel_num < 0) return; if (Nmodel_bitmap > -1) { model_set_forced_texture(Nmodel_bitmap); - flags |= MR_FORCE_TEXTURE; + Nmodel_flags |= MR_FORCE_TEXTURE; } // draw the model at the player's eye with no z-buffering - model_set_alpha(1.0f); + model_set_alpha(1.0f); +// light_filter_push(-1,NULL,0.0f); + if(!(Nmodel_flags & MR_NO_LIGHTING ))gr_set_lighting(true, true); +// void light_set_all_relevent(); +// light_set_all_relevent(); - model_render(Nmodel_num, &vmd_identity_matrix, &Eye_position, flags); + model_render(Nmodel_num, &vmd_identity_matrix, &Eye_position, Nmodel_flags, -1); + +// light_filter_pop(); + if(!(Nmodel_flags & MR_NO_ZBUFFER ))gr_zbuffer_clear(TRUE); + + if(!(Nmodel_flags & MR_NO_LIGHTING ))gr_set_lighting(false, false); +// model_render(Nmodel_num, &vmd_identity_matrix, &Eye_position, flags); if (Nmodel_bitmap > -1) model_set_forced_texture(-1); } // call this to set a specific model as the background model -void stars_set_background_model(char *model_name, char *texture_name) +void stars_set_background_model(char *model_name, char *texture_name, int flags) { if (Nmodel_bitmap >= 0) { bm_unload(Nmodel_bitmap); @@ -2982,6 +3043,7 @@ void stars_set_background_model(char *model_name, char *texture_name) if ( (model_name == NULL) || (strlen(model_name) < 1) ) return; + Nmodel_flags = flags; Nmodel_num = model_load(model_name, 0, NULL, 0); Nmodel_bitmap = bm_load(texture_name); diff --git a/code/starfield/starfield.h b/code/starfield/starfield.h index f2c0599e66..de2bcd75d9 100644 --- a/code/starfield/starfield.h +++ b/code/starfield/starfield.h @@ -9,14 +9,17 @@ /* * $Logfile: /Freespace2/code/Starfield/StarField.h $ - * $Revision: 2.20 $ - * $Date: 2006-11-24 22:46:25 $ - * $Author: Goober5000 $ + * $Revision: 2.21 $ + * $Date: 2007-01-14 14:03:40 $ + * $Author: bobboau $ * * Code to handle and draw starfields, background space image bitmaps, floating * debris, etc. * * $Log: not supported by cvs2svn $ + * Revision 2.20 2006/11/24 22:46:25 Goober5000 + * FRED again updates backgrounds while the user is editing them + * * Revision 2.19 2006/11/16 00:53:12 taylor * various bits of little cleanup * get rid of some more compiler warnings @@ -204,6 +207,11 @@ #include "globalincs/globals.h" #include "globalincs/pstypes.h" #include "graphics/2d.h" +#include "model/model.h" + +#define DEFALT_NMODEL_FLAGS (MR_NO_ZBUFFER | MR_NO_CULL | MR_ALL_XPARENT | MR_NO_LIGHTING) +extern int Nmodel_num; // model num +extern int Nmodel_flags; // model flags #include @@ -295,7 +303,7 @@ void stars_draw_sun_glow(int sun_n); void stars_camera_cut(); // call this to set a specific model as the background model -void stars_set_background_model(char *model_name, char *texture_name); +void stars_set_background_model(char *model_name, char *texture_name, int flags = DEFALT_NMODEL_FLAGS); // lookup a starfield bitmap, return index or -1 on fail int stars_find_bitmap(char *name); diff --git a/code/weapon/beam.cpp b/code/weapon/beam.cpp index cd68e38ddf..b8c4b614f8 100644 --- a/code/weapon/beam.cpp +++ b/code/weapon/beam.cpp @@ -9,13 +9,16 @@ /* * $Logfile: /Freespace2/code/Weapon/Beam.cpp $ - * $Revision: 2.76 $ - * $Date: 2007-01-14 10:26:39 $ - * $Author: wmcoolmon $ + * $Revision: 2.77 $ + * $Date: 2007-01-14 14:03:40 $ + * $Author: bobboau $ * * all sorts of cool stuff about ships * * $Log: not supported by cvs2svn $ + * Revision 2.76 2007/01/14 10:26:39 wmcoolmon + * Attempt to remove various warnings under MSVC 2003, mostly related to casting, but also some instances of inaccessible code. + * * Revision 2.75 2006/12/28 00:59:53 wmcoolmon * WMC codebase commit. See pre-commit build thread for details on changes. * @@ -1375,7 +1378,12 @@ void beam_type_c_move(beam *b) vm_vec_add2(&b->last_start, &b->objp->pos); vm_vec_scale_add(&b->last_shot, &b->last_start, &b->objp->orient.vec.fvec, b->range); - Ships[b->objp->instance].weapon_energy -= Weapon_info[b->weapon_info_index].energy_consumed * flFrametime; + float e = Weapon_info[b->weapon_info_index].energy_consumed * flFrametime; + if(b->warmdown_stamp == -1)Ships[b->objp->instance].weapon_energy -= e; + else Ships[b->objp->instance].weapon_energy += e; + + if(Ships[b->objp->instance].weapon_energy < 0) Ships[b->objp->instance].weapon_energy = 0; + if(Ships[b->objp->instance].weapon_energy > Ship_info[Ships[b->objp->instance].ship_info_index].max_weapon_reserve) Ships[b->objp->instance].weapon_energy = Ship_info[Ships[b->objp->instance].ship_info_index].max_weapon_reserve; } // type D functions @@ -1707,9 +1715,11 @@ void beam_move_all_post() #define P_VERTICES() do { for(idx=0; idx<4; idx++){ g3_project_vertex(verts[idx]); } } while(0); int poly_beam = 0; float U_offset =0.0f; // beam texture offset -Bobboau -void beam_render(beam_weapon_info *bwi, vec3d *start, vec3d *shot, float shrink) +void beam_render(beam_weapon_info *bwi, vec3d *start, vec3d *beam_shot, float shrink) { // mprintf(("about to render a beam\n")); + vec3d sh; + vec3d *shot = beam_shot; int idx, s_idx; vertex h1[4]; // halves of a beam section vertex *verts[4] = { &h1[0], &h1[1], &h1[2], &h1[3] }; @@ -1738,7 +1748,14 @@ void beam_render(beam_weapon_info *bwi, vec3d *start, vec3d *shot, float shrink) gr_set_cull(0); // draw all sections - for(s_idx=0; s_idxbeam_num_sections; s_idx++){ + for(s_idx=0; s_idxsections.size(); s_idx++){ + // calculate the beam points + if(bwi->sections[s_idx].length > 0.0f){ + shot = &sh; + vm_vec_scale_add(shot, start, &fvec, bwi->sections[s_idx].length); + }else{ + shot = beam_shot; + } if ( (bwi->sections[s_idx].texture < 0) || (bwi->sections[s_idx].width <= 0.0f) ) continue; @@ -3152,7 +3169,7 @@ int beam_collide_early_out(object *a, object *b) } if((vm_vec_dist(&bm->last_start, &b->pos)-b->radius) > bwi->b_info.range){ - return 1; + return 0;//it might get closer... dumbass }//if the object is too far away, don't bother trying to colide with it-Bobboau // baseline bails @@ -3211,7 +3228,7 @@ void beam_add_collision(beam *b, object *hit_object, mc_info *cinfo, int quad, i beam_collision *bc; int idx; int quadrant_num = -1; -// weapon_info *bwi = &Weapon_info[b->weapon_info_index]; + weapon_info *bwi = &Weapon_info[b->weapon_info_index]; // if we haven't reached the limit for beam collisions, just add if(b->f_collision_count < MAX_FRAME_COLLISIONS){ @@ -3243,7 +3260,7 @@ void beam_add_collision(beam *b, object *hit_object, mc_info *cinfo, int quad, i if (!(hit_object->flags & SF_DYING) ) { if (cinfo->flags & MC_CHECK_SHIELD) { // Don't do this for surface shields. - add_shield_point(hit_object-Objects, cinfo->shield_hit_tri, &cinfo->hit_point); + add_shield_point(hit_object-Objects, cinfo->shield_hit_tri, &cinfo->hit_point, bwi->shield_hit_radius); } hud_shield_quadrant_hit(hit_object, quadrant_num); } @@ -3528,7 +3545,7 @@ int beam_ok_to_fire(beam *b) // type C beams are ok to fire all the time if(b->type == BEAM_TYPE_C){ ship *shipp = &Ships[b->objp->instance]; - if(shipp->weapon_energy < 0.0){ + if(shipp->weapon_energy <= 0.0){ // shipp->weapons.next_primary_fire_stamp[b->bank] = timestamp(Weapon_info[shipp->weapons.primary_bank_weapons[b->bank]].b_info.beam_warmdown*2); shipp->weapons.next_primary_fire_stamp[b->bank] = timestamp(2000); int ship_maybe_play_primary_fail_sound(); @@ -3578,7 +3595,7 @@ float beam_get_widest(beam *b) } // lookup - for(idx=0; idxweapon_info_index].b_info.beam_num_sections; idx++){ + for(idx=0; idxweapon_info_index].b_info.sections.size(); idx++){ if(Weapon_info[b->weapon_info_index].b_info.sections[idx].width > widest){ widest = Weapon_info[b->weapon_info_index].b_info.sections[idx].width; } diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index 35ea41ed8b..e5d0c916ce 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -12,6 +12,11 @@ * * * $Log: not supported by cvs2svn $ + * Revision 2.73 2007/01/07 12:41:37 taylor + * make expl info dyanmic + * fix possible out-of-bounds on expl lod checking + * fix memory leak from modular tables + * * Revision 2.72 2006/12/28 00:59:54 wmcoolmon * WMC codebase commit. See pre-commit build thread for details on changes. * @@ -631,6 +636,7 @@ extern int Num_weapon_subtypes; #define WIF2_SAME_TURRET_COOLDOWN (1 << 7) // the weapon has the same cooldown time on turrets #define WIF2_MR_NO_LIGHTING (1 << 8) // don't render with lighting, regardless of user options #define WIF2_TRANSPARENT (1 << 9) // render as transparent +#define WIF2_MINE (1 << 10) // it's a mine, start motionless, can be shot down, by same iff if bomb #define WIF_HOMING (WIF_HOMING_HEAT | WIF_HOMING_ASPECT) #define WIF_HURTS_BIG_SHIPS (WIF_BOMB | WIF_BEAM | WIF_HUGE | WIF_BIG_ONLY) @@ -712,7 +718,17 @@ typedef struct weapon { // info specific to beam weapons #define MAX_BEAM_SECTIONS 5 typedef struct beam_weapon_section_info { + beam_weapon_section_info():length(0.0f),width(1.0f),texture(-1),nframes(1),fps(1),flicker(0.1f),z_add(0.0f),tile_type(0),tile_factor(1.0f),translation(0.0f){ + for(int j = 0; j < 4; j++) + { + rgba_inner[j] = 0; + rgba_outer[j] = 255; + } + + } + float width; // width of the section + float length; // length of the section int texture; // texture bitmap ubyte rgba_inner[4]; // for non-textured beams ubyte rgba_outer[4]; // for non-textured beams @@ -739,14 +755,14 @@ typedef struct beam_weapon_info { int beam_loop_sound; // looping beam sound int beam_warmup_sound; // warmup sound int beam_warmdown_sound; // warmdown sound - int beam_num_sections; // the # of visible "sections" on the beam +// int beam_num_sections; // the # of visible "sections" on the beam int beam_glow_bitmap; // muzzle glow bitmap int beam_glow_nframes; // number of frames, if animated int beam_glow_fps; // frames/sec, if animated int beam_shots; // # of shots the beam takes float beam_shrink_factor; // what percentage of total beam lifetime when the beam starts shrinking float beam_shrink_pct; // what percent/second the beam shrinks at - beam_weapon_section_info sections[MAX_BEAM_SECTIONS]; // info on the visible sections of the beam + std::vector sections; // info on the visible sections of the beam float range; //how far it will shoot-Bobboau float damage_threshold; //point at wich damage will start being atenuated from 0.0 to 1.0 } beam_weapon_info; @@ -795,6 +811,8 @@ typedef struct weapon_info { float mass; // mass of the weapon float fire_wait; // fire rate -- amount of time before you can refire the weapon + float hit_points; + float damage; // damage of weapon (for missile, damage within inner radius) shockwave_create_info shockwave; @@ -952,6 +970,11 @@ typedef struct weapon_info { float alpha_max; // maximum alpha value to use float alpha_min; // minimum alpha value to use float alpha_cycle; // cycle between max and min by this much each frame + + float shield_hit_radius; + + float proximity_detonate; + } weapon_info; // Data structure to track the active missiles @@ -1074,4 +1097,6 @@ void weapon_hit_do_sound(object *hit_obj, weapon_info *wip, vec3d *hitpos, bool // return a scale factor for damage which should be applied for 2 collisions float weapon_get_damage_scale(weapon_info *wip, object *wep, object *target); +bool weapon_armed(weapon *wp); + #endif diff --git a/code/weapon/weapons.cpp b/code/weapon/weapons.cpp index d6a628c1f7..1b15fadd8f 100644 --- a/code/weapon/weapons.cpp +++ b/code/weapon/weapons.cpp @@ -12,6 +12,9 @@ * * * $Log: not supported by cvs2svn $ + * Revision 2.190 2007/01/12 04:33:49 Goober5000 + * hmm... I guess when I fixed this back in 2004, I fixed it the wrong way :D + * * Revision 2.189 2007/01/07 12:41:37 taylor * make expl info dyanmic * fix possible out-of-bounds on expl lod checking @@ -1599,6 +1602,8 @@ void parse_wi_flags(weapon_info *weaponp) weaponp->wi_flags2 |= WIF2_SAME_TURRET_COOLDOWN; else if (!stricmp(NOX("apply no light"), weapon_strings[i])) weaponp->wi_flags2 |= WIF2_MR_NO_LIGHTING; + else if (!stricmp(NOX("mine"), weapon_strings[i])) + weaponp->wi_flags2 |= WIF2_MINE; else Warning(LOCATION, "Bogus string in weapon flags: %s\n", weapon_strings[i]); } @@ -1879,7 +1884,7 @@ void init_weapon_entry(int weap_info_index) wip->b_info.beam_loop_sound = -1; wip->b_info.beam_warmup_sound = -1; wip->b_info.beam_warmdown_sound = -1; - wip->b_info.beam_num_sections = 0; +// wip->b_info.beam_num_sections = 0; wip->b_info.beam_glow_bitmap = -1; wip->b_info.beam_glow_nframes = 1; wip->b_info.beam_glow_fps = 0; @@ -1889,8 +1894,9 @@ void init_weapon_entry(int weap_info_index) wip->b_info.range = BEAM_FAR_LENGTH; wip->b_info.damage_threshold = 1.0f; + wip->b_info.sections.clear(); //WMC - Okay, so this is needed now - beam_weapon_section_info *bsip; +/* beam_weapon_section_info *bsip; for(i = 0; i < MAX_BEAM_SECTIONS;i++) { bsip = &wip->b_info.sections[i]; @@ -1911,7 +1917,7 @@ void init_weapon_entry(int weap_info_index) bsip->tile_type = 0; bsip->tile_factor = 1.0f; bsip->translation = 0.0f; - } + }*/ wip->Weapon_particle_spew_count = 1; wip->Weapon_particle_spew_time = 25; @@ -2258,6 +2264,12 @@ int parse_weapon(int subtype, bool replace) diag_printf ("Weapon fire wait -- %7.3f\n", wip->fire_wait); } + if(optional_string("$Hitpoints:")) { + stuff_float( &wip->hit_points); + }else{ + wip->hit_points = 0.0f; + } + if(optional_string("$Damage:")) { stuff_float(&wip->damage); //WMC - now that shockwave damage can be set for them individually, @@ -3008,9 +3020,9 @@ int parse_weapon(int subtype, bool replace) if(optional_string("+Index:")) { stuff_int(&bsw_index_override); - if(bsw_index_override < 0 || bsw_index_override >= wip->b_info.beam_num_sections) + if(bsw_index_override < 0 || bsw_index_override >= wip->b_info.sections.size()) { - Warning(LOCATION, "Invalid +Index value of %d specified for beam section on weapon '%s'; valid values at this point are %d to %d.", bsw_index_override, wip->name, 0, wip->b_info.beam_num_sections -1); + Warning(LOCATION, "Invalid +Index value of %d specified for beam section on weapon '%s'; valid values at this point are %d to %d.", bsw_index_override, wip->name, 0, wip->b_info.sections.size() -1); } } if(optional_string("+nocreate")) { @@ -3020,7 +3032,7 @@ int parse_weapon(int subtype, bool replace) //Where are we saving data? if(bsw_index_override >= 0) { - if(bsw_index_override < wip->b_info.beam_num_sections) + if(bsw_index_override < wip->b_info.sections.size()) { ip = &wip->b_info.sections[bsw_index_override]; } @@ -3028,40 +3040,25 @@ int parse_weapon(int subtype, bool replace) { if(!nocreate) { - if((bsw_index_override == wip->b_info.beam_num_sections) && (bsw_index_override < MAX_BEAM_SECTIONS)) - { - ip = &wip->b_info.sections[wip->b_info.beam_num_sections++]; - } - else - { - Warning(LOCATION, "Invalid index for manually-indexed beam section %d (max %d) on weapon %s.", bsw_index_override, MAX_BEAM_SECTIONS, wip->name); - ip = &tbsw; - memset( ip, 0, sizeof(beam_weapon_section_info) ); - ip->texture = -1; - } - } - else - { - Warning(LOCATION, "Invalid index for manually-indexed beam section %d, and +nocreate specified, on weapon %s", bsw_index_override, wip->name); + //if we aren't suposed to make a new one, there does not exsist one to over ride + Warning(LOCATION, "Invalid index for manually-indexed beam section %d (max %d) on weapon %s.", bsw_index_override, wip->b_info.sections.size(), wip->name); ip = &tbsw; memset( ip, 0, sizeof(beam_weapon_section_info) ); ip->texture = -1; } + else + { + //here we can just make a new one + wip->b_info.sections.resize(wip->b_info.sections.size()+1); + ip = wip->b_info.sections.end()-1; + } } } else { - if(wip->b_info.beam_num_sections < MAX_BEAM_SECTIONS) { - ip = &wip->b_info.sections[wip->b_info.beam_num_sections++]; - } - else - { - Warning(LOCATION, "Too many beam sections for weapon %s - max is %d", wip->name, MAX_BEAM_SECTIONS); - ip = &tbsw; - memset( ip, 0, sizeof(beam_weapon_section_info) ); - ip->texture = -1; - } + wip->b_info.sections.resize(wip->b_info.sections.size()+1); + ip = wip->b_info.sections.end()-1; } char tex_name[MAX_FILENAME_LEN]; @@ -3071,6 +3068,12 @@ int parse_weapon(int subtype, bool replace) stuff_float(&ip->width); } + if(optional_string("+Length:")) { + stuff_float(&ip->length); + }else{ + ip->length = 0.0f; + } + // texture if(optional_string("+Texture:")) { @@ -3266,6 +3269,14 @@ int parse_weapon(int subtype, bool replace) Warning(LOCATION, "%s is a tag missile, but the target must be tagged to shoot it", wip->name); } + + if(optional_string("$Sheild Hit Radius:")){ + stuff_float(&wip->shield_hit_radius); + }else{ + wip->shield_hit_radius = (wip->render_type == WRT_LASER)?wip->laser_head_radius*4.0f:wip->shockwave.outer_rad; + } + + return WEAPON_INFO_INDEX(wip); } //Commented out with ifdef @@ -4693,6 +4704,7 @@ void weapon_process_pre( object *obj, float frame_time) if(wip->det_radius > 0.0f && wp->homing_object != NULL) { vec3d spos; + if(weapon_armed(wp)) if((wp->homing_subsys == NULL && vm_vec_dist(&obj->pos, &wp->homing_object->pos) <= wip->det_radius) || (wp->homing_subsys != NULL && get_subsystem_pos(&spos, wp->homing_object, wp->homing_subsys) && vm_vec_dist(&obj->pos, &spos) <= wip->det_radius)) { @@ -5308,7 +5320,9 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob objp->phys_info.max_vel.xyz.z = wip->max_speed; vm_vec_zero(&objp->phys_info.max_rotvel); objp->shield_quadrant[0] = wip->damage; - if (wip->wi_flags & WIF_BOMB){ + if(wip->hit_points > 0.0){ + objp->hull_strength = wip->hit_points; + }else if (wip->wi_flags & WIF_BOMB){ objp->hull_strength = 50.0f; } else { objp->hull_strength = 0.0f; @@ -5334,11 +5348,14 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob // For weapons that home, set velocity to sum of forward component of parent's velocity and 1/4 weapon's max speed. // Note that it is important to extract the forward component of the parent's velocity to factor out sliding, else // the missile will not be moving forward. - if(parent_objp != NULL){ - vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, vm_vec_dot(&parent_objp->phys_info.vel, &parent_objp->orient.vec.fvec) + objp->phys_info.max_vel.xyz.z/4 ); - } else { - vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z/4 ); - } + if(wip->max_speed > 0.0f) + if(parent_objp != NULL){ + vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, vm_vec_dot(&parent_objp->phys_info.vel, &parent_objp->orient.vec.fvec) + objp->phys_info.max_vel.xyz.z/4 ); + } else { + vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z/4 ); + } + else + vm_vec_zero(&objp->phys_info.desired_vel); objp->phys_info.vel = objp->phys_info.desired_vel; objp->phys_info.speed = vm_vec_mag(&objp->phys_info.vel); } @@ -5412,7 +5429,7 @@ int weapon_create( vec3d * pos, matrix * porient, int weapon_type, int parent_ob // since debug builds always have cheats enabled, we don't necessarily get the chance // to enable thrusters for previously non-loaded weapons (ie, weapons_page_in_cheats()) // when using cheat-keys, so we need to make sure and enable thrusters here if needed - if (pm->n_thrusters > 0) { + if (pm->submodel[pm->detail[0]].submodel_thruster.size() > 0) { wip->wi_flags |= WIF_THRUSTER; } #endif @@ -6200,7 +6217,7 @@ void weapons_page_in() // If it has a model, and the model pof has thrusters, then set // the flags - if ( pm->n_thrusters > 0 ) { + if ( pm->submodel[pm->detail[0]].submodel_thruster.size() > 0 ) { //mprintf(( "Weapon %s has thrusters!\n", wip->name )); wip->wi_flags |= WIF_THRUSTER; } @@ -6254,8 +6271,8 @@ void weapons_page_in() // if this is a beam weapon, page in its stuff if(wip->wi_flags & WIF_BEAM){ // all beam sections - for(idx=0; idxb_info.beam_num_sections; idx++){ - if((idx < MAX_BEAM_SECTIONS) && (wip->b_info.sections[idx].texture >= 0)){ + for(idx=0; idxb_info.sections.size(); idx++){ + if((idx < wip->b_info.sections.size()) && (wip->b_info.sections[idx].texture >= 0)){ bm_page_in_texture(wip->b_info.sections[idx].texture, wip->b_info.sections[idx].nframes); } } @@ -6358,7 +6375,7 @@ void weapons_page_in_cheats() // If it has a model, and the model pof has thrusters, then set // the flags - if ( pm->n_thrusters > 0 ) { + if ( pm->submodel[pm->detail[0]].submodel_thruster.size() > 0 ) { //mprintf(( "Weapon %s has thrusters!\n", wip->name )); wip->wi_flags |= WIF_THRUSTER; }