//************************************************************************** //** //** p_anim.c : Heretic 2 : Raven Software, Corp. //** //** $RCSfile: p_anim.c,v $ //** $Revision: 1.9 $ //** $Date: 95/07/17 18:50:37 $ //** $Author: bgokey $ //** //************************************************************************** // HEADER FILES ------------------------------------------------------------ #include "h2def.h" #include "p_local.h" // MACROS ------------------------------------------------------------------ #define ANIM_SCRIPT_NAME "ANIMDEFS" #define MAX_ANIM_DEFS 20 #define MAX_FRAME_DEFS 96 #define ANIM_FLAT 0 #define ANIM_TEXTURE 1 #define SCI_FLAT "flat" #define SCI_TEXTURE "texture" #define SCI_PIC "pic" #define SCI_TICS "tics" #define SCI_RAND "rand" #define LIGHTNING_SPECIAL 198 #define LIGHTNING_SPECIAL2 199 #define SKYCHANGE_SPECIAL 200 // TYPES ------------------------------------------------------------------- typedef struct { int index; int tics; } frameDef_t; typedef struct { int type; int index; int tics; int currentFrameDef; int startFrameDef; int endFrameDef; } animDef_t; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static void P_LightningFlash(void); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern fixed_t Sky1ColumnOffset; extern fixed_t Sky2ColumnOffset; extern int Sky1Texture; extern boolean DoubleSky; // PUBLIC DATA DEFINITIONS ------------------------------------------------- fixed_t Sky1ScrollDelta; fixed_t Sky2ScrollDelta; // PRIVATE DATA DEFINITIONS ------------------------------------------------ static animDef_t AnimDefs[MAX_ANIM_DEFS]; static frameDef_t FrameDefs[MAX_FRAME_DEFS]; static int AnimDefCount; static boolean LevelHasLightning; static int NextLightningFlash; static int LightningFlash; static int *LightningLightLevels; // CODE -------------------------------------------------------------------- //========================================================================== // // P_AnimateSurfaces // //========================================================================== void P_AnimateSurfaces(void) { int i; animDef_t *ad; line_t *line; // Animate flats and textures for(i = 0; i < AnimDefCount; i++) { ad = &AnimDefs[i]; ad->tics--; if(ad->tics == 0) { if(ad->currentFrameDef == ad->endFrameDef) { ad->currentFrameDef = ad->startFrameDef; } else { ad->currentFrameDef++; } ad->tics = FrameDefs[ad->currentFrameDef].tics; if(ad->tics > 255) { // Random tics ad->tics = (ad->tics>>16) +P_Random()%((ad->tics&0xff00)>>8); } if(ad->type == ANIM_FLAT) { flattranslation[ad->index] = FrameDefs[ad->currentFrameDef].index; } else { // Texture texturetranslation[ad->index] = FrameDefs[ad->currentFrameDef].index; } } } // Update scrolling textures for(i = 0; i < numlinespecials; i++) { line = linespeciallist[i]; switch(line->special) { case 100: // Scroll_Texture_Left sides[line->sidenum[0]].textureoffset += line->arg1<<10; break; case 101: // Scroll_Texture_Right sides[line->sidenum[0]].textureoffset -= line->arg1<<10; break; case 102: // Scroll_Texture_Up sides[line->sidenum[0]].rowoffset += line->arg1<<10; break; case 103: // Scroll_Texture_Down sides[line->sidenum[0]].rowoffset -= line->arg1<<10; break; } } // Update sky column offsets Sky1ColumnOffset += Sky1ScrollDelta; Sky2ColumnOffset += Sky2ScrollDelta; if(LevelHasLightning) { if(!NextLightningFlash || LightningFlash) { P_LightningFlash(); } else { NextLightningFlash--; } } } //========================================================================== // // P_LightningFlash // //========================================================================== static void P_LightningFlash(void) { int i; sector_t *tempSec; int *tempLight; boolean foundSec; int flashLight; if(LightningFlash) { LightningFlash--; if(LightningFlash) { tempLight = LightningLightLevels; tempSec = sectors; for(i = 0; i < numsectors; i++, tempSec++) { if(tempSec->ceilingpic == skyflatnum || tempSec->special == LIGHTNING_SPECIAL || tempSec->special == LIGHTNING_SPECIAL2) { if(*tempLight < tempSec->lightlevel-4) { tempSec->lightlevel -= 4; } tempLight++; } } } else { // remove the alternate lightning flash special tempLight = LightningLightLevels; tempSec = sectors; for(i = 0; i < numsectors; i++, tempSec++) { if(tempSec->ceilingpic == skyflatnum || tempSec->special == LIGHTNING_SPECIAL || tempSec->special == LIGHTNING_SPECIAL2) { tempSec->lightlevel = *tempLight; tempLight++; } } Sky1Texture = P_GetMapSky1Texture(gamemap); } return; } LightningFlash = (P_Random()&7)+8; flashLight = 200+(P_Random()&31); tempSec = sectors; tempLight = LightningLightLevels; foundSec = false; for(i = 0; i < numsectors; i++, tempSec++) { if(tempSec->ceilingpic == skyflatnum || tempSec->special == LIGHTNING_SPECIAL || tempSec->special == LIGHTNING_SPECIAL2) { *tempLight = tempSec->lightlevel; if(tempSec->special == LIGHTNING_SPECIAL) { tempSec->lightlevel += 64; if(tempSec->lightlevel > flashLight) { tempSec->lightlevel = flashLight; } } else if(tempSec->special == LIGHTNING_SPECIAL2) { tempSec->lightlevel += 32; if(tempSec->lightlevel > flashLight) { tempSec->lightlevel = flashLight; } } else { tempSec->lightlevel = flashLight; } if(tempSec->lightlevel < *tempLight) { tempSec->lightlevel = *tempLight; } tempLight++; foundSec = true; } } if(foundSec) { Sky1Texture = P_GetMapSky2Texture(gamemap); // set alternate sky S_StartSound(NULL, SFX_THUNDER_CRASH); } // Calculate the next lighting flash if(!NextLightningFlash) { if(P_Random() < 50) { // Immediate Quick flash NextLightningFlash = (P_Random()&15)+16; } else { if(P_Random() < 128 && !(leveltime&32)) { NextLightningFlash = ((P_Random()&7)+2)*35; } else { NextLightningFlash = ((P_Random()&15)+5)*35; } } } } //========================================================================== // // P_ForceLightning // //========================================================================== void P_ForceLightning(void) { NextLightningFlash = 0; } //========================================================================== // // P_InitLightning // //========================================================================== void P_InitLightning(void) { int i; int secCount; if(!P_GetMapLightning(gamemap)) { LevelHasLightning = false; LightningFlash = 0; return; } LightningFlash = 0; secCount = 0; for(i = 0; i < numsectors; i++) { if(sectors[i].ceilingpic == skyflatnum || sectors[i].special == LIGHTNING_SPECIAL || sectors[i].special == LIGHTNING_SPECIAL2) { secCount++; } } if(secCount) { LevelHasLightning = true; } else { LevelHasLightning = false; return; } LightningLightLevels = (int *)Z_Malloc(secCount*sizeof(int), PU_LEVEL, NULL); NextLightningFlash = ((P_Random()&15)+5)*35; // don't flash at level start } //========================================================================== // // P_InitFTAnims // // Initialize flat and texture animation lists. // //========================================================================== void P_InitFTAnims(void) { int base; int mod; int fd; animDef_t *ad; boolean ignore; boolean done; fd = 0; ad = AnimDefs; AnimDefCount = 0; SC_Open(ANIM_SCRIPT_NAME); while(SC_GetString()) { if(AnimDefCount == MAX_ANIM_DEFS) { I_Error("P_InitFTAnims: too many AnimDefs."); } if(SC_Compare(SCI_FLAT)) { ad->type = ANIM_FLAT; } else if(SC_Compare(SCI_TEXTURE)) { ad->type = ANIM_TEXTURE; } else { SC_ScriptError(NULL); } SC_MustGetString(); // Name ignore = false; if(ad->type == ANIM_FLAT) { if(W_CheckNumForName(sc_String) == -1) { ignore = true; } else { ad->index = R_FlatNumForName(sc_String); } } else { // Texture if(R_CheckTextureNumForName(sc_String) == -1) { ignore = true; } else { ad->index = R_TextureNumForName(sc_String); } } ad->startFrameDef = fd; done = false; while(done == false) { if(SC_GetString()) { if(SC_Compare(SCI_PIC)) { if(fd == MAX_FRAME_DEFS) { I_Error("P_InitFTAnims: too many FrameDefs."); } SC_MustGetNumber(); if(ignore == false) { FrameDefs[fd].index = ad->index+sc_Number-1; } SC_MustGetString(); if(SC_Compare(SCI_TICS)) { SC_MustGetNumber(); if(ignore == false) { FrameDefs[fd].tics = sc_Number; fd++; } } else if(SC_Compare(SCI_RAND)) { SC_MustGetNumber(); base = sc_Number; SC_MustGetNumber(); if(ignore == false) { mod = sc_Number-base+1; FrameDefs[fd].tics = (base<<16)+(mod<<8); fd++; } } else { SC_ScriptError(NULL); } } else { SC_UnGet(); done = true; } } else { done = true; } } if((ignore == false) && (fd-ad->startFrameDef < 2)) { I_Error("P_InitFTAnims: AnimDef has framecount < 2."); } if(ignore == false) { ad->endFrameDef = fd-1; ad->currentFrameDef = ad->endFrameDef; ad->tics = 1; // Force 1st game tic to animate AnimDefCount++; ad++; } } SC_Close(); }