FS2_Open
Open source remastering of the Freespace 2 engine
collideweaponweapon.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "freespace2/freespace.h"
13 #include "network/multi.h"
14 #include "object/objcollide.h"
15 #include "object/object.h"
16 #include "parse/scripting.h"
17 #include "ship/ship.h"
18 #include "stats/scoring.h"
19 #include "weapon/weapon.h"
20 
21 
28 {
29  float A_radius, B_radius;
30  object *A = pair->a;
31  object *B = pair->b;
32 
33  Assert( A->type == OBJ_WEAPON );
34  Assert( B->type == OBJ_WEAPON );
35 
36  // Don't allow ship to shoot down its own missile.
37  if (A->parent_sig == B->parent_sig)
38  return 1;
39 
40  // Only shoot down teammate's missile if not traveling in nearly same direction.
41  if (Weapons[A->instance].team == Weapons[B->instance].team)
42  if (vm_vec_dot(&A->orient.vec.fvec, &B->orient.vec.fvec) > 0.7f)
43  return 1;
44 
45  // Ignore collisions involving a bomb if the bomb is not yet armed.
46  weapon *wpA, *wpB;
47  weapon_info *wipA, *wipB;
48 
49  wpA = &Weapons[A->instance];
50  wpB = &Weapons[B->instance];
51  wipA = &Weapon_info[wpA->weapon_info_index];
52  wipB = &Weapon_info[wpB->weapon_info_index];
53 
54  A_radius = A->radius;
55  B_radius = B->radius;
56 
57  if (wipA->weapon_hitpoints > 0) {
58  if (!(wipA->wi_flags2 & WIF2_HARD_TARGET_BOMB)) {
59  A_radius *= 2; // Makes bombs easier to hit
60  }
61 
64  return 0;
65  }
67  return 0;
68  }
69 
70  if (wipB->weapon_hitpoints > 0) {
71  if (!(wipB->wi_flags2 & WIF2_HARD_TARGET_BOMB)) {
72  B_radius *= 2; // Makes bombs easier to hit
73  }
76  return 0;
77  }
79  return 0;
80  }
81 
82  // Rats, do collision detection.
83  if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius))
84  {
85  Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
87 
88  //Should be reversed
89  Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
91 
92  if(!a_override && !b_override)
93  {
94  float aDamage = wipA->damage;
95  if (wipB->armor_type_idx >= 0)
96  aDamage = Armor_types[wipB->armor_type_idx].GetDamage(aDamage, wipA->damage_type_idx, 1.0f);
97 
98  float bDamage = wipB->damage;
99  if (wipA->armor_type_idx >= 0)
100  bDamage = Armor_types[wipA->armor_type_idx].GetDamage(bDamage, wipB->damage_type_idx, 1.0f);
101 
102  if (wipA->weapon_hitpoints > 0) {
103  if (wipB->weapon_hitpoints > 0) { // Two bombs collide, detonate both.
104  if ((wipA->wi_flags & WIF_BOMB) && (wipB->wi_flags & WIF_BOMB)) {
105  Weapons[A->instance].lifeleft = 0.01f;
106  Weapons[B->instance].lifeleft = 0.01f;
109  } else {
110  A->hull_strength -= bDamage;
111  B->hull_strength -= aDamage;
112 
113  // safety to make sure either of the weapons die - allow 'bulkier' to keep going
114  if ((A->hull_strength > 0.0f) && (B->hull_strength > 0.0f)) {
115  if (wipA->weapon_hitpoints > wipB->weapon_hitpoints) {
116  B->hull_strength = -1.0f;
117  } else {
118  A->hull_strength = -1.0f;
119  }
120  }
121 
122  if (A->hull_strength < 0.0f) {
123  Weapons[A->instance].lifeleft = 0.01f;
125  }
126  if (B->hull_strength < 0.0f) {
127  Weapons[B->instance].lifeleft = 0.01f;
129  }
130  }
131  } else {
132  A->hull_strength -= bDamage;
133  Weapons[B->instance].lifeleft = 0.01f;
135  if (A->hull_strength < 0.0f) {
136  Weapons[A->instance].lifeleft = 0.01f;
138  }
139  }
140  } else if (wipB->weapon_hitpoints > 0) {
141  B->hull_strength -= aDamage;
142  Weapons[A->instance].lifeleft = 0.01f;
144  if (B->hull_strength < 0.0f) {
145  Weapons[B->instance].lifeleft = 0.01f;
147  }
148  }
149 
150  // single player and multiplayer masters evaluate the scoring and kill stuff
151  if (!MULTIPLAYER_CLIENT) {
152 
153  //Save damage for bomb so we can do scoring once it's destroyed. -Halleck
154  if (wipA->wi_flags & WIF_BOMB) {
156  //Update stats. -Halleck
157  scoring_eval_hit(A, B, 0);
158  }
159  if (wipB->wi_flags & WIF_BOMB) {
161  //Update stats. -Halleck
162  scoring_eval_hit(B, A, 0);
163  }
164  }
165  }
166 
167  if(!(b_override && !a_override))
168  {
169  Script_system.SetHookObjects(4, "Weapon", A, "WeaponB", B, "Self",A, "Object", B);
171  }
172  if((b_override && !a_override) || (!b_override && !a_override))
173  {
174  //Should be reversed
175  Script_system.SetHookObjects(4, "Weapon", B, "WeaponB", A, "Self",B, "Object", A);
177  }
178 
179  Script_system.RemHookVars(4, "Weapon", "WeaponB", "Self", "Object");
180  return 1;
181  }
182 
183  return 0;
184 }
185 
#define MULTIPLAYER_CLIENT
Definition: multi.h:132
weapon Weapons[MAX_WEAPONS]
Definition: weapons.cpp:78
SCP_vector< ArmorType > Armor_types
Definition: ship.cpp:170
int collide_weapon_weapon(obj_pair *pair)
object * homing_object
Definition: weapon.h:177
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
#define WIF_LOCKED_HOMING
Definition: weapon.h:130
Definition: weapon.h:163
#define AIPF2_ASPECT_INVULNERABILITY_FIX
Definition: ai_profiles.h:69
Assert(pm!=NULL)
object obj_used_list
Definition: object.cpp:53
matrix * B
Definition: lua.cpp:445
float lifeleft
Definition: weapon.h:169
vec3d pos
Definition: object.h:152
script_state Script_system("FS2_Open Scripting")
int weapon_info_index
Definition: weapon.h:164
float lifetime
Definition: weapon.h:382
int instance
Definition: object.h:150
int weapon_hitpoints
Definition: weapon.h:530
object * a
Definition: objcollide.h:55
vec3d last_pos
Definition: object.h:155
int weapon_flags
Definition: weapon.h:176
struct matrix::@228::@230 vec
int armor_type_idx
Definition: weapon.h:522
int team
Definition: weapon.h:167
ai_profile_t * ai_profile
Definition: missionparse.h:168
int damage_type_idx
Definition: weapon.h:519
#define OBJ_WEAPON
Definition: object.h:33
float delay_bomb_arm_timer[NUM_SKILL_LEVELS]
Definition: ai_profiles.h:144
float hull_strength
Definition: object.h:160
void scoring_add_damage_to_weapon(object *weapon_obj, object *other_obj, float damage)
Definition: scoring.cpp:1351
int wi_flags
Definition: weapon.h:384
#define CHA_COLLIDEWEAPON
Definition: scripting.h:48
matrix orient
Definition: object.h:153
int wi_flags2
Definition: weapon.h:385
#define WIF_BOMB
Definition: weapon.h:63
int RunCondition(int condition, char format='\0', void *data=NULL, class object *objp=NULL, int more_data=0)
Definition: scripting.cpp:924
void SetHookObjects(int num,...)
Definition: scripting.cpp:556
int collide_subdivide(vec3d *p0, vec3d *p1, float prad, vec3d *q0, vec3d *q1, float qrad)
Definition: objcollide.cpp:628
void RemHookVars(unsigned int num,...)
Definition: scripting.cpp:754
object * b
Definition: objcollide.h:56
#define WIF2_HARD_TARGET_BOMB
Definition: weapon.h:100
int Game_skill_level
Definition: fredstubs.cpp:170
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:312
matrix * A
Definition: lua.cpp:444
void scoring_eval_hit(object *hit_obj, object *other_obj, int from_blast)
Definition: scoring.cpp:1188
float radius
Definition: object.h:154
mission The_mission
#define WF_DESTROYED_BY_WEAPON
Definition: weapon.h:143
char type
Definition: object.h:146
float damage
Definition: weapon.h:363
bool IsConditionOverride(int action, object *objp=NULL)
Definition: scripting.cpp:938
int parent_sig
Definition: object.h:148
float max_lifetime
Definition: weapon.h:381