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_local.h"
24 #include "b_local.h"
25 #include "g_functions.h"
26 #include "wp_saber.h"
27 #include "w_local.h"
28 
29 //-----------------------
30 //	Det Pack
31 //-----------------------
32 
33 //---------------------------------------------------------
charge_stick(gentity_t * self,gentity_t * other,trace_t * trace)34 void charge_stick( gentity_t *self, gentity_t *other, trace_t *trace )
35 //---------------------------------------------------------
36 {
37 	self->s.eType = ET_GENERAL;
38 
39 	// make us so we can take damage
40 	self->clipmask = MASK_SHOT;
41 	self->contents = CONTENTS_SHOTCLIP;
42 	self->takedamage = qtrue;
43 	self->health = 25;
44 
45 	self->e_DieFunc = dieF_WP_ExplosiveDie;
46 
47 	VectorSet( self->maxs, 10, 10, 10 );
48 	VectorScale( self->maxs, -1, self->mins );
49 
50 	self->activator = self->owner;
51 	self->owner = NULL;
52 
53 	self->e_TouchFunc = touchF_NULL;
54 	self->e_ThinkFunc = thinkF_NULL;
55 	self->nextthink = -1;
56 
57 	WP_Stick( self, trace, 1.0f );
58 }
59 
60 //---------------------------------------------------------
WP_DropDetPack(gentity_t * self,vec3_t start,vec3_t dir)61 static void WP_DropDetPack( gentity_t *self, vec3_t start, vec3_t dir )
62 //---------------------------------------------------------
63 {
64 	// Chucking a new one
65 	AngleVectors( self->client->ps.viewangles, forwardVec, vrightVec, up );
66 	CalcMuzzlePoint( self, forwardVec, vrightVec, up, muzzle, 0 );
67 	VectorNormalize( forwardVec );
68 	VectorMA( muzzle, -4, forwardVec, muzzle );
69 
70 	VectorCopy( muzzle, start );
71 	WP_TraceSetStart( self, start, vec3_origin, vec3_origin );//make sure our start point isn't on the other side of a wall
72 
73 	gentity_t	*missile = CreateMissile( start, forwardVec, 300, 10000, self, qfalse );
74 
75 	missile->fxID = G_EffectIndex( "detpack/explosion" ); // if we set an explosion effect, explode death can use that instead
76 
77 	missile->classname = "detpack";
78 	missile->s.weapon = WP_DET_PACK;
79 
80 	missile->s.pos.trType = TR_GRAVITY;
81 
82 	missile->s.eFlags |= EF_MISSILE_STICK;
83 	missile->e_TouchFunc = touchF_charge_stick;
84 
85 	missile->damage = weaponData[WP_DET_PACK].damage;
86 	missile->methodOfDeath = MOD_DETPACK;
87 
88 	missile->splashDamage = weaponData[WP_DET_PACK].splashDamage;
89 	missile->splashRadius = weaponData[WP_DET_PACK].splashRadius;
90 	missile->splashMethodOfDeath = MOD_DETPACK;// ?SPLASH;
91 
92 	missile->clipmask = (CONTENTS_SOLID|CONTENTS_BODY|CONTENTS_SHOTCLIP);//MASK_SHOT;
93 
94 	// we don't want it to ever bounce
95 	missile->bounceCount = 0;
96 
97 	missile->s.radius = 30;
98 	VectorSet( missile->s.modelScale, 1.0f, 1.0f, 1.0f );
99 	gi.G2API_InitGhoul2Model( missile->ghoul2, weaponData[WP_DET_PACK].missileMdl, G_ModelIndex( weaponData[WP_DET_PACK].missileMdl ),
100 		NULL_HANDLE, NULL_HANDLE, 0, 0);
101 
102 	AddSoundEvent( NULL, missile->currentOrigin, 128, AEL_MINOR, qtrue );
103 	AddSightEvent( NULL, missile->currentOrigin, 128, AEL_SUSPICIOUS, 10 );
104 }
105 
106 //---------------------------------------------------------
WP_FireDetPack(gentity_t * ent,qboolean alt_fire)107 void WP_FireDetPack( gentity_t *ent, qboolean alt_fire )
108 //---------------------------------------------------------
109 {
110 	if ( !ent || !ent->client )
111 	{
112 		return;
113 	}
114 
115 	if ( alt_fire  )
116 	{
117 		if ( ent->client->ps.eFlags & EF_PLANTED_CHARGE )
118 		{
119 			gentity_t *found = NULL;
120 
121 			// loop through all ents and blow the crap out of them!
122 			while (( found = G_Find( found, FOFS( classname ), "detpack" )) != NULL )
123 			{
124 				if ( found->activator == ent )
125 				{
126 					VectorCopy( found->currentOrigin, found->s.origin );
127 					found->e_ThinkFunc = thinkF_WP_Explode;
128 					found->nextthink = level.time + 100 + Q_flrand(0.0f, 1.0f) * 100;
129 					G_Sound( found, G_SoundIndex( "sound/weapons/detpack/warning.wav" ));
130 
131 					// would be nice if this actually worked?
132 					AddSoundEvent( NULL, found->currentOrigin, found->splashRadius*2, AEL_DANGER, qfalse, qtrue );//FIXME: are we on ground or not?
133 					AddSightEvent( NULL, found->currentOrigin, found->splashRadius*2, AEL_DISCOVERED, 100 );
134 				}
135 			}
136 
137 			ent->client->ps.eFlags &= ~EF_PLANTED_CHARGE;
138 		}
139 	}
140 	else
141 	{
142 		WP_DropDetPack( ent, muzzle, forwardVec );
143 
144 		ent->client->ps.eFlags |= EF_PLANTED_CHARGE;
145 	}
146 }