Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 serge 1
// Emacs style mode select   -*- C++ -*-
2
//-----------------------------------------------------------------------------
3
//
4
// $Id:$
5
//
6
// Copyright (C) 1993-1996 by id Software, Inc.
7
//
8
// This source is available for distribution and/or modification
9
// only under the terms of the DOOM Source Code License as
10
// published by id Software. All rights reserved.
11
//
12
// The source is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15
// for more details.
16
//
17
// $Log:$
18
//
19
// DESCRIPTION:
20
//	Player related stuff.
21
//	Bobbing POV/weapon, movement.
22
//	Pending weapon.
23
//
24
//-----------------------------------------------------------------------------
25
 
26
 
27
static const char
28
rcsid[] = "$Id: p_user.c,v 1.3 1997/01/28 22:08:29 b1 Exp $";
29
 
30
 
31
#include "doomdef.h"
32
#include "d_event.h"
33
 
34
#include "p_local.h"
35
 
36
#include "doomstat.h"
37
 
38
 
39
 
40
// Index of the special effects (INVUL inverse) map.
41
#define INVERSECOLORMAP		32
42
 
43
 
44
//
45
// Movement.
46
//
47
 
48
// 16 pixels of bob
49
#define MAXBOB	0x100000
50
 
51
boolean		onground;
52
 
53
 
54
//
55
// P_Thrust
56
// Moves the given origin along a given angle.
57
//
58
void
59
P_Thrust
60
( player_t*	player,
61
  angle_t	angle,
62
  fixed_t	move )
63
{
64
    angle >>= ANGLETOFINESHIFT;
65
 
66
    player->mo->momx += FixedMul(move,finecosine[angle]);
67
    player->mo->momy += FixedMul(move,finesine[angle]);
68
}
69
 
70
 
71
 
72
 
73
//
74
// P_CalcHeight
75
// Calculate the walking / running height adjustment
76
//
77
void P_CalcHeight (player_t* player)
78
{
79
    int		angle;
80
    fixed_t	bob;
81
 
82
    // Regular movement bobbing
83
    // (needs to be calculated for gun swing
84
    // even if not on ground)
85
    // OPTIMIZE: tablify angle
86
    // Note: a LUT allows for effects
87
    //  like a ramp with low health.
88
    player->bob =
89
	FixedMul (player->mo->momx, player->mo->momx)
90
	+ FixedMul (player->mo->momy,player->mo->momy);
91
 
92
    player->bob >>= 2;
93
 
94
    if (player->bob>MAXBOB)
95
	player->bob = MAXBOB;
96
 
97
    if ((player->cheats & CF_NOMOMENTUM) || !onground)
98
    {
99
	player->viewz = player->mo->z + VIEWHEIGHT;
100
 
101
	if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
102
	    player->viewz = player->mo->ceilingz-4*FRACUNIT;
103
 
104
	player->viewz = player->mo->z + player->viewheight;
105
	return;
106
    }
107
 
108
    angle = (FINEANGLES/20*leveltime)&FINEMASK;
109
    bob = FixedMul ( player->bob/2, finesine[angle]);
110
 
111
 
112
    // move viewheight
113
    if (player->playerstate == PST_LIVE)
114
    {
115
	player->viewheight += player->deltaviewheight;
116
 
117
	if (player->viewheight > VIEWHEIGHT)
118
	{
119
	    player->viewheight = VIEWHEIGHT;
120
	    player->deltaviewheight = 0;
121
	}
122
 
123
	if (player->viewheight < VIEWHEIGHT/2)
124
	{
125
	    player->viewheight = VIEWHEIGHT/2;
126
	    if (player->deltaviewheight <= 0)
127
		player->deltaviewheight = 1;
128
	}
129
 
130
	if (player->deltaviewheight)
131
	{
132
	    player->deltaviewheight += FRACUNIT/4;
133
	    if (!player->deltaviewheight)
134
		player->deltaviewheight = 1;
135
	}
136
    }
137
    player->viewz = player->mo->z + player->viewheight + bob;
138
 
139
    if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
140
	player->viewz = player->mo->ceilingz-4*FRACUNIT;
141
}
142
 
143
 
144
 
145
//
146
// P_MovePlayer
147
//
148
void P_MovePlayer (player_t* player)
149
{
150
    ticcmd_t*		cmd;
151
 
152
    cmd = &player->cmd;
153
 
154
    player->mo->angle += (cmd->angleturn<<16);
155
 
156
    // Do not let the player control movement
157
    //  if not onground.
158
    onground = (player->mo->z <= player->mo->floorz);
159
 
160
    if (cmd->forwardmove && onground)
161
	P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
162
 
163
    if (cmd->sidemove && onground)
164
	P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);
165
 
166
    if ( (cmd->forwardmove || cmd->sidemove)
167
	 && player->mo->state == &states[S_PLAY] )
168
    {
169
	P_SetMobjState (player->mo, S_PLAY_RUN1);
170
    }
171
}
172
 
173
 
174
 
175
//
176
// P_DeathThink
177
// Fall on your face when dying.
178
// Decrease POV height to floor height.
179
//
180
#define ANG5   	(ANG90/18)
181
 
182
void P_DeathThink (player_t* player)
183
{
184
    angle_t		angle;
185
    angle_t		delta;
186
 
187
    P_MovePsprites (player);
188
 
189
    // fall to the ground
190
    if (player->viewheight > 6*FRACUNIT)
191
	player->viewheight -= FRACUNIT;
192
 
193
    if (player->viewheight < 6*FRACUNIT)
194
	player->viewheight = 6*FRACUNIT;
195
 
196
    player->deltaviewheight = 0;
197
    onground = (player->mo->z <= player->mo->floorz);
198
    P_CalcHeight (player);
199
 
200
    if (player->attacker && player->attacker != player->mo)
201
    {
202
	angle = R_PointToAngle2 (player->mo->x,
203
				 player->mo->y,
204
				 player->attacker->x,
205
				 player->attacker->y);
206
 
207
	delta = angle - player->mo->angle;
208
 
209
	if (delta < ANG5 || delta > (unsigned)-ANG5)
210
	{
211
	    // Looking at killer,
212
	    //  so fade damage flash down.
213
	    player->mo->angle = angle;
214
 
215
	    if (player->damagecount)
216
		player->damagecount--;
217
	}
218
	else if (delta < ANG180)
219
	    player->mo->angle += ANG5;
220
	else
221
	    player->mo->angle -= ANG5;
222
    }
223
    else if (player->damagecount)
224
	player->damagecount--;
225
 
226
 
227
    if (player->cmd.buttons & BT_USE)
228
	player->playerstate = PST_REBORN;
229
}
230
 
231
 
232
 
233
//
234
// P_PlayerThink
235
//
236
void P_PlayerThink (player_t* player)
237
{
238
    ticcmd_t*		cmd;
239
    weapontype_t	newweapon;
240
 
241
    // fixme: do this in the cheat code
242
    if (player->cheats & CF_NOCLIP)
243
	player->mo->flags |= MF_NOCLIP;
244
    else
245
	player->mo->flags &= ~MF_NOCLIP;
246
 
247
    // chain saw run forward
248
    cmd = &player->cmd;
249
    if (player->mo->flags & MF_JUSTATTACKED)
250
    {
251
	cmd->angleturn = 0;
252
	cmd->forwardmove = 0xc800/512;
253
	cmd->sidemove = 0;
254
	player->mo->flags &= ~MF_JUSTATTACKED;
255
    }
256
 
257
 
258
    if (player->playerstate == PST_DEAD)
259
    {
260
	P_DeathThink (player);
261
	return;
262
    }
263
 
264
    // Move around.
265
    // Reactiontime is used to prevent movement
266
    //  for a bit after a teleport.
267
    if (player->mo->reactiontime)
268
	player->mo->reactiontime--;
269
    else
270
	P_MovePlayer (player);
271
 
272
    P_CalcHeight (player);
273
 
274
    if (player->mo->subsector->sector->special)
275
	P_PlayerInSpecialSector (player);
276
 
277
    // Check for weapon change.
278
 
279
    // A special event has no other buttons.
280
    if (cmd->buttons & BT_SPECIAL)
281
	cmd->buttons = 0;
282
 
283
    if (cmd->buttons & BT_CHANGE)
284
    {
285
	// The actual changing of the weapon is done
286
	//  when the weapon psprite can do it
287
	//  (read: not in the middle of an attack).
288
	newweapon = (cmd->buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT;
289
 
290
	if (newweapon == wp_fist
291
	    && player->weaponowned[wp_chainsaw]
292
	    && !(player->readyweapon == wp_chainsaw
293
		 && player->powers[pw_strength]))
294
	{
295
	    newweapon = wp_chainsaw;
296
	}
297
 
298
	if ( (gamemode == commercial)
299
	    && newweapon == wp_shotgun
300
	    && player->weaponowned[wp_supershotgun]
301
	    && player->readyweapon != wp_supershotgun)
302
	{
303
	    newweapon = wp_supershotgun;
304
	}
305
 
306
 
307
	if (player->weaponowned[newweapon]
308
	    && newweapon != player->readyweapon)
309
	{
310
	    // Do not go to plasma or BFG in shareware,
311
	    //  even if cheated.
312
	    if ((newweapon != wp_plasma
313
		 && newweapon != wp_bfg)
314
		|| (gamemode != shareware) )
315
	    {
316
		player->pendingweapon = newweapon;
317
	    }
318
	}
319
    }
320
 
321
    // check for use
322
    if (cmd->buttons & BT_USE)
323
    {
324
	if (!player->usedown)
325
	{
326
	    P_UseLines (player);
327
	    player->usedown = true;
328
	}
329
    }
330
    else
331
	player->usedown = false;
332
 
333
    // cycle psprites
334
    P_MovePsprites (player);
335
 
336
    // Counters, time dependend power ups.
337
 
338
    // Strength counts up to diminish fade.
339
    if (player->powers[pw_strength])
340
	player->powers[pw_strength]++;
341
 
342
    if (player->powers[pw_invulnerability])
343
	player->powers[pw_invulnerability]--;
344
 
345
    if (player->powers[pw_invisibility])
346
	if (! --player->powers[pw_invisibility] )
347
	    player->mo->flags &= ~MF_SHADOW;
348
 
349
    if (player->powers[pw_infrared])
350
	player->powers[pw_infrared]--;
351
 
352
    if (player->powers[pw_ironfeet])
353
	player->powers[pw_ironfeet]--;
354
 
355
    if (player->damagecount)
356
	player->damagecount--;
357
 
358
    if (player->bonuscount)
359
	player->bonuscount--;
360
 
361
 
362
    // Handling colormaps.
363
    if (player->powers[pw_invulnerability])
364
    {
365
	if (player->powers[pw_invulnerability] > 4*32
366
	    || (player->powers[pw_invulnerability]&8) )
367
	    player->fixedcolormap = INVERSECOLORMAP;
368
	else
369
	    player->fixedcolormap = 0;
370
    }
371
    else if (player->powers[pw_infrared])
372
    {
373
	if (player->powers[pw_infrared] > 4*32
374
	    || (player->powers[pw_infrared]&8) )
375
	{
376
	    // almost full bright
377
	    player->fixedcolormap = 1;
378
	}
379
	else
380
	    player->fixedcolormap = 0;
381
    }
382
    else
383
	player->fixedcolormap = 0;
384
}
385
 
386