Skyscraper 2.0
directional.cpp
Go to the documentation of this file.
1/*
2 Scalable Building Simulator - Directional Indicator Object
3 The Skyscraper Project - Version 2.0
4 Copyright (C)2004-2024 Ryan Thoryk
5 https://www.skyscrapersim.net
6 https://sourceforge.net/projects/skyscraper/
7 Contact - ryan@skyscrapersim.net
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22*/
23
24#include "globals.h"
25#include "sbs.h"
26#include "floor.h"
27#include "mesh.h"
28#include "texture.h"
29#include "elevator.h"
30#include "elevatorcar.h"
31#include "timer.h"
32#include "directional.h"
33
34namespace SBS {
35
36//shut-off timer
38{
39public:
41 int type;
44
45 Timer(const std::string &name, DirectionalIndicator *parent, int type = 0) : TimerObject(parent, name)
46 {
47 indicator = parent;
48 this->type = type;
49 blink_up = false;
50 blink_down = false;
51 blink_count = 0;
52 }
53 virtual void Notify();
54};
55
56DirectionalIndicator::DirectionalIndicator(Object *parent, int elevator, int car, int floor, bool active_direction, bool single, bool vertical, const std::string &BackTexture, const std::string &uptexture, const std::string &uptexture_lit, const std::string &downtexture, const std::string &downtexture_lit, Real CenterX, Real CenterZ, Real voffset, const std::string &direction, Real BackWidth, Real BackHeight, bool ShowBack, Real tw, Real th) : Object(parent)
57{
58 //create a directional indicator
59
60 //set up SBS object
61 SetValues("DirectionalIndicator", "", false);
62
63 is_enabled = true;
64 this->elevator = elevator;
65 this->car = car;
66 this->floor = floor;
67 Direction = direction;
68 UpTextureUnlit = uptexture;
69 UpTextureLit = uptexture_lit;
70 DownTextureUnlit = downtexture;
71 DownTextureLit = downtexture_lit;
72 UpStatus = false;
73 DownStatus = false;
74 Single = single;
75 Vertical = vertical;
76 ActiveDirection = active_direction;
80 timer = 0;
81 blink_timer = 0;
82 blink = sbs->GetConfigInt("Skyscraper.SBS.DirectionalIndicator.Blink", 0);
83 blink_active = false;
84 timer_interval = sbs->GetConfigInt("Skyscraper.SBS.DirectionalIndicator.Timer", 15000);
85 blink_interval = sbs->GetConfigInt("Skyscraper.SBS.DirectionalIndicator.BlinkTimer", 500);
86
87 SetCase(Direction, false);
89
90 //validate objects
92 return;
94 return;
95 if (!sbs->GetFloor(floor))
96 return;
97
98 bool in_elevator = false;
99 if (parent->GetType() == "ElevatorCar")
100 in_elevator = true;
101
102 //create timer
103 if (ActiveDirection == false)
104 {
105 timer = new Timer("Shut-off Timer", this, 0);
106 blink_timer = new Timer("Blink Timer", this, 1);
107 }
108
109 //move object
110 Move(CenterX, voffset, CenterZ);
111
114
115 //create object mesh
116 SetName("Directional Indicator " + ToString(elevator) + ":" + ToString(car) + ":" + ToString(floor));
117 DirectionalMeshBack = new MeshObject(this, "Back", 0, "", "", sbs->GetConfigFloat("Skyscraper.SBS.MaxSmallRenderDistance", 100));
118
119 if (Single == false)
120 {
121 DirectionalMeshUp = new MeshObject(this, "Up", 0, "", "", sbs->GetConfigFloat("Skyscraper.SBS.MaxSmallRenderDistance", 100));
122 DirectionalMeshDown = new MeshObject(this, "Down", 0, "", "", sbs->GetConfigFloat("Skyscraper.SBS.MaxSmallRenderDistance", 100));
123 }
124 else
125 DirectionalMesh = new MeshObject(this, "Arrow", 0, "", "", sbs->GetConfigFloat("Skyscraper.SBS.MaxSmallRenderDistance", 100));
126
128
129 //create panel
130 if (ShowBack == true)
131 {
132 Wall *wall = DirectionalMeshBack->CreateWallObject("Panel");
133 if (Direction == "front" || Direction == "back")
134 {
135 if (Direction == "front")
136 sbs->DrawWalls(true, false, false, false, false, false);
137 else
138 sbs->DrawWalls(false, true, false, false, false, false);
139 sbs->AddWallMain(wall, "Panel", BackTexture, 0, -BackWidth / 2, 0, BackWidth / 2, 0, BackHeight, BackHeight, 0, 0, tw, th, false);
140 sbs->ResetWalls();
141
142 }
143 else if (Direction == "left" || Direction == "right")
144 {
145 if (Direction == "left")
146 sbs->DrawWalls(true, false, false, false, false, false);
147 else
148 sbs->DrawWalls(false, true, false, false, false, false);
149 sbs->AddWallMain(wall, "Panel", BackTexture, 0, 0, BackWidth / 2, 0, -BackWidth / 2, BackHeight, BackHeight, 0, 0, tw, th, false);
150 sbs->ResetWalls();
151 }
152 }
153
154 //create indicator lanterns
155 int bottomfloor = sbs->GetElevator(elevator)->GetCar(car)->GetBottomFloor();
156 int topfloor = sbs->GetElevator(elevator)->GetCar(car)->GetTopFloor();
157
158 if (Direction == "front" || Direction == "back")
159 {
160 Real x1 = -BackWidth / 4;
161 Real x2 = BackWidth / 4;
162 Real offset;
163 if (Direction == "front")
164 {
165 offset = -0.01;
166 sbs->DrawWalls(true, false, false, false, false, false);
167 }
168 else
169 {
170 offset = 0.01;
171 sbs->DrawWalls(false, true, false, false, false, false);
172 }
173 if (Single == false)
174 {
175 if (Vertical == true)
176 {
177 if ((floor > bottomfloor && floor < topfloor) || ActiveDirection == true || in_elevator == true)
178 {
179 Real height = (BackHeight / 7) * 2;
180 Real altitude = (BackHeight / 7) * 4;
181 Real altitude2 = BackHeight / 7;
182
183 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
184 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
185 wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
186 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude2, altitude2, 1, 1, false);
187 }
188 else
189 {
190 Real height = (BackHeight / 7) * 2;
191 Real altitude = (BackHeight / 7) * 2.5;
192 if (floor < topfloor)
193 {
194 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
195 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
196 }
197 if (floor > bottomfloor)
198 {
199 Wall *wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
200 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
201 }
202 }
203 }
204 else
205 {
206 //horizontal lights
207 if ((floor > bottomfloor && floor < topfloor) || ActiveDirection == true || in_elevator == true)
208 {
209 x1 = (-BackWidth / 2) + ((BackWidth / 7) * 4);
210 x2 = (-BackWidth / 2) + ((BackWidth / 7) * 6);
211 Real x3 = (-BackWidth / 2) + (BackWidth / 7);
212 Real x4 = (-BackWidth / 2) + ((BackWidth / 7) * 3);
213 Real height = (BackHeight / 6) * 4;
214 Real altitude = BackHeight / 6;
215
216 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
217 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
218 wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
219 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, x3, offset, x4, offset, height, height, altitude, altitude, 1, 1, false);
220 }
221 else
222 {
223 Real height = (BackHeight / 7) * 2;
224 Real altitude = (BackHeight / 7) * 2.5;
225 if (floor < topfloor)
226 {
227 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
228 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
229 }
230 if (floor > bottomfloor)
231 {
232 Wall *wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
233 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
234 }
235 }
236 }
237 }
238 else
239 {
240 Real height = (BackHeight / 6) * 4;
241 Real altitude = BackHeight / 6;
242 Wall *wall = DirectionalMesh->CreateWallObject("Directional");
243 sbs->AddWallMain(wall, "Directional", UpTextureUnlit, 0, x1, offset, x2, offset, height, height, altitude, altitude, 1, 1, false);
244 }
245 sbs->ResetWalls();
246 }
247 else
248 {
249 Real z1 = -BackWidth / 4;
250 Real z2 = BackWidth / 4;
251 Real offset;
252 if (Direction == "left")
253 {
254 offset = -0.01;
255 sbs->DrawWalls(true, false, false, false, false, false);
256 }
257 else
258 {
259 //right
260 offset = 0.01;
261 sbs->DrawWalls(false, true, false, false, false, false);
262 }
263 if (Single == false)
264 {
265 if (Vertical == true)
266 {
267 if ((floor > bottomfloor && floor < topfloor) || ActiveDirection == true || in_elevator == true)
268 {
269 Real height = (BackHeight / 7) * 2;
270 Real altitude = (BackHeight / 7) * 4;
271 Real altitude2 = BackHeight / 7;
272 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
273 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
274 wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
275 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude2, altitude2, 1, 1, false);
276 }
277 else
278 {
279 Real height = (BackHeight / 7) * 2;
280 Real altitude = (BackHeight / 7) * 2.5;
281 if (floor < topfloor)
282 {
283 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
284 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
285
286 }
287 if (floor > bottomfloor)
288 {
289 Wall *wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
290 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
291
292 }
293 }
294 }
295 else
296 {
297 //horizontal lights
298 if ((floor > bottomfloor && floor < topfloor) || ActiveDirection == true || in_elevator == true)
299 {
300 z1 = (-BackWidth / 2) + ((BackWidth / 7) * 4);
301 z2 = (-BackWidth / 2) + ((BackWidth / 7) * 6);
302 Real z3 = (-BackWidth / 2) + (BackWidth / 7);
303 Real z4 = (-BackWidth / 2) + ((BackWidth / 7) * 3);
304 Real height = (BackHeight / 6) * 4;
305 Real altitude = BackHeight / 6;
306 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
307 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
308 wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
309 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, offset, z3, offset, z4, height, height, altitude, altitude, 1, 1, false);
310 }
311 else
312 {
313 Real height = (BackHeight / 7) * 2;
314 Real altitude = (BackHeight / 7) * 2.5;
315 if (floor < topfloor)
316 {
317 Wall *wall = DirectionalMeshUp->CreateWallObject("DirectionalUp");
318 sbs->AddWallMain(wall, "DirectionalUp", UpTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
319 }
320 if (floor > bottomfloor)
321 {
322 Wall *wall = DirectionalMeshDown->CreateWallObject("DirectionalDown");
323 sbs->AddWallMain(wall, "DirectionalDown", DownTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
324 }
325 }
326 }
327 }
328 else
329 {
330 Real height = (BackHeight / 6) * 4;
331 Real altitude = BackHeight / 6;
332 Wall *wall = DirectionalMesh->CreateWallObject("Directional");
333 sbs->AddWallMain(wall, "Directional", UpTextureUnlit, 0, offset, z1, offset, z2, height, height, altitude, altitude, 1, 1, false);
334 }
335 sbs->ResetWalls();
336 }
338
339 EnableLoop(true);
340}
341
343{
344 if (timer)
345 {
346 timer->parent_deleting = true;
347 delete timer;
348 }
349 timer = 0;
350
351 if (blink_timer)
352 {
354 delete blink_timer;
355 }
356 blink_timer = 0;
357
358 if (DirectionalMesh)
359 {
361 delete DirectionalMesh;
362 }
363 DirectionalMesh = 0;
364
366 {
368 delete DirectionalMeshUp;
369 }
371
373 {
375 delete DirectionalMeshDown;
376 }
378
380 {
382 delete DirectionalMeshBack;
383 }
385
386 //unregister from parent
387 if (sbs->FastDelete == false && parent_deleting == false)
388 {
389 std::string type = GetParent()->GetType();
390
391 if (type == "ElevatorCar")
392 static_cast<ElevatorCar*>(GetParent())->RemoveDirectionalIndicator(this);
393 else if (type == "Floor")
394 static_cast<Floor*>(GetParent())->RemoveDirectionalIndicator(this);
395 }
396}
397
399{
400 //turns panel on/off
401
402 if (value == is_enabled)
403 return;
404
410 if (DirectionalMesh)
411 DirectionalMesh->Enabled(value);
412
413 is_enabled = value;
414}
415
417{
418 //turn on the 'up' directional light
419
421
422 if (!elev)
423 value = false;
424
425 if (timer && elev)
426 {
427 if (!elev->GetCar(car))
428 return;
429
430 //stop or start timer
431 if (value == false && DownStatus == false)
432 timer->Stop();
433 else if (value == true && (elev->AutoDoors == false || elev->GetCar(car)->ShaftDoorsExist(0, floor) == false))
434 timer->Start(timer_interval, true);
435 }
436
437 if (value == UpStatus)
438 return;
439
440 //turn off up status if in single mode, and switching directions
441 if (Single == true && DownStatus == true)
442 DownStatus = false;
443
444 //set light status
445 if (value == true)
446 SetLights(1, 0);
447 else
448 SetLights(2, 0);
449}
450
452{
453 //turn on the 'down' directional light
454
456
457 if (!elev)
458 value = false;
459
460 if (timer && elev)
461 {
462 if (!elev->GetCar(car))
463 return;
464
465 //stop or start timer
466 if (value == false && UpStatus == false)
467 timer->Stop();
468 else if (value == true && (elev->AutoDoors == false || elev->GetCar(car)->ShaftDoorsExist(0, floor) == false))
469 timer->Start(timer_interval, true);
470 }
471
472 if (value == DownStatus)
473 return;
474
475 //turn off up status if in single mode, and switching directions
476 if (Single == true && UpStatus == true)
477 UpStatus = false;
478
479 //set light status
480 if (value == true)
481 SetLights(0, 1);
482 else
483 SetLights(0, 2);
484}
485
487{
488 //set status of directional lights
489 //values are 0 for no change, 1 for on, and 2 for off
490
491 if (Single == false)
492 {
493 if (up == 1 && DirectionalMeshUp)
495 if (up == 2 && DirectionalMeshUp)
497 if (down == 1 && DirectionalMeshDown)
499 if (down == 2 && DirectionalMeshDown)
501 }
502 else
503 {
504 if (DirectionalMesh)
505 {
506 if (up == 1)
508 if (down == 1)
510 if (up == 2 || down == 2)
512 }
513 }
514
515 //change status
516 if (up == 1)
517 UpStatus = true;
518 if (up == 2)
519 UpStatus = false;
520 if (down == 1)
521 DownStatus = true;
522 if (down == 2)
523 DownStatus = false;
524
525 //blink indicator if specified
526 if (blink > 0 && blink_active == false && blink_timer)
527 {
532 blink_active = true;
533 }
534}
535
537{
538 //when shut-off timer triggers, switch off lights
539 if (type == 0)
540 {
541
542 if (indicator->UpStatus == false && indicator->DownStatus == false)
543 return;
544
545 //turn off all lights
546 indicator->UpLight(false);
547 indicator->DownLight(false);
548 }
549
550 //for blink timer, blink lights up to blink_count
551 if (type == 1)
552 {
553 if (blink_up == true)
554 {
555 //flip up indicator status
557 }
558 if (blink_down == true)
559 {
560 //flip down indicator status
562 }
563 blink_count--;
564
565 if (blink_count == 0)
566 {
567 Stop();
568 indicator->blink_active = false;
569 }
570 }
571}
572
574{
575 //turn off indicator
576
577 SetLights(2, 2);
578}
579
581{
582 if (sbs->GetPower() == false)
583 Off();
584}
585
586}
Timer(const std::string &name, DirectionalIndicator *parent, int type=0)
DirectionalIndicator * indicator
MeshObject * DirectionalMeshUp
Definition directional.h:61
MeshObject * DirectionalMeshDown
Definition directional.h:62
DirectionalIndicator(Object *parent, int elevator, int car, int floor, bool active_direction, bool single, bool vertical, const std::string &BackTexture, const std::string &uptexture, const std::string &uptexture_lit, const std::string &downtexture, const std::string &downtexture_lit, Real CenterX, Real CenterZ, Real voffset, const std::string &direction, Real BackWidth, Real BackHeight, bool ShowBack, Real tw, Real th)
void DownLight(bool value)
MeshObject * DirectionalMeshBack
Definition directional.h:60
MeshObject * DirectionalMesh
Definition directional.h:63
void SetLights(int up, int down)
bool ShaftDoorsExist(int number, int floor, bool include_nonserviced=false)
ElevatorCar * GetCar(int number)
void Enabled(bool value)
Definition mesh.cpp:154
bool ChangeTexture(const std::string &texture, bool matcheck=true)
Definition mesh.cpp:709
Wall * CreateWallObject(const std::string &name)
Definition mesh.cpp:208
Object * GetParent()
Definition object.cpp:42
void SetName(const std::string &name)
Definition object.cpp:72
bool parent_deleting
Definition object.h:64
virtual void Move(const Vector3 &vector, Real speed=1.0)
Definition object.cpp:253
void SetValues(const std::string &type, const std::string &name, bool is_permanent, bool is_movable=true)
Definition object.cpp:144
void EnableLoop(bool value)
Definition object.cpp:521
const std::string & GetType()
Definition object.cpp:177
Elevator * GetElevator(int number)
Definition sbs.cpp:1746
bool GetPower()
Definition sbs.cpp:4701
Real GetConfigFloat(const std::string &key, Real default_value)
Definition sbs.cpp:3249
bool AddWallMain(Wall *wallobject, const std::string &name, const std::string &texture, Real thickness, Real x1, Real z1, Real x2, Real z2, Real height_in1, Real height_in2, Real altitude1, Real altitude2, Real tw, Real th, bool autosize)
Definition sbs.cpp:690
void ResetWalls(bool ToDefaults=false)
Definition sbs.cpp:1854
Floor * GetFloor(int number)
Definition sbs.cpp:1739
bool FastDelete
Definition sbs.h:188
TextureManager * GetTextureManager()
Definition sbs.cpp:4558
int GetConfigInt(const std::string &key, int default_value)
Definition sbs.cpp:3232
void DrawWalls(bool MainN, bool MainP, bool SideN, bool SideP, bool Top, bool Bottom)
Definition sbs.cpp:1833
void ResetTextureMapping(bool todefaults=false)
Definition texture.cpp:1444
void EnableLighting(const std::string &material_name, bool value)
Definition texture.cpp:2207
void Start(int milliseconds=-1, bool oneshot=false)
Definition timer.cpp:49
Ogre::Real Real
Definition globals.h:57
void SetCase(std::string &string, bool uppercase)
Definition globals.cpp:172
std::string ToString(int number)
Definition globals.cpp:279
void TrimString(std::string &string)
Definition globals.cpp:188