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