p_plats.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:7k
源码类别:

射击游戏

开发平台:

Visual C++

  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. static const char
  24. rcsid[] = "$Id: p_plats.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
  25. #include "i_system.h"
  26. #include "z_zone.h"
  27. #include "m_random.h"
  28. #include "doomdef.h"
  29. #include "p_local.h"
  30. #include "s_sound.h"
  31. // State.
  32. #include "doomstat.h"
  33. #include "r_state.h"
  34. // Data.
  35. #include "sounds.h"
  36. plat_t* activeplats[MAXPLATS];
  37. //
  38. // Move a plat up and down
  39. //
  40. void T_PlatRaise(plat_t* plat)
  41. {
  42.     result_e res;
  43.     switch(plat->status)
  44.     {
  45.       case up:
  46. res = T_MovePlane(plat->sector,
  47.   plat->speed,
  48.   plat->high,
  49.   plat->crush,0,1);
  50. if (plat->type == raiseAndChange
  51.     || plat->type == raiseToNearestAndChange)
  52. {
  53.     if (!(leveltime&7))
  54. S_StartSound((mobj_t *)&plat->sector->soundorg,
  55.      sfx_stnmov);
  56. }
  57. if (res == crushed && (!plat->crush))
  58. {
  59.     plat->count = plat->wait;
  60.     plat->status = down;
  61.     S_StartSound((mobj_t *)&plat->sector->soundorg,
  62.  sfx_pstart);
  63. }
  64. else
  65. {
  66.     if (res == pastdest)
  67.     {
  68. plat->count = plat->wait;
  69. plat->status = waiting;
  70. S_StartSound((mobj_t *)&plat->sector->soundorg,
  71.      sfx_pstop);
  72. switch(plat->type)
  73. {
  74.   case blazeDWUS:
  75.   case downWaitUpStay:
  76.     P_RemoveActivePlat(plat);
  77.     break;
  78.     
  79.   case raiseAndChange:
  80.   case raiseToNearestAndChange:
  81.     P_RemoveActivePlat(plat);
  82.     break;
  83.     
  84.   default:
  85.     break;
  86. }
  87.     }
  88. }
  89. break;
  90.       case down:
  91. res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
  92. if (res == pastdest)
  93. {
  94.     plat->count = plat->wait;
  95.     plat->status = waiting;
  96.     S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
  97. }
  98. break;
  99.       case waiting:
  100. if (!--plat->count)
  101. {
  102.     if (plat->sector->floorheight == plat->low)
  103. plat->status = up;
  104.     else
  105. plat->status = down;
  106.     S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);
  107. }
  108.       case in_stasis:
  109. break;
  110.     }
  111. }
  112. //
  113. // Do Platforms
  114. //  "amount" is only used for SOME platforms.
  115. //
  116. int
  117. EV_DoPlat
  118. ( line_t* line,
  119.   plattype_e type,
  120.   int amount )
  121. {
  122.     plat_t* plat;
  123.     int secnum;
  124.     int rtn;
  125.     sector_t* sec;
  126.     secnum = -1;
  127.     rtn = 0;
  128.     
  129.     // Activate all <type> plats that are in_stasis
  130.     switch(type)
  131.     {
  132.       case perpetualRaise:
  133. P_ActivateInStasis(line->tag);
  134. break;
  135.       default:
  136. break;
  137.     }
  138.     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  139.     {
  140. sec = &sectors[secnum];
  141. if (sec->specialdata)
  142.     continue;
  143. // Find lowest & highest floors around sector
  144. rtn = 1;
  145. plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
  146. P_AddThinker(&plat->thinker);
  147. plat->type = type;
  148. plat->sector = sec;
  149. plat->sector->specialdata = plat;
  150. plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
  151. plat->crush = false;
  152. plat->tag = line->tag;
  153. switch(type)
  154. {
  155.   case raiseToNearestAndChange:
  156.     plat->speed = PLATSPEED/2;
  157.     sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
  158.     plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
  159.     plat->wait = 0;
  160.     plat->status = up;
  161.     // NO MORE DAMAGE, IF APPLICABLE
  162.     sec->special = 0;
  163.     S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
  164.     break;
  165.     
  166.   case raiseAndChange:
  167.     plat->speed = PLATSPEED/2;
  168.     sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
  169.     plat->high = sec->floorheight + amount*FRACUNIT;
  170.     plat->wait = 0;
  171.     plat->status = up;
  172.     S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
  173.     break;
  174.     
  175.   case downWaitUpStay:
  176.     plat->speed = PLATSPEED * 4;
  177.     plat->low = P_FindLowestFloorSurrounding(sec);
  178.     if (plat->low > sec->floorheight)
  179. plat->low = sec->floorheight;
  180.     plat->high = sec->floorheight;
  181.     plat->wait = 35*PLATWAIT;
  182.     plat->status = down;
  183.     S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
  184.     break;
  185.     
  186.   case blazeDWUS:
  187.     plat->speed = PLATSPEED * 8;
  188.     plat->low = P_FindLowestFloorSurrounding(sec);
  189.     if (plat->low > sec->floorheight)
  190. plat->low = sec->floorheight;
  191.     plat->high = sec->floorheight;
  192.     plat->wait = 35*PLATWAIT;
  193.     plat->status = down;
  194.     S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
  195.     break;
  196.     
  197.   case perpetualRaise:
  198.     plat->speed = PLATSPEED;
  199.     plat->low = P_FindLowestFloorSurrounding(sec);
  200.     if (plat->low > sec->floorheight)
  201. plat->low = sec->floorheight;
  202.     plat->high = P_FindHighestFloorSurrounding(sec);
  203.     if (plat->high < sec->floorheight)
  204. plat->high = sec->floorheight;
  205.     plat->wait = 35*PLATWAIT;
  206.     plat->status = P_Random()&1;
  207.     S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
  208.     break;
  209. }
  210. P_AddActivePlat(plat);
  211.     }
  212.     return rtn;
  213. }
  214. void P_ActivateInStasis(int tag)
  215. {
  216.     int i;
  217.     for (i = 0;i < MAXPLATS;i++)
  218. if (activeplats[i]
  219.     && (activeplats[i])->tag == tag
  220.     && (activeplats[i])->status == in_stasis)
  221. {
  222.     (activeplats[i])->status = (activeplats[i])->oldstatus;
  223.     (activeplats[i])->thinker.function.acp1
  224.       = (actionf_p1) T_PlatRaise;
  225. }
  226. }
  227. void EV_StopPlat(line_t* line)
  228. {
  229.     int j;
  230.     for (j = 0;j < MAXPLATS;j++)
  231. if (activeplats[j]
  232.     && ((activeplats[j])->status != in_stasis)
  233.     && ((activeplats[j])->tag == line->tag))
  234. {
  235.     (activeplats[j])->oldstatus = (activeplats[j])->status;
  236.     (activeplats[j])->status = in_stasis;
  237.     (activeplats[j])->thinker.function.acv = (actionf_v)NULL;
  238. }
  239. }
  240. void P_AddActivePlat(plat_t* plat)
  241. {
  242.     int i;
  243.     
  244.     for (i = 0;i < MAXPLATS;i++)
  245. if (activeplats[i] == NULL)
  246. {
  247.     activeplats[i] = plat;
  248.     return;
  249. }
  250.     I_Error ("P_AddActivePlat: no more plats!");
  251. }
  252. void P_RemoveActivePlat(plat_t* plat)
  253. {
  254.     int i;
  255.     for (i = 0;i < MAXPLATS;i++)
  256. if (plat == activeplats[i])
  257. {
  258.     (activeplats[i])->sector->specialdata = NULL;
  259.     P_RemoveThinker(&(activeplats[i])->thinker);
  260.     activeplats[i] = NULL;
  261.     
  262.     return;
  263. }
  264.     I_Error ("P_RemoveActivePlat: can't find plat!");
  265. }