]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/p_ceilng.c
Add .gitignore for ignoring generated files.
[theoddone33/hhexen.git] / base / p_ceilng.c
1
2 //**************************************************************************
3 //**
4 //** p_ceilng.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 #include "h2def.h"
14 #include "p_local.h"
15 #include "soundst.h"
16
17 //==================================================================
18 //==================================================================
19 //
20 //                                                      CEILINGS
21 //
22 //==================================================================
23 //==================================================================
24
25 ceiling_t       *activeceilings[MAXCEILINGS];
26
27 //==================================================================
28 //
29 //      T_MoveCeiling
30 //
31 //==================================================================
32 void T_MoveCeiling (ceiling_t *ceiling)
33 {
34         result_e        res;
35
36         switch(ceiling->direction)
37         {
38 //              case 0:         // IN STASIS
39 //                      break;
40                 case 1:         // UP
41                         res = T_MovePlane(ceiling->sector,ceiling->speed,
42                                         ceiling->topheight, false, 1, ceiling->direction);
43                         if (res == RES_PASTDEST)
44                         {
45                                 SN_StopSequence((mobj_t *)&ceiling->sector->soundorg);
46                                 switch(ceiling->type)
47                                 {
48                                         case CLEV_CRUSHANDRAISE:
49                                                 ceiling->direction = -1;
50                                                 ceiling->speed = ceiling->speed*2;
51                                                 break;
52                                         default:
53                                                 P_RemoveActiveCeiling(ceiling);
54                                                 break;
55                                 }
56                         }
57                         break;
58                 case -1:        // DOWN
59                         res = T_MovePlane(ceiling->sector,ceiling->speed,
60                                 ceiling->bottomheight, ceiling->crush, 1, ceiling->direction);
61                         if(res == RES_PASTDEST)
62                         {
63                                 SN_StopSequence((mobj_t *)&ceiling->sector->soundorg);
64                                 switch(ceiling->type)
65                                 {
66                                         case CLEV_CRUSHANDRAISE:
67                                         case CLEV_CRUSHRAISEANDSTAY:
68                                                 ceiling->direction = 1;
69                                                 ceiling->speed = ceiling->speed/2;
70                                                 break;
71                                         default:
72                                                 P_RemoveActiveCeiling(ceiling);
73                                                 break;
74                                 }
75                         } 
76                         else if(res == RES_CRUSHED)
77                         {
78                                 switch(ceiling->type)
79                                 {
80                                         case CLEV_CRUSHANDRAISE:
81                                         case CLEV_LOWERANDCRUSH:
82                                         case CLEV_CRUSHRAISEANDSTAY:
83                                                 //ceiling->speed = ceiling->speed/4;
84                                                 break;
85                                         default:
86                                                 break;
87                                 }
88                         }
89                         break;
90         }
91 }
92
93 //==================================================================
94 //
95 //              EV_DoCeiling
96 //              Move a ceiling up/down and all around!
97 //
98 //==================================================================
99 int EV_DoCeiling (line_t *line, byte *arg, ceiling_e type)
100 {
101         int                     secnum,rtn;
102         sector_t                *sec;
103         ceiling_t               *ceiling;
104
105         secnum = -1;
106         rtn = 0;
107
108 /* Old Ceiling stasis code
109         //
110         //      Reactivate in-stasis ceilings...for certain types.
111         //
112         switch(type)
113         {
114                 case CLEV_CRUSHANDRAISE:
115                         P_ActivateInStasisCeiling(line);
116                 default:
117                         break;
118         }
119 */
120         while ((secnum = P_FindSectorFromTag(arg[0], secnum)) >= 0)
121         {
122                 sec = &sectors[secnum];
123                 if (sec->specialdata)
124                         continue;
125
126                 //
127                 // new door thinker
128                 //
129                 rtn = 1;
130                 ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
131                 P_AddThinker (&ceiling->thinker);
132                 sec->specialdata = ceiling;
133                 ceiling->thinker.function = T_MoveCeiling;
134                 ceiling->sector = sec;
135                 ceiling->crush = 0;
136                 ceiling->speed = arg[1]*(FRACUNIT/8);
137                 switch(type)
138                 {
139                         case CLEV_CRUSHRAISEANDSTAY:
140                                 ceiling->crush = arg[2]; // arg[2] = crushing value
141                                 ceiling->topheight = sec->ceilingheight;
142                                 ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
143                                 ceiling->direction = -1;
144                                 break;
145                         case CLEV_CRUSHANDRAISE:
146                                 ceiling->topheight = sec->ceilingheight;
147                         case CLEV_LOWERANDCRUSH:
148                                 ceiling->crush = arg[2]; // arg[2] = crushing value
149                         case CLEV_LOWERTOFLOOR:
150                                 ceiling->bottomheight = sec->floorheight;
151                                 if(type != CLEV_LOWERTOFLOOR)
152                                 {
153                                         ceiling->bottomheight += 8*FRACUNIT;
154                                 }
155                                 ceiling->direction = -1;
156                                 break;
157                         case CLEV_RAISETOHIGHEST:
158                                 ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
159                                 ceiling->direction = 1;
160                                 break;
161                         case CLEV_LOWERBYVALUE:
162                                 ceiling->bottomheight = sec->ceilingheight-arg[2]*FRACUNIT;
163                                 ceiling->direction = -1;
164                                 break;
165                         case CLEV_RAISEBYVALUE:
166                                 ceiling->topheight = sec->ceilingheight+arg[2]*FRACUNIT;
167                                 ceiling->direction = 1;
168                                 break;
169                         case CLEV_MOVETOVALUETIMES8:
170                         {
171                                 int destHeight = arg[2]*FRACUNIT*8;
172
173                                 if(arg[3])
174                                 {
175                                         destHeight = -destHeight;
176                                 }
177                                 if(sec->ceilingheight <= destHeight)
178                                 {
179                                         ceiling->direction = 1;
180                                         ceiling->topheight = destHeight;
181                                         if(sec->ceilingheight == destHeight)
182                                         {
183                                                 rtn = 0;
184                                         }
185                                 }
186                                 else if(sec->ceilingheight > destHeight)
187                                 {
188                                         ceiling->direction = -1;
189                                         ceiling->bottomheight = destHeight;
190                                 }
191                                 break;
192                         }
193                         default:
194                                 rtn = 0;
195                                 break;
196                 }
197                 ceiling->tag = sec->tag;
198                 ceiling->type = type;
199                 P_AddActiveCeiling(ceiling);
200                 if(rtn)
201                 {
202                         SN_StartSequence((mobj_t *)&ceiling->sector->soundorg, 
203                                 SEQ_PLATFORM+ceiling->sector->seqType);
204                 }
205         }
206         return rtn;
207 }
208
209 //==================================================================
210 //
211 //              Add an active ceiling
212 //
213 //==================================================================
214 void P_AddActiveCeiling(ceiling_t *c)
215 {
216         int             i;
217         for (i = 0; i < MAXCEILINGS;i++)
218                 if (activeceilings[i] == NULL)
219                 {
220                         activeceilings[i] = c;
221                         return;
222                 }
223 }
224
225 //==================================================================
226 //
227 //              Remove a ceiling's thinker
228 //
229 //==================================================================
230 void P_RemoveActiveCeiling(ceiling_t *c)
231 {
232         int             i;
233
234         for (i = 0;i < MAXCEILINGS;i++)
235                 if (activeceilings[i] == c)
236                 {
237                         activeceilings[i]->sector->specialdata = NULL;
238                         P_RemoveThinker (&activeceilings[i]->thinker);
239                         P_TagFinished(activeceilings[i]->sector->tag);
240                         activeceilings[i] = NULL;
241                         break;
242                 }
243 }
244
245 #if 0
246 //==================================================================
247 //
248 //              Restart a ceiling that's in-stasis
249 //
250 //==================================================================
251 void P_ActivateInStasisCeiling(line_t *line)
252 {
253         int     i;
254
255         for (i = 0;i < MAXCEILINGS;i++)
256                 if (activeceilings[i] && (activeceilings[i]->tag == line->arg1) &&
257                         (activeceilings[i]->direction == 0))
258                 {
259                         activeceilings[i]->direction = activeceilings[i]->olddirection;
260                         activeceilings[i]->thinker.function = T_MoveCeiling;
261                         SN_StartSequence((mobj_t *)&activeceilings[i]->sector->soundorg,
262                                 SEQ_PLATFORM+activeceilings[i]->sector->seqType);
263                 }
264 }
265 #endif
266
267 //==================================================================
268 //
269 //              EV_CeilingCrushStop
270 //              Stop a ceiling from crushing!
271 //
272 //==================================================================
273
274 int EV_CeilingCrushStop(line_t *line, byte *args)
275 {
276         int             i;
277         int             rtn;
278
279         rtn = 0;
280         for (i = 0;i < MAXCEILINGS;i++)
281         {
282                 if(activeceilings[i] && activeceilings[i]->tag == args[0])              
283                 {
284                         rtn = 1;
285                         SN_StopSequence((mobj_t*)&activeceilings[i]->sector->soundorg);
286                         activeceilings[i]->sector->specialdata = NULL;
287                         P_RemoveThinker (&activeceilings[i]->thinker);
288                         P_TagFinished(activeceilings[i]->sector->tag);
289                         activeceilings[i] = NULL;
290                         break;
291                 }
292         }
293         return rtn;
294 }
295