1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 #include "g_headers.h"
24 
25 #include "b_local.h"
26 #include "g_local.h"
27 #include "wp_saber.h"
28 #include "w_local.h"
29 #include "g_functions.h"
30 
31 //---------------
32 //	Blaster
33 //---------------
34 
35 //---------------------------------------------------------
WP_FireBlasterMissile(gentity_t * ent,vec3_t start,vec3_t dir,qboolean altFire)36 static void WP_FireBlasterMissile( gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire )
37 //---------------------------------------------------------
38 {
39 	int velocity	= BLASTER_VELOCITY;
40 	int	damage		= !altFire ? weaponData[WP_BLASTER].damage : weaponData[WP_BLASTER].altDamage;
41 
42 	// If an enemy is shooting at us, lower the velocity so you have a chance to evade
43 	if ( ent->client && ent->client->ps.clientNum != 0 )
44 	{
45 		if ( g_spskill->integer < 2 )
46 		{
47 			velocity *= BLASTER_NPC_VEL_CUT;
48 		}
49 		else
50 		{
51 			velocity *= BLASTER_NPC_HARD_VEL_CUT;
52 		}
53 	}
54 
55 	WP_TraceSetStart( ent, start, vec3_origin, vec3_origin );//make sure our start point isn't on the other side of a wall
56 
57 	gentity_t *missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );
58 
59 	missile->classname = "blaster_proj";
60 	missile->s.weapon = WP_BLASTER;
61 
62 	// Do the damages
63 	if ( ent->s.number != 0 )
64 	{
65 		if ( g_spskill->integer == 0 )
66 		{
67 			damage = BLASTER_NPC_DAMAGE_EASY;
68 		}
69 		else if ( g_spskill->integer == 1 )
70 		{
71 			damage = BLASTER_NPC_DAMAGE_NORMAL;
72 		}
73 		else
74 		{
75 			damage = BLASTER_NPC_DAMAGE_HARD;
76 		}
77 	}
78 
79 //	if ( ent->client )
80 //	{
81 //		if ( ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > 0 && ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > cg.time )
82 //		{
83 //			// in overcharge mode, so doing double damage
84 //			missile->flags |= FL_OVERCHARGED;
85 //			damage *= 2;
86 //		}
87 //	}
88 
89 	missile->damage = damage;
90 	missile->dflags = DAMAGE_DEATH_KNOCKBACK;
91 	if ( altFire )
92 	{
93 		missile->methodOfDeath = MOD_BLASTER_ALT;
94 	}
95 	else
96 	{
97 		missile->methodOfDeath = MOD_BLASTER;
98 	}
99 	missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
100 
101 	// we don't want it to bounce forever
102 	missile->bounceCount = 8;
103 }
104 
105 //---------------------------------------------------------
WP_FireBlaster(gentity_t * ent,qboolean alt_fire)106 void WP_FireBlaster( gentity_t *ent, qboolean alt_fire )
107 //---------------------------------------------------------
108 {
109 	vec3_t	dir, angs;
110 
111 	vectoangles( wpFwd, angs );
112 
113 	if ( alt_fire )
114 	{
115 		// add some slop to the alt-fire direction
116 		angs[PITCH] += Q_flrand(-1.0f, 1.0f) * BLASTER_ALT_SPREAD;
117 		angs[YAW]	+= Q_flrand(-1.0f, 1.0f) * BLASTER_ALT_SPREAD;
118 	}
119 	else
120 	{
121 		// Troopers use their aim values as well as the gun's inherent inaccuracy
122 		// so check for all classes of stormtroopers and anyone else that has aim error
123 		if ( ent->client && ent->NPC &&
124 			( ent->client->NPC_class == CLASS_STORMTROOPER ||
125 			ent->client->NPC_class == CLASS_SWAMPTROOPER ) )
126 		{
127 			angs[PITCH] += ( Q_flrand(-1.0f, 1.0f) * (BLASTER_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f
128 			angs[YAW]	+= ( Q_flrand(-1.0f, 1.0f) * (BLASTER_NPC_SPREAD+(6-ent->NPC->currentAim)*0.25f));//was 0.5f
129 		}
130 		else
131 		{
132 			// add some slop to the main-fire direction
133 			angs[PITCH] += Q_flrand(-1.0f, 1.0f) * BLASTER_MAIN_SPREAD;
134 			angs[YAW]	+= Q_flrand(-1.0f, 1.0f) * BLASTER_MAIN_SPREAD;
135 		}
136 	}
137 
138 	AngleVectors( angs, dir, NULL, NULL );
139 
140 	// FIXME: if temp_org does not have clear trace to inside the bbox, don't shoot!
141 	WP_FireBlasterMissile( ent, wpMuzzle, dir, alt_fire );
142 }