// // 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(const line_t *line, ceiling_e type) { int secnum = -1; int rtn = 0; int noise = CNOISE_NORMAL; // haleyjd 09/28/06 sector_t *sec; CeilingThinker *ceiling; // 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, line->tag); 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 = new CeilingThinker; ceiling->addThinker(); sec->ceilingdata = ceiling; //jff 2/22/98 ceiling->sector = sec; ceiling->crush = -1; ceiling->crushflags = 0; // ioanch 20160305 // setup ceiling structure according to type of function switch(type) { case fastCrushAndRaise: ceiling->crush = 10; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); ceiling->direction = plat_down; ceiling->speed = CEILSPEED * 2; break; case silentCrushAndRaise: noise = CNOISE_SEMISILENT; case crushAndRaise: ceiling->crush = 10; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if(type != lowerToFloor) ceiling->bottomheight += 8*FRACUNIT; ceiling->direction = plat_down; ceiling->speed = CEILSPEED; break; case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = plat_up; ceiling->speed = CEILSPEED; break; case lowerToLowest: ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); ceiling->direction = plat_down; ceiling->speed = CEILSPEED; break; case lowerToMaxFloor: ceiling->bottomheight = P_FindHighestFloorSurrounding(sec); ceiling->direction = plat_down; ceiling->speed = CEILSPEED; break; default: break; } // add the ceiling to the active list ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); // haleyjd 09/28/06: sound sequences P_CeilingSequence(ceiling->sector, noise); } return rtn; }
//================================================================== // // EV_VerticalDoor : open a door manually, no tag value // //================================================================== boolean EV_VerticalDoor(line_t * line, mobj_t * thing) { sector_t *sec; vldoor_t *door; int side; side = 0; // only front sides can be used // if the sector has an active thinker, use it sec = sides[line->sidenum[side ^ 1]].sector; if (sec->specialdata) { return false; /* door = sec->specialdata; switch(line->special) { // only for raise doors case 12: if(door->direction == -1) { door->direction = 1; // go back up } else { if(!thing->player) { // Monsters don't close doors return; } door->direction = -1; // start going down immediately } return; } */ } // // new door thinker // door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; door->thinker.function = T_VerticalDoor; door->sector = sec; door->direction = 1; switch (line->special) { case 11: door->type = DREV_OPEN; line->special = 0; break; case 12: case 13: door->type = DREV_NORMAL; break; default: door->type = DREV_NORMAL; break; } door->speed = line->arg2 * (FRACUNIT / 8); door->topwait = line->arg3; // // find the top and bottom of the movement range // door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4 * FRACUNIT; SN_StartSequence((mobj_t *) & door->sector->soundorg, SEQ_DOOR_STONE + door->sector->seqType); return true; }
// // EV_VerticalDoor // // Handle opening a door manually, no tag value // // Passed the line activating the door and the thing activating it // Returns true if a thinker created // // jff 2/12/98 added int return value, fixed all returns // int EV_VerticalDoor(line_t *line, mobj_t *thing) { player_t *player; sector_t *sec; vldoor_t *door; // Check for locks player = thing->player; switch(line->special) { case 26: // Blue Lock case 32: if (!player) return 0; if (!player->cards[it_bluecard] && !player->cards[it_blueskull]) { P_Echo(consoleplayer, s_PD_BLUEK); // Ty 03/27/98 - externalized S_StartSound(player->mo, sfx_oof); // killough 3/20/98 return 0; } break; case 27: // Yellow Lock case 34: if (!player) return 0; if (!player->cards[it_yellowcard] && !player->cards[it_yellowskull]) { P_Echo(consoleplayer, s_PD_YELLOWK); // Ty 03/27/98 - externalized S_StartSound(player->mo, sfx_oof); // killough 3/20/98 return 0; } break; case 28: // Red Lock case 33: if (!player) return 0; if (!player->cards[it_redcard] && !player->cards[it_redskull]) { P_Echo(consoleplayer, s_PD_REDK); // Ty 03/27/98 - externalized S_StartSound(player->mo, sfx_oof); // killough 3/20/98 return 0; } break; } // if the wrong side of door is pushed, give oof sound if (line->sidenum[1] == NO_INDEX) { // killough S_StartSound(player->mo, sfx_oof); // killough 3/20/98 return 0; } // get the sector on the second side of activating linedef sec = sides[line->sidenum[1]].sector; /* if door already has a thinker, use it * cph 2001/04/05 - * Ok, this is a disaster area. We're assuming that sec->ceilingdata * is a vldoor_t! What if this door is controlled by both DR lines * and by switches? I don't know how to fix that. * Secondly, original Doom didn't distinguish floor/lighting/ceiling * actions, so we need to do the same in demo compatibility mode. */ door = sec->ceilingdata; if (demo_compatibility) { if (!door) door = sec->floordata; if (!door) door = sec->lightingdata; } /* If this is a repeatable line, and the door is already moving, then we can * just reverse the current action. Note that in prboom 2.3.0 I erroneously * removed the if-this-is-repeatable check, hence the prboom_4_compatibility * clause below (foolishly assumed that already moving implies repeatable - * but it could be moving due to another switch, e.g. lv19-509) */ if (door && ((compatibility_level == prboom_4_compatibility) || (line->special == 1) || (line->special == 117) || (line->special == 26) || (line->special == 27) || (line->special == 28))) { /* For old demos we have to emulate the old buggy behavior and * mess up non-T_VerticalDoor actions. */ if (compatibility_level < prboom_4_compatibility || door->thinker.function == T_VerticalDoor) { /* cph - we are writing outval to door->direction iff it is non-zero */ signed int outval = 0; /* An already moving repeatable door which is being re-pressed, or a * monster is trying to open a closing door - so change direction * DEMOSYNC: we only read door->direction now if it really is a door. */ if (door->thinker.function == T_VerticalDoor && door->direction == -1) outval = 1; /* go back up */ else if (player) outval = -1; /* go back down */ /* Write this to the thinker. In demo compatibility mode, we might be * overwriting a field of a non-vldoor_t thinker - we need to add any * other thinker types here if any demos depend on specific fields * being corrupted by this. */ if (outval) { if (door->thinker.function == T_VerticalDoor) { door->direction = outval; } else if (door->thinker.function == T_PlatRaise) { plat_t* p = (plat_t*)door; p->wait = outval; } else { lprintf(LO_DEBUG, "EV_VerticalDoor: unknown thinker.function in thinker corruption " "emulation" ); } return 1; } } /* Either we're in prboom >=v2.3 and it's not a door, or it's a door but * we're a monster and don't want to shut it; exit with no action. */ return 0; } // emit proper sound switch(line->special) { case 117: // blazing door raise case 118: // blazing door open S_StartSound((mobj_t *)&sec->soundorg, sfx_bdopn); break; default: // normal or locked door sound S_StartSound((mobj_t *)&sec->soundorg, sfx_doropn); break; } // new door thinker 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->direction = 1; door->speed = VDOORSPEED; door->topwait = VDOORWAIT; door->line = line; // jff 1/31/98 remember line that triggered us /* killough 10/98: use gradual lighting changes if nonzero tag given */ door->lighttag = comp[comp_doorlight] ? 0 : line->tag; // set the type of door from the activating linedef type switch(line->special) { case 1: case 26: case 27: case 28: door->type = normal; break; case 31: case 32: case 33: case 34: door->type = openDoor; line->special = 0; break; case 117: // blazing door raise door->type = blazeRaise; door->speed = VDOORSPEED*4; break; case 118: // blazing door open door->type = blazeOpen; line->special = 0; door->speed = VDOORSPEED*4; break; default: door->lighttag = 0; // killough 10/98 break; } // find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4 * FRACUNIT; return 1; }
// // 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 = 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; R_SoundNumForDoor(door); // villsa [STRIFE] set door sounds switch(type) { // villsa [STRIFE] new door type case splitOpen: door->direction = -2; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = FRACUNIT; // yes, it using topwait to get the floor height door->topwait = P_FindLowestFloorSurrounding(sec); if(door->topheight == sec->ceilingheight) continue; S_StartSound(&sec->soundorg, door->opensound); break; // villsa [STRIFE] new door type case splitRaiseNearest: door->direction = -2; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = FRACUNIT; // yes, it using topwait to get the floor height door->topwait = P_FindHighestFloorSurrounding(sec); if(door->topheight == sec->ceilingheight) continue; S_StartSound(&sec->soundorg, door->opensound); break; case blazeClose: case shopClose: // villsa [STRIFE] door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; door->speed = VDOORSPEED * 4; S_StartSound(&door->sector->soundorg, sfx_bdcls); break; case close: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; // villsa [STRIFE] set door sounds S_StartSound(&door->sector->soundorg, door->opensound); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; // villsa [STRIFE] set door sounds S_StartSound(&door->sector->soundorg, door->closesound); 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(&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(&door->sector->soundorg, door->opensound); break; default: break; } } 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; int 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; }
DPlat::DPlat(sector_t *sec, DPlat::EPlatType type, fixed_t height, int speed, int delay, fixed_t lip) : DMovingFloor(sec), m_Status(init) { m_Type = type; m_Crush = false; m_Speed = speed; m_Wait = delay; m_Height = height; m_Lip = lip; //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default lower to plat height when triggered m_Low = P_FloorHeight(sec); switch (type) { case DPlat::platRaiseAndStay: m_High = P_FindNextHighestFloor(sec); m_Status = DPlat::midup; PlayPlatSound(); break; case DPlat::platUpByValue: case DPlat::platUpByValueStay: m_High = P_FloorHeight(sec) + height; m_Status = DPlat::midup; PlayPlatSound(); break; case DPlat::platDownByValue: m_Low = P_FloorHeight(sec) - height; m_Status = DPlat::middown; PlayPlatSound(); break; case DPlat::platDownWaitUpStay: m_Low = P_FindLowestFloorSurrounding(sec) + lip; if (m_Low > P_FloorHeight(sec)) m_Low = P_FloorHeight(sec); m_High = P_FloorHeight(sec); m_Status = DPlat::down; PlayPlatSound(); break; case DPlat::platUpWaitDownStay: m_High = P_FindHighestFloorSurrounding(sec); if (m_High < P_FloorHeight(sec)) m_High = P_FloorHeight(sec); m_Status = DPlat::up; PlayPlatSound(); break; case DPlat::platPerpetualRaise: m_Low = P_FindLowestFloorSurrounding(sec) + lip; if (m_Low > P_FloorHeight(sec)) m_Low = P_FloorHeight(sec); m_High = P_FindHighestFloorSurrounding (sec); if (m_High < P_FloorHeight(sec)) m_High = P_FloorHeight(sec); m_Status = P_Random () & 1 ? DPlat::down : DPlat::up; PlayPlatSound(); break; case DPlat::platToggle: //jff 3/14/98 add new type to support instant toggle m_Crush = false; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive m_Low = P_CeilingHeight(sec); m_High = P_FloorHeight(sec); m_Status = DPlat::down; // SN_StartSequence (sec, "Silence"); break; case DPlat::platDownToNearestFloor: m_Low = P_FindNextLowestFloor(sec) + lip; m_Status = DPlat::down; m_High = P_FloorHeight(sec); PlayPlatSound(); break; case DPlat::platDownToLowestCeiling: m_Low = P_FindLowestCeilingSurrounding (sec); m_High = P_FloorHeight(sec); if (m_Low > P_FloorHeight(sec)) m_Low = P_FloorHeight(sec); m_Status = DPlat::down; PlayPlatSound(); break; default: break; } }
// // EV_VerticalDoor // Open a door manually, no tag value // void EV_VerticalDoor(line_t *line, mobj_t *thing) { player_t *player = thing->player; sector_t *sec; vldoor_t *door; int i; switch (line->special) { case DR_OpenDoorWait4SecondsCloseBlueKeyRequired: case D1_OpenDoorStayOpenBlueKeyRequired: if (!player) return; if (player->cards[it_bluecard] <= 0 && player->cards[it_blueskull] <= 0) { if (player->cards[it_bluecard] == CARDNOTFOUNDYET) { if (!player->neededcardtics || player->neededcard != it_bluecard) { player->neededcard = it_bluecard; player->neededcardtics = NEEDEDCARDTICS; } player->message = s_PD_BLUEK; } else { if (!player->neededcardtics || player->neededcard != it_blueskull) { player->neededcard = it_blueskull; player->neededcardtics = NEEDEDCARDTICS; } player->message = s_PD_BLUEK2; } S_StartSound(player->mo, sfx_noway); return; } break; case DR_OpenDoorWait4SecondsCloseYellowKeyRequired: case D1_OpenDoorStayOpenYellowKeyRequired: if (!player) return; if (player->cards[it_yellowcard] <= 0 && player->cards[it_yellowskull] <= 0) { if (player->cards[it_yellowcard] == CARDNOTFOUNDYET) { if (!player->neededcardtics || player->neededcard != it_yellowcard) { player->neededcard = it_yellowcard; player->neededcardtics = NEEDEDCARDTICS; } player->message = s_PD_YELLOWK; } else { if (!player->neededcardtics || player->neededcard != it_yellowskull) { player->neededcard = it_yellowskull; player->neededcardtics = NEEDEDCARDTICS; } player->message = s_PD_YELLOWK2; } S_StartSound(player->mo, sfx_noway); return; } break; case DR_OpenDoorWait4SecondsCloseRedKeyRequired: case D1_OpenDoorStayOpenRedKeyRequired: if (!player) return; if (player->cards[it_redcard] <= 0 && player->cards[it_redskull] <= 0) { if (player->cards[it_redcard] == CARDNOTFOUNDYET) { if (!player->neededcardtics || player->neededcard != it_redcard) { player->neededcard = it_redcard; player->neededcardtics = NEEDEDCARDTICS; } player->message = s_PD_REDK; } else { if (!player->neededcardtics || player->neededcard != it_redskull) { player->neededcard = it_redskull; player->neededcardtics = NEEDEDCARDTICS; } player->message = s_PD_REDK2; } S_StartSound(player->mo, sfx_noway); return; } break; } // if the wrong side of door is pushed, give oof sound if (line->sidenum[1] == NO_INDEX) // killough { S_StartSound(player->mo, sfx_noway); // killough 3/20/98 return; } sec = sides[line->sidenum[1]].sector; if (sec->specialdata) { door = (vldoor_t *)sec->specialdata; switch (line->special) { case DR_OpenDoorWait4SecondsClose: case DR_OpenDoorWait4SecondsCloseBlueKeyRequired: case DR_OpenDoorWait4SecondsCloseYellowKeyRequired: case DR_OpenDoorWait4SecondsCloseRedKeyRequired: case DR_OpenFastDoorWait4SecondsClose: if (door->direction == -1) { door->direction = 1; // go back up if (door->type == blazeRaise) S_StartSound(&door->sector->soundorg, sfx_bdopn); else S_StartSound(&door->sector->soundorg, sfx_doropn); } else { if (!thing->player) return; if (door->thinker.function.acp1 == T_VerticalDoor) { door->direction = -1; // start going down immediately if (door->type == blazeRaise) S_StartSound(&door->sector->soundorg, sfx_bdcls); else S_StartSound(&door->sector->soundorg, sfx_dorcls); } else if (door->thinker.function.acp1 == T_PlatRaise) { plat_t *plat = (plat_t *)door; plat->wait = -1; } else door->direction = -1; } return; } } // for proper sound switch (line->special) { case DR_OpenFastDoorWait4SecondsClose: case D1_OpenFastDoorStayOpen: S_StartSound(&sec->soundorg, sfx_bdopn); break; case DR_OpenDoorWait4SecondsClose: case D1_OpenDoorStayOpen: S_StartSound(&sec->soundorg, sfx_doropn); break; default: // LOCKED DOOR SOUND S_StartSound(&sec->soundorg, sfx_doropn); break; } // new door thinker door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; door->thinker.function.acp1 = T_VerticalDoor; door->sector = sec; door->direction = 1; door->speed = VDOORSPEED; door->topwait = VDOORWAIT; switch (line->special) { case DR_OpenDoorWait4SecondsClose: case DR_OpenDoorWait4SecondsCloseBlueKeyRequired: case DR_OpenDoorWait4SecondsCloseYellowKeyRequired: case DR_OpenDoorWait4SecondsCloseRedKeyRequired: door->type = normal; break; case D1_OpenDoorStayOpen: case D1_OpenDoorStayOpenBlueKeyRequired: case D1_OpenDoorStayOpenRedKeyRequired: case D1_OpenDoorStayOpenYellowKeyRequired: door->type = open; line->special = 0; break; case DR_OpenFastDoorWait4SecondsClose: door->type = blazeRaise; door->speed = VDOORSPEED * 4; break; case D1_OpenFastDoorStayOpen: door->type = blazeOpen; line->special = 0; door->speed = VDOORSPEED * 4; break; } // find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4 * FRACUNIT; for (i = 0; i < sec->linecount; i++) sec->lines[i]->flags &= ~ML_SECRET; }
// // EV_DoCeiling // Move a ceiling up/down and all around! // dboolean EV_DoCeiling(line_t *line, ceiling_e type) { int secnum = -1; dboolean rtn = false; sector_t *sec; ceiling_t *ceiling; // Reactivate in-stasis ceilings...for certain types. switch (type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: rtn = P_ActivateInStasisCeiling(line); default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if (P_SectorActive(ceiling_special, sec)) continue; // new door thinker rtn = true; ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0); memset(ceiling, 0, sizeof(*ceiling)); P_AddThinker(&ceiling->thinker); sec->ceilingdata = ceiling; ceiling->thinker.function = 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 && !(gamemission == doom2 && gamemap == 4 && canmodify)) 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; } ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); } return rtn; }
/*================================================================== */ void EV_VerticalDoor (line_t *line, mobj_t *thing) { player_t *player; int secnum; sector_t *sec; vldoor_t *door; int side; side = 0; /* only front sides can be used */ /* */ /* Check for locks */ /* */ player = thing->player; switch(line->special) { case 26: /* Blue Card Lock */ case 32: if ( player && !player->cards[it_bluecard] && !player->cards[it_blueskull]) { S_StartSound(thing,sfx_oof); if (player == &players[consoleplayer]) stbar.tryopen[it_bluecard] = true; return; } break; case 99: /* Blue Skull Lock */ case 106: if ( player && !player->cards[it_bluecard] && !player->cards[it_blueskull]) { S_StartSound(thing,sfx_oof); if (player == &players[consoleplayer]) stbar.tryopen[it_blueskull] = true; return; } break; case 27: /* Yellow Card Lock */ case 34: if ( player && !player->cards[it_yellowcard] && !player->cards[it_yellowskull]) { S_StartSound(thing,sfx_oof); if (player == &players[consoleplayer]) stbar.tryopen[it_yellowcard] = true; return; } break; case 105: /* Yellow Skull Lock */ case 108: if ( player && !player->cards[it_yellowcard] && !player->cards[it_yellowskull]) { S_StartSound(thing,sfx_oof); if (player == &players[consoleplayer]) stbar.tryopen[it_yellowskull] = true; return; } break; case 28: /* Red Card Lock */ case 33: if ( player && !player->cards[it_redcard] && !player->cards[it_redskull]) { S_StartSound(thing,sfx_oof); if (player == &players[consoleplayer]) stbar.tryopen[it_redcard] = true; return; } break; case 100: /* Red Skull Lock */ case 107: if ( player && !player->cards[it_redcard] && !player->cards[it_redskull]) { S_StartSound(thing,sfx_oof); if (player == &players[consoleplayer]) stbar.tryopen[it_redskull] = true; return; } break; } /* if the sector has an active thinker, use it */ sec = sides[ line->sidenum[side^1]] .sector; secnum = sec-sectors; if (sec->specialdata) { door = sec->specialdata; switch(line->special) { case 1: /* ONLY FOR "RAISE" DOORS, NOT "OPEN"s */ case 26: /* BLUE CARD */ case 27: /* YELLOW CARD */ case 28: /* RED CARD */ case 106: /* BLUE SKULL */ case 108: /* YELLOW SKULL */ case 107: /* RED SKULL */ if (door->direction == -1) door->direction = 1; /* go back up */ else { if (!thing->player) return; /* JDC: bad guys never close doors */ door->direction = -1; /* start going down immediately */ } return; } } /* for proper sound */ switch(line->special) { case 1: /* NORMAL DOOR SOUND */ case 31: S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn); break; default: /* LOCKED DOOR SOUND */ S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn); break; } /* */ /* new door thinker */ /* */ door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->thinker.function = T_VerticalDoor; door->sector = sec; door->direction = 1; switch(line->special) { case 1: case 26: case 27: case 28: door->type = normal; break; case 31: case 32: case 33: case 34: door->type = open; break; } door->speed = VDOORSPEED; door->topwait = VDOORWAIT; /* */ /* find the top and bottom of the movement range */ /* */ door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; }
// // EV_VerticalDoor // // Handle opening a door manually, no tag value // // Passed the line activating the door and the thing activating it // Returns true if a thinker created // // jff 2/12/98 added int return value, fixed all returns // int EV_VerticalDoor(line_t *line, const Mobj *thing, int lockID) { player_t *player = thing ? thing->player : nullptr; sector_t *sec; VerticalDoorThinker *door; SectorThinker *secThinker; // Check for locks if(lockID) { if(!player) return 0; if(!E_PlayerCanUnlock(player, lockID, false)) return 0; } // if the wrong side of door is pushed, give oof sound if(line->sidenum[1] == -1) // killough { if(player) S_StartSound(player->mo, GameModeInfo->playerSounds[sk_oof]); // killough 3/20/98 return 0; } // get the sector on the second side of activating linedef sec = sides[line->sidenum[1]].sector; // haleyjd: adapted cph's prboom fix for demo compatibility and // corruption of thinkers // Two bugs: // 1. DOOM used any thinker that was on a door // 2. DOOM assumed the thinker was a T_VerticalDoor thinker, and // this bug was even still in Eternity -- fixed when not in // demo_compatibility (only VerticalDoorThinker::reTriggerVerticalDoor // will actually do anything outside of demo_compatibility mode) secThinker = thinker_cast<SectorThinker *>(sec->ceilingdata); // exactly only one at most of these pointers is valid during demo_compatibility if(demo_compatibility) { if(!secThinker) secThinker = thinker_cast<SectorThinker *>(sec->floordata); if(!secThinker) secThinker = thinker_cast<SectorThinker *>(sec->lightingdata); } // if door already has a thinker, use it if(secThinker) { switch(line->special) { case 1: // only for "raise" doors, not "open"s case 26: case 27: case 28: case 117: return secThinker->reTriggerVerticalDoor(thing && thing->player); } // haleyjd 01/22/12: never start multiple thinkers on a door sector. // This bug has been here since the beginning, and got especially bad // in Strife. In Vanilla DOOM, door types 31-34 and 118 can fall through // here and cause the sector to become jammed as multiple thinkers fight // for control. if(full_demo_version >= make_full_version(340, 22)) return 0; // sector is busy. } // emit proper sound switch(line->special) { case 117: // blazing door raise case 118: // blazing door open P_DoorSequence(true, true, false, sec); // haleyjd break; default: // normal door sound P_DoorSequence(true, false, false, sec); // haleyjd break; } // new door thinker door = new VerticalDoorThinker; door->addThinker(); sec->ceilingdata = door; //jff 2/22/98 door->sector = sec; door->direction = plat_up; door->speed = VDOORSPEED; door->turbo = false; door->topwait = VDOORWAIT; // killough 10/98: use gradual lighting changes if nonzero tag given door->lighttag = comp[comp_doorlight] ? 0 : line->args[0]; // killough 10/98 // set the type of door from the activating linedef type switch(line->special) { case 1: case 26: case 27: case 28: door->type = doorNormal; break; case 31: case 32: case 33: case 34: door->type = doorOpen; line->special = 0; break; case 117: // blazing door raise door->type = blazeRaise; door->speed = VDOORSPEED*4; door->turbo = true; break; case 118: // blazing door open door->type = blazeOpen; line->special = 0; door->speed = VDOORSPEED*4; door->turbo = true; break; default: door->lighttag = 0; // killough 10/98 break; } // find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; return 1; }
// // 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(const line_t *line, vldoor_e type) { int secnum = -1, rtn = 0; sector_t *sec; VerticalDoorThinker *door; // open all doors with the same tag as the activating line while((secnum = P_FindSectorFromLineArg0(line, secnum)) >= 0) { sec = §ors[secnum]; // if the ceiling already moving, don't start the door action if(P_SectorActive(ceiling_special, sec)) //jff 2/22/98 continue; // new door thinker rtn = 1; door = new VerticalDoorThinker; door->addThinker(); sec->ceilingdata = door; //jff 2/22/98 door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; 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 = plat_down; door->speed = VDOORSPEED * 4; door->turbo = true; P_DoorSequence(false, true, false, door->sector); // haleyjd break; case doorClose: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = plat_down; door->turbo = false; P_DoorSequence(false, false, false, door->sector); // haleyjd break; case closeThenOpen: door->topheight = sec->ceilingheight; door->direction = plat_down; door->topwait = 30 * TICRATE; // haleyjd 01/16/12: set here door->turbo = false; P_DoorSequence(false, false, false, door->sector); // haleyjd break; case blazeRaise: case blazeOpen: door->direction = plat_up; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = VDOORSPEED * 4; door->turbo = true; if(door->topheight != sec->ceilingheight) P_DoorSequence(true, true, false, door->sector); // haleyjd break; case doorNormal: case doorOpen: door->direction = plat_up; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->turbo = false; if(door->topheight != sec->ceilingheight) P_DoorSequence(true, false, false, door->sector); // haleyjd break; default: break; } } return rtn; }
// // EV_VerticalDoor : open a door manually, no tag value // // [STRIFE] Tons of new door types were added. // void EV_VerticalDoor(line_t* line, mobj_t* thing) { player_t* player; sector_t* sec; vldoor_t* door; int side; side = 0; // only front sides can be used // Check for locks player = thing->player; // haleyjd 09/15/10: [STRIFE] myriad checks here... switch(line->special) { case 26: // DR ID Card door case 32: // D1 ID Card door if(!player->cards[key_IDCard]) { player->message = DEH_String("You need an id card to open this door"); S_StartSound(NULL, sfx_oof); return; } break; case 27: // DR Pass Card door case 34: // D1 Pass Card door if(!player->cards[key_Passcard]) { player->message = DEH_String("You need a pass card key to open this door"); S_StartSound(NULL, sfx_oof); return; } break; case 28: // DR ID Badge door case 33: // D1 ID Badge door if(!player->cards[key_IDBadge]) { player->message = DEH_String("You need an id badge to open this door"); S_StartSound(NULL, sfx_oof); return; } break; case 156: // D1 brass key door case 161: // DR brass key door if(!player->cards[key_BrassKey]) { player->message = DEH_String("You need a brass key"); S_StartSound(NULL, sfx_oof); return; } break; case 157: // D1 silver key door case 160: // DR silver key door if(!player->cards[key_SilverKey]) { player->message = DEH_String("You need a silver key"); S_StartSound(NULL, sfx_oof); return; } break; case 158: // D1 gold key door case 159: // DR gold key door if(!player->cards[key_GoldKey]) { player->message = DEH_String("You need a gold key"); S_StartSound(NULL, sfx_oof); return; } break; // villsa [STRIFE] added 09/15/10 case 165: player->message = DEH_String("That doesn't seem to work"); S_StartSound(NULL, sfx_oof); return; case 166: // DR Hand Print door if(!player->cards[key_SeveredHand]) { player->message = DEH_String("Hand print not on file"); S_StartSound(NULL, sfx_oof); return; } break; case 169: // DR Base key door if(!player->cards[key_BaseKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 170: // DR Gov's Key door if(!player->cards[key_GovsKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 190: // DR Order Key door if(!player->cards[key_OrderKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 205: // DR "Only in retail" player->message = DEH_String("THIS AREA IS ONLY AVAILABLE IN THE " "RETAIL VERSION OF STRIFE"); S_StartSound(NULL, sfx_oof); return; case 213: // DR Chalice door if(!P_PlayerHasItem(player, MT_INV_CHALICE)) { player->message = DEH_String("You need the chalice!"); S_StartSound(NULL, sfx_oof); return; } break; case 217: // DR Core Key door if(!player->cards[key_CoreKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 221: // DR Mauler Key door if(!player->cards[key_MaulerKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 224: // DR Chapel Key door if(!player->cards[key_ChapelKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 225: // DR Catacomb Key door if(!player->cards[key_CatacombKey]) { player->message = DEH_String("You don't have the key"); S_StartSound(NULL, sfx_oof); return; } break; case 232: // DR Oracle Pass door if(!(player->questflags & QF_QUEST18)) { player->message = DEH_String("You need the Oracle Pass!"); S_StartSound(NULL, sfx_oof); return; } break; default: break; } // if the sector has an active thinker, use it sec = sides[ line->sidenum[side^1]] .sector; if (sec->specialdata) { door = sec->specialdata; // [STRIFE] Adjusted to handle linetypes handled here by Strife. // BUG: Not all door types are checked here. This means that certain // door lines are allowed to fall through and start a new thinker on the // sector! This is why some doors can become jammed in Strife - stuck in // midair, or unable to be opened at all. Multiple thinkers will fight // over how to move the door. They should have added a default return if // they weren't going to handle this unconditionally... switch(line->special) { case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s case 26: case 27: case 28: case 117: case 159: // villsa case 160: // haleyjd case 161: // villsa case 166: // villsa case 169: // villsa case 170: // villsa case 190: // villsa case 213: // villsa case 232: // villsa if(door->direction == -1) door->direction = 1; // go back up else { if (!thing->player) return; // When is a door not a door? // In Vanilla, door->direction is set, even though // "specialdata" might not actually point at a door. if (door->thinker.function.acp1 == (actionf_p1) T_VerticalDoor) { door->direction = -1; // start going down immediately } else if (door->thinker.function.acp1 == (actionf_p1) T_PlatRaise) { // Erm, this is a plat, not a door. // This notably causes a problem in ep1-0500.lmp where // a plat and a door are cross-referenced; the door // doesn't open on 64-bit. // The direction field in vldoor_t corresponds to the wait // field in plat_t. Let's set that to -1 instead. plat_t *plat; plat = (plat_t *) door; plat->wait = -1; } else { // This isn't a door OR a plat. Now we're in trouble. fprintf(stderr, "EV_VerticalDoor: Tried to close " "something that wasn't a door.\n"); // Try closing it anyway. At least it will work on 32-bit // machines. door->direction = -1; } } return; default: break; } } // haleyjd 09/15/10: [STRIFE] Removed DOOM door sounds // new door thinker 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->direction = 1; door->speed = VDOORSPEED; door->topwait = VDOORWAIT; R_SoundNumForDoor(door); // haleyjd 09/15/10: [STRIFE] Get door sounds // for proper sound - [STRIFE] - verified complete switch(line->special) { case 117: // BLAZING DOOR RAISE case 118: // BLAZING DOOR OPEN S_StartSound(&sec->soundorg, sfx_bdopn); break; default: // NORMAL DOOR SOUND S_StartSound(&sec->soundorg, door->opensound); break; } // haleyjd: [STRIFE] - verified all. switch(line->special) { case 1: case 26: case 27: case 28: door->type = normal; break; case 31: case 32: case 33: case 34: case 156: // villsa [STRIFE] case 157: // villsa [STRIFE] case 158: // villsa [STRIFE] door->type = open; line->special = 0; break; case 117: // blazing door raise door->type = blazeRaise; door->speed = VDOORSPEED*4; break; case 118: // blazing door open door->type = blazeOpen; line->special = 0; door->speed = VDOORSPEED*4; break; default: // haleyjd: [STRIFE] pretty important to have this here! door->type = normal; break; } // find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; }
// // EV_VerticalDoor : open a door manually, no tag value // void EV_VerticalDoor ( line_t* line, mobj_t* thing ) { player_t* player; sector_t* sec; vldoor_t* door; int side; side = 0; // only front sides can be used // Check for locks player = thing->player; switch(line->special) { case 26: // Blue Lock case 32: if ( !player ) return; if (!player->cards[it_bluecard] && !player->cards[it_blueskull]) { player->message = PD_BLUEK; S_StartSound(NULL,sfx_oof); return; } break; case 27: // Yellow Lock case 34: if ( !player ) return; if (!player->cards[it_yellowcard] && !player->cards[it_yellowskull]) { player->message = PD_YELLOWK; S_StartSound(NULL,sfx_oof); return; } break; case 28: // Red Lock case 33: if ( !player ) return; if (!player->cards[it_redcard] && !player->cards[it_redskull]) { player->message = PD_REDK; S_StartSound(NULL,sfx_oof); return; } break; } // if the sector has an active thinker, use it sec = sides[ line->sidenum[side^1]] .sector; if (sec->specialdata) { door = sec->specialdata; switch(line->special) { case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s case 26: case 27: case 28: case 117: if (door->direction == -1) door->direction = 1; // go back up else { if (!thing->player) return; // JDC: bad guys never close doors door->direction = -1; // start going down immediately } return; } } // for proper sound switch(line->special) { case 117: // BLAZING DOOR RAISE case 118: // BLAZING DOOR OPEN S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn); break; case 1: // NORMAL DOOR SOUND case 31: S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn); break; default: // LOCKED DOOR SOUND S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn); break; } // new door thinker door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->thinker.function = T_VerticalDoor; door->sector = sec; door->direction = 1; door->speed = VDOORSPEED; door->topwait = VDOORWAIT; switch(line->special) { case 1: case 26: case 27: case 28: door->type = Normal; break; case 31: case 32: case 33: case 34: door->type = Open; line->special = 0; break; case 117: // blazing door raise door->type = BlazeRaise; door->speed = VDOORSPEED*4; break; case 118: // blazing door open door->type = BlazeOpen; line->special = 0; door->speed = VDOORSPEED*4; break; } // find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; }
// // 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->floordata) continue; // new floor thinker rtn = 1; floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, (void *)0); P_AddThinker(&floor->thinker); sec->floordata = floor; floor->thinker.function.acp1 = (actionf_p1)T_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 lowerFloorToNearest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextLowestFloor(sec, floor->sector->floorheight); 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; }
int EV_DoDoorR ( line_t* line, vldoor_e type, mobj_t* thing ) { int secnum,rtn; int newheight; sector_t* sec; vldoor_t* door; rtn = 0; secnum = -1; while ((secnum = P_FindSectorFromLineTag (line,secnum)) >= 0) { sec = §ors[secnum]; #if 0 if (P_SectorActive(ceiling_special, sec)) continue; #else door = sec->ceilingdata; if (door) { if ((line -> tag == 0) && (door->thinker.function.acp1 == (actionf_p1) T_VerticalDoor)) { switch (door->type) { case normal: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s case blazeRaise: if (door->direction == -1) { door->direction = 1; // go back up } else if ((thing)&&(thing->player))// JDC: bad guys never close doors { door->direction = -1; // start going down immediately } } } continue; } #endif // new door thinker rtn = 1; door = get_door_block (sec); door->type = type; switch(type) { case blazeClose: door->speed = VDOORSPEED * 4; case normalClose: newheight = P_FindLowestCeilingSurrounding(sec); door->topheight = newheight - 4*FRACUNIT; door->direction = -1; T_Makedoorsound (door); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; T_Makedoorsound (door); break; case blazeRaise: case blazeOpen: door->speed = VDOORSPEED * 4; case normal: case normalOpen: // door->direction = 1; newheight = P_FindNextHighestCeiling (sec, sec->ceilingheight); if (newheight > sec->ceilingheight) // Returns current height if none found... { newheight -= 4*FRACUNIT; if (newheight > sec->ceilingheight) // Is door going to move? T_Makedoorsound (door); } door->topheight = newheight; break; } } return rtn; }
// // EV_VerticalDoor : open a door manually, no tag value // void EV_VerticalDoor ( line_t* line, mobj_t* thing ) { player_t* player; sector_t* sec; vldoor_t* door; int side; side = 0; // only front sides can be used // Check for locks player = thing->player; switch(line->special) { case 26: // Blue Lock case 32: if ( !player ) return; if (!player->cards[it_bluecard] && !player->cards[it_blueskull]) { player->message = DEH_String(PD_BLUEK); S_StartSound(NULL,sfx_oof); return; } break; case 27: // Yellow Lock case 34: if ( !player ) return; if (!player->cards[it_yellowcard] && !player->cards[it_yellowskull]) { player->message = DEH_String(PD_YELLOWK); S_StartSound(NULL,sfx_oof); return; } break; case 28: // Red Lock case 33: if ( !player ) return; if (!player->cards[it_redcard] && !player->cards[it_redskull]) { player->message = DEH_String(PD_REDK); S_StartSound(NULL,sfx_oof); return; } break; } // if the sector has an active thinker, use it sec = sides[ line->sidenum[side^1]] .sector; if (sec->specialdata) { door = sec->specialdata; switch(line->special) { case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s case 26: case 27: case 28: case 117: if (door->direction == -1) door->direction = 1; // go back up else { if (!thing->player) return; // JDC: bad guys never close doors // When is a door not a door? // In Vanilla, door->direction is set, even though // "specialdata" might not actually point at a door. if (door->thinker.function.acp1 == (actionf_p1) T_VerticalDoor) { door->direction = -1; // start going down immediately } else if (door->thinker.function.acp1 == (actionf_p1) T_PlatRaise) { // Erm, this is a plat, not a door. // This notably causes a problem in ep1-0500.lmp where // a plat and a door are cross-referenced; the door // doesn't open on 64-bit. // The direction field in vldoor_t corresponds to the wait // field in plat_t. Let's set that to -1 instead. plat_t *plat; plat = (plat_t *) door; plat->wait = -1; } else { // This isn't a door OR a plat. Now we're in trouble. fprintf(stderr, "EV_VerticalDoor: Tried to close " "something that wasn't a door.\n"); // Try closing it anyway. At least it will work on 32-bit // machines. door->direction = -1; } } return; } } // for proper sound switch(line->special) { case 117: // BLAZING DOOR RAISE case 118: // BLAZING DOOR OPEN S_StartSound(&sec->soundorg,sfx_bdopn); break; case 1: // NORMAL DOOR SOUND case 31: S_StartSound(&sec->soundorg,sfx_doropn); break; default: // LOCKED DOOR SOUND S_StartSound(&sec->soundorg,sfx_doropn); break; } // new door thinker 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->direction = 1; door->speed = VDOORSPEED; door->topwait = VDOORWAIT; switch(line->special) { case 1: case 26: case 27: case 28: door->type = vld_normal; break; case 31: case 32: case 33: case 34: door->type = vld_open; line->special = 0; break; case 117: // blazing door raise door->type = vld_blazeRaise; door->speed = VDOORSPEED*4; break; case 118: // blazing door open door->type = vld_blazeOpen; line->special = 0; door->speed = VDOORSPEED*4; break; } // find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; }
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; 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; }
// // EV_SlidingDoor // // villsa [STRIFE] // void EV_SlidingDoor(line_t* line, mobj_t* thing) { sector_t* sec; slidedoor_t* door; int i; line_t* secline; // Make sure door isn't already being animated sec = sides[line->sidenum[1]].sector; door = NULL; if(sec->specialdata) { if (!thing->player) return; door = sec->specialdata; if(door->type == sdt_openAndClose) { if(door->status == sd_waiting) { door->status = sd_closing; door->timer = SWAITTICS; // villsa [STRIFE] } } else return; } // Init sliding door vars if(!door) { door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->type = sdt_openAndClose; door->status = sd_opening; door->whichDoorIndex = P_FindSlidingDoorType(line); // villsa [STRIFE] different error message if(door->whichDoorIndex < 0) I_Error(DEH_String("EV_SlidingDoor: Textures are not defined for sliding door!")); sides[line->sidenum[0]].midtexture = sides[line->sidenum[0]].toptexture; // villsa [STRIFE] door->line1 = line; door->line2 = line; // villsa [STRIFE] this loop assumes that the sliding door is made up // of only four linedefs! for(i = 0; i < 4; i++) { secline = sec->lines[i]; if(secline != line) { side_t* side1; side_t* side2; side1 = &sides[secline->sidenum[0]]; side2 = &sides[line->sidenum[0]]; if(side1->toptexture == side2->toptexture) door->line2 = secline; } } door->thinker.function.acp1 = (actionf_p1)T_SlidingDoor; door->timer = SWAITTICS; door->frontsector = sec; door->frame = 0; // villsa [STRIFE] preset flags door->line1->flags |= ML_BLOCKING; door->line2->flags |= ML_BLOCKING; // villsa [STRIFE] set the closing sector T_MovePlane( door->frontsector, (128*FRACUNIT), P_FindLowestCeilingSurrounding(door->frontsector), 0, 1, 1); // villsa [STRIFE] play open sound S_StartSound(&door->frontsector->soundorg, slideOpenSounds[door->whichDoorIndex]); } }