// // EV_ClearForceFields // // villsa [STRIFE] new function // boolean EV_ClearForceFields(line_t* line) { int secnum; sector_t* sec; int i; line_t* secline; boolean ret = false; secnum = -1; while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; line->special = 0; ret = true; // haleyjd 09/18/10: fixed to continue w/linecount == 0, not return for(i = 0; i < sec->linecount; i++) { secline = sec->lines[i]; if(!(secline->flags & ML_TWOSIDED)) continue; if(secline->special != 148) continue; secline->flags &= ~ML_BLOCKING; secline->special = 0; sides[secline->sidenum[0]].midtexture = 0; sides[secline->sidenum[1]].midtexture = 0; } } return ret; }
// // TURN LINE'S TAG LIGHTS ON // void EV_LightTurnOn(line_t *line, int bright) { int i; int j; sector_t *sector; sector_t *temp; line_t *templine; for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) { sector = sectors + i; // bright = 0 means to search // for highest light level // surrounding sector if (!bright) { for (j = 0; j < sector->linecount; j++) { templine = sector->lines[j]; temp = getNextSector(templine, sector); if (!temp) continue; if (temp->lightlevel > bright) bright = temp->lightlevel; } } sector-> lightlevel = bright; } }
// // EV_LightTurnOn() // // Turn sectors tagged to line lights on to specified or max neighbor level // // Passed the activating line, and a level to set the light to // If level passed is 0, the maximum neighbor lighting is used // Returns true // // jff 2/12/98 added int return value, fixed return // int EV_LightTurnOn(line_t *line, int bright) { int i; // search all sectors for ones with same tag as activating line // killough 10/98: replace inefficient search with fast search for (i = -1; (i = P_FindSectorFromLineTag(line,i)) >= 0;) { sector_t *temp, *sector = sectors+i; int j, tbright = bright; //jff 5/17/98 search for maximum PER sector // bright = 0 means to search for highest light level surrounding sector if (!bright) for (j = 0;j < sector->linecount; j++) if ((temp = getNextSector(sector->lines[j],sector)) && temp->lightlevel > tbright) tbright = temp->lightlevel; sector->lightlevel = tbright; //jff 5/17/98 unless compatibility optioned //then maximum near ANY tagged sector if (compatibility) bright = tbright; } return 1; }
// // TURN LINE'S TAG LIGHTS OFF // void EV_TurnTagLightsOff(line_t *line) { int i; int j; int min; sector_t *sector; sector_t *tsec; line_t *templine; for (j = -1; (j = P_FindSectorFromLineTag(line, j)) >= 0;) { sector = sectors + j; min = sector->lightlevel; for (i = 0; i < sector->linecount; i++) { templine = sector->lines[i]; tsec = getNextSector(templine, sector); if (!tsec) continue; if (tsec->lightlevel < min) min = tsec->lightlevel; } sector->lightlevel = min; } }
// // Special Stuff that can not be categorized // int EV_DoDonut(line_t* line) { sector_t* s1; sector_t* s2; sector_t* s3; int secnum; int rtn; int i; floormove_t* floor; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { s1 = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (s1->specialdata) continue; rtn = 1; s2 = getNextSector(s1->lines[0],s1); for (i = 0;i < s2->linecount;i++) { //isn't this always false? /*if ((!s2->lines[i]->flags & ML_TWOSIDED) || (s2->lines[i]->backsector == s1)) continue;*/ s3 = s2->lines[i]->backsector; // Spawn rising slime floor = (floormove_t*)malloc (sizeof(*floor)); P_AddThinker (&floor->thinker); s2->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->type = donutRaise; floor->crush = false; floor->direction = Direction::UP; floor->sector = s2; floor->speed = FLOORSPEED / 2; floor->texture = s3->floorpic; floor->newspecial = 0; floor->floordestheight = s3->floorheight; // Spawn lowering donut-hole floor = (floormove_t*)malloc (sizeof(*floor)); P_AddThinker (&floor->thinker); s1->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->type = lowerFloor; floor->crush = false; floor->direction = Direction::DOWN; floor->sector = s1; floor->speed = FLOORSPEED / 2; floor->floordestheight = s3->floorheight; break; } } return rtn; }
int P_DoSectorLightChange(line_t* line, short tag) { int j = 0; int ptr1 = 0; int ptr2 = 0; sector_t* sec1; sector_t* sec2; int secnum; int rtn; secnum = P_FindSectorFromTag(tag); if(secnum == -1) { return 0; } sec2 = §ors[secnum]; secnum = -1; rtn = 0; while((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec1 = §ors[secnum]; rtn = 1; for(j = 0; j < 5; j++) { ptr1 = (sec1->colors[j]); ptr2 = (sec2->colors[j]); P_UpdateLightThinker(&lights[ptr1], &lights[ptr2]); } } return 1; }
int EV_LightTurnOnPartway(line_t *line, fixed_t level) { int i; if (level < 0) // clip at extremes level = 0; if (level > FRACUNIT) level = FRACUNIT; // search all sectors for ones with same tag as activating line for (i = -1; (i = P_FindSectorFromLineTag(line,i)) >= 0;) { sector_t *temp, *sector = sectors+i; int j, bright = 0, min = sector->lightlevel; for (j = 0; j < sector->linecount; j++) if ((temp = getNextSector(sector->lines[j],sector))) { if (temp->lightlevel > bright) bright = temp->lightlevel; if (temp->lightlevel < min) min = temp->lightlevel; } sector->lightlevel = // Set level in-between extremes (level * bright + (FRACUNIT-level) * min) >> FRACBITS; } return 1; }
int EV_LightTurnOn(line_t *line, int bright) { int i; for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) { sector_t *temp, *sector = sectors + i; int j, tbright = bright; if (!bright) { for (j = 0;j < sector->linecount; j++) { if ((temp = getNextSector(sector->lines[j],sector)) && temp->lightlevel > tbright) tbright = temp->lightlevel; } sector->lightlevel = tbright; } } return 1; }
int EV_TurnTagLightsOff(line_t *line) { int j; for (j = -1; (j = P_FindSectorFromLineTag(line,j)) >= 0;) { sector_t *sector = sectors + j, *tsec; int i, min = sector->lightlevel; for (i = 0;i < sector->linecount; i++) { if ((tsec = getNextSector(sector->lines[i], sector)) && tsec->lightlevel < min) min = tsec->lightlevel; } sector->lightlevel = min; } return 1; }
// // EV_RemoteSlidingDoor // // villsa [STRIFE] new function // int EV_RemoteSlidingDoor(line_t* line, mobj_t* thing) { int secnum; sector_t* sec; int i; int rtn; line_t* secline; secnum = -1; rtn = 0; while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if(sec->specialdata) continue; for(i = 0; i < 4; i++) { secline = sec->lines[i]; if(P_FindSlidingDoorType(secline) < 0) continue; EV_SlidingDoor(secline, thing); rtn = 1; } } return rtn; }
int EV_DoDoor(line_t * line, vldoor_e type, fixed_t speed) { int secnum; int retcode; sector_t *sec; vldoor_t *door; secnum = -1; retcode = 0; while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) { continue; } // Add new door thinker retcode = 1; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; door->thinker.function = T_VerticalDoor; door->sector = sec; switch (type) { case close: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4 * FRACUNIT; door->direction = -1; S_StartSound(&door->sector->soundorg, sfx_doropn); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; S_StartSound(&door->sector->soundorg, sfx_doropn); break; case normal: case open: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4 * FRACUNIT; if (door->topheight != sec->ceilingheight) { S_StartSound(&door->sector->soundorg, sfx_doropn); } break; default: break; } door->type = type; door->speed = speed; door->topwait = VDOORWAIT; } return (retcode); }
void EV_StartLightStrobing(line_t* line) { int secnum; sector_t* sec; secnum = -1; while((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if(sec->specialdata) { continue; } P_SpawnStrobeFlash(sec, SLOWDARK); } }
// // EV_StartLightStrobing() // // Start strobing lights (usually from a trigger) // // Passed the line that activated the strobing // Returns true // // jff 2/12/98 added int return value, fixed return // int EV_StartLightStrobing(line_t* line) { int secnum; sector_t* sec; secnum = -1; // start lights strobing in all sectors tagged same as line while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // if already doing a lighting function, don't start a second if (P_SectorActive(lighting_special,sec)) //jff 2/22/98 continue; P_SpawnStrobeFlash (sec,SLOWDARK, 0); } return 1; }
// // EV_TurnTagLightsOff() // // Turn line's tagged sector's lights to min adjacent neighbor level // // Passed the line that activated the lights being turned off // Returns true // // jff 2/12/98 added int return value, fixed return // int EV_TurnTagLightsOff(line_t* line) { int j; // search sectors for those with same tag as activating line // killough 10/98: replaced inefficient search with fast search for (j = -1; (j = P_FindSectorFromLineTag(line,j)) >= 0;) { sector_t *sector = sectors + j, *tsec; int i, min = sector->lightlevel; // find min neighbor light level for (i = 0;i < sector->linecount; i++) if ((tsec = getNextSector(sector->lines[i], sector)) && tsec->lightlevel < min) min = tsec->lightlevel; sector->lightlevel = min; } return 1; }
int EV_StartLightStrobing(line_t *line) { int secnum = -1; sector_t* sec; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (P_SectorActive(lighting_special,sec)) continue; P_SpawnStrobeFlash (sec,SLOWDARK, 0); } return 1; }
int EV_LightTurnOnPartway(line_t *line, fixed_t level) { int i; if (level < 0) level = 0; if (level > FRACUNIT) level = FRACUNIT; for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) { sector_t *temp, *sector = sectors + i; int j, bright = 0, min = sector->lightlevel; for (j = 0; j < sector->linecount; j++) { if ((temp = getNextSector(sector->lines[j], sector))) { if (temp->lightlevel > bright) bright = temp->lightlevel; if (temp->lightlevel < min) min = temp->lightlevel; } } sector->lightlevel = (level * bright + (FRACUNIT-level) * min) >> FRACBITS; } return 1; }
// // TURN LINE'S TAG LIGHTS OFF // int EV_TurnTagLightsOff(line_t *line) { int i; // search sectors for those with same tag as activating line // killough 10/98: replaced inefficient search with fast search for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) { sector_t *temp; sector_t *sector = sectors + i; int j; int min = sector->lightlevel; // find min neighbor light level for (j = 0; j < sector->linecount; j++) if ((temp = getNextSector(sector->lines[j], sector)) && temp->lightlevel < min) min = temp->lightlevel; sector->lightlevel = min; } return 1; }
//================================================================== // // Do Platforms // "amount" is only used for SOME platforms. // //================================================================== int EV_DoPlat(line_t * line, plattype_e type, int amount) { plat_t *plat; int secnum; int rtn; sector_t *sec; secnum = -1; rtn = 0; // // Activate all <type> plats that are in_stasis // switch (type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // // Find lowest & highest floors around sector // rtn = 1; plat = Z_Malloc(sizeof(*plat), PU_LEVSPEC, 0); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->specialdata = plat; plat->thinker.function = T_PlatRaise; plat->crush = false; plat->tag = line->tag; switch (type) { case raiseToNearestAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->wait = 0; plat->status = up; sec->special = 0; // NO MORE DAMAGE, IF APPLICABLE S_StartSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound(&sec->soundorg, sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35 * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if (plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = 35 * PLATWAIT; plat->status = P_Random() & 1; S_StartSound(&sec->soundorg, sfx_pstart); break; } P_AddActivePlat(plat); } return rtn; }
// // EV_DoCeiling // Move a ceiling up/down and all around! // int EV_DoCeiling ( line_t* line, ceiling_e type ) { int secnum; int rtn; sector_t* sec; ceiling_t* ceiling; secnum = -1; rtn = 0; // Reactivate in-stasis ceilings...for certain types. switch(type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: P_ActivateInStasisCeiling(line); default: break; } while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // new door thinker rtn = 1; ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0); P_AddThinker (&ceiling->thinker); sec->specialdata = ceiling; ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; ceiling->sector = sec; ceiling->crush = false; switch(type) { case fastCrushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); ceiling->direction = -1; ceiling->speed = CEILSPEED * 2; break; case silentCrushAndRaise: case crushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if (type != lowerToFloor) ceiling->bottomheight += 8*FRACUNIT; ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; ceiling->speed = CEILSPEED; break; } ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); } return rtn; }
// // HANDLE FLOOR TYPES // int EV_DoFloor( line_t* line, floor_e floortype ) { int secnum; int rtn; int i; sector_t* sec; floormove_t* floor; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (sec->specialdata) continue; // new floor thinker rtn = 1; floor = (floormove_t *)Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker,floor); sec->specialdata = floor; floor->thinker.function = TT_MoveFloor; floor->type = floortype; floor->crush = false; switch(floortype) { case lowerFloor: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindHighestFloorSurrounding(sec); break; case lowerFloorToLowest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); break; case turboLower: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED * 4; floor->floordestheight = P_FindHighestFloorSurrounding(sec); if (floor->floordestheight != sec->floorheight) floor->floordestheight += 8*FRACUNIT; break; case raiseFloorCrush: floor->crush = true; case raiseFloor: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestCeilingSurrounding(sec); if (floor->floordestheight > sec->ceilingheight) floor->floordestheight = sec->ceilingheight; floor->floordestheight -= (8*FRACUNIT)* (floortype == raiseFloorCrush); break; case raiseFloorTurbo: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED*4; floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); break; case raiseFloorToNearest: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); break; case raiseFloor24: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; break; case raiseFloor512: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 512 * FRACUNIT; break; case raiseFloor24AndChange: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; sec->floorpic = line->frontsector->floorpic; sec->special = line->frontsector->special; break; case raiseToTexture: { int minsize = MAXINT; side_t* side; floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; for (i = 0; i < sec->linecount; i++) { if (twoSided (secnum, i) ) { side = getSide(secnum,i,0); if (side->bottomtexture >= 0) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; side = getSide(secnum,i,1); if (side->bottomtexture >= 0) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; } } floor->floordestheight = floor->sector->floorheight + minsize; } break; case lowerAndChange: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); floor->texture = sec->floorpic; for (i = 0; i < sec->linecount; i++) { if ( twoSided(secnum, i) ) { if (getSide(secnum,i,0)->sector-sectors == secnum) { sec = getSector(secnum,i,1); if (sec->floorheight == floor->floordestheight) { floor->texture = sec->floorpic; floor->newspecial = sec->special; break; } } else { sec = getSector(secnum,i,0); if (sec->floorheight == floor->floordestheight) { floor->texture = sec->floorpic; floor->newspecial = sec->special; break; } } } } default: break; } } return rtn; }
// // BUILD A STAIRCASE! // int EV_BuildStairs( line_t* line, stair_e type ) { int secnum; int height; int i; int newsecnum; int texture; int ok; int rtn; sector_t* sec; sector_t* tsec; floormove_t* floor; fixed_t stairsize = 0; fixed_t speed = 0; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (sec->specialdata) continue; // new floor thinker rtn = 1; floor = (floormove_t *)Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker, floor); sec->specialdata = floor; floor->thinker.function = TT_MoveFloor; floor->direction = 1; floor->sector = sec; switch(type) { case build8: speed = FLOORSPEED/4; stairsize = 8*FRACUNIT; break; case turbo16: speed = FLOORSPEED*4; stairsize = 16*FRACUNIT; break; } floor->speed = speed; height = sec->floorheight + stairsize; floor->floordestheight = height; texture = sec->floorpic; // Find next sector to raise // 1. Find 2-sided line with same sector side[0] // 2. Other side is the next sector to raise do { ok = 0; for (i = 0;i < sec->linecount;i++) { if ( !((sec->lines[i])->flags & ML_TWOSIDED) ) continue; tsec = (sec->lines[i])->frontsector; newsecnum = tsec-sectors; if (secnum != newsecnum) continue; tsec = (sec->lines[i])->backsector; newsecnum = tsec - sectors; if (tsec->floorpic != texture) continue; height += stairsize; if (tsec->specialdata) continue; sec = tsec; secnum = newsecnum; floor = (floormove_t *)Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker, floor); sec->specialdata = floor; floor->thinker.function = TT_MoveFloor; floor->direction = 1; floor->sector = sec; floor->speed = speed; floor->floordestheight = height; ok = 1; break; } } while(ok); } return rtn; }
// // Do Platforms // "amount" is only used for SOME platforms. // dboolean EV_DoPlat(line_t *line, plattype_e type, int amount) { plat_t *plat; int secnum = -1; dboolean rtn = false; sector_t *sec = NULL; // Activate all <type> plats that are in_stasis switch (type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; case toggleUpDn: P_ActivateInStasis(line->tag); rtn = true; break; default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = sectors + secnum; if (P_SectorActive(floor_special, sec)) continue; // Find lowest & highest floors around sector rtn = true; plat = Z_Calloc(1, sizeof(*plat), PU_LEVSPEC, NULL); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->floordata = plat; plat->thinker.function = T_PlatRaise; plat->tag = line->tag; plat->low = sec->floorheight; switch (type) { case raiseToNearestAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->status = up; sec->special = 0; S_StartSectorSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->status = up; S_StartSectorSound(&sec->soundorg, sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = MAX(sec->floorheight, P_FindHighestFloorSurrounding(sec)); plat->wait = TICRATE * PLATWAIT; plat->status = (plat_e)(M_Random() & 1); S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case toggleUpDn: // jff 3/14/98 add new type to support instant toggle plat->speed = PLATSPEED; // not used plat->wait = TICRATE * PLATWAIT; // not used plat->crush = true; // jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->low = sec->ceilingheight; plat->high = sec->floorheight; plat->status = down; break; default: break; } P_AddActivePlat(plat); } if (sec) for (int i = 0; i < sec->linecount; i++) sec->lines[i]->flags &= ~ML_SECRET; return rtn; }
// // EV_DoDoor // // Handle opening a tagged door // // Passed the line activating the door and the type of door // Returns true if a thinker created // int EV_DoDoor ( line_t* line, vldoor_e type ) { int secnum,rtn; sector_t* sec; vldoor_t* door; secnum = -1; rtn = 0; if (ProcessNoTagLines(line, &sec, &secnum)) {if (zerotag_manual) goto manual_door; else {return rtn;}};//e6y // open all doors with the same tag as the activating line while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; manual_door://e6y // if the ceiling already moving, don't start the door action if (P_SectorActive(ceiling_special,sec)) { //jff 2/22/98 if (!zerotag_manual) continue; else {return rtn;}}; //e6y // new door thinker rtn = 1; door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); memset(door, 0, sizeof(*door)); P_AddThinker (&door->thinker); sec->ceilingdata = door; //jff 2/22/98 door->thinker.function = T_VerticalDoor; door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; door->line = line; // jff 1/31/98 remember line that triggered us door->lighttag = 0; /* killough 10/98: no light effects with tagged doors */ // setup door parameters according to type of door switch(type) { case blazeClose: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; door->speed = VDOORSPEED * 4; S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdcls); break; case closeDoor: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg,sfx_dorcls); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg,sfx_dorcls); break; case blazeRaise: case blazeOpen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = VDOORSPEED * 4; if (door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdopn); break; case normal: case openDoor: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; if (door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg,sfx_doropn); break; default: break; } if (zerotag_manual) return rtn; //e6y } return rtn; }
// // EV_DoPlat // // Handle Plat linedef types // // Passed the linedef that activated the plat, the type of plat action, // and for some plat types, an amount to raise // Returns true if a thinker is started, or restarted from stasis // int EV_DoPlat ( line_t* line, plattype_e type, int amount ) { plat_t* plat; int secnum; int rtn; sector_t* sec; secnum = -1; rtn = 0; // Activate all <type> plats that are in_stasis switch(type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; case toggleUpDn: P_ActivateInStasis(line->tag); rtn=1; break; default: break; } // act on all sectors tagged the same as the activating linedef while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // don't start a second floor function if already moving if (P_SectorActive(floor_special,sec)) //jff 2/23/98 multiple thinkers continue; // Create a thinker rtn = 1; plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0); memset(plat, 0, sizeof(*plat)); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers plat->thinker.function = T_PlatRaise; plat->crush = false; plat->tag = line->tag; //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default low to plat height when triggered plat->low = sec->floorheight; // set up plat according to type switch(type) { case raiseToNearestAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec,sec->floorheight); plat->wait = 0; plat->status = up; sec->special = 0; //jff 3/14/98 clear old field as well sec->oldspecial = 0; S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount*FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if (plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = P_Random(pr_plats)&1; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case toggleUpDn: //jff 3/14/98 add new type to support instant toggle plat->speed = PLATSPEED; //not used plat->wait = 35*PLATWAIT; //not used plat->crush = true; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->low = sec->ceilingheight; plat->high = sec->floorheight; plat->status = down; break; default: break; } P_AddActivePlat(plat); // add plat to list of active plats } return rtn; }
int EV_DoDoor(line_t* line, vldoor_e type) { int secnum, rtn; sector_t* sec; vldoor_t* door; secnum = -1; rtn = 0; while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if(sec->specialdata) { continue; } // new door thinker rtn = 1; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor; door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; door->bottomheight = sec->floorheight; door->initceiling = sec->floorheight; switch(type) { case blazeClose: door->topheight = P_FindLowestCeilingSurrounding(sec) - 4*FRACUNIT; door->direction = -1; door->speed = VDOORBLAZESPEED; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_door2dwn); break; case doorclose: door->topheight = P_FindLowestCeilingSurrounding(sec) - 4*FRACUNIT; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doordown); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doordown); break; case blazeRaise: case blazeOpen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec) - 4*FRACUNIT; door->speed = VDOORBLAZESPEED; if(door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg, sfx_door2up); break; case normal: case dooropen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec) - 4*FRACUNIT; if(door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doorup); break; default: break; } } return rtn; }
// // TELEPORTATION // dboolean EV_Teleport(line_t *line, int side, mobj_t *thing) { thinker_t *thinker; int i; // Don't teleport missiles. // Don't teleport if hit back of line, so you can get out of teleporter. if (side || (thing->flags & MF_MISSILE)) return false; // killough 1/31/98: improve performance by using // P_FindSectorFromLineTag instead of simple linear search. for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) for (thinker = thinkerclasscap[th_mobj].cnext; thinker != &thinkerclasscap[th_mobj]; thinker = thinker->cnext) { mobj_t *m; if ((m = (mobj_t *)thinker)->type == MT_TELEPORTMAN && m->subsector->sector - sectors == i) { fixed_t oldx = thing->x; fixed_t oldy = thing->y; fixed_t oldz = thing->z; player_t *player = thing->player; // killough 5/12/98: exclude voodoo dolls: if (player && player->mo != thing) player = NULL; if (P_TeleportMove(thing, m->x, m->y, m->z, false)) // killough 8/9/98 { mobj_t *fog; fixed_t newx = m->x; fixed_t newy = m->y; // spawn teleport fog at source fog = P_SpawnMobj(oldx, oldy, oldz, MT_TFOG); fog->angle = thing->angle; S_StartSound(fog, sfx_telept); // spawn teleport fog at destination thing->z = thing->floorz; if (player) { unsigned int an = m->angle >> ANGLETOFINESHIFT; newx += 20 * finecosine[an]; newy += 20 * finesine[an]; player->viewz = thing->z + player->viewheight; } fog = P_SpawnMobj(newx, newy, thing->z, MT_TFOG); fog->angle = m->angle; S_StartSound(fog, sfx_telept); if (player) { // [BH] teleport can be drawn on automap if (line->backsector) { int j; for (j = 0; j < line->backsector->linecount; j++) line->backsector->lines[j]->flags |= ML_TELEPORTTRIGGERED; } // don't move for a bit thing->reactiontime = 18; player->psprites[ps_weapon].sx = 0; player->psprites[ps_weapon].sy = WEAPONTOP; player->momx = player->momy = 0; } thing->angle = m->angle; thing->momx = thing->momy = thing->momz = 0; return true; } }
// // EV_DoCeiling // // Move a ceiling up/down or start a crusher // // Passed the linedef activating the function and the type of function desired // returns true if a thinker started // int EV_DoCeiling (line_t* line, ceiling_e type) { int secnum; int rtn; sector_t* sec; ceiling_t* ceiling; secnum = -1; rtn = 0; // Reactivate in-stasis ceilings...for certain types. // This restarts a crusher after it has been stopped switch (type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: //jff 4/5/98 return if activated rtn = P_ActivateInStasisCeiling(line); default: break; } // affects all sectors with the same tag as the linedef while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; // if ceiling already moving, don't start a second function on it if (P_SectorActive(ceiling_special, sec)) //jff 2/22/98 continue; // create a new ceiling thinker rtn = 1; ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0); P_AddThinker(&ceiling->thinker); sec->ceilingdata = ceiling; //jff 2/22/98 ceiling->thinker.function = T_MoveCeiling; ceiling->sector = sec; ceiling->crush = false; // setup ceiling structure according to type of function switch (type) { case fastCrushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (8 * FRACUNIT); ceiling->direction = -1; ceiling->speed = CEILSPEED * 2; break; case silentCrushAndRaise: case crushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if (type != lowerToFloor) ceiling->bottomheight += 8 * FRACUNIT; ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; ceiling->speed = CEILSPEED; break; case lowerToLowest: ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case lowerToMaxFloor: ceiling->bottomheight = P_FindHighestFloorSurrounding(sec); ceiling->direction = -1; ceiling->speed = CEILSPEED; break; default: break; } // add the ceiling to the active list ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); } return rtn; }
int EV_DoDoor( line_t* line, vldoor_e type ) { int secnum,rtn; sector_t* sec; vldoor_t* door; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // new door thinker rtn = 1; door = (vldoor_t *)Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker, door); sec->specialdata = door; door->thinker.function = TT_VerticalDoor; door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; switch(type) { case blazeClose: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; door->speed = VDOORSPEED * 4; break; case close: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; break; case blazeRaise: case blazeOpen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = VDOORSPEED * 4; break; case normal: case open: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; break; default: break; } } return rtn; }
// // Special Stuff that can not be categorized // int EV_DoDonut(line_t* line) { sector_t* s1; sector_t* s2; sector_t* s3; int secnum; int rtn; int i; floormove_t* floor; fixed_t s3_floorheight; short s3_floorpic; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { s1 = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (s1->specialdata) continue; rtn = 1; s2 = getNextSector(s1->lines[0],s1); // Vanilla Doom does not check if the linedef is one sided. The // game does not crash, but reads invalid memory and causes the // sector floor to move "down" to some unknown height. // DOSbox prints a warning about an invalid memory access. // // I'm not sure exactly what invalid memory is being read. This // isn't something that should be done, anyway. // Just print a warning and return. if (s2 == NULL) { fprintf(stderr, "EV_DoDonut: linedef had no second sidedef! " "Unexpected behavior may occur in Vanilla Doom. \n"); break; } for (i = 0; i < s2->linecount; i++) { s3 = s2->lines[i]->backsector; if (s3 == s1) continue; if (s3 == NULL) { // e6y // s3 is NULL, so // s3->floorheight is an int at 0000:0000 // s3->floorpic is a short at 0000:0008 // Trying to emulate fprintf(stderr, "EV_DoDonut: WARNING: emulating buffer overrun due to " "NULL back sector. " "Unexpected behavior may occur in Vanilla Doom.\n"); DonutOverrun(&s3_floorheight, &s3_floorpic, line, s1); } else { s3_floorheight = s3->floorheight; s3_floorpic = s3->floorpic; } // Spawn rising slime floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker); s2->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->type = donutRaise; floor->crush = false; floor->direction = 1; floor->sector = s2; floor->speed = FLOORSPEED / 2; floor->texture = s3_floorpic; floor->newspecial = 0; floor->floordestheight = s3_floorheight; // Spawn lowering donut-hole floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker); s1->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->type = lowerFloor; floor->crush = false; floor->direction = -1; floor->sector = s1; floor->speed = FLOORSPEED / 2; floor->floordestheight = s3_floorheight; break; } } return rtn; }
int EV_DoDoor ( line_t* line, vldoor_e type ) { int secnum,rtn; sector_t* sec; vldoor_t* door; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = P_GetSector(secnum); if (sec->specialdata) continue; // new door thinker rtn = 1; door = P_NewThinker (sizeof(*door)); sec->specialdata = door; door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor; door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; switch(type) { case blazeClose: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; door->speed = VDOORSPEED * 4; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls); break; case close: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_dorcls); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_dorcls); break; case blazeRaise: case blazeOpen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = VDOORSPEED * 4; if (door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdopn); break; case normal: case open: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; if (door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn); break; default: break; } } return rtn; }