Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Iskhodnyy_kod_Doom

.pdf
Скачиваний:
7
Добавлен:
13.02.2015
Размер:
1.01 Mб
Скачать

case

waiting:

if (!--plat->count)

{

 

 

if (plat->sector->floorheight == plat->low)

 

plat->status = up;

 

else

 

plat->status = down;

 

S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);

}

 

case

in_stasis:

break;

}

}

//

//Do Platforms

//"amount" is only used for SOME platforms.

int EV_DoPlat

( line_t* line,

plattype_e

type,

int

amount )

{

 

plat_t*

plat;

int

secnum;

int

rtn;

sector_t*

sec;

secnum = -1;

 

rtn = 0;

 

// Activate all <type> plats that are in_stasis switch(type)

{

case perpetualRaise: P_ActivateInStasis(line->tag); break;

default:

break;

}

while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)

{

sec = &sectors[secnum];

if (sec->specialdata) continue;

// Find lowest & highest floors around sector rtn = 1;

plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0); P_AddThinker(&plat->thinker);

plat->type = type; plat->sector = sec;

plat->sector->specialdata = plat; plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise; plat->crush = false;

plat->tag = line->tag;

501

switch(type)

{

case raiseToNearestAndChange: plat->speed = PLATSPEED/2;

sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec,sec->floorheight); plat->wait = 0;

plat->status = up;

// NO MORE DAMAGE, IF APPLICABLE sec->special = 0;

S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break;

case raiseAndChange: plat->speed = PLATSPEED/2;

sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount*FRACUNIT; plat->wait = 0;

plat->status = up;

S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break;

case downWaitUpStay: plat->speed = PLATSPEED * 4;

plat->low = P_FindLowestFloorSurrounding(sec);

if (plat->low > sec->floorheight) plat->low = sec->floorheight;

plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down;

S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break;

case blazeDWUS:

plat->speed = PLATSPEED * 8;

plat->low = P_FindLowestFloorSurrounding(sec);

if (plat->low > sec->floorheight) plat->low = sec->floorheight;

plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down;

S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break;

case perpetualRaise: plat->speed = PLATSPEED;

plat->low = P_FindLowestFloorSurrounding(sec);

if (plat->low > sec->floorheight) plat->low = sec->floorheight;

plat->high = P_FindHighestFloorSurrounding(sec);

if (plat->high < sec->floorheight) plat->high = sec->floorheight;

plat->wait = 35*PLATWAIT; plat->status = P_Random()&1;

502

S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break;

}

P_AddActivePlat(plat);

}

return rtn;

}

void P_ActivateInStasis(int tag)

{

int

i;

for (i = 0;i < MAXPLATS;i++) if (activeplats[i]

&&(activeplats[i])->tag == tag

&&(activeplats[i])->status == in_stasis)

{

(activeplats[i])->status = (activeplats[i])->oldstatus; (activeplats[i])->thinker.function.acp1

= (actionf_p1) T_PlatRaise;

}

}

void EV_StopPlat(line_t* line)

{

int

j;

for (j = 0;j < MAXPLATS;j++) if (activeplats[j]

&&((activeplats[j])->status != in_stasis)

&&((activeplats[j])->tag == line->tag))

{

(activeplats[j])->oldstatus = (activeplats[j])->status; (activeplats[j])->status = in_stasis; (activeplats[j])->thinker.function.acv = (actionf_v)NULL;

}

}

void P_AddActivePlat(plat_t* plat)

{

int i;

for (i = 0;i < MAXPLATS;i++)

if (activeplats[i] == NULL)

{

activeplats[i] = plat; return;

}

I_Error ("P_AddActivePlat: no more plats!");

}

void P_RemoveActivePlat(plat_t* plat)

{

int i;

for (i = 0;i < MAXPLATS;i++)

if (plat == activeplats[i])

{

(activeplats[i])->sector->specialdata = NULL; P_RemoveThinker(&(activeplats[i])->thinker); activeplats[i] = NULL;

return;

}

503

I_Error ("P_RemoveActivePlat: can’t find plat!");

}

9.16 p pspr.c

// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------

//

//$Id:$

//Copyright (C) 1993-1996 by 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.

//

//$Log:$

//DESCRIPTION:

//Weapon sprite animation, weapon objects.

//Action functions for weapons.

//

//-----------------------------------------------------------------------------

static const char

rcsid[] = "$Id: p_pspr.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";

#include "doomdef.h" #include "d_event.h"

#include

"m_random.h"

#include

"p_local.h"

#include

"s_sound.h"

// State.

 

#include

"doomstat.h"

// Data.

 

#include

"sounds.h"

#include

"p_pspr.h"

#define LOWERSPEED

FRACUNIT*6

#define RAISESPEED

FRACUNIT*6

#define WEAPONBOTTOM

128*FRACUNIT

#define WEAPONTOP

32*FRACUNIT

// plasma cells for a bfg attack

#define BFGCELLS

40

//

// P_SetPsprite

//

void P_SetPsprite

504

( player_t*

player,

int

position,

statenum_t

stnum )

{

 

pspdef_t*

psp;

state_t*

state;

psp = &player->psprites[position];

do

{

if (!stnum)

{

// object removed itself psp->state = NULL; break;

}

 

state = &states[stnum];

 

psp->state = state;

 

psp->tics = state->tics;

// could be 0

if (state->misc1)

{

// coordinate set

psp->sx = state->misc1 << FRACBITS; psp->sy = state->misc2 << FRACBITS;

}

//Call action routine.

//Modified handling. if (state->action.acp2)

{

state->action.acp2(player, psp); if (!psp->state)

break;

}

stnum = psp->state->nextstate;

} while (!psp->tics);

// an initial state of 0 could cycle through

}

 

 

//

 

 

// P_CalcSwing

 

 

//

 

 

fixed_t

swingx;

 

fixed_t

swingy;

 

void P_CalcSwing (player_t*

player)

{

 

 

fixed_t

swing;

 

int

angle;

 

//OPTIMIZE: tablify this.

//A LUT would allow for different modes,

//and add flexibility.

swing = player->bob;

angle = (FINEANGLES/70*leveltime)&FINEMASK; swingx = FixedMul ( swing, finesine[angle]);

505

angle = (FINEANGLES/70*leveltime+FINEANGLES/2)&FINEMASK; swingy = -FixedMul ( swingx, finesine[angle]);

}

//

//P_BringUpWeapon

//Starts bringing the pending weapon up

//from the bottom of the screen.

//Uses player

//

void P_BringUpWeapon (player_t* player)

{

statenum_t newstate;

if (player->pendingweapon == wp_nochange) player->pendingweapon = player->readyweapon;

if (player->pendingweapon == wp_chainsaw) S_StartSound (player->mo, sfx_sawup);

newstate = weaponinfo[player->pendingweapon].upstate;

player->pendingweapon = wp_nochange; player->psprites[ps_weapon].sy = WEAPONBOTTOM;

P_SetPsprite (player, ps_weapon, newstate);

}

//

//P_CheckAmmo

//Returns true if there is enough ammo to shoot.

//If not, selects the next weapon to use.

//

boolean P_CheckAmmo (player_t* player)

{

ammotype_t

ammo;

int

count;

ammo = weaponinfo[player->readyweapon].ammo;

// Minimal amount for one shot varies. if (player->readyweapon == wp_bfg)

count = BFGCELLS;

else

if (player->readyweapon == wp_supershotgun)

 

count =

2;

// Double barrel.

else

 

 

 

 

count =

1;

// Regular.

//Some do not need ammunition anyway.

//Return if current ammunition sufficient.

if (ammo == am_noammo || player->ammo[ammo] >= count) return true;

//Out of ammo, pick a weapon to change to.

//Preferences are set here.

do

{

if (player->weaponowned[wp_plasma]

&&player->ammo[am_cell]

&&(gamemode != shareware) )

{

player->pendingweapon = wp_plasma;

506

}

else if (player->weaponowned[wp_supershotgun]

&&player->ammo[am_shell]>2

&&(gamemode == commercial) )

{

player->pendingweapon = wp_supershotgun;

}

else if (player->weaponowned[wp_chaingun] && player->ammo[am_clip])

{

player->pendingweapon = wp_chaingun;

}

else if (player->weaponowned[wp_shotgun] && player->ammo[am_shell])

{

player->pendingweapon = wp_shotgun;

}

else if (player->ammo[am_clip])

{

player->pendingweapon = wp_pistol;

}

else if (player->weaponowned[wp_chainsaw])

{

player->pendingweapon = wp_chainsaw;

}

else if (player->weaponowned[wp_missile] && player->ammo[am_misl])

{

player->pendingweapon = wp_missile;

}

else if (player->weaponowned[wp_bfg]

&&player->ammo[am_cell]>40

&&(gamemode != shareware) )

{

player->pendingweapon = wp_bfg;

}

else

{

// If everything fails. player->pendingweapon = wp_fist;

}

} while (player->pendingweapon == wp_nochange);

// Now set appropriate weapon overlay. P_SetPsprite (player,

ps_weapon, weaponinfo[player->readyweapon].downstate);

return false;

}

//

// P_FireWeapon.

//

void P_FireWeapon (player_t* player)

{

statenum_t newstate;

if (!P_CheckAmmo (player)) return;

P_SetMobjState (player->mo, S_PLAY_ATK1);

newstate = weaponinfo[player->readyweapon].atkstate;

507

P_SetPsprite (player, ps_weapon, newstate);

P_NoiseAlert (player->mo, player->mo);

}

//

//P_DropWeapon

//Player died, so put the weapon away.

void P_DropWeapon (player_t* player)

{

P_SetPsprite (player,

ps_weapon,

weaponinfo[player->readyweapon].downstate);

}

//

//A_WeaponReady

//The player can fire the weapon

//or change to another weapon at this time.

//Follows after getting weapon up,

//or after previous attack/fire sequence.

void A_WeaponReady

( player_t* player,

pspdef_t*

psp )

{

 

statenum_t

newstate;

int

angle;

// get out of attack state

if (player->mo->state == &states[S_PLAY_ATK1]

|| player->mo->state == &states[S_PLAY_ATK2] )

{

P_SetMobjState (player->mo, S_PLAY);

}

if (player->readyweapon == wp_chainsaw && psp->state == &states[S_SAW])

{

S_StartSound (player->mo, sfx_sawidl);

}

//check for change

//if player is dead, put the weapon away

if (player->pendingweapon != wp_nochange || !player->health)

{

//change weapon

//(pending weapon should allready be validated) newstate = weaponinfo[player->readyweapon].downstate; P_SetPsprite (player, ps_weapon, newstate);

return;

}

//check for fire

//the missile launcher and bfg do not auto fire if (player->cmd.buttons & BT_ATTACK)

{

if ( !player->attackdown

||(player->readyweapon != wp_missile

&&player->readyweapon != wp_bfg) )

508

{

player->attackdown = true; P_FireWeapon (player); return;

}

}

else

player->attackdown = false;

// bob the weapon based on movement speed angle = (128*leveltime)&FINEMASK;

psp->sx = FRACUNIT + FixedMul (player->bob, finecosine[angle]); angle &= FINEANGLES/2-1;

psp->sy = WEAPONTOP + FixedMul (player->bob, finesine[angle]);

}

//

//A_ReFire

//The player can re-fire the weapon

//without lowering it entirely.

//

 

void A_ReFire

 

( player_t*

player,

pspdef_t*

psp )

{

 

//check for fire

//(if a weaponchange is pending, let it go through instead) if ( (player->cmd.buttons & BT_ATTACK)

&&player->pendingweapon == wp_nochange

&&player->health)

{

player->refire++; P_FireWeapon (player);

}

else

{

player->refire = 0; P_CheckAmmo (player);

}

}

 

void

 

A_CheckReload

 

( player_t*

player,

pspdef_t*

psp )

{

 

P_CheckAmmo (player); #if 0

if (player->ammo[am_shell]<2)

P_SetPsprite (player, ps_weapon, S_DSNR1);

#endif

}

//

//A_Lower

//Lowers current weapon,

//and changes weapon at bottom.

void

509

A_Lower

 

( player_t*

player,

pspdef_t*

psp )

{

 

psp->sy += LOWERSPEED;

// Is already down.

if (psp->sy < WEAPONBOTTOM ) return;

// Player is dead.

if (player->playerstate == PST_DEAD)

{

psp->sy = WEAPONBOTTOM;

// don’t bring weapon back up return;

}

//The old weapon has been lowered off the screen,

//so change the weapon and start raising it

if (!player->health)

{

// Player is dead, so keep the weapon off screen. P_SetPsprite (player, ps_weapon, S_NULL); return;

}

player->readyweapon = player->pendingweapon;

P_BringUpWeapon (player);

}

//

 

// A_Raise

 

//

 

void

 

A_Raise

 

( player_t*

player,

pspdef_t*

psp )

{

 

statenum_t

newstate;

psp->sy -= RAISESPEED;

if (psp->sy > WEAPONTOP ) return;

psp->sy = WEAPONTOP;

//The weapon has been raised all the way,

//so change to the ready state.

newstate = weaponinfo[player->readyweapon].readystate;

P_SetPsprite (player, ps_weapon, newstate);

}

//

// A_GunFlash

//

void A_GunFlash

510

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]