]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/p_ceilng.c
Initial revision
[theoddone33/hheretic.git] / base / p_ceilng.c
1
2 #include "doomdef.h"
3 #include "p_local.h"
4 #include "soundst.h"
5
6 //==================================================================
7 //==================================================================
8 //
9 //                                                      CEILINGS
10 //
11 //==================================================================
12 //==================================================================
13
14 ceiling_t       *activeceilings[MAXCEILINGS];
15
16 //==================================================================
17 //
18 //      T_MoveCeiling
19 //
20 //==================================================================
21 void T_MoveCeiling (ceiling_t *ceiling)
22 {
23         result_e        res;
24         
25         switch(ceiling->direction)
26         {
27                 case 0:         // IN STASIS
28                         break;
29                 case 1:         // UP
30                         res = T_MovePlane(ceiling->sector,ceiling->speed,
31                                         ceiling->topheight,false,1,ceiling->direction);
32                         if(!(leveltime&7))
33                                 S_StartSound((mobj_t *)&ceiling->sector->soundorg, sfx_dormov);
34                         if (res == pastdest)
35                                 switch(ceiling->type)
36                                 {
37                                         case raiseToHighest:
38                                                 P_RemoveActiveCeiling(ceiling);
39                                                 break;
40                                         case fastCrushAndRaise:
41                                         case crushAndRaise:
42                                                 ceiling->direction = -1;
43                                                 break;
44                                         default:
45                                                 break;
46                                 }
47                         break;
48                 case -1:        // DOWN
49                         res = T_MovePlane(ceiling->sector,ceiling->speed,
50                                 ceiling->bottomheight,ceiling->crush,1,ceiling->direction);
51                         if (!(leveltime&7))
52                                 S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_dormov);
53                         if (res == pastdest)
54                                 switch(ceiling->type)
55                                 {
56                                         case crushAndRaise:
57                                                 ceiling->speed = CEILSPEED;
58                                         case fastCrushAndRaise:
59                                                 ceiling->direction = 1;
60                                                 break;
61                                         case lowerAndCrush:
62                                         case lowerToFloor:
63                                                 P_RemoveActiveCeiling(ceiling);
64                                                 break;
65                                         default:
66                                                 break;
67                                 }
68                         else
69                         if (res == crushed)
70                                 switch(ceiling->type)
71                                 {
72                                         case crushAndRaise:
73                                         case lowerAndCrush:
74                                                 ceiling->speed = CEILSPEED / 8;
75                                                 break;
76                                         default:
77                                                 break;
78                                 }
79                         break;
80         }
81 }
82
83 //==================================================================
84 //
85 //              EV_DoCeiling
86 //              Move a ceiling up/down and all around!
87 //
88 //==================================================================
89 int EV_DoCeiling (line_t *line, ceiling_e  type)
90 {
91         int                     secnum,rtn;
92         sector_t                *sec;
93         ceiling_t               *ceiling;
94         
95         secnum = -1;
96         rtn = 0;
97         
98         //
99         //      Reactivate in-stasis ceilings...for certain types.
100         //
101         switch(type)
102         {
103                 case fastCrushAndRaise:
104                 case crushAndRaise:
105                         P_ActivateInStasisCeiling(line);
106                 default:
107                         break;
108         }
109         
110         while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
111         {
112                 sec = &sectors[secnum];
113                 if (sec->specialdata)
114                         continue;
115                 
116                 //
117                 // new door thinker
118                 //
119                 rtn = 1;
120                 ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
121                 P_AddThinker (&ceiling->thinker);
122                 sec->specialdata = ceiling;
123                 ceiling->thinker.function = T_MoveCeiling;
124                 ceiling->sector = sec;
125                 ceiling->crush = false;
126                 switch(type)
127                 {
128                         case fastCrushAndRaise:
129                                 ceiling->crush = true;
130                                 ceiling->topheight = sec->ceilingheight;
131                                 ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
132                                 ceiling->direction = -1;
133                                 ceiling->speed = CEILSPEED * 2;
134                                 break;
135                         case crushAndRaise:
136                                 ceiling->crush = true;
137                                 ceiling->topheight = sec->ceilingheight;
138                         case lowerAndCrush:
139                         case lowerToFloor:
140                                 ceiling->bottomheight = sec->floorheight;
141                                 if (type != lowerToFloor)
142                                         ceiling->bottomheight += 8*FRACUNIT;
143                                 ceiling->direction = -1;
144                                 ceiling->speed = CEILSPEED;
145                                 break;
146                         case raiseToHighest:
147                                 ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
148                                 ceiling->direction = 1;
149                                 ceiling->speed = CEILSPEED;
150                                 break;
151                 }
152                 
153                 ceiling->tag = sec->tag;
154                 ceiling->type = type;
155                 P_AddActiveCeiling(ceiling);
156         }
157         return rtn;
158 }
159
160 //==================================================================
161 //
162 //              Add an active ceiling
163 //
164 //==================================================================
165 void P_AddActiveCeiling(ceiling_t *c)
166 {
167         int             i;
168         for (i = 0; i < MAXCEILINGS;i++)
169                 if (activeceilings[i] == NULL)
170                 {
171                         activeceilings[i] = c;
172                         return;
173                 }
174 }
175
176 //==================================================================
177 //
178 //              Remove a ceiling's thinker
179 //
180 //==================================================================
181 void P_RemoveActiveCeiling(ceiling_t *c)
182 {
183         int             i;
184         
185         for (i = 0;i < MAXCEILINGS;i++)
186                 if (activeceilings[i] == c)
187                 {
188                         activeceilings[i]->sector->specialdata = NULL;
189                         P_RemoveThinker (&activeceilings[i]->thinker);
190                         activeceilings[i] = NULL;
191                         break;
192                 }
193 }
194
195 //==================================================================
196 //
197 //              Restart a ceiling that's in-stasis
198 //
199 //==================================================================
200 void P_ActivateInStasisCeiling(line_t *line)
201 {
202         int     i;
203         
204         for (i = 0;i < MAXCEILINGS;i++)
205                 if (activeceilings[i] && (activeceilings[i]->tag == line->tag) &&
206                         (activeceilings[i]->direction == 0))
207                 {
208                         activeceilings[i]->direction = activeceilings[i]->olddirection;
209                         activeceilings[i]->thinker.function = T_MoveCeiling;
210                 }
211 }
212
213 //==================================================================
214 //
215 //              EV_CeilingCrushStop
216 //              Stop a ceiling from crushing!
217 //
218 //==================================================================
219 int     EV_CeilingCrushStop(line_t      *line)
220 {
221         int             i;
222         int             rtn;
223         
224         rtn = 0;
225         for (i = 0;i < MAXCEILINGS;i++)
226                 if (activeceilings[i] && (activeceilings[i]->tag == line->tag) &&
227                         (activeceilings[i]->direction != 0))
228                 {
229                         activeceilings[i]->olddirection = activeceilings[i]->direction;
230                         activeceilings[i]->thinker.function = NULL;
231                         activeceilings[i]->direction = 0;               // in-stasis
232                         rtn = 1;
233                 }
234
235         return rtn;
236 }