1 /*
2 ** a_skies.cpp
3 ** Skybox-related actors
4 **
5 **---------------------------------------------------------------------------
6 ** Copyright 1998-2006 Randy Heit
7 ** All rights reserved.
8 **
9 ** Redistribution and use in source and binary forms, with or without
10 ** modification, are permitted provided that the following conditions
11 ** are met:
12 **
13 ** 1. Redistributions of source code must retain the above copyright
14 ** notice, this list of conditions and the following disclaimer.
15 ** 2. Redistributions in binary form must reproduce the above copyright
16 ** notice, this list of conditions and the following disclaimer in the
17 ** documentation and/or other materials provided with the distribution.
18 ** 3. The name of the author may not be used to endorse or promote products
19 ** derived from this software without specific prior written permission.
20 **
21 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 **---------------------------------------------------------------------------
32 **
33 */
34
35 #include "actor.h"
36 #include "a_sharedglobal.h"
37 #include "p_local.h"
38 #include "p_lnspec.h"
39 #include "farchive.h"
40 #include "r_sky.h"
41
42 // arg0 = Visibility*4 for this skybox
43
44 IMPLEMENT_POINTY_CLASS (ASkyViewpoint)
DECLARE_POINTER(Mate)45 DECLARE_POINTER(Mate)
46 END_POINTERS
47
48 // If this actor has no TID, make it the default sky box
49 void ASkyViewpoint::BeginPlay ()
50 {
51 Super::BeginPlay ();
52
53 if (tid == 0 && level.DefaultSkybox == NULL)
54 {
55 level.DefaultSkybox = this;
56 }
57 }
58
Serialize(FArchive & arc)59 void ASkyViewpoint::Serialize (FArchive &arc)
60 {
61 Super::Serialize (arc);
62 arc << bInSkybox << bAlways << Mate;
63 }
64
Destroy()65 void ASkyViewpoint::Destroy ()
66 {
67 // remove all sector references to ourselves.
68 for (int i = 0; i <numsectors; i++)
69 {
70 if (sectors[i].SkyBoxes[sector_t::floor] == this)
71 {
72 sectors[i].SkyBoxes[sector_t::floor] = NULL;
73 }
74 if (sectors[i].SkyBoxes[sector_t::ceiling] == this)
75 {
76 sectors[i].SkyBoxes[sector_t::ceiling] = NULL;
77 }
78 }
79 if (level.DefaultSkybox == this)
80 {
81 level.DefaultSkybox = NULL;
82 }
83 Super::Destroy();
84 }
85
86 IMPLEMENT_CLASS (ASkyCamCompat)
87
88
89 //---------------------------------------------------------------------------
90
91 // arg0 = tid of matching SkyViewpoint
92 // A value of 0 means to use a regular stretched texture, in case
93 // there is a default SkyViewpoint in the level.
94 //
95 // arg1 = 0: set both floor and ceiling skybox
96 // = 1: set only ceiling skybox
97 // = 2: set only floor skybox
98
99 class ASkyPicker : public AActor
100 {
101 DECLARE_CLASS (ASkyPicker, AActor)
102 public:
103 void PostBeginPlay ();
104 };
105
IMPLEMENT_CLASS(ASkyPicker)106 IMPLEMENT_CLASS (ASkyPicker)
107
108 void ASkyPicker::PostBeginPlay ()
109 {
110 ASkyViewpoint *box;
111 Super::PostBeginPlay ();
112
113 if (args[0] == 0)
114 {
115 box = NULL;
116 }
117 else
118 {
119 TActorIterator<ASkyViewpoint> iterator (args[0]);
120 box = iterator.Next ();
121 }
122
123 if (box == NULL && args[0] != 0)
124 {
125 Printf ("Can't find SkyViewpoint %d for sector %td\n",
126 args[0], Sector - sectors);
127 }
128 else
129 {
130 if (0 == (args[1] & 2))
131 {
132 Sector->SkyBoxes[sector_t::ceiling] = box;
133 if (box == NULL) Sector->MoreFlags |= SECF_NOCEILINGSKYBOX; // sector should ignore the level's default skybox
134 }
135 if (0 == (args[1] & 1))
136 {
137 Sector->SkyBoxes[sector_t::floor] = box;
138 if (box == NULL) Sector->MoreFlags |= SECF_NOFLOORSKYBOX; // sector should ignore the level's default skybox
139 }
140 }
141 Destroy ();
142 }
143
144 //---------------------------------------------------------------------------
145 // Stacked sectors.
146
147 // arg0 = opacity of plane; 0 = invisible, 255 = fully opaque
148
IMPLEMENT_CLASS(AStackPoint)149 IMPLEMENT_CLASS (AStackPoint)
150
151 void AStackPoint::BeginPlay ()
152 {
153 // Skip SkyViewpoint's initialization
154 AActor::BeginPlay ();
155
156 bAlways = true;
157 }
158
159 //---------------------------------------------------------------------------
160
161 class ASectorSilencer : public AActor
162 {
163 DECLARE_CLASS (ASectorSilencer, AActor)
164 public:
165 void BeginPlay ();
166 void Destroy ();
167 };
168
IMPLEMENT_CLASS(ASectorSilencer)169 IMPLEMENT_CLASS (ASectorSilencer)
170
171 void ASectorSilencer::BeginPlay ()
172 {
173 Super::BeginPlay ();
174 Sector->Flags |= SECF_SILENT;
175 }
176
Destroy()177 void ASectorSilencer::Destroy ()
178 {
179 Sector->Flags &= ~SECF_SILENT;
180 Super::Destroy ();
181 }
182
183 class ASectorFlagSetter : public AActor
184 {
185 DECLARE_CLASS (ASectorFlagSetter, AActor)
186 public:
187 void BeginPlay ();
188 };
189
IMPLEMENT_CLASS(ASectorFlagSetter)190 IMPLEMENT_CLASS (ASectorFlagSetter)
191
192 void ASectorFlagSetter::BeginPlay ()
193 {
194 Super::BeginPlay ();
195 Sector->Flags |= args[0];
196 }
197
198