home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -screenplay- / otherstuff / adoomppc_src / p_plats.c < prev    next >
C/C++ Source or Header  |  1998-04-23  |  7KB  |  315 lines

  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 = §ors[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.