Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //      Plats (i.e. elevator platforms) code, raising/lowering.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24. static const char
  25. rcsid[] = "$Id: p_plats.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
  26.  
  27.  
  28. #include "i_system.h"
  29. #include "z_zone.h"
  30. #include "m_random.h"
  31.  
  32. #include "doomdef.h"
  33. #include "p_local.h"
  34.  
  35. #include "s_sound.h"
  36.  
  37. // State.
  38. #include "doomstat.h"
  39. #include "r_state.h"
  40.  
  41. // Data.
  42. #include "sounds.h"
  43.  
  44.  
  45. plat_t*         activeplats[MAXPLATS];
  46.  
  47.  
  48.  
  49. //
  50. // Move a plat up and down
  51. //
  52. void T_PlatRaise(plat_t* plat)
  53. {
  54.     result_e    res;
  55.        
  56.     switch(plat->status)
  57.     {
  58.       case up:
  59.         res = T_MovePlane(plat->sector,
  60.                           plat->speed,
  61.                           plat->high,
  62.                           plat->crush,0,1);
  63.                                        
  64.         if (plat->type == raiseAndChange
  65.             || plat->type == raiseToNearestAndChange)
  66.         {
  67.             if (!(leveltime&7))
  68.                 S_StartSound((mobj_t *)&plat->sector->soundorg,
  69.                              sfx_stnmov);
  70.         }
  71.        
  72.                                
  73.         if (res == crushed && (!plat->crush))
  74.         {
  75.             plat->count = plat->wait;
  76.             plat->status = down;
  77.             S_StartSound((mobj_t *)&plat->sector->soundorg,
  78.                          sfx_pstart);
  79.         }
  80.         else
  81.         {
  82.             if (res == pastdest)
  83.             {
  84.                 plat->count = plat->wait;
  85.                 plat->status = waiting;
  86.                 S_StartSound((mobj_t *)&plat->sector->soundorg,
  87.                              sfx_pstop);
  88.  
  89.                 switch(plat->type)
  90.                 {
  91.                   case blazeDWUS:
  92.                   case downWaitUpStay:
  93.                     P_RemoveActivePlat(plat);
  94.                     break;
  95.                    
  96.                   case raiseAndChange:
  97.                   case raiseToNearestAndChange:
  98.                     P_RemoveActivePlat(plat);
  99.                     break;
  100.                    
  101.                   default:
  102.                     break;
  103.                 }
  104.             }
  105.         }
  106.         break;
  107.        
  108.       case      down:
  109.         res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
  110.  
  111.         if (res == pastdest)
  112.         {
  113.             plat->count = plat->wait;
  114.             plat->status = waiting;
  115.             S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
  116.         }
  117.         break;
  118.        
  119.       case      waiting:
  120.         if (!--plat->count)
  121.         {
  122.             if (plat->sector->floorheight == plat->low)
  123.                 plat->status = up;
  124.             else
  125.                 plat->status = down;
  126.             S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);
  127.         }
  128.       case      in_stasis:
  129.         break;
  130.     }
  131. }
  132.  
  133.  
  134. //
  135. // Do Platforms
  136. //  "amount" is only used for SOME platforms.
  137. //
  138. int
  139. EV_DoPlat
  140. ( line_t*       line,
  141.   plattype_e    type,
  142.   int           amount )
  143. {
  144.     plat_t*     plat;
  145.     int         secnum;
  146.     int         rtn;
  147.     sector_t*   sec;
  148.        
  149.     secnum = -1;
  150.     rtn = 0;
  151.  
  152.    
  153.     //  Activate all <type> plats that are in_stasis
  154.     switch(type)
  155.     {
  156.       case perpetualRaise:
  157.         P_ActivateInStasis(line->tag);
  158.         break;
  159.        
  160.       default:
  161.         break;
  162.     }
  163.        
  164.     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  165.     {
  166.         sec = &sectors[secnum];
  167.  
  168.         if (sec->specialdata)
  169.             continue;
  170.        
  171.         // Find lowest & highest floors around sector
  172.         rtn = 1;
  173.         plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
  174.         P_AddThinker(&plat->thinker);
  175.                
  176.         plat->type = type;
  177.         plat->sector = sec;
  178.         plat->sector->specialdata = plat;
  179.         plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
  180.         plat->crush = false;
  181.         plat->tag = line->tag;
  182.        
  183.         switch(type)
  184.         {
  185.           case raiseToNearestAndChange:
  186.             plat->speed = PLATSPEED/2;
  187.             sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
  188.             plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
  189.             plat->wait = 0;
  190.             plat->status = up;
  191.             // NO MORE DAMAGE, IF APPLICABLE
  192.             sec->special = 0;          
  193.  
  194.             S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
  195.             break;
  196.            
  197.           case raiseAndChange:
  198.             plat->speed = PLATSPEED/2;
  199.             sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
  200.             plat->high = sec->floorheight + amount*FRACUNIT;
  201.             plat->wait = 0;
  202.             plat->status = up;
  203.  
  204.             S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
  205.             break;
  206.            
  207.           case downWaitUpStay:
  208.             plat->speed = PLATSPEED * 4;
  209.             plat->low = P_FindLowestFloorSurrounding(sec);
  210.  
  211.             if (plat->low > sec->floorheight)
  212.                 plat->low = sec->floorheight;
  213.  
  214.             plat->high = sec->floorheight;
  215.             plat->wait = 35*PLATWAIT;
  216.             plat->status = down;
  217.             S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
  218.             break;
  219.            
  220.           case blazeDWUS:
  221.             plat->speed = PLATSPEED * 8;
  222.             plat->low = P_FindLowestFloorSurrounding(sec);
  223.  
  224.             if (plat->low > sec->floorheight)
  225.                 plat->low = sec->floorheight;
  226.  
  227.             plat->high = sec->floorheight;
  228.             plat->wait = 35*PLATWAIT;
  229.             plat->status = down;
  230.             S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
  231.             break;
  232.            
  233.           case perpetualRaise:
  234.             plat->speed = PLATSPEED;
  235.             plat->low = P_FindLowestFloorSurrounding(sec);
  236.  
  237.             if (plat->low > sec->floorheight)
  238.                 plat->low = sec->floorheight;
  239.  
  240.             plat->high = P_FindHighestFloorSurrounding(sec);
  241.  
  242.             if (plat->high < sec->floorheight)
  243.                 plat->high = sec->floorheight;
  244.  
  245.             plat->wait = 35*PLATWAIT;
  246.             plat->status = P_Random()&1;
  247.  
  248.             S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
  249.             break;
  250.         }
  251.         P_AddActivePlat(plat);
  252.     }
  253.     return rtn;
  254. }
  255.  
  256.  
  257.  
  258. void P_ActivateInStasis(int tag)
  259. {
  260.     int         i;
  261.        
  262.     for (i = 0;i < MAXPLATS;i++)
  263.         if (activeplats[i]
  264.             && (activeplats[i])->tag == tag
  265.             && (activeplats[i])->status == in_stasis)
  266.         {
  267.             (activeplats[i])->status = (activeplats[i])->oldstatus;
  268.             (activeplats[i])->thinker.function.acp1
  269.               = (actionf_p1) T_PlatRaise;
  270.         }
  271. }
  272.  
  273. void EV_StopPlat(line_t* line)
  274. {
  275.     int         j;
  276.        
  277.     for (j = 0;j < MAXPLATS;j++)
  278.         if (activeplats[j]
  279.             && ((activeplats[j])->status != in_stasis)
  280.             && ((activeplats[j])->tag == line->tag))
  281.         {
  282.             (activeplats[j])->oldstatus = (activeplats[j])->status;
  283.             (activeplats[j])->status = in_stasis;
  284.             (activeplats[j])->thinker.function.acv = (actionf_v)NULL;
  285.         }
  286. }
  287.  
  288. void P_AddActivePlat(plat_t* plat)
  289. {
  290.     int         i;
  291.    
  292.     for (i = 0;i < MAXPLATS;i++)
  293.         if (activeplats[i] == NULL)
  294.         {
  295.             activeplats[i] = plat;
  296.             return;
  297.         }
  298.     I_Error ("P_AddActivePlat: no more plats!");
  299. }
  300.  
  301. void P_RemoveActivePlat(plat_t* plat)
  302. {
  303.     int         i;
  304.     for (i = 0;i < MAXPLATS;i++)
  305.         if (plat == activeplats[i])
  306.         {
  307.             (activeplats[i])->sector->specialdata = NULL;
  308.             P_RemoveThinker(&(activeplats[i])->thinker);
  309.             activeplats[i] = NULL;
  310.            
  311.             return;
  312.         }
  313.     I_Error ("P_RemoveActivePlat: can't find plat!");
  314. }
  315.