// // EV_canUnlockGenDoor() // // Passed a generalized locked door linedef and a player, returns whether // the player has the keys necessary to unlock that door. // // Note: The linedef passed MUST be a generalized locked door type // or results are undefined. // // jff 02/05/98 routine added to test for unlockability of // generalized locked doors // // killough 11/98: reformatted // // haleyjd 08/22/00: fixed bug found by fraggle // static bool EV_canUnlockGenDoor(line_t *line, player_t *player) { int lockdefID = EV_lockdefIDForGenSpec(line->special); itemeffect_t *yskull = E_ItemEffectForName(ARTI_YELLOWSKULL); bool hasYellowSkull = (E_GetItemOwnedAmount(player, yskull) > 0); // MBF compatibility hack - if lockdef ID is ALL3 and the player has the // YellowSkull, we have to take it away; if he doesn't have it, we have to // give it. if(demo_version == 203 && lockdefID == EV_LOCKDEF_ALL3) { if(hasYellowSkull) E_RemoveInventoryItem(player, yskull, -1); else E_GiveInventoryItem(player, yskull); } bool result = E_PlayerCanUnlock(player, lockdefID, false); // restore inventory state if lockdef was ALL3 and playing back an MBF demo if(demo_version == 203 && lockdefID == EV_LOCKDEF_ALL3) { if(hasYellowSkull) E_GiveInventoryItem(player, yskull); else E_RemoveInventoryItem(player, yskull, -1); } return result; }
// // 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; }