DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

p_setup.cpp (17038B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "Precompiled.h"
     30 #include "globaldata.h"
     31 
     32 
     33 #include <math.h>
     34 
     35 #include "z_zone.h"
     36 
     37 #include "m_swap.h"
     38 #include "m_bbox.h"
     39 
     40 #include "g_game.h"
     41 
     42 #include "i_system.h"
     43 #include "w_wad.h"
     44 
     45 #include "doomdef.h"
     46 #include "p_local.h"
     47 
     48 #include "s_sound.h"
     49 
     50 #include "doomstat.h"
     51 
     52 
     53 void	P_SpawnMapThing (mapthing_t*	mthing);
     54 
     55 
     56 //
     57 // MAP related Lookup tables.
     58 // Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
     59 //
     60 
     61 
     62 
     63 
     64 
     65 
     66 
     67 
     68 // BLOCKMAP
     69 // Created from axis aligned bounding box
     70 // of the map, a rectangular array of
     71 // blocks of size ...
     72 // Used to speed up collision detection
     73 // by spatial subdivision in 2D.
     74 //
     75 // Blockmap size.
     76 // offsets in ::g->blockmap are from here
     77 // origin of block map
     78 // for thing chains
     79 
     80 
     81 // REJECT
     82 // For fast sight rejection.
     83 // Speeds up enemy AI by skipping detailed
     84 //  LineOf Sight calculation.
     85 // Without special effect, this could be
     86 //  used as a PVS lookup as well.
     87 //
     88 
     89 
     90 // Maintain single and multi player starting spots.
     91 
     92 
     93 
     94 
     95 
     96 
     97 //
     98 // P_LoadVertexes
     99 //
    100 void P_LoadVertexes (int lump)
    101 {
    102 	byte*		data;
    103 	int			i;
    104 	mapvertex_t*	ml;
    105 	vertex_t*		li;
    106 
    107 	// Determine number of lumps:
    108 	//  total lump length / vertex record length.
    109 	::g->numvertexes = W_LumpLength (lump) / sizeof(mapvertex_t);
    110 
    111 	// Allocate zone memory for buffer.
    112 //	::g->vertexes = (vertex_t*)Z_Malloc (::g->numvertexes*sizeof(vertex_t),PU_LEVEL,0);	
    113 	if (MallocForLump( lump, ::g->numvertexes*sizeof(vertex_t ), ::g->vertexes, PU_LEVEL_SHARED ))
    114 	{
    115 		// Load data into cache.
    116 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    117 
    118 		ml = (mapvertex_t *)data;
    119 		li = ::g->vertexes;
    120 
    121 		// Copy and convert vertex coordinates,
    122 		// internal representation as fixed.
    123 		for (i=0 ; i < ::g->numvertexes ; i++, li++, ml++)
    124 		{
    125 			li->x = SHORT(ml->x)<<FRACBITS;
    126 			li->y = SHORT(ml->y)<<FRACBITS;
    127 		}
    128 
    129 		// Free buffer memory.
    130 		Z_Free(data);
    131 	}
    132 }
    133 
    134 
    135 
    136 //
    137 // P_LoadSegs
    138 //
    139 void P_LoadSegs (int lump)
    140 {
    141 	byte*		data;
    142 	int			i;
    143 	mapseg_t*		ml;
    144 	seg_t*		li;
    145 	line_t*		ldef;
    146 	int			psetup_linedef;
    147 	int			side;
    148 
    149 	::g->numsegs = W_LumpLength (lump) / sizeof(mapseg_t);
    150 //	::g->segs = (seg_t*)Z_Malloc (::g->numsegs*sizeof(seg_t),PU_LEVEL,0);	
    151 
    152 	if (MallocForLump( lump, ::g->numsegs*sizeof(seg_t), ::g->segs, PU_LEVEL_SHARED ))
    153 	{
    154 		memset (::g->segs, 0, ::g->numsegs*sizeof(seg_t));
    155 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    156 
    157 		ml = (mapseg_t *)data;
    158 		li = ::g->segs;
    159 		for (i=0 ; i < ::g->numsegs ; i++, li++, ml++)
    160 		{
    161 			li->v1 = &::g->vertexes[SHORT(ml->v1)];
    162 			li->v2 = &::g->vertexes[SHORT(ml->v2)];
    163 
    164 			li->angle = (SHORT(ml->angle))<<16;
    165 			li->offset = (SHORT(ml->offset))<<16;
    166 			psetup_linedef = SHORT(ml->linedef);
    167 			ldef = &::g->lines[psetup_linedef];
    168 			li->linedef = ldef;
    169 			side = SHORT(ml->side);
    170 			li->sidedef = &::g->sides[ldef->sidenum[side]];
    171 			li->frontsector = ::g->sides[ldef->sidenum[side]].sector;
    172 			if (ldef-> flags & ML_TWOSIDED)
    173 				li->backsector = ::g->sides[ldef->sidenum[side^1]].sector;
    174 			else
    175 				li->backsector = 0;
    176 		}
    177 
    178 		Z_Free(data);
    179 	}
    180 }
    181 
    182 
    183 //
    184 // P_LoadSubsectors
    185 //
    186 void P_LoadSubsectors (int lump)
    187 {
    188 	byte*		data;
    189 	int			i;
    190 	mapsubsector_t*	ms;
    191 	subsector_t*	ss;
    192 
    193 	::g->numsubsectors = W_LumpLength (lump) / sizeof(mapsubsector_t);
    194 
    195 	if (MallocForLump( lump, ::g->numsubsectors*sizeof(subsector_t), ::g->subsectors, PU_LEVEL_SHARED ))
    196 	{
    197 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    198 
    199 		ms = (mapsubsector_t *)data;
    200 		memset (::g->subsectors,0, ::g->numsubsectors*sizeof(subsector_t));
    201 		ss = ::g->subsectors;
    202 
    203 		for (i=0 ; i < ::g->numsubsectors ; i++, ss++, ms++)
    204 		{
    205 			ss->numlines = SHORT(ms->numsegs);
    206 			ss->firstline = SHORT(ms->firstseg);
    207 		}
    208 
    209 		Z_Free(data);
    210 	}
    211 }
    212 
    213 
    214 
    215 //
    216 // P_LoadSectors
    217 //
    218 void P_LoadSectors (int lump)
    219 {
    220 	byte*		data;
    221 	int			i;
    222 	mapsector_t*	ms;
    223 	sector_t*		ss;
    224 
    225 	::g->numsectors = W_LumpLength (lump) / sizeof(mapsector_t);
    226 	
    227 	::g->sectors = (sector_t*)Z_Malloc( ::g->numsectors*sizeof(sector_t), PU_LEVEL, NULL );
    228 	memset (::g->sectors, 0, ::g->numsectors*sizeof(sector_t));
    229 	data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    230 
    231 	ms = (mapsector_t *)data;
    232 	ss = ::g->sectors;
    233 	for (i=0 ; i < ::g->numsectors ; i++, ss++, ms++)
    234 	{
    235 		ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
    236 		ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
    237 		ss->floorpic = R_FlatNumForName(ms->floorpic);
    238 		ss->ceilingpic = R_FlatNumForName(ms->ceilingpic);
    239 		ss->lightlevel = SHORT(ms->lightlevel);
    240 		ss->special = SHORT(ms->special);
    241 		ss->tag = SHORT(ms->tag);
    242 		ss->thinglist = NULL;
    243 	}
    244 
    245 	Z_Free(data);
    246 
    247 /*
    248 	if (MallocForLump( lump, ::g->numsectors*sizeof(sector_t), (void**)&::g->sectors, PU_LEVEL_SHARED ))
    249 	{
    250 		memset (::g->sectors, 0, ::g->numsectors*sizeof(sector_t));
    251 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    252 
    253 		ms = (mapsector_t *)data;
    254 		ss = ::g->sectors;
    255 		for (i=0 ; i < ::g->numsectors ; i++, ss++, ms++)
    256 		{
    257 			ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
    258 			ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
    259 			ss->floorpic = R_FlatNumForName(ms->floorpic);
    260 			ss->ceilingpic = R_FlatNumForName(ms->ceilingpic);
    261 			ss->lightlevel = SHORT(ms->lightlevel);
    262 			ss->special = SHORT(ms->special);
    263 			ss->tag = SHORT(ms->tag);
    264 			ss->thinglist = NULL;
    265 		}
    266 
    267 		DoomLib::Z_Free(data);
    268 	}
    269 */	
    270 }
    271 
    272 
    273 //
    274 // P_LoadNodes
    275 //
    276 void P_LoadNodes (int lump)
    277 {
    278 	byte*	data;
    279 	int		i;
    280 	int		j;
    281 	int		k;
    282 	mapnode_t*	mn;
    283 	node_t*	no;
    284 
    285 	::g->numnodes = W_LumpLength (lump) / sizeof(mapnode_t);
    286 	if (MallocForLump( lump, ::g->numnodes*sizeof(node_t), ::g->nodes, PU_LEVEL_SHARED ))
    287 	{
    288 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    289 
    290 		mn = (mapnode_t *)data;
    291 		no = ::g->nodes;
    292 
    293 		for (i=0 ; i < ::g->numnodes ; i++, no++, mn++)
    294 		{
    295 			no->x = SHORT(mn->x)<<FRACBITS;
    296 			no->y = SHORT(mn->y)<<FRACBITS;
    297 			no->dx = SHORT(mn->dx)<<FRACBITS;
    298 			no->dy = SHORT(mn->dy)<<FRACBITS;
    299 			for (j=0 ; j<2 ; j++)
    300 			{
    301 				no->children[j] = SHORT(mn->children[j]);
    302 				for (k=0 ; k<4 ; k++)
    303 					no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
    304 			}
    305 		}
    306 
    307 		Z_Free(data);
    308 	}
    309 }
    310 
    311 
    312 //
    313 // P_LoadThings
    314 //
    315 void P_LoadThings (int lump)
    316 {
    317 	byte*		data;
    318 	int			i;
    319 	mapthing_t*		mt;
    320 	int			numthings;
    321 	qboolean		spawn;
    322 
    323 	data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    324 	numthings = (W_LumpLength (lump) / sizeof(mapthing_t));
    325 
    326 	mt = (mapthing_t *)data;
    327 	for (i=0 ; i<numthings ; i++, mt++)
    328 	{
    329 		spawn = true;
    330 
    331 		// Do not spawn cool, new monsters if !commercial
    332 		if ( ::g->gamemode != commercial)
    333 		{
    334 			switch(mt->type)
    335 			{
    336 			case 68:	// Arachnotron
    337 			case 64:	// Archvile
    338 			case 88:	// Boss Brain
    339 			case 89:	// Boss Shooter
    340 			case 69:	// Hell Knight
    341 			case 67:	// Mancubus
    342 			case 71:	// Pain Elemental
    343 			case 65:	// Former Human Commando
    344 			case 66:	// Revenant
    345 			case 84:	// Wolf SS
    346 				spawn = false;
    347 				break;
    348 			}
    349 		}
    350 		if (spawn == false)
    351 			break;
    352 
    353 		// Do spawn all other stuff. 
    354 		mt->x = SHORT(mt->x);
    355 		mt->y = SHORT(mt->y);
    356 		mt->angle = SHORT(mt->angle);
    357 		mt->type = SHORT(mt->type);
    358 		mt->options = SHORT(mt->options);
    359 
    360 		P_SpawnMapThing (mt);
    361 	}
    362 
    363 	Z_Free(data);
    364 }
    365 
    366 
    367 //
    368 // P_LoadLineDefs
    369 // Also counts secret ::g->lines for intermissions.
    370 //
    371 void P_LoadLineDefs (int lump)
    372 {
    373 	byte*		data;
    374 	int			i;
    375 	maplinedef_t*	mld;
    376 	line_t*		ld;
    377 	vertex_t*		v1;
    378 	vertex_t*		v2;
    379 
    380 	::g->numlines = W_LumpLength (lump) / sizeof(maplinedef_t);
    381 	if (MallocForLump( lump, ::g->numlines*sizeof(line_t), ::g->lines, PU_LEVEL_SHARED ))
    382 	{
    383 		memset (::g->lines, 0, ::g->numlines*sizeof(line_t));
    384 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    385 
    386 		mld = (maplinedef_t *)data;
    387 		ld = ::g->lines;
    388 		for (i=0 ; i < ::g->numlines ; i++, mld++, ld++)
    389 		{
    390 			ld->flags = SHORT(mld->flags);
    391 			ld->special = SHORT(mld->special);
    392 			ld->tag = SHORT(mld->tag);
    393 			v1 = ld->v1 = &::g->vertexes[SHORT(mld->v1)];
    394 			v2 = ld->v2 = &::g->vertexes[SHORT(mld->v2)];
    395 			ld->dx = v2->x - v1->x;
    396 			ld->dy = v2->y - v1->y;
    397 
    398 			if (!ld->dx)
    399 				ld->slopetype = ST_VERTICAL;
    400 			else if (!ld->dy)
    401 				ld->slopetype = ST_HORIZONTAL;
    402 			else
    403 			{
    404 				if (FixedDiv (ld->dy , ld->dx) > 0)
    405 					ld->slopetype = ST_POSITIVE;
    406 				else
    407 					ld->slopetype = ST_NEGATIVE;
    408 			}
    409 
    410 			if (v1->x < v2->x)
    411 			{
    412 				ld->bbox[BOXLEFT] = v1->x;
    413 				ld->bbox[BOXRIGHT] = v2->x;
    414 			}
    415 			else
    416 			{
    417 				ld->bbox[BOXLEFT] = v2->x;
    418 				ld->bbox[BOXRIGHT] = v1->x;
    419 			}
    420 
    421 			if (v1->y < v2->y)
    422 			{
    423 				ld->bbox[BOXBOTTOM] = v1->y;
    424 				ld->bbox[BOXTOP] = v2->y;
    425 			}
    426 			else
    427 			{
    428 				ld->bbox[BOXBOTTOM] = v2->y;
    429 				ld->bbox[BOXTOP] = v1->y;
    430 			}
    431 
    432 			ld->sidenum[0] = SHORT(mld->sidenum[0]);
    433 			ld->sidenum[1] = SHORT(mld->sidenum[1]);
    434 
    435 			if (ld->sidenum[0] != -1)
    436 				ld->frontsector = ::g->sides[ld->sidenum[0]].sector;
    437 			else
    438 				ld->frontsector = 0;
    439 
    440 			if (ld->sidenum[1] != -1)
    441 				ld->backsector = ::g->sides[ld->sidenum[1]].sector;
    442 			else
    443 				ld->backsector = 0;
    444 		}
    445 
    446 		Z_Free(data);
    447 	}
    448 }
    449 
    450 
    451 //
    452 // P_LoadSideDefs
    453 //
    454 void P_LoadSideDefs (int lump)
    455 {
    456 	byte*		data;
    457 	int			i;
    458 	mapsidedef_t*	msd;
    459 	side_t*		sd;
    460 
    461 	::g->numsides = W_LumpLength (lump) / sizeof(mapsidedef_t);
    462 	if (MallocForLump( lump, ::g->numsides*sizeof(side_t), ::g->sides, PU_LEVEL_SHARED))
    463 	{
    464 		memset (::g->sides, 0, ::g->numsides*sizeof(side_t));
    465 		data = (byte*)W_CacheLumpNum (lump,PU_CACHE_SHARED); // ALAN: LOADTIME
    466 
    467 		msd = (mapsidedef_t *)data;
    468 		sd = ::g->sides;
    469 		for (i=0 ; i < ::g->numsides ; i++, msd++, sd++)
    470 		{
    471 			sd->textureoffset = SHORT(msd->textureoffset)<<FRACBITS;
    472 			sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS;
    473 			sd->toptexture = R_TextureNumForName(msd->toptexture);
    474 			sd->bottomtexture = R_TextureNumForName(msd->bottomtexture);
    475 			sd->midtexture = R_TextureNumForName(msd->midtexture);
    476 			sd->sector = &::g->sectors[SHORT(msd->sector)];
    477 		}
    478 
    479 		Z_Free(data);
    480 	}
    481 }
    482 
    483 
    484 //
    485 // P_LoadBlockMap
    486 //
    487 void P_LoadBlockMap (int lump)
    488 {
    489 	int		i;
    490 	int		count;
    491 
    492 	bool firstTime = false;
    493 	if (!lumpcache[lump]) {			// SMF - solution for double endian conversion issue
    494 		firstTime = true;
    495 	}
    496 
    497 	::g->blockmaplump = (short*)W_CacheLumpNum (lump,PU_LEVEL_SHARED); // ALAN: This is initialized somewhere else as shared...
    498 	::g->blockmap = ::g->blockmaplump+4;
    499 	count = W_LumpLength (lump)/2;
    500 
    501 	if ( firstTime ) {				// SMF
    502 		for (i=0 ; i<count ; i++)
    503 			::g->blockmaplump[i] = SHORT(::g->blockmaplump[i]);
    504 	}
    505 
    506 	::g->bmaporgx = ( ::g->blockmaplump[0] )<<FRACBITS;
    507 	::g->bmaporgy = ( ::g->blockmaplump[1] )<<FRACBITS;
    508 	::g->bmapwidth = ( ::g->blockmaplump[2] );
    509 	::g->bmapheight = ( ::g->blockmaplump[3] );
    510 
    511 	// clear out mobj chains
    512 	count = sizeof(*::g->blocklinks)* ::g->bmapwidth*::g->bmapheight;
    513 	::g->blocklinks = (mobj_t**)Z_Malloc (count,PU_LEVEL, 0);
    514 	memset (::g->blocklinks, 0, count);
    515 }
    516 
    517 
    518 
    519 //
    520 // P_GroupLines
    521 // Builds sector line lists and subsector sector numbers.
    522 // Finds block bounding boxes for ::g->sectors.
    523 //
    524 void P_GroupLines (void)
    525 {
    526 	line_t**		linebuffer;
    527 	int			i;
    528 	int			j;
    529 	int			total;
    530 	line_t*		li;
    531 	sector_t*		sector;
    532 	subsector_t*	ss;
    533 	seg_t*		seg;
    534 	fixed_t		bbox[4];
    535 	int			block;
    536 
    537 	
    538 	// look up sector number for each subsector
    539 	ss = ::g->subsectors;
    540 	for (i=0 ; i < ::g->numsubsectors ; i++, ss++)
    541 	{
    542 		seg = &::g->segs[ss->firstline];
    543 		ss->sector = seg->sidedef->sector;
    544 	}
    545 
    546 	// count number of ::g->lines in each sector
    547 	li = ::g->lines;
    548 	total = 0;
    549 	for (i=0 ; i < ::g->numlines ; i++, li++)
    550 	{
    551 		total++;
    552 		li->frontsector->linecount++;
    553 
    554 		if (li->backsector && li->backsector != li->frontsector)
    555 		{
    556 			li->backsector->linecount++;
    557 			total++;
    558 		}
    559 	}
    560 
    561 	// build line tables for each sector	
    562 	linebuffer = (line_t**)Z_Malloc (total*4, PU_LEVEL, 0);
    563 	sector = ::g->sectors;
    564 	for (i=0 ; i < ::g->numsectors ; i++, sector++)
    565 	{
    566 		M_ClearBox (bbox);
    567 		sector->lines = linebuffer;
    568 		li = ::g->lines;
    569 		for (j=0 ; j < ::g->numlines ; j++, li++)
    570 		{
    571 			if (li->frontsector == sector || li->backsector == sector)
    572 			{
    573 				*linebuffer++ = li;
    574 				M_AddToBox (bbox, li->v1->x, li->v1->y);
    575 				M_AddToBox (bbox, li->v2->x, li->v2->y);
    576 			}
    577 		}
    578 		if (linebuffer - sector->lines != sector->linecount)
    579 			I_Error ("P_GroupLines: miscounted");
    580 
    581 		// set the degenmobj_t to the middle of the bounding box
    582 		sector->soundorg.x = (bbox[BOXRIGHT]+bbox[BOXLEFT])/2;
    583 		sector->soundorg.y = (bbox[BOXTOP]+bbox[BOXBOTTOM])/2;
    584 
    585 		// adjust bounding box to map blocks
    586 		block = (bbox[BOXTOP]-::g->bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT;
    587 		block = block >= ::g->bmapheight ? ::g->bmapheight-1 : block;
    588 		sector->blockbox[BOXTOP]=block;
    589 
    590 		block = (bbox[BOXBOTTOM]-::g->bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT;
    591 		block = block < 0 ? 0 : block;
    592 		sector->blockbox[BOXBOTTOM]=block;
    593 
    594 		block = (bbox[BOXRIGHT]-::g->bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT;
    595 		block = block >= ::g->bmapwidth ? ::g->bmapwidth-1 : block;
    596 		sector->blockbox[BOXRIGHT]=block;
    597 
    598 		block = (bbox[BOXLEFT]-::g->bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT;
    599 		block = block < 0 ? 0 : block;
    600 		sector->blockbox[BOXLEFT]=block;
    601 	}
    602 
    603 }
    604 
    605 
    606 //
    607 // P_SetupLevel
    608 //
    609 void
    610 P_SetupLevel
    611 ( int		episode,
    612  int		map,
    613  int		playermask,
    614  skill_t	skill)
    615 {
    616 	int		i;
    617 	char	lumpname[9];
    618 	int		lumpnum;
    619 
    620 	::g->totalkills = ::g->totalitems = ::g->totalsecret = ::g->wminfo.maxfrags = 0;
    621 	::g->wminfo.partime = 180;
    622 	for (i=0 ; i<MAXPLAYERS ; i++)
    623 	{
    624 		::g->players[i].killcount = ::g->players[i].secretcount 
    625 			= ::g->players[i].itemcount = 0;
    626 
    627 		::g->players[i].chainsawKills = 0;
    628 		::g->players[i].berserkKills = 0;
    629 	}
    630 
    631 	// Initial height of PointOfView
    632 	// will be set by player think.
    633 	::g->players[::g->consoleplayer].viewz = 1; 
    634 
    635 	// Make sure all sounds are stopped before Z_FreeTags.
    636 	S_Start ();			
    637 
    638 	Z_FreeTags( PU_LEVEL, PU_PURGELEVEL-1 );
    639 
    640 	// UNUSED W_Profile ();
    641 	P_InitThinkers ();
    642 
    643 	// if working with a devlopment map, reload it
    644 	// W_Reload ();
    645 
    646 	// DHM - NERVE :: Update the cached asset pointers in case the wad files were reloaded
    647 	{
    648 		void ST_loadData(void);
    649 		ST_loadData();
    650 
    651 		void HU_Init(void);
    652 		HU_Init();
    653 	}
    654 
    655 	// find map name
    656 	if ( ::g->gamemode == commercial)
    657 	{
    658 		if (map<10)
    659 			sprintf (lumpname,"map0%i", map);
    660 		else
    661 			sprintf (lumpname,"map%i", map);
    662 	}
    663 	else
    664 	{
    665 		lumpname[0] = 'E';
    666 		lumpname[1] = '0' + episode;
    667 		lumpname[2] = 'M';
    668 		lumpname[3] = '0' + map;
    669 		lumpname[4] = 0;
    670 	}
    671 
    672 	lumpnum = W_GetNumForName (lumpname);
    673 
    674 	::g->leveltime = 0;
    675 
    676 	// note: most of this ordering is important	
    677 	P_LoadBlockMap (lumpnum+ML_BLOCKMAP);
    678 	P_LoadVertexes (lumpnum+ML_VERTEXES);
    679 	P_LoadSectors (lumpnum+ML_SECTORS);
    680 	P_LoadSideDefs (lumpnum+ML_SIDEDEFS);
    681 
    682 	P_LoadLineDefs (lumpnum+ML_LINEDEFS);
    683 	P_LoadSubsectors (lumpnum+ML_SSECTORS);
    684 	P_LoadNodes (lumpnum+ML_NODES);
    685 	P_LoadSegs (lumpnum+ML_SEGS);
    686 
    687 	::g->rejectmatrix = (byte*)W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL);
    688 
    689 	P_GroupLines ();
    690 
    691 	::g->bodyqueslot = 0;
    692 	::g->deathmatch_p = ::g->deathmatchstarts;
    693 	P_LoadThings (lumpnum+ML_THINGS);
    694 
    695 	// if ::g->deathmatch, randomly spawn the active ::g->players
    696 	if (::g->deathmatch)
    697 	{
    698 		for (i=0 ; i<MAXPLAYERS ; i++)
    699 			if (::g->playeringame[i])
    700 			{
    701 				// DHM - Nerve :: In deathmatch, reset every player at match start
    702 				::g->players[i].playerstate = PST_REBORN;
    703 
    704 				::g->players[i].mo = NULL;
    705 				G_DeathMatchSpawnPlayer (i);
    706 			}
    707 
    708 	}
    709 
    710 	// clear special respawning que
    711 	::g->iquehead = ::g->iquetail = 0;		
    712 
    713 	// set up world state
    714 	P_SpawnSpecials ();
    715 
    716 	// build subsector connect matrix
    717 	//	UNUSED P_ConnectSubsectors ();
    718 
    719 	// preload graphics
    720 	if (::g->precache)
    721 		R_PrecacheLevel ();
    722 }
    723 
    724 
    725 
    726 //
    727 // P_Init
    728 //
    729 void P_Init (void)
    730 {
    731 	P_InitSwitchList ();
    732 	P_InitPicAnims ();
    733 	R_InitSprites (sprnames);
    734 }
    735 
    736 
    737 
    738