Files
fs2open.github.com/code/cmeasure/cmeasure.cpp
T
2005-12-04 19:07:49 +00:00

516 lines
15 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
/*
* $Logfile: /Freespace2/code/CMeasure/CMeasure.cpp $
* $Revision: 2.9 $
* $Date: 2005-12-04 19:07:48 $
* $Author: wmcoolmon $
*
* Counter measures. Created by Mike Kulas, May 12, 1997.
*
* $Log: not supported by cvs2svn $
* Revision 2.8 2005/11/21 02:43:30 Goober5000
* change from "setting" to "profile"; this way makes more sense
* --Goober5000
*
* Revision 2.7 2005/11/21 00:46:06 Goober5000
* add ai_settings.tbl
* --Goober5000
*
* Revision 2.6 2005/04/05 05:53:15 taylor
* s/vector/vec3d/g, better support for different compilers (Jens Granseuer)
*
* Revision 2.5 2004/07/26 20:47:25 Kazan
* remove MCD complete
*
* Revision 2.4 2004/07/12 16:32:43 Kazan
* MCD - define _MCD_CHECK to use memory tracking
*
* Revision 2.3 2004/03/05 09:01:57 Goober5000
* Uber pass at reducing #includes
* --Goober5000
*
* Revision 2.2 2003/03/18 10:07:00 unknownplayer
* The big DX/main line merge. This has been uploaded to the main CVS since I can't manage to get it to upload to the DX branch. Apologies to all who may be affected adversely, but I'll work to debug it as fast as I can.
*
* Revision 2.1.2.1 2002/09/24 18:56:41 randomtiger
* DX8 branch commit
*
* This is the scub of UP's previous code with the more up to date RT code.
* For full details check previous dev e-mails
*
* Revision 2.1 2002/08/01 01:41:04 penguin
* The big include file move
*
* Revision 2.0 2002/06/03 04:02:21 penguin
* Warpcore CVS sync
*
* Revision 1.2 2002/05/03 22:07:08 mharris
* got some stuff to compile
*
* Revision 1.1 2002/05/02 18:03:04 mharris
* Initial checkin - converted filenames and includes to lower case
*
*
* 5 9/05/99 11:25p Mikek
* Debug code (only on NDEBUG). Don't drop countermeasures if
* Ai_firing_enabled not set.
*
* 4 11/05/98 5:55p Dave
* Big pass at reducing #includes
*
* 3 10/13/98 9:28a Dave
* Started neatening up freespace.h. Many variables renamed and
* reorganized. Added AlphaColors.[h,cpp]
*
* 2 10/07/98 10:52a Dave
* Initial checkin.
*
* 1 10/07/98 10:48a Dave
*
* 44 4/29/98 9:36p Allender
* ingame join tweaks. added network message for countermeasures
*
* 43 4/13/98 5:11p Mike
* More improvement to countermeasure code.
*
* 42 4/13/98 2:14p Mike
* Countermeasure balance testing for Jim.
*
* 41 4/10/98 11:02p Mike
* Make countermeasures less effective against aspect seekers than against
* heat seekers.
* Make AI ships match bank with each other when attacking a faraway
* target.
* Make ships not do silly loop-de-loop sometimes when attacking a faraway
* target.
*
* 40 3/31/98 5:11p John
* Removed demo/save/restore. Made NDEBUG defined compile. Removed a
* bunch of debug stuff out of player file. Made model code be able to
* unload models and malloc out only however many models are needed.
*
* 39 3/17/98 3:49p John
* Turned off lighting on counter measures.
*
* 38 2/26/98 10:07p Hoffoss
* Rewrote state saving and restoring to fix bugs and simplify the code.
*
* 37 2/23/98 5:44p Johnson
* Resolve build error.
*
* 36 2/23/98 4:30p Mike
* Make homing missiles detonate after they pass up their target. Make
* countermeasures less effective.
*
* 35 2/09/98 8:04p Lawrance
* Add objnum to cmeasure struct, correctly set source_objnum
*
* 34 2/05/98 11:20p Lawrance
* save/restore countermeasure data
*
* 33 2/05/98 12:51a Mike
* Early asteroid stuff.
*
* 32 2/04/98 12:20p Mike
* Make countermeasures detonate in a smaller radius. Make all in radius,
* not just homing one, detonate.
*
* 31 1/29/98 11:48a John
* Added new counter measure rendering as model code. Made weapons be
* able to have impact explosion.
*
* 30 1/29/98 11:11a John
* Put in code to show dummy counter measure object.
*
* 29 1/23/98 5:06p John
* Took L out of vertex structure used B (blue) instead. Took all small
* fireballs out of fireball types and used particles instead. Fixed some
* debris explosion things. Restructured fireball code. Restructured
* some lighting code. Made dynamic lighting on by default. Made groups
* of lasers only cast one light. Made fireballs not cast light.
*
* 28 1/23/98 9:43a Mike
* Debug-C to disallow countermeasure firing.
* Fix bug in countermeasure tracking by aspect seekers.
*
* 27 1/20/98 9:47a Mike
* Suppress optimized compiler warnings.
* Some secondary weapon work.
*
* 26 1/16/98 11:43a Mike
* Fix countermeasures.
*
* 25 12/30/97 6:44p John
* Made g3_Draw_bitmap functions account for aspect of bitmap.
*
* 24 11/29/97 2:05p John
* made g3_draw_bitmap and g3_draw_rotated bitmap take w&h, not w/2 & h/2,
* like they used to incorrectly assume. Added code to model to read in
* thruster radius's.
*
* 23 10/27/97 3:24p Lawrance
* ensure countermeasures keep their initial velocity
*
* 22 9/14/97 4:50p Lawrance
* added some demo debugging code
*
* 21 9/04/97 5:09p Andsager
* implement physics using moment of inertia and mass (from BSPgen).
* Added to phys_info struct. Updated ship_info, polymodel structs.
* Updated weapon ($Mass and $Force) and ship ($Mass -> $Density) tables
*
* 20 8/20/97 11:09a Mike
* Make countermeasure lifetime based on skill level.
*
* 19 8/13/97 9:50p Allender
* split *_move into *_process_pre and *_process_post functions.
* process_pre functions called before object is moved. _process_post
* functions called after object is moved. Reordered code in ship_post
* and weapon_post for multiplayer
*
* 18 8/13/97 4:45p Allender
* fixed ship_fire_primary and fire_secondary to not take parameter for
* determining whether to count ammo or not. Fixed countermeasure firing
* for multiplayer
*
* 17 8/13/97 12:06p Lawrance
* supporting multiple types of fireball explosions
*
* 16 8/11/97 6:03p Mike
* Make ships with no shields not claim to have shields in target box.
*
* 15 8/08/97 4:29p Allender
* countermeasure stuff for multiplayer
*
* 14 7/31/97 5:55p John
* made so you pass flags to obj_create.
* Added new collision code that ignores any pairs that will never
* collide.
*
* 13 7/15/97 12:03p Andsager
* New physics stuff
*
* 12 7/11/97 11:54a John
* added rotated 3d bitmaps.
*
* 11 6/24/97 10:04a Allender
* major multiplayer improvements. Better sequencing before game.
* Dealing with weapon/fireball/counter measure objects between
* client/host.
*
* 10 6/24/97 12:38a Lawrance
* fix minor bug with cycling cmeasure
*
* 9 6/05/97 1:37a Lawrance
* change syntax of a snd_play()
*
* 8 5/22/97 5:45p Mike
* Better countermeasure firing, key off availability, specify in
* weapons.tbl
*
* 7 5/22/97 12:06p Lawrance
* include Sound.h for playing sound fx
*
* 6 5/22/97 12:04p Lawrance
* added soundhook for cmeasure cycle
*
* 5 5/15/97 5:05p Mike
* In the midst of changing subsystem targetnig from type-based to
* pointer-based.
* Also allowed you to view a target while dead.
*
* 4 5/14/97 4:08p Lawrance
* removing my_index from game arrays
*
* 3 5/14/97 10:50a Mike
* More countermeasure stuff.
*
* 2 5/12/97 5:58p Mike
* Add countermeasures.
*
* 1 5/12/97 2:23p Mike
*
* $NoKeywords: $
*/
#include "cmeasure/cmeasure.h"
//#include "freespace2/freespace.h"
//#include "model/model.h"
#include "ship/ship.h"
#include "math/staticrand.h"
#include "object/object.h"
#include "weapon/weapon.h"
#include "hud/hud.h"
#include "gamesnd/gamesnd.h"
#include "network/multimsgs.h"
#include "mission/missionparse.h"
//cmeasure_info Cmeasure_info[MAX_CMEASURE_TYPES];
//cmeasure Cmeasures[MAX_CMEASURES];
//int Num_cmeasure_types = 0;
//int Num_cmeasures = 0;
//int Cmeasure_inited = 0;
int Cmeasures_homing_check = 0;
int Countermeasures_enabled = 1; // Debug, set to 0 means no one can fire countermeasures.
// This will get called at the start of each level.
//Not anymore - WMC
/*
void cmeasure_init()
{
int i;
if ( !Cmeasure_inited )
Cmeasure_inited = 1;
// Reset everything between levels
Num_cmeasures = 0;
for (i=0; i<MAX_CMEASURES; i++ ) {
Cmeasures[i].subtype = CMEASURE_UNUSED;
}
}*/
/*
void cmeasure_render(object * objp)
{
// JAS TODO: Replace with proper fireball
cmeasure *cmp;
cmeasure_info *cmip;
cmp = &Cmeasures[objp->instance];
cmip = &Cmeasure_info[cmp->subtype];
if ( cmp->subtype == CMEASURE_UNUSED ) {
Int3(); // Hey, what are we doing in here?
return;
}
if ( cmip->model_num > -1 ) {
model_clear_instance(cmip->model_num);
model_render(cmip->model_num, &objp->orient, &objp->pos, MR_NO_LIGHTING );
} else {
mprintf(( "Not rendering countermeasure because model_num is negative\n" ));
}
}*/
/*
void cmeasure_delete( object * objp )
{
int num;
num = objp->instance;
// Assert( Cmeasures[num].objnum == OBJ_INDEX(objp));
Cmeasures[num].subtype = CMEASURE_UNUSED;
Num_cmeasures--;
Assert( Num_cmeasures >= 0 );
}*/
// broke cmeasure_move into two functions -- process_pre and process_post (as was done with
// all *_move functions). Nothing to do for process_pre
/*
void cmeasure_process_pre( object *objp, float frame_time)
{
}*/
/*
void cmeasure_process_post(object * objp, float frame_time)
{
int num;
num = objp->instance;
// Assert( Cmeasures[num].objnum == objnum );
cmeasure *cmp = &Cmeasures[num];
if ( cmp->lifeleft >= 0.0f) {
cmp->lifeleft -= frame_time;
if ( cmp->lifeleft < 0.0f ) {
objp->flags |= OF_SHOULD_BE_DEAD;
// demo_do_flag_dead(OBJ_INDEX(objp));
}
}
}*/
// creates one countermeasure. A ship fires 1 of these per launch. rand_val is used
// in multiplayer. If -1, then create a random number. If non-negative, use this
// number for static_rand functions
/*
int cmeasure_create( object * source_obj, vec3d * pos, int cm_type, int rand_val )
{
int n, objnum, parent_objnum, arand;
object * obj;
ship *shipp;
cmeasure *cmp;
cmeasure_info *cmeasurep;
Cmeasures_homing_check = 2; // Tell homing code to scan everything for two frames. If only one frame, get sync problems due to objects being created at end of frame!
parent_objnum = OBJ_INDEX(source_obj);
Assert( source_obj->type == OBJ_SHIP );
Assert( source_obj->instance >= 0 && source_obj->instance < MAX_SHIPS );
shipp = &Ships[source_obj->instance];
if ( Num_cmeasures >= MAX_CMEASURES)
return -1;
for (n=0; n<MAX_CMEASURES; n++ )
if ( Cmeasures[n].subtype == CMEASURE_UNUSED)
break;
if ( n == MAX_CMEASURES)
return -1;
nprintf(("Network", "Cmeasure created by %s\n", Ships[source_obj->instance].ship_name));
cmp = &Cmeasures[n];
cmeasurep = &Cmeasure_info[cm_type];
if ( pos == NULL )
pos = &source_obj->pos;
objnum = obj_create( OBJ_CMEASURE, parent_objnum, n, &source_obj->orient, pos, 1.0f, OF_RENDERS | OF_PHYSICS );
Assert( objnum >= 0 && objnum < MAX_OBJECTS );
// Create Debris piece n!
if ( rand_val == -1 )
arand = myrand(); // use a random number to get lifeleft, and random vector for displacement from ship
else
arand = rand_val;
cmp->lifeleft = static_randf(arand) * (cmeasurep->life_max - cmeasurep->life_min) / cmeasurep->life_min;
if (source_obj->flags & OF_PLAYER_SHIP){
cmp->lifeleft *= The_mission.ai_profile->cmeasure_life_scale[Game_skill_level];
}
cmp->lifeleft = cmeasurep->life_min + cmp->lifeleft * (cmeasurep->life_max - cmeasurep->life_min);
// cmp->objnum = objnum;
cmp->team = shipp->team;
cmp->subtype = cm_type;
cmp->objnum = objnum;
cmp->source_objnum = parent_objnum;
cmp->source_sig = Objects[objnum].signature;
cmp->flags = 0;
nprintf(("Jim", "Frame %i: Launching countermeasure #%i\n", Framecount, Objects[objnum].signature));
obj = &Objects[objnum];
Num_cmeasures++;
//Set countermeasure velocity
vec3d vel, rand_vec;
//Get cmeasure rear velocity in world
vm_vec_scale_add(&vel, &source_obj->phys_info.vel, &source_obj->orient.vec.fvec, -25.0f);
//Get random velocity vector
static_randvec(arand+1, &rand_vec);
//Add it to the rear velocity
vm_vec_scale_add2(&vel, &rand_vec, 2.0f);
obj->phys_info.vel = vel;
vm_vec_zero(&obj->phys_info.rotvel);
vm_vec_zero(&obj->phys_info.max_vel);
vm_vec_zero(&obj->phys_info.max_rotvel);
// blow out his reverse thrusters. Or drag, same thing.
obj->phys_info.rotdamp = 10000.0f;
obj->phys_info.side_slip_time_const = 10000.0f;
obj->phys_info.max_vel.xyz.z = -25.0f;
vm_vec_copy_scale(&obj->phys_info.desired_vel, &obj->orient.vec.fvec, obj->phys_info.max_vel.xyz.z );
return arand; // need to return this value for multiplayer purposes
}*/
//Used to set a countermeasure velocity after being launched from a ship as a countermeasure
//ie not as a primary or secondary.
void cmeasure_set_ship_launch_vel(object *objp, object *parent_objp, int arand)
{
vec3d vel, rand_vec;
//Get cmeasure rear velocity in world
vm_vec_scale_add(&vel, &parent_objp->phys_info.vel, &parent_objp->orient.vec.fvec, -25.0f);
//Get random velocity vector
static_randvec(arand+1, &rand_vec);
//Add it to the rear velocity
vm_vec_scale_add2(&vel, &rand_vec, 2.0f);
objp->phys_info.vel = vel;
//Zero out this stuff so it isn't moving
vm_vec_zero(&objp->phys_info.rotvel);
vm_vec_zero(&objp->phys_info.max_vel);
vm_vec_zero(&objp->phys_info.max_rotvel);
//Idunnit. -WMC
//objp->phys_info.flags |= PF_CONST_VEL;
//WMC - I don't think this stuff is needed with the flag I set
//WMC - Or maybe it is.
// blow out his reverse thrusters. Or drag, same thing.
objp->phys_info.rotdamp = 10000.0f;
objp->phys_info.side_slip_time_const = 10000.0f;
objp->phys_info.max_vel.xyz.z = -25.0f;
vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, objp->phys_info.max_vel.xyz.z );
}
void cmeasure_select_next(ship *shipp)
{
Assert(shipp != NULL);
int i, new_index;
for (i = 1; i < Num_weapon_types; i++)
{
new_index = (shipp->current_cmeasure + i) % Num_weapon_types;
if(Weapon_info[new_index].wi_flags & WIF_CMEASURE)
{
shipp->current_cmeasure = new_index;
return;
}
}
//snd_play( &Snds[SND_CMEASURE_CYCLE] );
mprintf(("Countermeasure type set to %i in frame %i\n", shipp->current_cmeasure, Framecount));
}
// If this is a player countermeasure, let the player know he evaded a missile
void cmeasure_maybe_alert_success(object *objp)
{
//Is this a countermeasure, and does it have a parent
if ( objp->type != OBJ_WEAPON || objp->parent < 0) {
return;
}
Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_CMEASURE);
if ( objp->parent == OBJ_INDEX(Player_obj) ) {
hud_start_text_flash(XSTR("Evaded", 1430), 800);
snd_play(&Snds[SND_MISSILE_EVADED_POPUP]);
} else if ( Objects[objp->parent].flags & OF_PLAYER_SHIP ) {
send_countermeasure_success_packet( objp->parent );
}
}