doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

p_spec.c (16701B)


      1 /*
      2  *
      3  *
      4  * P_ShootSpecialLine funny
      5  *
      6  *
      7  */
      8 #include <stdlib.h>
      9 
     10 #include "doomdef.h"
     11 #include "doomstat.h"
     12 #include "i_system.h"
     13 #include "z_zone.h"
     14 #include "m_argv.h"
     15 #include "m_random.h"
     16 #include "w_wad.h"
     17 #include "r_local.h"
     18 #include "p_local.h"
     19 #include "g_game.h"
     20 #include "s_sound.h"
     21 #include "r_state.h"
     22 #include "sounds.h"
     23 
     24 typedef struct {
     25 	boolean	istexture;
     26 	int		picnum;
     27 	int		basepic;
     28 	int		numpics;
     29 	int		speed;
     30 } anim_t;
     31 
     32 typedef struct {
     33 	boolean	istexture;	
     34 	char	endname[9];
     35 	char	startname[9];
     36 	int		speed;
     37 } animdef_t;
     38 
     39 #define MAXANIMS 32
     40 
     41 extern anim_t  anims[MAXANIMS];
     42 extern anim_t* lastanim;
     43 
     44 animdef_t animdefs[] = {
     45 	{false,	"NUKAGE3",	"NUKAGE1",	8},
     46 	{false,	"FWATER4",	"FWATER1",	8},
     47 	{false,	"SWATER4",	"SWATER1", 	8},
     48 	{false,	"LAVA4",	"LAVA1",	8},
     49 	{false,	"BLOOD3",	"BLOOD1",	8},
     50 	{false,	"RROCK08",	"RROCK05",	8},		
     51 	{false,	"SLIME04",	"SLIME01",	8},
     52 	{false,	"SLIME08",	"SLIME05",	8},
     53 	{false,	"SLIME12",	"SLIME09",	8},
     54 	{true,	"BLODGR4",	"BLODGR1",	8},
     55 	{true,	"SLADRIP3",	"SLADRIP1",	8},
     56 	{true,	"BLODRIP4",	"BLODRIP1",	8},
     57 	{true,	"FIREWALL",	"FIREWALA",	8},
     58 	{true,	"GSTFONT3",	"GSTFONT1",	8},
     59 	{true,	"FIRELAVA",	"FIRELAV3",	8},
     60 	{true,	"FIREMAG3",	"FIREMAG1",	8},
     61 	{true,	"FIREBLU2",	"FIREBLU1",	8},
     62 	{true,	"ROCKRED3",	"ROCKRED1",	8},
     63 	{true,	"BFALL4",	"BFALL1",	8},
     64 	{true,	"SFALL4",	"SFALL1",	8},
     65 	{true,	"WFALL4",	"WFALL1",	8},
     66 	{true,	"DBRAIN4",	"DBRAIN1",	8},
     67 	{-1}
     68 };
     69 
     70 anim_t  anims[MAXANIMS];
     71 anim_t* lastanim;
     72 
     73 #define MAXLINEANIMS 64
     74 
     75 extern short   numlinespecials;
     76 extern line_t* linespeciallist[MAXLINEANIMS];
     77 
     78 void
     79 P_InitPicAnims()
     80 {
     81 	int i;
     82 	
     83 	lastanim = anims;
     84 	for (i = 0; animdefs[i].istexture != -1 ; ++i) {
     85 		if (animdefs[i].istexture) {
     86 			if (R_CheckTextureNumForName(animdefs[i].startname) == -1)
     87 				continue;	
     88 			lastanim->picnum = R_TextureNumForName (animdefs[i].endname);
     89 			lastanim->basepic = R_TextureNumForName (animdefs[i].startname);
     90 		} else {
     91 			if (W_CheckNumForName(animdefs[i].startname) == -1)
     92 				continue;
     93 			lastanim->picnum = R_FlatNumForName (animdefs[i].endname);
     94 			lastanim->basepic = R_FlatNumForName (animdefs[i].startname);
     95 		}
     96 		lastanim->istexture = animdefs[i].istexture;
     97 		lastanim->numpics = lastanim->picnum - lastanim->basepic + 1;
     98 		if (lastanim->numpics < 2)
     99 			I_Error ("P_InitPicAnims: bad cycle from %s to %s", animdefs[i].startname, animdefs[i].endname);
    100 		lastanim->speed = animdefs[i].speed;
    101 		++lastanim;
    102 	}
    103 }
    104 
    105 side_t*
    106 getSide(int currentSector, int line, int side)
    107 {
    108 	return &sides[(sectors[currentSector].lines[line])->sidenum[side]];
    109 }
    110 
    111 sector_t*
    112 getSector(int currentSector, int line, int side)
    113 {
    114 	return sides[(sectors[currentSector].lines[line])->sidenum[side]].sector;
    115 }
    116 
    117 int
    118 twoSided(int sector, int line)
    119 {
    120 	return (sectors[sector].lines[line])->flags & ML_TWOSIDED;
    121 }
    122 
    123 sector_t*
    124 getNextSector(line_t* line, sector_t* sec)
    125 {
    126 	if (!(line->flags & ML_TWOSIDED))
    127 		return NULL;
    128 	if (line->frontsector == sec)
    129 		return line->backsector;
    130 	return line->frontsector;
    131 }
    132 
    133 fixed_t
    134 P_FindLowestFloorSurrounding(sector_t* sec)
    135 {
    136 	line_t*   check;
    137 	sector_t* other;
    138 	fixed_t   floor;
    139 	int       i;
    140 	
    141 	floor = sec->floorheight;
    142 	for (i = 0; i < sec->linecount; ++i) {
    143 		check = sec->lines[i];
    144 		other = getNextSector(check,sec);
    145 		if (!other)
    146 			continue;
    147 		if (other->floorheight < floor)
    148 			floor = other->floorheight;
    149 	}
    150 	return floor;
    151 }
    152 
    153 fixed_t
    154 P_FindHighestFloorSurrounding(sector_t *sec)
    155 {
    156 	line_t*   check;
    157 	sector_t* other;
    158 	fixed_t   floor;
    159 	int       i;
    160 	
    161 	floor = -500 * FRACUNIT;
    162 	for (i = 0; i < sec->linecount; ++i) {
    163 		check = sec->lines[i];
    164 		other = getNextSector(check,sec);
    165 		if (!other)
    166 			continue;
    167 		if (other->floorheight > floor)
    168 			floor = other->floorheight;
    169 	}
    170 	return floor;
    171 }
    172 
    173 #define MAX_ADJOINING_SECTORS 20
    174 
    175 fixed_t
    176 P_FindNextHighestFloor(sector_t* sec, int currentheight)
    177 {
    178 	line_t*   check;
    179 	sector_t* other;
    180 	fixed_t   height, heightlist[MAX_ADJOINING_SECTORS];		
    181 	int       i, h, min;
    182 	
    183 	height = currentheight;
    184 	for (i = 0, h = 0; i < sec->linecount; ++i) {
    185 		check = sec->lines[i];
    186 		other = getNextSector(check,sec);
    187 		if (!other)
    188 			continue;
    189 		if (other->floorheight > height)
    190 			heightlist[h++] = other->floorheight;
    191 		if (h >= MAX_ADJOINING_SECTORS) {
    192 			fprintf(stderr, "Sector with more than 20 adjoining sectors\n");
    193 			break;
    194 		}
    195 	}
    196 	if (!h)
    197 		return currentheight;
    198 	min = heightlist[0];
    199 	for (i = 1; i < h; ++i)
    200 		if (heightlist[i] < min)
    201 			min = heightlist[i];
    202 	return min;
    203 }
    204 
    205 fixed_t
    206 P_FindLowestCeilingSurrounding(sector_t* sec)
    207 {
    208 	line_t*   check;
    209 	sector_t* other;
    210 	fixed_t   height;
    211 	int       i;
    212 	
    213 	height = INT_MAX;
    214 	for (i = 0; i < sec->linecount; ++i) {
    215 		check = sec->lines[i];
    216 		other = getNextSector(check,sec);
    217 		if (!other)
    218 			continue;
    219 		if (other->ceilingheight < height)
    220 			height = other->ceilingheight;
    221 	}
    222 	return height;
    223 }
    224 
    225 fixed_t
    226 P_FindHighestCeilingSurrounding(sector_t* sec)
    227 {
    228 	line_t*   check;
    229 	sector_t* other;
    230 	fixed_t   height;
    231 	int       i;
    232 	
    233 	height = 0;
    234 	for (i = 0; i < sec->linecount; ++i) {
    235 		check = sec->lines[i];
    236 		other = getNextSector(check,sec);
    237 		if (!other)
    238 			continue;
    239 		if (other->ceilingheight > height)
    240 			height = other->ceilingheight;
    241 	}
    242 	return height;
    243 }
    244 
    245 int
    246 P_FindSectorFromLineTag(line_t* line, int start)
    247 {
    248 	int	i;
    249 	
    250 	for (i = start + 1; i < numsectors; ++i)
    251 		if (sectors[i].tag == line->tag)
    252 			return i;
    253 	return -1;
    254 }
    255 
    256 int
    257 P_FindMinSurroundingLight(sector_t* sector, int max)
    258 {
    259 	line_t*   line;
    260 	sector_t* check;
    261 	int       i, min;
    262 	
    263 	min = max;
    264 	for (i = 0; i < sector->linecount; ++i) {
    265 		line = sector->lines[i];
    266 		check = getNextSector(line,sector);
    267 		if (!check)
    268 			continue;
    269 		if (check->lightlevel < min)
    270 			min = check->lightlevel;
    271 	}
    272 	return min;
    273 }
    274 
    275 void
    276 P_CrossSpecialLine(int linenum, int side, mobj_t* thing)
    277 {
    278 	line_t* line;
    279 	int     ok;
    280 
    281 	line = &lines[linenum];
    282 	if (!thing->player) {
    283 		switch (thing->type) {
    284 			case MT_ROCKET:
    285 			case MT_PLASMA:
    286 			case MT_BFG:
    287 			case MT_TROOPSHOT:
    288 			case MT_HEADSHOT:
    289 			case MT_BRUISERSHOT:
    290 			return;
    291 		  default: break;
    292 		}
    293 		ok = 0;
    294 		switch (line->special) {
    295 			case 39:	
    296 			case 97:	
    297 			case 125:	
    298 			case 126:	
    299 			case 4:	
    300 			case 10:	
    301 			case 88:	
    302 			ok = 1;
    303 			break;
    304 		}
    305 		if (!ok)
    306 			return;
    307 	}
    308 	switch (line->special) {
    309 		case 2:
    310 			EV_DoDoor(line,open);
    311 			line->special = 0;
    312 			break;
    313 
    314 		case 3:
    315 			EV_DoDoor(line,close);
    316 			line->special = 0;
    317 			break;
    318 		case 4:
    319 			EV_DoDoor(line,normal);
    320 			line->special = 0;
    321 			break;
    322 		case 5:
    323 			EV_DoFloor(line,raiseFloor);
    324 			line->special = 0;
    325 			break;
    326 		case 6:
    327 			EV_DoCeiling(line,fastCrushAndRaise);
    328 			line->special = 0;
    329 			break;
    330 		case 8:
    331 			EV_BuildStairs(line,build8);
    332 			line->special = 0;
    333 			break;
    334 		case 10:
    335 			EV_DoPlat(line,downWaitUpStay,0);
    336 			line->special = 0;
    337 			break;
    338 		case 12:
    339 			EV_LightTurnOn(line,0);
    340 			line->special = 0;
    341 			break;
    342 		case 13:
    343 			EV_LightTurnOn(line,255);
    344 			line->special = 0;
    345 			break;
    346 		case 16:
    347 			EV_DoDoor(line,close30ThenOpen);
    348 			line->special = 0;
    349 			break;
    350 		case 17:
    351 			EV_StartLightStrobing(line);
    352 			line->special = 0;
    353 			break;
    354 		case 19:
    355 			EV_DoFloor(line,lowerFloor);
    356 			line->special = 0;
    357 			break;
    358 		case 22:
    359 			EV_DoPlat(line,raiseToNearestAndChange,0);
    360 			line->special = 0;
    361 			break;
    362 		case 25:
    363 			EV_DoCeiling(line,crushAndRaise);
    364 			line->special = 0;
    365 			break;
    366 		case 30:
    367 			EV_DoFloor(line,raiseToTexture);
    368 			line->special = 0;
    369 			break;
    370 		case 35:
    371 			EV_LightTurnOn(line,35);
    372 			line->special = 0;
    373 			break;
    374 		case 36:
    375 			EV_DoFloor(line,turboLower);
    376 			line->special = 0;
    377 			break;
    378 		case 37:
    379 			EV_DoFloor(line,lowerAndChange);
    380 			line->special = 0;
    381 			break;
    382 		case 38:
    383 			EV_DoFloor(line, lowerFloorToLowest);
    384 			line->special = 0;
    385 			break;
    386 		case 39:
    387 			EV_Teleport(line, side, thing);
    388 			line->special = 0;
    389 			break;
    390 		case 40:
    391 			EV_DoCeiling(line, raiseToHighest);
    392 			EV_DoFloor(line, lowerFloorToLowest);
    393 			line->special = 0;
    394 			break;
    395 		case 44:
    396 			EV_DoCeiling(line, lowerAndCrush);
    397 			line->special = 0;
    398 			break;
    399 		case 52: G_ExitLevel(); break;
    400 		case 53:
    401 			EV_DoPlat(line,perpetualRaise,0);
    402 			line->special = 0;
    403 			break;
    404 		case 54:
    405 			EV_StopPlat(line);
    406 			line->special = 0;
    407 			break;
    408 		case 56:
    409 			EV_DoFloor(line,raiseFloorCrush);
    410 			line->special = 0;
    411 			break;
    412 		case 57:
    413 			EV_CeilingCrushStop(line);
    414 			line->special = 0;
    415 			break;
    416 		case 58:
    417 			EV_DoFloor(line,raiseFloor24);
    418 			line->special = 0;
    419 			break;
    420 		case 59:
    421 			EV_DoFloor(line,raiseFloor24AndChange);
    422 			line->special = 0;
    423 			break;
    424 		case 104:
    425 			EV_TurnTagLightsOff(line);
    426 			line->special = 0;
    427 			break;
    428 		case 108:
    429 			EV_DoDoor (line,blazeRaise);
    430 			line->special = 0;
    431 			break;
    432 		case 109:
    433 			EV_DoDoor (line,blazeOpen);
    434 			line->special = 0;
    435 			break;
    436 		case 100:
    437 			EV_BuildStairs(line,turbo16);
    438 			line->special = 0;
    439 			break;
    440 		case 110:
    441 			EV_DoDoor (line,blazeClose);
    442 			line->special = 0;
    443 			break;
    444 		case 119:
    445 			EV_DoFloor(line,raiseFloorToNearest);
    446 			line->special = 0;
    447 			break;
    448 		case 121:
    449 			EV_DoPlat(line,blazeDWUS,0);
    450 			line->special = 0;
    451 			break;
    452 		case 124: G_SecretExitLevel (); break;
    453 		case 125:
    454 			if (!thing->player) {
    455 				EV_Teleport(line, side, thing);
    456 				line->special = 0;
    457 			}
    458 			break;
    459 		case 130:
    460 			EV_DoFloor(line,raiseFloorTurbo);
    461 			line->special = 0;
    462 			break;
    463 		case 141:
    464 			EV_DoCeiling(line,silentCrushAndRaise);
    465 			line->special = 0;
    466 			break;
    467 		case 72: EV_DoCeiling(line, lowerAndCrush); break;
    468 		case 73: EV_DoCeiling(line,crushAndRaise); break;
    469 		case 74: EV_CeilingCrushStop(line); break;
    470 		case 75: EV_DoDoor(line,close); break;
    471 		case 76: EV_DoDoor(line,close30ThenOpen); break;
    472 		case 77: EV_DoCeiling(line,fastCrushAndRaise); break;
    473 		case 79: EV_LightTurnOn(line,35); break;
    474 		case 80: EV_LightTurnOn(line,0); break;
    475 		case 81: EV_LightTurnOn(line,255); break;
    476 		case 82: EV_DoFloor(line, lowerFloorToLowest); break;
    477 		case 83: EV_DoFloor(line,lowerFloor); break;
    478 		case 84: EV_DoFloor(line,lowerAndChange); break;
    479 		case 86: EV_DoDoor(line,open); break;
    480 		case 87: EV_DoPlat(line,perpetualRaise,0); break;
    481 		case 88: EV_DoPlat(line,downWaitUpStay,0); break;
    482 		case 89: EV_StopPlat(line); break;
    483 		case 90: EV_DoDoor(line,normal); break;
    484 		case 91: EV_DoFloor(line,raiseFloor); break;
    485 		case 92: EV_DoFloor(line,raiseFloor24); break;
    486 		case 93: EV_DoFloor(line,raiseFloor24AndChange); break;
    487 		case 94: EV_DoFloor(line,raiseFloorCrush); break;
    488 		case 95: EV_DoPlat(line,raiseToNearestAndChange,0); break;
    489 		case 96: EV_DoFloor(line,raiseToTexture); break;
    490 		case 97: EV_Teleport(line, side, thing); break;
    491 		case 98: EV_DoFloor(line,turboLower); break;
    492 		case 105: EV_DoDoor(line,blazeRaise); break;
    493 		case 106: EV_DoDoor(line,blazeOpen); break;
    494 		case 107: EV_DoDoor(line,blazeClose); break;
    495 		case 120: EV_DoPlat(line,blazeDWUS,0); break;
    496 		case 126:
    497 			if (!thing->player)
    498 				EV_Teleport(line, side, thing);
    499 			break;
    500 		case 128: EV_DoFloor(line,raiseFloorToNearest); break;
    501 		case 129: EV_DoFloor(line,raiseFloorTurbo); break;
    502 	}
    503 }
    504 
    505 void
    506 P_ShootSpecialLine(mobj_t* thing, line_t* line)
    507 {
    508 	if (!thing->player && line->special != 46)
    509 		return;
    510 	switch (line->special) {
    511 		case 24:
    512 			EV_DoFloor(line,raiseFloor);
    513 			P_ChangeSwitchTexture(line,0);
    514 			break;
    515 		case 46:
    516 			EV_DoDoor(line,open);
    517 			P_ChangeSwitchTexture(line,1);
    518 			break;
    519 		case 47:
    520 			EV_DoPlat(line,raiseToNearestAndChange,0);
    521 			P_ChangeSwitchTexture(line,0);
    522 			break;
    523 	}
    524 }
    525 
    526 void
    527 P_PlayerInSpecialSector(player_t* player)
    528 {
    529 	sector_t* sector;
    530 
    531 	sector = player->mo->subsector->sector;
    532 
    533 	
    534 	if (player->mo->z != sector->floorheight)
    535 	return;	
    536 
    537 	
    538 	switch (sector->special)
    539 	{
    540 		case 5:
    541 	
    542 	if (!player->powers[pw_ironfeet])
    543 	    if (!(leveltime&0x1f))
    544 		P_DamageMobj (player->mo, NULL, NULL, 10);
    545 	break;
    546 	
    547 		case 7:
    548 	
    549 	if (!player->powers[pw_ironfeet])
    550 	    if (!(leveltime&0x1f))
    551 		P_DamageMobj (player->mo, NULL, NULL, 5);
    552 	break;
    553 	
    554 		case 16:
    555 	
    556 		case 4:
    557 	
    558 	if (!player->powers[pw_ironfeet]
    559 	    || (P_Random()<5))
    560 	{
    561 	    if (!(leveltime&0x1f))
    562 		P_DamageMobj (player->mo, NULL, NULL, 20);
    563 	}
    564 	break;
    565 			
    566 		case 9:
    567 	
    568 	player->secretcount++;
    569 	sector->special = 0;
    570 	break;
    571 			
    572 		case 11:
    573 	
    574 	player->cheats &= ~CF_GODMODE;
    575 
    576 	if (!(leveltime&0x1f))
    577 	    P_DamageMobj (player->mo, NULL, NULL, 20);
    578 
    579 	if (player->health <= 10)
    580 	    G_ExitLevel();
    581 	break;
    582 			
    583 	  default:
    584 	I_Error ("P_PlayerInSpecialSector: "
    585 		 "unknown special %i",
    586 		 sector->special);
    587 	break;
    588 	};
    589 }
    590 
    591 
    592 
    593 
    594 
    595 
    596 
    597 
    598 boolean		levelTimer;
    599 int		levelTimeCount;
    600 
    601 void P_UpdateSpecials (void)
    602 {
    603 	anim_t*	anim;
    604 	int		pic;
    605 	int		i;
    606 	line_t*	line;
    607 
    608 	
    609 	
    610 	if (levelTimer == true)
    611 	{
    612 	levelTimeCount--;
    613 	if (!levelTimeCount)
    614 	    G_ExitLevel();
    615 	}
    616 	
    617 	
    618 	for (anim = anims ; anim < lastanim ; anim++)
    619 	{
    620 	for (i=anim->basepic ; i<anim->basepic+anim->numpics ; i++)
    621 	{
    622 	    pic = anim->basepic + ((leveltime/anim->speed + i)%anim->numpics);
    623 	    if (anim->istexture)
    624 		texturetranslation[i] = pic;
    625 	    else
    626 		flattranslation[i] = pic;
    627 	}
    628 	}
    629 
    630 	
    631 	
    632 	for (i = 0; i < numlinespecials; i++)
    633 	{
    634 	line = linespeciallist[i];
    635 	switch(line->special)
    636 	{
    637 		case 48:
    638 	    
    639 	    sides[line->sidenum[0]].textureoffset += FRACUNIT;
    640 	    break;
    641 	}
    642 	}
    643 
    644 	
    645 	
    646 	for (i = 0; i < MAXBUTTONS; i++)
    647 	if (buttonlist[i].btimer)
    648 	{
    649 	    buttonlist[i].btimer--;
    650 	    if (!buttonlist[i].btimer)
    651 	    {
    652 		switch(buttonlist[i].where)
    653 		{
    654 			case top:
    655 		    sides[buttonlist[i].line->sidenum[0]].toptexture =
    656 			buttonlist[i].btexture;
    657 		    break;
    658 		    
    659 			case middle:
    660 		    sides[buttonlist[i].line->sidenum[0]].midtexture =
    661 			buttonlist[i].btexture;
    662 		    break;
    663 		    
    664 			case bottom:
    665 		    sides[buttonlist[i].line->sidenum[0]].bottomtexture =
    666 			buttonlist[i].btexture;
    667 		    break;
    668 		}
    669 		S_StartSound((mobj_t *)&buttonlist[i].soundorg,sfx_swtchn);
    670 		memset(&buttonlist[i],0,sizeof(button_t));
    671 	    }
    672 	}
    673 	
    674 }
    675 
    676 
    677 
    678 
    679 
    680 
    681 int EV_DoDonut(line_t*	line)
    682 {
    683 	sector_t*		s1;
    684 	sector_t*		s2;
    685 	sector_t*		s3;
    686 	int			secnum;
    687 	int			rtn;
    688 	int			i;
    689 	floormove_t*	floor;
    690 	
    691 	secnum = -1;
    692 	rtn = 0;
    693 	while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    694 	{
    695 	s1 = &sectors[secnum];
    696 		
    697 	
    698 	if (s1->specialdata)
    699 	    continue;
    700 			
    701 	rtn = 1;
    702 	s2 = getNextSector(s1->lines[0],s1);
    703 	for (i = 0;i < s2->linecount;i++)
    704 	{
    705 	    if (((!s2->lines[i]->flags) & ML_TWOSIDED) || (s2->lines[i]->backsector == s1)) continue;
    706 	    s3 = s2->lines[i]->backsector;
    707 	    
    708 	    
    709 	    floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    710 	    P_AddThinker (&floor->thinker);
    711 	    s2->specialdata = floor;
    712 	    floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
    713 	    floor->type = donutRaise;
    714 	    floor->crush = false;
    715 	    floor->direction = 1;
    716 	    floor->sector = s2;
    717 	    floor->speed = FLOORSPEED / 2;
    718 	    floor->texture = s3->floorpic;
    719 	    floor->newspecial = 0;
    720 	    floor->floordestheight = s3->floorheight;
    721 	    
    722 	    
    723 	    floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    724 	    P_AddThinker (&floor->thinker);
    725 	    s1->specialdata = floor;
    726 	    floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
    727 	    floor->type = lowerFloor;
    728 	    floor->crush = false;
    729 	    floor->direction = -1;
    730 	    floor->sector = s1;
    731 	    floor->speed = FLOORSPEED / 2;
    732 	    floor->floordestheight = s3->floorheight;
    733 	    break;
    734 	}
    735 	}
    736 	return rtn;
    737 }
    738 
    739 
    740 
    741 
    742 
    743 
    744 
    745 
    746 
    747 
    748 
    749 
    750 short		numlinespecials;
    751 line_t*		linespeciallist[MAXLINEANIMS];
    752 
    753 
    754 
    755 void P_SpawnSpecials (void)
    756 {
    757 	sector_t*	sector;
    758 	int		i;
    759 
    760 	if (W_CheckNumForName("texture2") >= 0)
    761 
    762 	
    763 	
    764 	levelTimer = false;
    765 	
    766 	i = M_CheckParm("-avg");
    767 	if (i && deathmatch)
    768 	{
    769 	levelTimer = true;
    770 	levelTimeCount = 20 * 60 * 35;
    771 	}
    772 	
    773 	i = M_CheckParm("-timer");
    774 	if (i && deathmatch)
    775 	{
    776 	int	time;
    777 	time = atoi(myargv[i+1]) * 60 * 35;
    778 	levelTimer = true;
    779 	levelTimeCount = time;
    780 	}
    781 	
    782 	
    783 	sector = sectors;
    784 	for (i=0 ; i<numsectors ; i++, sector++)
    785 	{
    786 	if (!sector->special)
    787 	    continue;
    788 	
    789 	switch (sector->special) {
    790 		case 1:
    791 			P_SpawnLightFlash (sector);
    792 			break;
    793 		case 2:
    794 			P_SpawnStrobeFlash(sector,FASTDARK,0);
    795 			break;
    796 		case 3:
    797 			P_SpawnStrobeFlash(sector,SLOWDARK,0);
    798 			break;
    799 		case 4:
    800 			P_SpawnStrobeFlash(sector,FASTDARK,0);
    801 			sector->special = 4;
    802 			break;
    803 		case 8:
    804 			P_SpawnGlowingLight(sector);
    805 			break;
    806 		case 9:
    807 			totalsecret++;
    808 			break;
    809 		case 10:
    810 			P_SpawnDoorCloseIn30(sector);
    811 			break;
    812 		case 12:
    813 			P_SpawnStrobeFlash(sector, SLOWDARK, 1);
    814 			break;
    815 		case 13:
    816 			P_SpawnStrobeFlash(sector, FASTDARK, 1);
    817 			break;
    818 		case 14:
    819 			P_SpawnDoorRaiseIn5Mins(sector, i);
    820 			break;
    821 		case 17:
    822 			P_SpawnFireFlicker(sector);
    823 			break;
    824 	}
    825 	}
    826 
    827 	
    828 	
    829 	numlinespecials = 0;
    830 	for (i = 0;i < numlines; i++)
    831 	{
    832 	switch(lines[i].special)
    833 	{
    834 		case 48:
    835 	    
    836 	    linespeciallist[numlinespecials] = &lines[i];
    837 	    numlinespecials++;
    838 	    break;
    839 	}
    840 	}
    841 
    842 	
    843 	
    844 	for (i = 0;i < MAXCEILINGS;i++)
    845 	activeceilings[i] = NULL;
    846 
    847 	for (i = 0;i < MAXPLATS;i++)
    848 	activeplats[i] = NULL;
    849 	
    850 	for (i = 0;i < MAXBUTTONS;i++)
    851 	memset(&buttonlist[i],0,sizeof(button_t));
    852 
    853 	
    854 	
    855 }