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