OSDN Git Service

10a8aa7cc6fc04e19cbaa1dd661e14dad37faed8
[skyscrapersim/skyscraper.git] / src / directional.cpp
1 /* $Id$ */
2
3 /*
4         Scalable Building Simulator - Directional Indicator Class
5         The Skyscraper Project - Version 1.4 Alpha
6         Copyright (C)2005-2009 Ryan Thoryk
7         http://www.skyscrapersim.com
8         http://sourceforge.net/projects/skyscraper
9         Contact - ryan@tliquest.net
10
11         This program is free software; you can redistribute it and/or
12         modify it under the terms of the GNU General Public License
13         as published by the Free Software Foundation; either version 2
14         of the License, or (at your option) any later version.
15
16         This program is distributed in the hope that it will be useful,
17         but WITHOUT ANY WARRANTY; without even the implied warranty of
18         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19         GNU General Public License for more details.
20
21         You should have received a copy of the GNU General Public License
22         along with this program; if not, write to the Free Software
23         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24 */
25
26 #include "globals.h"
27 #include "directional.h"
28 #include "sbs.h"
29 #include "elevator.h"
30
31 extern SBS *sbs; //external pointer to the SBS engine
32
33 DirectionalIndicator::DirectionalIndicator(int elevator, int floor, bool single, bool vertical, const char *BackTexture, const char *uptexture, const char *uptexture_lit, const char *downtexture, const char *downtexture_lit, float CenterX, float CenterZ, float voffset, const char *direction, float BackWidth, float BackHeight, bool ShowBack, float tw, float th)
34 {
35         //create a directional indicator
36
37         IsEnabled = true;
38         elevator_num = elevator;
39         floor_num = floor;
40         Direction = direction;
41         UpTextureUnlit = uptexture;
42         UpTextureLit = uptexture_lit;
43         DownTextureUnlit = downtexture;
44         DownTextureLit = downtexture_lit;
45         UpStatus = false;
46         DownStatus = false;
47         Single = single;
48         Vertical = vertical;
49
50         //create object mesh
51         csString buffer, buffer2, buffer3;
52         buffer2 = elevator;
53         buffer3 = floor;
54         buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Back";
55         buffer.Trim();
56         DirectionalMeshBack = sbs->engine->CreateSectorWallsMesh (sbs->area, buffer.GetData());
57         Directional_back_state = scfQueryInterface<iThingFactoryState> (DirectionalMeshBack->GetMeshObject()->GetFactory());
58         DirectionalMeshBack->SetZBufMode(CS_ZBUF_USE);
59         DirectionalMeshBack->SetRenderPriority(sbs->engine->GetAlphaRenderPriority());
60         DirectionalMeshBack->GetMeshObject()->SetMixMode(CS_FX_ALPHA);
61
62         if (Single == false)
63         {
64                 buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Up";
65                 DirectionalMeshUp = CS::Geometry::GeneralMeshBuilder::CreateFactoryAndMesh(sbs->engine, sbs->area, buffer, buffer + " factory");
66                 DirectionalMeshUp->SetZBufMode(CS_ZBUF_USE);
67                 DirectionalMeshUp->SetRenderPriority(sbs->engine->GetAlphaRenderPriority());
68                 DirectionalMeshUp->GetMeshObject()->SetMixMode(CS_FX_ALPHA);
69                 csRef<iMaterialWrapper> mat = sbs->engine->GetMaterialList()->FindByName(UpTextureUnlit);
70                 DirectionalMeshUp->GetMeshObject()->SetMaterialWrapper(mat);
71
72                 buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Down";
73                 DirectionalMeshDown = CS::Geometry::GeneralMeshBuilder::CreateFactoryAndMesh(sbs->engine, sbs->area, buffer, buffer + " factory");
74                 DirectionalMeshDown->SetZBufMode(CS_ZBUF_USE);
75                 DirectionalMeshDown->SetRenderPriority(sbs->engine->GetAlphaRenderPriority());
76                 DirectionalMeshDown->GetMeshObject()->SetMixMode(CS_FX_ALPHA);
77                 mat = sbs->engine->GetMaterialList()->FindByName(DownTextureUnlit);
78                 DirectionalMeshDown->GetMeshObject()->SetMaterialWrapper(mat);
79         }
80         else
81         {
82                 buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Arrow";
83                 DirectionalMesh = CS::Geometry::GeneralMeshBuilder::CreateFactoryAndMesh(sbs->engine, sbs->area, buffer, buffer + " factory");
84                 DirectionalMesh->SetZBufMode(CS_ZBUF_USE);
85                 DirectionalMesh->SetRenderPriority(sbs->engine->GetAlphaRenderPriority());
86                 DirectionalMesh->GetMeshObject()->SetMixMode(CS_FX_ALPHA);
87                 csRef<iMaterialWrapper> mat = sbs->engine->GetMaterialList()->FindByName(UpTextureUnlit);
88                 DirectionalMesh->GetMeshObject()->SetMaterialWrapper(mat);
89         }
90
91         sbs->ReverseExtents(false, false, false);
92
93         //create panel
94         if (ShowBack == true)
95         {
96                 if (Direction == "front" || Direction == "back")
97                 {
98                         if (Direction == "front")
99                                 sbs->DrawWalls(true, false, false, false, false, false);
100                         else
101                                 sbs->DrawWalls(false, true, false, false, false, false);
102                         sbs->AddWallMain(Directional_back_state, "Panel", BackTexture, 0, CenterX - (BackWidth / 2), CenterZ, CenterX + (BackWidth / 2), CenterZ, BackHeight, BackHeight, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, tw, th);
103                         sbs->ResetWalls();
104                 }
105                 if (Direction == "left" || Direction == "right")
106                 {
107                         if (Direction == "left")
108                                 sbs->DrawWalls(true, false, false, false, false, false);
109                         else
110                                 sbs->DrawWalls(false, true, false, false, false, false);
111                         sbs->AddWallMain(Directional_back_state, "Panel", BackTexture, 0, CenterX, CenterZ + (BackWidth / 2), CenterX, CenterZ - (BackWidth / 2), BackHeight, BackHeight, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, tw, th);
112                         sbs->ResetWalls();
113                 }
114         }
115
116         //create indicator lanterns
117         int bottomfloor = sbs->GetElevator(elevator)->GetBottomFloor();
118         int topfloor = sbs->GetElevator(elevator)->GetTopFloor();
119
120         if (Direction == "front" || Direction == "back")
121         {
122                 float x1, x2;
123                 float offset;
124                 if (Direction == "front")
125                 {
126                         sbs->DrawWalls(true, false, false, false, false, false);
127                         offset = -0.01f;
128                         x1 = CenterX - (BackWidth / 4);
129                         x2 = CenterX + (BackWidth / 4);
130                 }
131                 else
132                 {
133                         sbs->DrawWalls(false, true, false, false, false, false);
134                         offset = 0.01f;
135                         x2 = CenterX - (BackWidth / 4);
136                         x1 = CenterX + (BackWidth / 4);
137                 }
138                 if (Single == false)
139                 {
140                         if (Vertical == true)
141                         {
142                                 if (floor > bottomfloor && floor < topfloor)
143                                 {
144                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 4), 1, 1);
145                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 7), 1, 1);
146                                 }
147                                 else
148                                 {
149                                         if (floor < topfloor)
150                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
151                                         if (floor > bottomfloor)
152                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
153                                 }
154                         }
155                         else
156                         {
157                                 //horizontal lights
158                                 if (floor > bottomfloor && floor < topfloor)
159                                 {
160                                         float x3, x4;
161                                         if (Direction == "front")
162                                         {
163                                                 x1 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 4);
164                                                 x2 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 6);
165                                                 x3 = (CenterX - (BackWidth / 2)) + (BackWidth / 7);
166                                                 x4 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 3);
167                                         }
168                                         else
169                                         {
170                                                 x1 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 6);
171                                                 x2 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 4);
172                                                 x3 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7)) * 3;
173                                                 x4 = (CenterX - (BackWidth / 2)) + (BackWidth / 7);
174                                         }
175                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
176                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x3, CenterZ + offset, x4, CenterZ + offset, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
177                                 }
178                                 else
179                                 {
180                                         if (floor < topfloor)
181                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
182                                         if (floor > bottomfloor)
183                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
184                                 }
185                         }
186                 }
187                 else
188                         sbs->AddGenWall(DirectionalMesh, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
189
190                 sbs->ResetWalls();
191         }
192         else
193         {
194                 float z1, z2;
195                 float offset;
196                 if (Direction == "left")
197                 {
198                         sbs->DrawWalls(true, false, false, false, false, false);
199                         offset = -0.01f;
200                         z2 = CenterZ - (BackWidth / 4);
201                         z1 = CenterZ + (BackWidth / 4);
202                 }
203                 else
204                 {
205                         //right
206                         sbs->DrawWalls(false, true, false, false, false, false);
207                         offset = 0.01f;
208                         z1 = CenterZ - (BackWidth / 4);
209                         z2 = CenterZ + (BackWidth / 4);
210                 }
211                 if (Single == false)
212                 {
213                         if (Vertical == true)
214                         {
215                                 if (floor > bottomfloor && floor < topfloor)
216                                 {
217                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 4), 1, 1);
218                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 7), 1, 1);
219                                 }
220                                 else
221                                 {
222                                         if (floor < topfloor)
223                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
224                                         if (floor > bottomfloor)
225                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
226                                 }
227                         }
228                         else
229                         {
230                                 //horizontal lights
231                                 if (floor > bottomfloor && floor < topfloor)
232                                 {
233                                         float z3, z4;
234                                         if (Direction == "left")
235                                         {
236                                                 z1 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 6);
237                                                 z2 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 4);
238                                                 z3 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7)) * 3;
239                                                 z4 = (CenterZ - (BackWidth / 2)) + (BackWidth / 7);
240                                         }
241                                         else
242                                         {
243                                                 z1 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 4);
244                                                 z2 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 6);
245                                                 z3 = (CenterZ - (BackWidth / 2)) + (BackWidth / 7);
246                                                 z4 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 3);
247                                         }
248                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
249                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z3, CenterX + offset, z4, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
250                                 }
251                                 else
252                                 {
253                                         if (floor < topfloor)
254                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
255                                         if (floor > bottomfloor)
256                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
257                                 }
258                         }
259                 }
260                 else
261                         sbs->AddGenWall(DirectionalMesh, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
262
263                 sbs->ResetWalls();
264         }
265         sbs->ResetExtents();
266 }
267
268 DirectionalIndicator::~DirectionalIndicator()
269 {
270
271 }
272
273 void DirectionalIndicator::Enabled(bool value)
274 {
275         //turns panel on/off
276         if (value == IsEnabled)
277                 return;
278
279         sbs->EnableMesh(DirectionalMeshBack, value);
280         if (DirectionalMeshUp)
281                 sbs->EnableMesh(DirectionalMeshUp, value);
282         if (DirectionalMeshDown)
283                 sbs->EnableMesh(DirectionalMeshDown, value);
284         if (DirectionalMesh)
285                 sbs->EnableMesh(DirectionalMesh, value);
286
287         IsEnabled = value;
288 }
289
290 void DirectionalIndicator::UpLight(bool value)
291 {
292         //turn on the 'up' directional light
293         if (value == UpStatus)
294                 return;
295
296         //exit if indicator is disabled
297         if (IsEnabled == false)
298                 return;
299
300         //set light status
301         if (value == true)
302                 SetLights(1, 0);
303         else
304                 SetLights(2, 0);
305
306         UpStatus = value;
307 }
308
309 void DirectionalIndicator::DownLight(bool value)
310 {
311         //turn on the 'down' directional light
312         if (value == DownStatus)
313                 return;
314
315         //exit if indicator is disabled
316         if (IsEnabled == false)
317                 return;
318
319         //set light status
320         if (value == true)
321                 SetLights(0, 1);
322         else
323                 SetLights(0, 2);
324
325         DownStatus = value;
326 }
327
328 void DirectionalIndicator::SetLights(int up, int down)
329 {
330         //set status of directional lights
331         //values are 0 for no change, 1 for on, and 2 for off
332
333         if (Single == false)
334         {
335                 if (up == 1 && DirectionalMeshUp)
336                         sbs->ChangeTexture(DirectionalMeshUp, UpTextureLit);
337                 if (up == 2 && DirectionalMeshUp)
338                         sbs->ChangeTexture(DirectionalMeshUp, UpTextureUnlit);
339                 if (down == 1 && DirectionalMeshDown)
340                         sbs->ChangeTexture(DirectionalMeshDown, DownTextureLit);
341                 if (down == 2 && DirectionalMeshDown)
342                         sbs->ChangeTexture(DirectionalMeshDown, DownTextureUnlit);
343         }
344         else
345         {
346                 if (DirectionalMesh)
347                 {
348                         if (up == 1)
349                                 sbs->ChangeTexture(DirectionalMesh, UpTextureLit);
350                         if (down == 1)
351                                 sbs->ChangeTexture(DirectionalMesh, DownTextureLit);
352                         if (up == 2 || down == 2)
353                                 sbs->ChangeTexture(DirectionalMesh, UpTextureUnlit);
354                 }
355         }
356 }