Iskhodnyy_kod_Doom
.pdfI_Error ("P_SpawnMapThing: Unknown type %i at (%i, %i)",
mthing->type,
mthing->x, mthing->y);
//don’t spawn keycards and players in deathmatch if (deathmatch && mobjinfo[i].flags & MF_NOTDMATCH)
return;
//don’t spawn any monsters if -nomonsters
if (nomonsters
&&( i == MT_SKULL
||(mobjinfo[i].flags & MF_COUNTKILL)) )
{
return;
}
// spawn it
x = mthing->x << FRACBITS; y = mthing->y << FRACBITS;
if (mobjinfo[i].flags & MF_SPAWNCEILING) z = ONCEILINGZ;
else
z = ONFLOORZ;
mobj = P_SpawnMobj (x,y,z, i); mobj->spawnpoint = *mthing;
if (mobj->tics > 0)
mobj->tics = 1 + (P_Random () % mobj->tics); if (mobj->flags & MF_COUNTKILL)
totalkills++;
if (mobj->flags & MF_COUNTITEM) totalitems++;
mobj->angle = ANG45 * (mthing->angle/45); if (mthing->options & MTF_AMBUSH)
mobj->flags |= MF_AMBUSH;
}
//
// GAME SPAWN FUNCTIONS
//
//
// P_SpawnPuff
//
extern fixed_t attackrange;
void P_SpawnPuff
(fixed_t x, fixed_t y,
fixed_t  | 
	z )  | 
{
mobj_t* th;
z += ((P_Random()-P_Random())<<10);
th = P_SpawnMobj (x,y,z, MT_PUFF); th->momz = FRACUNIT;
th->tics -= P_Random()&3;
491
if (th->tics < 1) th->tics = 1;
// don’t make punches spark on the wall if (attackrange == MELEERANGE)
P_SetMobjState (th, S_PUFF3);
}
//
// P_SpawnBlood
//
void P_SpawnBlood
(fixed_t x, fixed_t y,
fixed_t  | 
	z,  | 
int  | 
	damage )  | 
{
mobj_t* th;
z += ((P_Random()-P_Random())<<10); th = P_SpawnMobj (x,y,z, MT_BLOOD); th->momz = FRACUNIT*2;
th->tics -= P_Random()&3;
if (th->tics < 1) th->tics = 1;
if (damage <= 12 && damage >= 9) P_SetMobjState (th,S_BLOOD2);
else if (damage < 9) P_SetMobjState (th,S_BLOOD3);
}
//
//P_CheckMissileSpawn
//Moves the missile forward a bit
//and possibly explodes it right there.
void P_CheckMissileSpawn (mobj_t* th)
{
th->tics -= P_Random()&3; if (th->tics < 1)
th->tics = 1;
//move a little forward so an angle can
//be computed if it immediately explodes th->x += (th->momx>>1);
th->y += (th->momy>>1); th->z += (th->momz>>1);
if (!P_TryMove (th, th->x, th->y)) P_ExplodeMissile (th);
}
//
// P_SpawnMissile
//
mobj_t*
492
P_SpawnMissile  | 
	
  | 
( mobj_t*  | 
	source,  | 
mobj_t*  | 
	dest,  | 
mobjtype_t  | 
	type )  | 
{  | 
	
  | 
mobj_t*  | 
	th;  | 
angle_t  | 
	an;  | 
int  | 
	dist;  | 
th = P_SpawnMobj (source->x, source->y,
source->z + 4*8*FRACUNIT, type);
if (th->info->seesound)
S_StartSound (th, th->info->seesound);
th->target = source; // where it came from
an = R_PointToAngle2 (source->x, source->y, dest->x, dest->y);
// fuzzy player
if (dest->flags & MF_SHADOW)
an += (P_Random()-P_Random())<<20;
th->angle = an;
an >>= ANGLETOFINESHIFT;
th->momx = FixedMul (th->info->speed, finecosine[an]); th->momy = FixedMul (th->info->speed, finesine[an]);
dist = P_AproxDistance (dest->x - source->x, dest->y - source->y); dist = dist / th->info->speed;
if (dist < 1) dist = 1;
th->momz = (dest->z - source->z) / dist; P_CheckMissileSpawn (th);
return th;
}
//
//P_SpawnPlayerMissile
//Tries to aim at a nearby monster
void P_SpawnPlayerMissile
( mobj_t* source,
mobjtype_t type )
{
mobj_t*  | 
	th;  | 
angle_t  | 
	an;  | 
fixed_t  | 
	x;  | 
fixed_t  | 
	y;  | 
fixed_t  | 
	z;  | 
fixed_t  | 
	slope;  | 
// see which target is to be aimed at an = source->angle;
slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
if (!linetarget)
{
an += 1<<26;
493
slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
if (!linetarget)
{
an -= 2<<26;
slope = P_AimLineAttack (source, an, 16*64*FRACUNIT);
}
if (!linetarget)
{
an = source->angle; slope = 0;
}
}
x = source->x; y = source->y;
z = source->z + 4*8*FRACUNIT;
th = P_SpawnMobj (x,y,z, type);
if (th->info->seesound)
S_StartSound (th, th->info->seesound);
th->target = source; th->angle = an;
th->momx = FixedMul( th->info->speed, finecosine[an>>ANGLETOFINESHIFT]);
th->momy = FixedMul( th->info->speed, finesine[an>>ANGLETOFINESHIFT]);
th->momz = FixedMul( th->info->speed, slope);
P_CheckMissileSpawn (th);
}
9.14p mobj.h
// 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.
//
//DESCRIPTION:
//Map Objects, MObj, definition and handling.
//-----------------------------------------------------------------------------
#ifndef __P_MOBJ__ #define __P_MOBJ__
// Basics.
494
#include "tables.h"
#include "m_fixed.h"
//We need the thinker_t stuff. #include "d_think.h"
//We need the WAD data structure for Map things,
//from the THINGS lump.
#include "doomdata.h"
//States are tied to finite states are
//tied to animation frames.
//Needs precompiled tables/data structures. #include "info.h"
#ifdef __GNUG__ #pragma interface #endif
//
//NOTES: mobj_t
//mobj_ts are used to tell the refresh where to draw an image,
//tell the world simulation when objects are contacted,
//and tell the sound driver how to position a sound.
//
//The refresh uses the next and prev links to follow
//lists of things in sectors as they are being drawn.
//The sprite, frame, and angle elements determine which patch_t
//is used to draw the sprite if it is visible.
//The sprite and frame values are allmost allways set
//from state_t structures.
//The statescr.exe utility generates the states.h and states.c
//files that contain the sprite/frame numbers from the
//statescr.txt source file.
//The xyz origin point represents a point at the bottom middle
//of the sprite (between the feet of a biped).
//This is the default origin position for patch_ts grabbed
//with lumpy.exe.
//A walking creature will have its z equal to the floor
//it is standing on.
//
//The sound code uses the x,y, and subsector fields
//to do stereo positioning of any sound effited by the mobj_t.
//The play simulation uses the blocklinks, x,y,z, radius, height
//to determine when mobj_ts are touching each other,
//touching lines in the map, or hit by trace lines (gunshots,
//lines of sight, etc).
//The mobj_t->flags element has various bit flags
//used by the simulation.
//
//Every mobj_t is linked into a single sector
//based on its origin coordinates.
//The subsector_t is found with R_PointInSubsector(x,y),
//and the sector_t can be found with subsector->sector.
//The sector links are only used by the rendering code,
//the play simulation does not care about them at all.
//Any mobj_t that needs to be acted upon by something else
//in the play world (block movement, be shot, etc) will also
495
//need to be linked into the blockmap.
//If the thing has the MF_NOBLOCK flag set, it will not use
//the block links. It can still interact with other things,
//but only as the instigator (missiles will run into other
//things, but nothing can run into a missile).
//Each block in the grid is 128*128 units, and knows about
//every line_t that it contains a piece of, and every
//interactable mobj_t that has its origin contained.
//
//A valid mobj_t is a mobj_t that has the proper subsector_t
//filled in for its xy coordinates and is linked into the
//sector from which the subsector was made, or has the
//MF_NOSECTOR flag set (the subsector_t needs to be valid
//even if MF_NOSECTOR is set), and is linked into a blockmap
//block or has the MF_NOBLOCKMAP flag set.
//Links should only be modified by the P_[Un]SetThingPosition()
//functions.
//Do not change the MF_NO? flags while a thing is valid.
//
// Any questions?
//
//
// Misc. mobj flags
//
typedef enum
{
// Call P_SpecialThing when touched.
MF_SPECIAL  | 
	= 1,  | 
|
//  | 
	Blocks.  | 
	
  | 
MF_SOLID  | 
	= 2,  | 
|
//  | 
	Can be hit.  | 
	
  | 
MF_SHOOTABLE  | 
	= 4,  | 
|
// Don’t use the sector links (invisible but touchable).
MF_NOSECTOR  | 
	= 8,  | 
// Don’t use the blocklinks  | 
	(inert but displayable)  | 
|
MF_NOBLOCKMAP  | 
	= 16,  | 
	
  | 
// Not to be activated by sound, deaf monster.  | 
||
MF_AMBUSH  | 
	= 32,  | 
|
// Will try to attack right  | 
	back.  | 
|
MF_JUSTHIT  | 
	=  | 
	64,  | 
// Will take at least one step before attacking.  | 
||
MF_JUSTATTACKED  | 
	= 128,  | 
|
//On level spawning (initial position),
//hang from ceiling instead of stand on floor.
MF_SPAWNCEILING  | 
	= 256,  | 
//Don’t apply gravity (every tic),
//that is, object will float, keeping current height
//or changing it actively.
MF_NOGRAVITY  | 
	= 512,  | 
//Movement flags.
//This allows jumps from high places.
MF_DROPOFF  | 
	
  | 
	= 0x400,  | 
// For players, will pick  | 
	up items.  | 
|
MF_PICKUP  | 
	=  | 
	0x800,  | 
// Player cheat. ???  | 
	
  | 
	
  | 
MF_NOCLIP  | 
	=  | 
	0x1000,  | 
// Player: keep info about  | 
	sliding along walls.  | 
|
MF_SLIDE  | 
	=  | 
	0x2000,  | 
//Allow moves to any height, no gravity.
//For active floaters, e.g. cacodemons, pain elementals.
MF_FLOAT  | 
	= 0x4000,  | 
// Don’t cross lines
496
//??? or look at heights on teleport.
MF_TELEPORT  | 
	= 0x8000,  | 
//Don’t hit same species, explode on block.
//Player missiles as well as fireballs of various kinds.
MF_MISSILE  | 
	= 0x10000,  | 
//Dropped by a demon, not level spawned.
//E.g. ammo clips dropped by dying former humans.
MF_DROPPED  | 
	= 0x20000,  | 
//Use fuzzy draw (shadow demons or spectres),
//temporary player invisibility powerup.
MF_SHADOW  | 
	= 0x40000,  | 
//Flag: don’t bleed when shot (use puff),
//barrels and shootable furniture shall not bleed.
MF_NOBLOOD  | 
	= 0x80000,  | 
//Don’t stop moving halfway off a step,
//that is, have dead bodies slide down all the way.
MF_CORPSE  | 
	= 0x100000,  | 
//Floating to a height for a move, ???
//don’t auto float to target’s height.
MF_INFLOAT  | 
	= 0x200000,  | 
//On kill, count this enemy object
//towards intermission kill total.
//Happy gathering.
MF_COUNTKILL  | 
	= 0x400000,  | 
//On picking up, count this item object
//towards intermission item total.
MF_COUNTITEM  | 
	= 0x800000,  | 
//Special handling: skull in flight.
//Neither a cacodemon nor a missile.
MF_SKULLFLY  | 
	= 0x1000000,  | 
//Don’t spawn this object
//in death match mode (e.g. key cards).
MF_NOTDMATCH  | 
	= 0x2000000,  | 
//Player sprites in multiplayer modes are modified
//using an internal color lookup table for re-indexing.
//If 0x4 0x8 or 0xc,
//use a translation table for player colormaps
MF_TRANSLATION  | 
	=  | 
	0xc000000,  | 
// Hmm ???.  | 
	
  | 
	
  | 
MF_TRANSSHIFT  | 
	= 26  | 
	
  | 
} mobjflag_t;
// Map Object definition. typedef struct mobj_s
{
// List: thinker links.
thinker_t  | 
	thinker;  | 
|
// Info  | 
	for drawing: position.  | 
|
fixed_t  | 
	
  | 
	x;  | 
fixed_t  | 
	
  | 
	y;  | 
fixed_t  | 
	
  | 
	z;  | 
// More  | 
	list: links in sector (if needed)  | 
|
struct mobj_s*  | 
	snext;  | 
|
struct mobj_s*  | 
	sprev;  | 
|
//More drawing info: to determine current sprite.
497
angle_t  | 
	angle;  | 
	// orientation  | 
|
spritenum_t  | 
	sprite;  | 
	// used  | 
	to find patch_t and flip value  | 
int  | 
	frame;  | 
	// might  | 
	be ORed with FF_FULLBRIGHT  | 
//Interaction info, by BLOCKMAP.
//Links in blocks (if needed).
struct mobj_s*  | 
	bnext;  | 
	
  | 
struct mobj_s*  | 
	bprev;  | 
	
  | 
struct subsector_s*  | 
	subsector;  | 
	
  | 
// The closest interval over all contacted Sectors.  | 
||
fixed_t  | 
	floorz;  | 
	
  | 
fixed_t  | 
	ceilingz;  | 
	
  | 
// For movement checking.  | 
	
  | 
|
fixed_t  | 
	radius;  | 
	
  | 
fixed_t  | 
	height;  | 
	
  | 
// Momentums, used to update position.  | 
	
  | 
|
fixed_t  | 
	momx;  | 
	
  | 
fixed_t  | 
	momy;  | 
	
  | 
fixed_t  | 
	momz;  | 
	
  | 
// If == validcount, already checked.  | 
	
  | 
|
int  | 
	validcount;  | 
	
  | 
mobjtype_t  | 
	type;  | 
	
  | 
mobjinfo_t*  | 
	info;  | 
	// &mobjinfo[mobj->type]  | 
int  | 
	tics;  | 
	// state tic counter  | 
state_t*  | 
	state;  | 
	
  | 
int  | 
	flags;  | 
	
  | 
int  | 
	health;  | 
	
  | 
// Movement direction, movement generation (zig-zagging).  | 
||
int  | 
	movedir;  | 
	// 0-7  | 
int  | 
	movecount;  | 
	// when 0, select a new dir  | 
//Thing being chased/attacked (or NULL),
//also the originator for missiles.
struct mobj_s*  | 
	target;  | 
//Reaction time: if non 0, don’t attack yet.
//Used by player to freeze a bit after teleporting.
int  | 
	reactiontime;  | 
//If >0, the target will be chased
//no matter what (even if shot)
int  | 
	threshold;  | 
//Additional info record for player avatars only.
//Only valid if type == MT_PLAYER
struct  | 
	player_s*  | 
	player;  | 
// Player number  | 
	last looked for.  | 
|
int  | 
	
  | 
	lastlook;  | 
// For  | 
	nightmare  | 
	respawn.  | 
mapthing_t  | 
	spawnpoint;  | 
|
// Thing being chased/attacked for tracers.  | 
||
struct  | 
	mobj_s*  | 
	tracer;  | 
} mobj_t;
498
#endif
//-----------------------------------------------------------------------------
//
// $Log:$
//
//-----------------------------------------------------------------------------
9.15 p plats.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:
//Plats (i.e. elevator platforms) code, raising/lowering.
//-----------------------------------------------------------------------------
static const char
rcsid[] = "$Id: p_plats.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
#include  | 
	"i_system.h"  | 
#include  | 
	"z_zone.h"  | 
#include  | 
	"m_random.h"  | 
#include  | 
	"doomdef.h"  | 
#include  | 
	"p_local.h"  | 
#include  | 
	"s_sound.h"  | 
// State.  | 
	
  | 
#include  | 
	"doomstat.h"  | 
#include  | 
	"r_state.h"  | 
// Data.  | 
	
  | 
#include  | 
	"sounds.h"  | 
plat_t*  | 
	activeplats[MAXPLATS];  | 
//
// Move a plat up and down
//
void T_PlatRaise(plat_t* plat)
499
{
result_e res;
switch(plat->status)
{
case up:
res = T_MovePlane(plat->sector,
plat->speed, plat->high, plat->crush,0,1);
if (plat->type == raiseAndChange
|| plat->type == raiseToNearestAndChange)
{
if (!(leveltime&7))
S_StartSound((mobj_t *)&plat->sector->soundorg,
sfx_stnmov);
}
if (res == crushed && (!plat->crush))
{
plat->count = plat->wait; plat->status = down;
S_StartSound((mobj_t *)&plat->sector->soundorg,
sfx_pstart);
}
else
{
if (res == pastdest)
{
plat->count = plat->wait; plat->status = waiting;
S_StartSound((mobj_t *)&plat->sector->soundorg,
sfx_pstop);
switch(plat->type)
{
case blazeDWUS:
case downWaitUpStay: P_RemoveActivePlat(plat); break;
case raiseAndChange:
case raiseToNearestAndChange: P_RemoveActivePlat(plat); break;
default:
break;
}
}
}
break;
case down:
res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
if (res == pastdest)
{
plat->count = plat->wait; plat->status = waiting;
S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
}
break;
500
