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 #ifndef __WP_SABER_H
24 #define __WP_SABER_H
25 
26 #include "b_public.h"
27 
28 #define ARMOR_EFFECT_TIME	500
29 
30 #define JSF_AMBUSH		16	//ambusher Jedi
31 
32 //saberEventFlags
33 #define	SEF_HITENEMY	0x1		//Hit the enemy
34 #define	SEF_HITOBJECT	0x2		//Hit some other object
35 #define	SEF_HITWALL		0x4		//Hit a wall
36 #define	SEF_PARRIED		0x8		//Parried a saber swipe
37 #define	SEF_DEFLECTED	0x10	//Deflected a missile or saberInFlight
38 #define	SEF_BLOCKED		0x20	//Was blocked by a parry
39 #define	SEF_EVENTS		(SEF_HITENEMY|SEF_HITOBJECT|SEF_HITWALL|SEF_PARRIED|SEF_DEFLECTED|SEF_BLOCKED)
40 #define	SEF_LOCKED		0x40	//Sabers locked with someone else
41 #define	SEF_INWATER		0x80	//Saber is in water
42 #define	SEF_LOCK_WON	0x100	//Won a saberLock
43 //saberEntityState
44 #define SES_LEAVING		1
45 #define SES_HOVERING	2
46 #define SES_RETURNING	3
47 
48 #define SABER_EXTRAPOLATE_DIST 16.0f
49 
50 #define	SABER_MAX_DIST	400.0f
51 #define	SABER_MAX_DIST_SQUARED	(SABER_MAX_DIST*SABER_MAX_DIST)
52 
53 #define	FORCE_POWER_MAX	100
54 
55 #define	SABER_REFLECT_MISSILE_CONE	0.2f
56 
57 #define SABER_RADIUS_STANDARD	3.0f
58 
59 #define	SABER_LOCK_TIME			10000
60 #define	SABER_LOCK_DELAYED_TIME 9500
61 typedef enum
62 {
63 	LOCK_VICTORY = 0,//one side won
64 	LOCK_STALEMATE,//neither side won
65 	LOCK_DRAW//both people fall back
66 } saberLockResult_t;
67 
68 typedef enum
69 {
70 	LOCK_FIRST = 0,
71 	LOCK_TOP = LOCK_FIRST,
72 	LOCK_DIAG_TR,
73 	LOCK_DIAG_TL,
74 	LOCK_DIAG_BR,
75 	LOCK_DIAG_BL,
76 	LOCK_R,
77 	LOCK_L,
78 	LOCK_RANDOM,
79 	LOCK_KYLE_GRAB1,
80 	LOCK_KYLE_GRAB2,
81 	LOCK_KYLE_GRAB3,
82 	LOCK_FORCE_DRAIN
83 } sabersLockMode_t;
84 
85 enum
86 {
87 	SABERLOCK_TOP,
88 	SABERLOCK_SIDE,
89 	SABERLOCK_LOCK,
90 	SABERLOCK_BREAK,
91 	SABERLOCK_SUPERBREAK,
92 	SABERLOCK_WIN,
93 	SABERLOCK_LOSE
94 };
95 
96 enum
97 {
98 	DIR_RIGHT,
99 	DIR_LEFT,
100 	DIR_FRONT,
101 	DIR_BACK
102 };
103 
104 #define FORCE_LIGHTSIDE			1
105 #define FORCE_DARKSIDE			2
106 
107 #define	MAX_FORCE_HEAL_HARD		25
108 #define	MAX_FORCE_HEAL_MEDIUM	50
109 #define	MAX_FORCE_HEAL_EASY		75
110 #define	FORCE_HEAL_INTERVAL	200//FIXME: maybe level 1 is slower or level 2 is faster?
111 
112 #define	FORCE_GRIP_3_MIN_DIST	128.0f
113 #define	FORCE_GRIP_3_MAX_DIST	256.0f
114 #define	FORCE_GRIP_DIST			512.0f//FIXME: vary by power level?
115 #define	FORCE_GRIP_DIST_SQUARED	(FORCE_GRIP_DIST*FORCE_GRIP_DIST)
116 
117 #define	FORCE_DRAIN_DIST	64.0f//FIXME: vary by power level?
118 #define	FORCE_DRAIN_DIST_SQUARED	(FORCE_DRAIN_DIST*FORCE_DRAIN_DIST)
119 
120 #define MAX_DRAIN_DISTANCE 512
121 
122 #define MIN_SABERBLADE_DRAW_LENGTH 0.5f
123 
124 #define STAFF_KICK_RANGE 16
125 
126 #define	JUMP_OFF_WALL_SPEED	200.0f
127 
128 #define	FORCE_LONG_LEAP_SPEED	475.0f//300
129 
130 
131 //#define DUAL_SPIN_PROTECT_POWER	50	//power required to do the dual spin attack
132 //#define SINGLE_SPECIAL_POWER	20	//power required to do the single saber special attacks
133 
134 #define SABER_ALT_ATTACK_POWER		50//75?
135 #define SABER_ALT_ATTACK_POWER_LR	10//30?
136 #define SABER_ALT_ATTACK_POWER_FB	25//30/50?
137 
138 #define FORCE_LONGJUMP_POWER	20
139 
140 #define WALL_RUN_UP_BACKFLIP_SPEED	-150.0f//was -300.0f
141 #define	MAX_WALL_RUN_Z_NORMAL	0.4f//was 0.0f
142 
143 #define	PLAYER_KNOCKDOWN_HOLD_EXTRA_TIME	4000	//player stays down after a knockdown for 4 whole seconds before automatically doing one of the slow get-ups
144 
145 #define MAX_WALL_GRAB_SLOPE	0.2f
146 
147 //"Matrix" effect flags
148 #define MEF_NO_TIMESCALE		0x000001	//no timescale
149 #define MEF_NO_VERTBOB			0x000002	//no vert bob
150 #define MEF_NO_SPIN				0x000004	//no spin
151 #define MEF_NO_RANGEVAR			0x000008	//no camera range variation
152 #define MEF_HIT_GROUND_STOP		0x000010	//stop effect when subject hits the ground
153 #define MEF_REVERSE_SPIN		0x000020	//spin counter-clockwise instead of clockwise
154 #define MEF_MULTI_SPIN			0x000040	//spin once every second, until the effect stops
155 #define	MEF_LOOK_AT_ENEMY		0x000200
156 
157 #define SABER_PITCH_HACK 90
158 
159 extern float forceJumpStrength[];
160 extern float forceJumpHeight[];
161 extern float forceJumpHeightMax[];
162 
163 extern float forcePushPullRadius[];
164 
165 extern void ForceSpeed( gentity_t *self, int duration = 0 );
166 extern float forceSpeedValue[];
167 extern float forceSpeedRangeMod[];
168 extern float forceSpeedFOVMod[];
169 extern const char *saberColorStringForColor[];
170 #define FORCE_SPEED_DURATION 10000.0f
171 #define FORCE_RAGE_DURATION 10000.0f
172 
173 #define MASK_FORCE_PUSH (MASK_OPAQUE|CONTENTS_SOLID)
174 
175 enum
176 {
177 	FORCE_LEVEL_0,
178 	FORCE_LEVEL_1,
179 	FORCE_LEVEL_2,
180 	FORCE_LEVEL_3,
181 	NUM_FORCE_POWER_LEVELS
182 };
183 #define	FORCE_LEVEL_4 (FORCE_LEVEL_3+1)
184 #define	FORCE_LEVEL_5 (FORCE_LEVEL_4+1)
185 
186 enum
187 {
188 	FJ_FORWARD,
189 	FJ_BACKWARD,
190 	FJ_RIGHT,
191 	FJ_LEFT,
192 	FJ_UP
193 };
194 
195 #define FORCE_JUMP_CHARGE_TIME 1000.0f	//Force jump reaches maximum power in one second
196 
197 #define FORCE_POWERS_ROSH_FROM_TWINS ((1<<FP_SPEED)|(1<<FP_GRIP)|(1<<FP_RAGE)|(1<<FP_SABERTHROW))
198 
199 extern void WP_InitForcePowers( gentity_t *ent );
200 extern int WP_GetVelocityForForceJump( gentity_t *self, vec3_t jumpVel, usercmd_t *ucmd );
201 extern int WP_SaberInitBladeData( gentity_t *ent );
202 extern void G_CreateG2AttachedWeaponModel( gentity_t *ent, const char *weaponModel, int boltNum, int weaponNum );
203 extern void WP_SaberAddG2SaberModels( gentity_t *ent, int specificSaberNum = -1 );
204 extern qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber, qboolean setColors = qtrue );
205 extern qboolean WP_BreakSaber( gentity_t *ent, const char *surfName, saberType_t saberType = SABER_NONE );
206 extern void ForceThrow( gentity_t *self, qboolean pull, qboolean fake = qfalse );
207 extern qboolean G_GetHitLocFromSurfName( gentity_t *ent, const char *surfName, int *hitLoc, vec3_t point, vec3_t dir, vec3_t bladeDir, int mod, saberType_t saberType = SABER_NONE );
208 extern qboolean G_CheckEnemyPresence( gentity_t *ent, int dir, float radius, float tolerance = 0.75f );
209 extern void WP_SaberFreeStrings( saberInfo_t &saber );
210 extern qboolean G_EnoughPowerForSpecialMove( int forcePower, int cost, qboolean kataMove = qfalse );
211 extern void G_DrainPowerForSpecialMove( gentity_t *self, forcePowers_t fp, int cost, qboolean kataMove = qfalse );
212 extern int G_CostForSpecialMove( int cost, qboolean kataMove = qfalse );
213 extern gentity_t *G_DropSaberItem( const char *saberType, saber_colors_t saberColor, vec3_t saberPos, vec3_t saberVel, vec3_t saberAngles, gentity_t *copySaber = NULL );
214 
215 typedef enum
216 {
217 	EVASION_NONE = 0,
218 	EVASION_PARRY,
219 	EVASION_DUCK_PARRY,
220 	EVASION_JUMP_PARRY,
221 	EVASION_DODGE,
222 	EVASION_JUMP,
223 	EVASION_DUCK,
224 	EVASION_FJUMP,
225 	EVASION_CARTWHEEL,
226 	EVASION_OTHER,
227 	NUM_EVASION_TYPES
228 } evasionType_t;
229 
230 typedef enum
231 {
232 	SWING_FAST,
233 	SWING_MEDIUM,
234 	SWING_STRONG
235 } swingType_t;
236 // Okay, here lies the much-dreaded Pat-created FSM movement chart...  Heretic II strikes again!
237 // Why am I inflicting this on you?  Well, it's better than hardcoded states.
238 // Ideally this will be replaced with an external file or more sophisticated move-picker
239 // once the game gets out of prototype stage. <- HAHA!
240 
241 #ifdef LS_NONE
242 #undef LS_NONE
243 #endif
244 
245 typedef enum {
246 	// Invalid, or saber not armed
247 	LS_INVALID	= -1,
248 	LS_NONE		= 0,
249 
250 	// General movements with saber
251 	LS_READY,
252 	LS_DRAW,
253 	LS_PUTAWAY,
254 
255 	// Attacks
256 	LS_A_TL2BR,//4
257 	LS_A_L2R,
258 	LS_A_BL2TR,
259 	LS_A_BR2TL,
260 	LS_A_R2L,
261 	LS_A_TR2BL,
262 	LS_A_T2B,
263 	LS_A_BACKSTAB,
264 	LS_A_BACK,
265 	LS_A_BACK_CR,
266 	LS_ROLL_STAB,
267 	LS_A_LUNGE,
268 	LS_A_JUMP_T__B_,
269 	LS_A_FLIP_STAB,
270 	LS_A_FLIP_SLASH,
271 	LS_JUMPATTACK_DUAL,
272 	LS_JUMPATTACK_ARIAL_LEFT,
273 	LS_JUMPATTACK_ARIAL_RIGHT,
274 	LS_JUMPATTACK_CART_LEFT,
275 	LS_JUMPATTACK_CART_RIGHT,
276 	LS_JUMPATTACK_STAFF_LEFT,
277 	LS_JUMPATTACK_STAFF_RIGHT,
278 	LS_BUTTERFLY_LEFT,
279 	LS_BUTTERFLY_RIGHT,
280 	LS_A_BACKFLIP_ATK,
281 	LS_SPINATTACK_DUAL,
282 	LS_SPINATTACK,
283 	LS_LEAP_ATTACK,
284 	LS_SWOOP_ATTACK_RIGHT,
285 	LS_SWOOP_ATTACK_LEFT,
286 	LS_TAUNTAUN_ATTACK_RIGHT,
287 	LS_TAUNTAUN_ATTACK_LEFT,
288 	LS_KICK_F,
289 	LS_KICK_B,
290 	LS_KICK_R,
291 	LS_KICK_L,
292 	LS_KICK_S,
293 	LS_KICK_BF,
294 	LS_KICK_RL,
295 	LS_KICK_F_AIR,
296 	LS_KICK_B_AIR,
297 	LS_KICK_R_AIR,
298 	LS_KICK_L_AIR,
299 	LS_STABDOWN,
300 	LS_STABDOWN_STAFF,
301 	LS_STABDOWN_DUAL,
302 	LS_DUAL_SPIN_PROTECT,
303 	LS_STAFF_SOULCAL,
304 	LS_A1_SPECIAL,
305 	LS_A2_SPECIAL,
306 	LS_A3_SPECIAL,
307 	LS_UPSIDE_DOWN_ATTACK,
308 	LS_PULL_ATTACK_STAB,
309 	LS_PULL_ATTACK_SWING,
310 	LS_SPINATTACK_ALORA,
311 	LS_DUAL_FB,
312 	LS_DUAL_LR,
313 	LS_HILT_BASH,
314 
315 	//starts
316 	LS_S_TL2BR,//26
317 	LS_S_L2R,
318 	LS_S_BL2TR,//# Start of attack chaining to SLASH LR2UL
319 	LS_S_BR2TL,//# Start of attack chaining to SLASH LR2UL
320 	LS_S_R2L,
321 	LS_S_TR2BL,
322 	LS_S_T2B,
323 
324 	//returns
325 	LS_R_TL2BR,//33
326 	LS_R_L2R,
327 	LS_R_BL2TR,
328 	LS_R_BR2TL,
329 	LS_R_R2L,
330 	LS_R_TR2BL,
331 	LS_R_T2B,
332 
333 	//transitions
334 	LS_T1_BR__R,//40
335 	LS_T1_BR_TR,
336 	LS_T1_BR_T_,
337 	LS_T1_BR_TL,
338 	LS_T1_BR__L,
339 	LS_T1_BR_BL,
340 	LS_T1__R_BR,//46
341 	LS_T1__R_TR,
342 	LS_T1__R_T_,
343 	LS_T1__R_TL,
344 	LS_T1__R__L,
345 	LS_T1__R_BL,
346 	LS_T1_TR_BR,//52
347 	LS_T1_TR__R,
348 	LS_T1_TR_T_,
349 	LS_T1_TR_TL,
350 	LS_T1_TR__L,
351 	LS_T1_TR_BL,
352 	LS_T1_T__BR,//58
353 	LS_T1_T___R,
354 	LS_T1_T__TR,
355 	LS_T1_T__TL,
356 	LS_T1_T___L,
357 	LS_T1_T__BL,
358 	LS_T1_TL_BR,//64
359 	LS_T1_TL__R,
360 	LS_T1_TL_TR,
361 	LS_T1_TL_T_,
362 	LS_T1_TL__L,
363 	LS_T1_TL_BL,
364 	LS_T1__L_BR,//70
365 	LS_T1__L__R,
366 	LS_T1__L_TR,
367 	LS_T1__L_T_,
368 	LS_T1__L_TL,
369 	LS_T1__L_BL,
370 	LS_T1_BL_BR,//76
371 	LS_T1_BL__R,
372 	LS_T1_BL_TR,
373 	LS_T1_BL_T_,
374 	LS_T1_BL_TL,
375 	LS_T1_BL__L,
376 
377 	//Bounces
378 	LS_B1_BR,
379 	LS_B1__R,
380 	LS_B1_TR,
381 	LS_B1_T_,
382 	LS_B1_TL,
383 	LS_B1__L,
384 	LS_B1_BL,
385 
386 	//Deflected attacks
387 	LS_D1_BR,
388 	LS_D1__R,
389 	LS_D1_TR,
390 	LS_D1_T_,
391 	LS_D1_TL,
392 	LS_D1__L,
393 	LS_D1_BL,
394 	LS_D1_B_,
395 
396 	//Reflected attacks
397 	LS_V1_BR,
398 	LS_V1__R,
399 	LS_V1_TR,
400 	LS_V1_T_,
401 	LS_V1_TL,
402 	LS_V1__L,
403 	LS_V1_BL,
404 	LS_V1_B_,
405 
406 	// Broken parries
407 	LS_H1_T_,//
408 	LS_H1_TR,
409 	LS_H1_TL,
410 	LS_H1_BR,
411 	LS_H1_B_,
412 	LS_H1_BL,
413 
414 	// Knockaways
415 	LS_K1_T_,//
416 	LS_K1_TR,
417 	LS_K1_TL,
418 	LS_K1_BR,
419 	LS_K1_BL,
420 
421 	// Parries
422 	LS_PARRY_UP,//
423 	LS_PARRY_UR,
424 	LS_PARRY_UL,
425 	LS_PARRY_LR,
426 	LS_PARRY_LL,
427 
428 	// Projectile Reflections
429 	LS_REFLECT_UP,//
430 	LS_REFLECT_UR,
431 	LS_REFLECT_UL,
432 	LS_REFLECT_LR,
433 	LS_REFLECT_LL,
434 
435 	LS_MOVE_MAX//
436 } saberMoveName_t;
437 
438 void PM_SetSaberMove(saberMoveName_t newMove);
439 
440 typedef enum {
441 	Q_BR,
442 	Q_R,
443 	Q_TR,
444 	Q_T,
445 	Q_TL,
446 	Q_L,
447 	Q_BL,
448 	Q_B,
449 	Q_NUM_QUADS
450 } saberQuadrant_t;
451 
452 typedef struct
453 {
454 	const char *name;
455 	int animToUse;
456 	int	startQuad;
457 	int	endQuad;
458 	unsigned animSetFlags;
459 	int blendTime;
460 	int blocking;
461 	saberMoveName_t chain_idle;			// What move to call if the attack button is not pressed at the end of this anim
462 	saberMoveName_t chain_attack;		// What move to call if the attack button (and nothing else) is pressed
463 	int trailLength;
464 } saberMoveData_t;
465 
466 extern saberMoveData_t	saberMoveData[LS_MOVE_MAX];
467 
468 #endif	// __WP_SABER_H
469