📄 p_spec.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: p_spec.c,v 1.2 2003/09/08 22:34:30 jasonk Exp $//// Copyright (C) 1993-1996 by id Software, Inc.//// This source is available for distribution and/or modification// only under the terms of the DOOM Source Code License as// published by id Software. All rights reserved.//// The source is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License// for more details.//// $Log: p_spec.c,v $// Revision 1.2 2003/09/08 22:34:30 jasonk// Updated files because this fucker won't build for no fucking good reason.//// Revision 1.1.1.1 2003/09/04 21:08:13 jasonk// Initial import//// Revision 1.1 2000/12/08 21:07:54 jeffw// nxdoom initial entry -- No nxdoom/Makefile so it won't build automatically////// DESCRIPTION:// Implements special effects:// Texture animation, height or lighting changes// according to adjacent sectors, respective// utility functions, etc.// Line Tag handling. Line and Sector triggers.////-----------------------------------------------------------------------------static const charrcsid[] = "$Id: p_spec.c,v 1.2 2003/09/08 22:34:30 jasonk Exp $";#include <stdlib.h>#include "doomdef.h"#include "doomstat.h"#include "i_system.h"#include "z_zone.h"#include "m_argv.h"#include "m_random.h"#include "w_wad.h"#include "r_local.h"#include "p_local.h"#include "g_game.h"#include "s_sound.h"// State.#include "r_state.h"// Data.#include "sounds.h"//// Animating textures and planes// There is another anim_t used in wi_stuff, unrelated.//typedef struct{ boolean istexture; int picnum; int basepic; int numpics; int speed; } anim_t;//// source animation definition//typedef struct{ boolean istexture; // if false, it is a flat char endname[9]; char startname[9]; int speed;} animdef_t;#define MAXANIMS 32extern anim_t anims[MAXANIMS];extern anim_t* lastanim;//// P_InitPicAnims//// Floor/ceiling animation sequences,// defined by first and last frame,// i.e. the flat (64x64 tile) name to// be used.// The full animation sequence is given// using all the flats between the start// and end entry, in the order found in// the WAD file.//animdef_t animdefs[] ={ {false, "NUKAGE3", "NUKAGE1", 8}, {false, "FWATER4", "FWATER1", 8}, {false, "SWATER4", "SWATER1", 8}, {false, "LAVA4", "LAVA1", 8}, {false, "BLOOD3", "BLOOD1", 8}, // DOOM II flat animations. {false, "RROCK08", "RROCK05", 8}, {false, "SLIME04", "SLIME01", 8}, {false, "SLIME08", "SLIME05", 8}, {false, "SLIME12", "SLIME09", 8}, {true, "BLODGR4", "BLODGR1", 8}, {true, "SLADRIP3", "SLADRIP1", 8}, {true, "BLODRIP4", "BLODRIP1", 8}, {true, "FIREWALL", "FIREWALA", 8}, {true, "GSTFONT3", "GSTFONT1", 8}, {true, "FIRELAVA", "FIRELAV3", 8}, {true, "FIREMAG3", "FIREMAG1", 8}, {true, "FIREBLU2", "FIREBLU1", 8}, {true, "ROCKRED3", "ROCKRED1", 8}, {true, "BFALL4", "BFALL1", 8}, {true, "SFALL4", "SFALL1", 8}, {true, "WFALL4", "WFALL1", 8}, {true, "DBRAIN4", "DBRAIN1", 8}, {-1}};anim_t anims[MAXANIMS];anim_t* lastanim;//// Animating line specials//#define MAXLINEANIMS 64extern short numlinespecials;extern line_t* linespeciallist[MAXLINEANIMS];void P_InitPicAnims (void){ int i; // Init animation lastanim = anims; for (i=0 ; animdefs[i].istexture != -1 ; i++) { if (animdefs[i].istexture) { // different episode ? if (R_CheckTextureNumForName(animdefs[i].startname) == -1) continue; lastanim->picnum = R_TextureNumForName (animdefs[i].endname); lastanim->basepic = R_TextureNumForName (animdefs[i].startname); } else { if (W_CheckNumForName(animdefs[i].startname) == -1) continue; lastanim->picnum = R_FlatNumForName (animdefs[i].endname); lastanim->basepic = R_FlatNumForName (animdefs[i].startname); } lastanim->istexture = animdefs[i].istexture; lastanim->numpics = lastanim->picnum - lastanim->basepic + 1; if (lastanim->numpics < 2) I_Error ("P_InitPicAnims: bad cycle from %s to %s", animdefs[i].startname, animdefs[i].endname); lastanim->speed = animdefs[i].speed; lastanim++; } }//// UTILITIES////// getSide()// Will return a side_t*// given the number of the current sector,// the line number, and the side (0/1) that you want.//side_t*getSide( int currentSector, int line, int side ){ return &sides[ (sectors[currentSector].lines[line])->sidenum[side] ];}//// getSector()// Will return a sector_t*// given the number of the current sector,// the line number and the side (0/1) that you want.//sector_t*getSector( int currentSector, int line, int side ){ return sides[ (sectors[currentSector].lines[line])->sidenum[side] ].sector;}//// twoSided()// Given the sector number and the line number,// it will tell you whether the line is two-sided or not.//inttwoSided( int sector, int line ){ return (sectors[sector].lines[line])->flags & ML_TWOSIDED;}//// getNextSector()// Return sector_t * of sector next to current.// NULL if not two-sided line//sector_t*getNextSector( line_t* line, sector_t* sec ){ if (!(line->flags & ML_TWOSIDED)) return NULL; if (line->frontsector == sec) return line->backsector; return line->frontsector;}//// P_FindLowestFloorSurrounding()// FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS//fixed_t P_FindLowestFloorSurrounding(sector_t* sec){ int i; line_t* check; sector_t* other; fixed_t floor = sec->floorheight; for (i=0 ;i < sec->linecount ; i++) { check = sec->lines[i]; other = getNextSector(check,sec); if (!other) continue; if (other->floorheight < floor) floor = other->floorheight; } return floor;}//// P_FindHighestFloorSurrounding()// FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS//fixed_t P_FindHighestFloorSurrounding(sector_t *sec){ int i; line_t* check; sector_t* other; fixed_t floor = -500*FRACUNIT; for (i=0 ;i < sec->linecount ; i++) { check = sec->lines[i]; other = getNextSector(check,sec); if (!other) continue; if (other->floorheight > floor) floor = other->floorheight; } return floor;}//// P_FindNextHighestFloor// FIND NEXT HIGHEST FLOOR IN SURROUNDING SECTORS// Note: this should be doable w/o a fixed array.// 20 adjoining sectors max!#define MAX_ADJOINING_SECTORS 20fixed_tP_FindNextHighestFloor( sector_t* sec, int currentheight ){ int i; int h; int min; line_t* check; sector_t* other; fixed_t height = currentheight; fixed_t heightlist[MAX_ADJOINING_SECTORS]; for (i=0, h=0 ;i < sec->linecount ; i++) { check = sec->lines[i]; other = getNextSector(check,sec); if (!other) continue; if (other->floorheight > height) heightlist[h++] = other->floorheight; // Check for overflow. Exit. if ( h >= MAX_ADJOINING_SECTORS ) { fprintf( stderr, "Sector with more than 20 adjoining sectors\n" ); break; } } // Find lowest height in list if (!h) return currentheight; min = heightlist[0]; // Range checking? for (i = 1;i < h;i++) if (heightlist[i] < min) min = heightlist[i]; return min;}//// FIND LOWEST CEILING IN THE SURROUNDING SECTORS//fixed_tP_FindLowestCeilingSurrounding(sector_t* sec){ int i; line_t* check; sector_t* other; fixed_t height = MAXINT; for (i=0 ;i < sec->linecount ; i++) { check = sec->lines[i]; other = getNextSector(check,sec); if (!other) continue; if (other->ceilingheight < height) height = other->ceilingheight; } return height;}//// FIND HIGHEST CEILING IN THE SURROUNDING SECTORS//fixed_t P_FindHighestCeilingSurrounding(sector_t* sec){ int i; line_t* check; sector_t* other; fixed_t height = 0; for (i=0 ;i < sec->linecount ; i++) { check = sec->lines[i]; other = getNextSector(check,sec); if (!other) continue; if (other->ceilingheight > height) height = other->ceilingheight; } return height;}//// RETURN NEXT SECTOR # THAT LINE TAG REFERS TO//intP_FindSectorFromLineTag( line_t* line, int start ){ int i; for (i=start+1;i<numsectors;i++) if (sectors[i].tag == line->tag) return i; return -1;}//// Find minimum light from an adjacent sector//intP_FindMinSurroundingLight( sector_t* sector, int max ){ int i; int min; line_t* line; sector_t* check; min = max; for (i=0 ; i < sector->linecount ; i++) { line = sector->lines[i]; check = getNextSector(line,sector); if (!check) continue; if (check->lightlevel < min) min = check->lightlevel; } return min;}//// EVENTS// Events are operations triggered by using, crossing,// or shooting special lines, or by timed thinkers.////// P_CrossSpecialLine - TRIGGER// Called every time a thing origin is about// to cross a line with a non 0 special.//voidP_CrossSpecialLine( int linenum, int side, mobj_t* thing ){ line_t* line; int ok; line = &lines[linenum]; // Triggers that other things can activate if (!thing->player) { // Things that should NOT trigger specials... switch(thing->type) { case MT_ROCKET: case MT_PLASMA: case MT_BFG: case MT_TROOPSHOT: case MT_HEADSHOT: case MT_BRUISERSHOT: return; break; default: break; } ok = 0; switch(line->special) { case 39: // TELEPORT TRIGGER case 97: // TELEPORT RETRIGGER case 125: // TELEPORT MONSTERONLY TRIGGER case 126: // TELEPORT MONSTERONLY RETRIGGER case 4: // RAISE DOOR case 10: // PLAT DOWN-WAIT-UP-STAY TRIGGER case 88: // PLAT DOWN-WAIT-UP-STAY RETRIGGER ok = 1; break; } if (!ok) return; } // Note: could use some const's here. switch (line->special) { // TRIGGERS. // All from here to RETRIGGERS. case 2: // Open Door EV_DoDoor(line,open); line->special = 0; break; case 3: // Close Door EV_DoDoor(line,close); line->special = 0; break; case 4: // Raise Door EV_DoDoor(line,normal); line->special = 0; break; case 5: // Raise Floor EV_DoFloor(line,raiseFloor); line->special = 0; break; case 6: // Fast Ceiling Crush & Raise EV_DoCeiling(line,fastCrushAndRaise); line->special = 0; break; case 8: // Build Stairs EV_BuildStairs(line,build8); line->special = 0; break; case 10: // PlatDownWaitUp EV_DoPlat(line,downWaitUpStay,0); line->special = 0; break; case 12: // Light Turn On - brightest near EV_LightTurnOn(line,0); line->special = 0; break; case 13: // Light Turn On 255 EV_LightTurnOn(line,255); line->special = 0; break; case 16: // Close Door 30 EV_DoDoor(line,close30ThenOpen); line->special = 0; break; case 17: // Start Light Strobing EV_StartLightStrobing(line); line->special = 0; break; case 19: // Lower Floor EV_DoFloor(line,lowerFloor); line->special = 0; break; case 22: // Raise floor to nearest height and change texture EV_DoPlat(line,raiseToNearestAndChange,0); line->special = 0; break; case 25: // Ceiling Crush and Raise EV_DoCeiling(line,crushAndRaise); line->special = 0; break; case 30: // Raise floor to shortest texture height // on either side of lines. EV_DoFloor(line,raiseToTexture); line->special = 0; break; case 35: // Lights Very Dark EV_LightTurnOn(line,35); line->special = 0; break; case 36: // Lower Floor (TURBO) EV_DoFloor(line,turboLower); line->special = 0; break; case 37: // LowerAndChange EV_DoFloor(line,lowerAndChange); line->special = 0; break; case 38: // Lower Floor To Lowest EV_DoFloor( line, lowerFloorToLowest ); line->special = 0; break; case 39: // TELEPORT! EV_Teleport( line, side, thing ); line->special = 0; break; case 40: // RaiseCeilingLowerFloor EV_DoCeiling( line, raiseToHighest ); EV_DoFloor( line, lowerFloorToLowest ); line->special = 0; break; case 44: // Ceiling Crush EV_DoCeiling( line, lowerAndCrush ); line->special = 0; break; case 52:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -