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