Exemple #1
0
//
// 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;
}
Exemple #2
0
//
// 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;
}