summaryrefslogtreecommitdiffstats
path: root/src/jake2/game/GameWeapon.java
blob: 5431584fc101948b285a173f30f9f6bbba249fb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

// Created on 12.11.2003 by RST.
// $Id: GameWeapon.java,v 1.2 2004-07-08 15:58:44 hzi Exp $

package jake2.game;

import jake2.Defines;
import jake2.Globals;
import jake2.util.*;

public class GameWeapon extends GameAI {

	/*
	===============
	PlayerNoise
	
	Each player can have two noise objects associated with it:
	a personal noise (jumping, pain, weapon firing), and a weapon
	target noise (bullet wall impacts)
	
	Monsters that don't directly see the player can move
	to a noise in hopes of seeing the player from there.
	===============
	*/
	static void PlayerNoise(edict_t who, float[] where, int type) {
		edict_t noise;

		if (type == PNOISE_WEAPON) {
			if (who.client.silencer_shots == 0) {
				who.client.silencer_shots--;
				return;
			}
		}

		if (deathmatch.value != 0)
			return;

		if ((who.flags & FL_NOTARGET) != 0)
			return;

		if (who.mynoise == null) {
			noise= G_Spawn();
			noise.classname= "player_noise";
			Math3D.VectorSet(noise.mins, -8, -8, -8);
			Math3D.VectorSet(noise.maxs, 8, 8, 8);
			noise.owner= who;
			noise.svflags= SVF_NOCLIENT;
			who.mynoise= noise;

			noise= G_Spawn();
			noise.classname= "player_noise";
			Math3D.VectorSet(noise.mins, -8, -8, -8);
			Math3D.VectorSet(noise.maxs, 8, 8, 8);
			noise.owner= who;
			noise.svflags= SVF_NOCLIENT;
			who.mynoise2= noise;
		}

		if (type == PNOISE_SELF || type == PNOISE_WEAPON) {
			noise= who.mynoise;
			level.sound_entity= noise;
			level.sound_entity_framenum= level.framenum;
		} else // type == PNOISE_IMPACT
			{
			noise= who.mynoise2;
			level.sound2_entity= noise;
			level.sound2_entity_framenum= level.framenum;
		}

		Math3D.VectorCopy(where, noise.s.origin);
		Math3D.VectorSubtract(where, noise.maxs, noise.absmin);
		Math3D.VectorAdd(where, noise.maxs, noise.absmax);
		noise.teleport_time= level.time;
		gi.linkentity(noise);
	}

	/*
	=================
	check_dodge
	
	This is a support routine used when a client is firing
	a non-instant attack weapon.  It checks to see if a
	monster's dodge function should be called.
	=================
	*/
	static void check_dodge(edict_t self, float[] start, float[] dir, int speed) {
		float[] end= { 0, 0, 0 };
		float[] v= { 0, 0, 0 };
		trace_t tr;
		float eta;

		// easy mode only ducks one quarter the time
		if (skill.value == 0) {
			if (Lib.random() > 0.25)
				return;
		}
		Math3D.VectorMA(start, 8192, dir, end);
		tr= gi.trace(start, null, null, end, self, MASK_SHOT);
		if ((tr.ent != null)
			&& (tr.ent.svflags & SVF_MONSTER) != 0
			&& (tr.ent.health > 0)
			&& (null != tr.ent.monsterinfo.dodge)
			&& infront(tr.ent, self)) {
			Math3D.VectorSubtract(tr.endpos, start, v);
			eta= (Math3D.VectorLength(v) - tr.ent.maxs[0]) / speed;
			tr.ent.monsterinfo.dodge.dodge(tr.ent, self, eta);
		}
	}

}