4 Scalable Building Simulator - Floor Object
5 The Skyscraper Project - Version 1.10 Alpha
6 Copyright (C)2004-2015 Ryan Thoryk
7 http://www.skyscrapersim.com
8 http://sourceforge.net/projects/skyscraper
9 Contact - ryan@tliquest.net
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.
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.
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.
32 extern SBS *sbs; //external pointer to the SBS engine
34 Floor::Floor(int number)
37 SetValues(this, sbs, "Floor", "", false);
39 //Set floor's object number
41 std::string num = ToString2(Number);
42 SetName(std::string("Floor " + num).c_str());
44 //Create primary level mesh
45 Level = new MeshObject(this, std::string("Level " + num).c_str());
47 //Create interfloor mesh
48 Interfloor = new MeshObject(this,std::string("Interfloor " + num).c_str());
50 //Create columnframe mesh
51 ColumnFrame = new MeshObject(this, std::string("ColumnFrame " + num).c_str());
55 IsColumnFrameEnabled = true;
56 IsInterfloorEnabled = true;
58 //init other variables
63 IndicatorTexture = "";
68 EnabledGroup_Floor = 0;
76 for (int i = 0; i < (int)EscalatorArray.size(); i++)
78 if (EscalatorArray[i])
80 EscalatorArray[i]->parent_deleting = true;
81 delete EscalatorArray[i];
83 EscalatorArray[i] = 0;
86 //delete camera textures
87 for (int i = 0; i < (int)CameraTextureArray.size(); i++)
89 if (CameraTextureArray[i])
91 CameraTextureArray[i]->parent_deleting = true;
92 delete CameraTextureArray[i];
94 CameraTextureArray[i] = 0;
98 for (int i = 0; i < (int)ControlArray.size(); i++)
102 ControlArray[i]->parent_deleting = true;
103 delete ControlArray[i];
109 for (int i = 0; i < (int)TriggerArray.size(); i++)
113 TriggerArray[i]->parent_deleting = true;
114 delete TriggerArray[i];
120 for (int i = 0; i < (int)ModelArray.size(); i++)
124 ModelArray[i]->parent_deleting = true;
125 delete ModelArray[i];
131 for (int i = 0; i < (int)lights.size(); i++)
135 lights[i]->parent_deleting = true;
141 //delete call buttons
142 for (int i = 0; i < (int)CallButtonArray.size(); i++)
144 if (CallButtonArray[i])
146 CallButtonArray[i]->parent_deleting = true;
147 delete CallButtonArray[i];
149 CallButtonArray[i] = 0;
153 for (int i = 0; i < (int)DoorArray.size(); i++)
157 DoorArray[i]->parent_deleting = true;
163 //delete floor indicators
164 for (int i = 0; i < (int)FloorIndicatorArray.size(); i++)
166 if (FloorIndicatorArray[i])
168 FloorIndicatorArray[i]->parent_deleting = true;
169 delete FloorIndicatorArray[i];
171 FloorIndicatorArray[i] = 0;
174 //delete directional indicators
175 for (int i = 0; i < (int)DirIndicatorArray.size(); i++)
177 if (DirIndicatorArray[i])
179 DirIndicatorArray[i]->parent_deleting = true;
180 delete DirIndicatorArray[i];
182 DirIndicatorArray[i] = 0;
186 for (int i = 0; i < (int)sounds.size(); i++)
190 sounds[i]->parent_deleting = true;
199 Level->parent_deleting = true;
206 Interfloor->parent_deleting = true;
213 ColumnFrame->parent_deleting = true;
218 //delete walls in external mesh
219 if (sbs->FastDelete == false)
220 sbs->External->DeleteWalls(this);
222 //unregister from parent
223 if (sbs->FastDelete == false && parent_deleting == false)
224 sbs->RemoveFloor(this);
227 WallObject* Floor::AddFloor(const char *name, const char *texture, float thickness, float x1, float z1, float x2, float z2, float voffset1, float voffset2, bool reverse_axis, bool texture_direction, float tw, float th, bool isexternal, bool legacy_behavior)
229 //Adds a floor with the specified dimensions and vertical offset
233 if (isexternal == false)
235 wall = Level->CreateWallObject(name);
236 sbs->AddFloorMain(wall, name, texture, thickness, x1, z1, x2, z2, GetBase(true) + voffset1, GetBase(true) + voffset2, reverse_axis, texture_direction, tw, th, true, legacy_behavior);
240 wall = sbs->External->CreateWallObject(name);
241 sbs->AddFloorMain(wall, name, texture, thickness, x1, z1, x2, z2, Altitude + voffset1, Altitude + voffset2, reverse_axis, texture_direction, tw, th, true, legacy_behavior);
246 WallObject* Floor::AddInterfloorFloor(const char *name, const char *texture, float thickness, float x1, float z1, float x2, float z2, float voffset1, float voffset2, bool reverse_axis, bool texture_direction, float tw, float th, bool legacy_behavior)
248 //Adds an interfloor floor with the specified dimensions and vertical offset
250 WallObject *wall = Interfloor->CreateWallObject(name);
251 sbs->AddFloorMain(wall, name, texture, thickness, x1, z1, x2, z2, voffset1, voffset2, reverse_axis, texture_direction, tw, th, true, legacy_behavior);
255 WallObject* Floor::AddWall(const char *name, const char *texture, float thickness, float x1, float z1, float x2, float z2, float height_in1, float height_in2, float voffset1, float voffset2, float tw, float th, bool isexternal)
257 //Adds a wall with the specified dimensions
260 if (isexternal == false)
262 wall = Level->CreateWallObject(name);
263 sbs->AddWallMain(wall, name, texture, thickness, x1, z1, x2, z2, height_in1, height_in2, GetBase(true) + voffset1, GetBase(true) + voffset2, tw, th, true);
267 wall = sbs->External->CreateWallObject(name);
268 sbs->AddWallMain(wall, name, texture, thickness, x1, z1, x2, z2, height_in1, height_in2, Altitude + voffset1, Altitude + voffset2, tw, th, true);
273 WallObject* Floor::AddInterfloorWall(const char *name, const char *texture, float thickness, float x1, float z1, float x2, float z2, float height_in1, float height_in2, float voffset1, float voffset2, float tw, float th)
275 //Adds an interfloor wall with the specified dimensions
277 WallObject *wall = Interfloor->CreateWallObject(name);
278 sbs->AddWallMain(wall, name, texture, thickness, x1, z1, x2, z2, height_in1, height_in2, voffset1, voffset2, tw, th, true);
282 void Floor::Enabled(bool value)
286 if (IsEnabled == value)
289 SBS_PROFILE("Floor::Enabled");
290 Level->Enable(value);
304 if (sbs->InterfloorOnTop == false)
306 //only turn off interfloor if floor below is disabled
307 Floor *floor = sbs->GetFloor(Number - 1);
310 if (floor->IsEnabled == false)
311 EnableInterfloor(false);
314 EnableInterfloor(false);
316 //turn off adjacent interfloor
317 floor = sbs->GetFloor(Number + 1);
320 if (floor->IsEnabled == false)
321 floor->EnableInterfloor(false);
326 //only turn off interfloor if floor above is disabled
327 Floor *floor = sbs->GetFloor(Number + 1);
330 if (floor->IsEnabled == false)
331 EnableInterfloor(false);
334 EnableInterfloor(false);
336 //turn off adjacent interfloor
337 floor = sbs->GetFloor(Number - 1);
340 if (floor->IsEnabled == false)
341 floor->EnableInterfloor(false);
347 if (sbs->InterfloorOnTop == false)
349 //turn on interfloor for next floor
350 if (sbs->GetFloor(Number + 1))
351 sbs->GetFloor(Number + 1)->EnableInterfloor(true);
355 //turn on interfloor for previous floor
356 if (sbs->GetFloor(Number - 1))
357 sbs->GetFloor(Number - 1)->EnableInterfloor(true);
359 EnableInterfloor(true);
362 EnableColumnFrame(value);
365 for (size_t i = 0; i < (int)ControlArray.size(); i++)
368 ControlArray[i]->Enabled(value);
372 for (size_t i = 0; i < (int)TriggerArray.size(); i++)
375 TriggerArray[i]->Enabled(value);
379 for (size_t i = 0; i < (int)ModelArray.size(); i++)
382 ModelArray[i]->Enable(value);
386 for (size_t i = 0; i < (int)CallButtonArray.size(); i++)
388 if (CallButtonArray[i])
389 CallButtonArray[i]->Enabled(value);
393 for (size_t i = 0; i < (int)DoorArray.size(); i++)
396 DoorArray[i]->Enabled(value);
399 //turn on/off directional indicators
400 for (int i = 0; i < (int)DirIndicatorArray.size(); i++)
402 if (DirIndicatorArray[i])
403 DirIndicatorArray[i]->Enabled(value);
405 UpdateDirectionalIndicators();
408 for (int i = 0; i < (int)FloorIndicatorArray.size(); i++)
410 if (FloorIndicatorArray[i])
411 FloorIndicatorArray[i]->Enabled(value);
413 //update floor indicator values
414 UpdateFloorIndicators();
417 for (int i = 0; i < (int)sounds.size(); i++)
421 if (sounds[i]->GetLoopState() == true)
432 float Floor::FullHeight()
434 //calculate full height of a floor
435 return InterfloorHeight + Height;
438 Object* Floor::AddCallButtons(std::vector<int> &elevators, const char *sound_file, const char *BackTexture, const char *UpButtonTexture, const char *UpButtonTexture_Lit, const char *DownButtonTexture, const char *DownButtonTexture_Lit, float CenterX, float CenterZ, float voffset, const char *direction, float BackWidth, float BackHeight, bool ShowBack, float tw, float th)
442 //check if any of the elevators serve the current floor
444 for (int i = 0; i < (int)elevators.size(); i++)
446 Elevator *elev = sbs->GetElevator(elevators[i]);
449 if (elev->IsServicedFloor(Number) == true)
457 //exit if none of the elevators serve the floor
462 int Current = (int)CallButtonArray.size();
463 CallButton *button = new CallButton(elevators, Number, Current, sound_file, BackTexture, UpButtonTexture, UpButtonTexture_Lit, DownButtonTexture, DownButtonTexture_Lit, CenterX, CenterZ, voffset, direction, BackWidth, BackHeight, ShowBack, tw, th);
464 CallButtonArray.push_back(button);
468 void Floor::Cut(const Ogre::Vector3 &start, const Ogre::Vector3 &end, bool cutwalls, bool cutfloors, bool fast, int checkwallnumber, bool prepare)
470 //caller to SBS cut function
471 //Y values are relative to the floor's altitude
472 //if fast is specified, skips the interfloor scan
474 for (int i = 0; i < (int)Level->Walls.size(); i++)
480 sbs->Cut(Level->Walls[i], Ogre::Vector3(start.x, start.y, start.z), Ogre::Vector3(end.x, end.y, end.z), cutwalls, cutfloors, checkwallnumber, reset);
484 for (int i = 0; i < (int)Interfloor->Walls.size(); i++)
486 sbs->Cut(Interfloor->Walls[i], Ogre::Vector3(start.x, start.y, start.z), Ogre::Vector3(end.x, end.y, end.z), cutwalls, cutfloors, checkwallnumber, false);
491 void Floor::CutAll(const Ogre::Vector3 &start, const Ogre::Vector3 &end, bool cutwalls, bool cutfloors, bool prepare)
493 //cuts all objects related to this floor (floor, interfloor, shafts, stairs and external)
494 //Y values are relative to the floor's altitude
497 Cut(start, end, cutwalls, cutfloors, false);
500 for (int i = 1; i <= sbs->Shafts(); i++)
502 if (sbs->GetShaft(i))
503 sbs->GetShaft(i)->Cut(false, Number, start, end, cutwalls, cutfloors);
507 for (int i = 1; i <= sbs->StairsNum(); i++)
509 if (sbs->GetStairs(i))
510 sbs->GetStairs(i)->Cut(false, Number, start, end, cutwalls, cutfloors);
514 for (int i = 0; i < (int)sbs->External->Walls.size(); i++)
515 sbs->Cut(sbs->External->Walls[i], Ogre::Vector3(start.x, Altitude + start.y, start.z), Ogre::Vector3(end.x, Altitude + end.y, end.z), cutwalls, cutfloors);
518 void Floor::AddGroupFloor(int number)
520 //adds a floor number to the group list.
521 //Groups are used to enable multiple floors at the same time when
522 //a user arrives at a floor
524 if (IsInGroup(number))
527 Group.push_back(number);
528 std::sort(Group.begin(), Group.end());
531 void Floor::RemoveGroupFloor(int number)
533 //removes a floor number from the group list
535 for (int i = 0; i < (int)Group.size(); i++)
537 if (Group[i] == number)
539 Group.erase(Group.begin() + i);
545 void Floor::EnableGroup(bool value)
547 //enable floors grouped with this floor
549 SBS_PROFILE("Floor::EnableGroup");
550 if (Group.size() > 0)
552 for (size_t i = 0; i < Group.size(); i++)
554 Floor *floor = sbs->GetFloor(Group[i]);
556 //check if floor exists
560 floor->Enabled(value);
564 floor->EnabledGroup = true;
565 floor->EnabledGroup_Floor = Number;
569 floor->EnabledGroup = false;
570 floor->EnabledGroup_Floor = 0;
573 //enable shafts and stairs for other floor
574 for (int j = 1; j <= sbs->Shafts(); j++)
576 Shaft *shaft = sbs->GetShaft(j);
579 if (shaft->IsEnabled == false)
580 shaft->Enabled(Group[i], value, true);
583 for (int j = 1; j <= sbs->StairsNum(); j++)
585 Stairs *stairs = sbs->GetStairs(j);
588 if (stairs->IsEnabled == false)
589 stairs->Enabled(Group[i], value);
597 bool Floor::IsInGroup(int floor)
599 //return true if the specified floor is in the group listing
601 if (Group.size() > 0)
603 for (size_t i = 0; i < Group.size(); i++)
605 if (Group[i] == floor)
612 Object* Floor::AddDoor(const char *open_sound, const char *close_sound, bool open_state, const char *texture, float thickness, int direction, float speed, float CenterX, float CenterZ, float width, float height, float voffset, float tw, float th)
614 //interface to the SBS AddDoor function
616 if (direction > 8 || direction < 1)
618 ReportError("Door direction out of range");
622 float x1, z1, x2, z2;
628 z1 = CenterZ - (width / 2);
629 z2 = CenterZ + (width / 2);
633 x1 = CenterX - (width / 2);
634 x2 = CenterX + (width / 2);
641 CutAll(Ogre::Vector3(x1 - 1, GetBase(true) + voffset, z1), Ogre::Vector3(x2 + 1, GetBase(true) + voffset + height, z2), true, false);
643 CutAll(Ogre::Vector3(x1, GetBase(true) + voffset, z1 - 1), Ogre::Vector3(x2, GetBase(true) + voffset + height, z2 + 1), true, false);
645 int number = (int)DoorArray.size();
646 std::string name = "Floor " + ToString2(Number) + ":Door " + ToString2(number);
647 Door* door = new Door(this, name.c_str(), open_sound, close_sound, open_state, texture, thickness, direction, speed, CenterX, CenterZ, width, height, GetBase(true) + voffset, tw, th);
648 DoorArray.push_back(door);
652 bool Floor::CalculateAltitude()
654 //calculate the floor's altitude in relation to floor below (or above it, if it's a basement level)
655 //and return the altitude value
656 //if the related floor does not have an adjacent floor, return false
662 if (sbs->GetFloor(Number - 1))
663 Altitude = sbs->GetFloor(Number - 1)->Altitude + sbs->GetFloor(Number - 1)->FullHeight();
666 return ReportError("Invalid floor number specified - no adjacent floor");
671 Altitude = -FullHeight();
675 if (sbs->GetFloor(Number + 1))
676 Altitude = sbs->GetFloor(Number + 1)->Altitude - FullHeight();
678 return ReportError("Invalid floor number specified - no adjacent floor");
683 SetAltitude(Altitude);
688 void Floor::EnableColumnFrame(bool value)
690 //enable/disable columnframe mesh
691 ColumnFrame->Enable(value);
692 IsColumnFrameEnabled = value;
695 void Floor::EnableInterfloor(bool value)
697 //enable/disable interfloor mesh
698 Interfloor->Enable(value);
699 IsInterfloorEnabled = value;
702 WallObject* Floor::ColumnWallBox(const char *name, const char *texture, float x1, float x2, float z1, float z2, float height_in, float voffset, float tw, float th, bool inside, bool outside, bool top, bool bottom)
704 //create columnframe wall box
706 WallObject *wall = ColumnFrame->CreateWallObject(name);
707 sbs->CreateWallBox(wall, name, texture, x1, x2, z1, z2, height_in, voffset, tw, th, inside, outside, top, bottom, true);
711 WallObject* Floor::ColumnWallBox2(const char *name, const char *texture, float CenterX, float CenterZ, float WidthX, float LengthZ, float height_in, float voffset, float tw, float th, bool inside, bool outside, bool top, bool bottom)
713 //create columnframe wall box from a central location
715 WallObject *wall = ColumnFrame->CreateWallObject(name);
716 sbs->CreateWallBox2(wall, name, texture, CenterX, CenterZ, WidthX, LengthZ, height_in, voffset, tw, th, inside, outside, top, bottom, true);
720 Object* Floor::AddFloorIndicator(int elevator, bool relative, const char *texture_prefix, const char *direction, float CenterX, float CenterZ, float width, float height, float voffset)
722 //Creates a floor indicator at the specified location
724 if (relative == false)
726 FloorIndicator *ind = new FloorIndicator(this, elevator, texture_prefix, direction, CenterX, CenterZ, width, height, GetBase(true) + voffset);
727 FloorIndicatorArray.push_back(ind);
732 Elevator* elev = sbs->GetElevator(elevator);
735 FloorIndicator *ind = new FloorIndicator(this, elevator, texture_prefix, direction, elev->GetPosition().x + CenterX, elev->GetPosition().z + CenterZ, width, height, GetBase(true) + voffset);
736 FloorIndicatorArray.push_back(ind);
744 void Floor::UpdateFloorIndicators(int elevator)
746 //updates a floor indicator for a specified elevator
748 for (int i = 0; i < (int)FloorIndicatorArray.size(); i++)
750 if (FloorIndicatorArray[i])
752 if (FloorIndicatorArray[i]->elev == elevator)
753 FloorIndicatorArray[i]->Update();
758 void Floor::UpdateFloorIndicators()
760 //updates all floor indicators
762 for (int i = 0; i < (int)FloorIndicatorArray.size(); i++)
764 if (FloorIndicatorArray[i])
765 FloorIndicatorArray[i]->Update();
771 //floor object main loop; runs if camera is currently on this floor
773 if (IsEnabled == true)
775 for (int i = 0; i < (int)TriggerArray.size(); i++)
778 TriggerArray[i]->Check();
783 std::vector<int> Floor::GetCallButtons(int elevator)
785 //get numbers of call buttons that service the specified elevator
787 std::vector<int> buttons;
788 buttons.reserve(CallButtonArray.size());
789 for (int i = 0; i < (int)CallButtonArray.size(); i++)
791 //put button number onto the array if it serves the elevator
792 if (CallButtonArray[i])
794 if (CallButtonArray[i]->ServicesElevator(elevator) == true)
795 buttons.push_back(i);
801 CallButton* Floor::GetCallButton(int elevator)
803 //returns the first call button object that services the specified elevator
805 for (int i = 0; i < (int)CallButtonArray.size(); i++)
807 if (CallButtonArray[i])
809 if (CallButtonArray[i]->ServicesElevator(elevator) == true)
810 return CallButtonArray[i];
816 void Floor::AddFillerWalls(const char *texture, float thickness, float CenterX, float CenterZ, float width, float height, float voffset, bool direction, float tw, float th)
818 //convenience function for adding filler walls around doors
819 //direction is either "false" for a door that faces left/right, or "true" for one that faces front/back
821 float x1 = 0, x2 = 0, z1 = 0, z2 = 0, depth1 = 0, depth2 = 0;
823 //exit if no height given
826 ReportError("AddFillerWalls: no wall height specified");
830 if (sbs->GetWallOrientation() == 0)
835 if (sbs->GetWallOrientation() == 1)
837 depth1 = thickness / 2;
838 depth2 = thickness / 2;
840 if (sbs->GetWallOrientation() == 2)
846 if (direction == false)
848 //door faces left/right
849 x1 = CenterX - depth1;
850 x2 = CenterX + depth2;
851 z1 = CenterZ - (width / 2);
852 z2 = CenterZ + (width / 2);
856 //door faces front/back
857 x1 = CenterX - (width / 2);
858 x2 = CenterX + (width / 2);
859 z1 = CenterZ - depth1;
860 z2 = CenterZ + depth2;
863 //perform a cut in the area
864 CutAll(Ogre::Vector3(x1, GetBase(true) + voffset, z1), Ogre::Vector3(x2, GetBase(true) + voffset + height, z2), true, false);
867 sbs->DrawWalls(false, true, false, false, false, false);
868 if (direction == false)
869 AddWall("FillerWallLeft", texture, 0, x1, z1, x2, z1, height, height, voffset, voffset, tw, th, false);
871 AddWall("FillerWallLeft", texture, 0, x1, z1, x1, z2, height, height, voffset, voffset, tw, th, false);
874 sbs->DrawWalls(true, false, false, false, false, false);
875 if (direction == false)
876 AddWall("FillerWallRight", texture, 0, x1, z2, x2, z2, height, height, voffset, voffset, tw, th, false);
878 AddWall("FillerWallRight", texture, 0, x2, z1, x2, z2, height, height, voffset, voffset, tw, th, false);
880 AddFloor("FillerWallTop", texture, 0, x1, z1, x2, z2, height + voffset, height + voffset, false, false, tw, th, false);
884 Object* Floor::AddSound(const char *name, const char *filename, Ogre::Vector3 position, bool loop, float volume, int speed, float min_distance, float max_distance, float doppler_level, float cone_inside_angle, float cone_outside_angle, float cone_outside_volume, Ogre::Vector3 direction)
886 //create a looping sound object
888 Sound *sound = new Sound(this, name, false);
889 sounds.push_back(sound);
891 //set parameters and play sound
892 sound->Move(position.x, GetBase(true) + position.y, position.z);
893 sound->SetDirection(direction);
894 sound->SetVolume(volume);
895 sound->SetSpeed(speed);
896 sound->SetDistances(min_distance, max_distance);
897 sound->SetDirection(direction);
898 sound->SetDopplerLevel(doppler_level);
899 sound->SetConeSettings(cone_inside_angle, cone_outside_angle, cone_outside_volume);
900 sound->Load(filename);
902 if (loop && sbs->IsRunning == true && sbs->camera->CurrentFloor == Number)
908 std::vector<Sound*> Floor::GetSound(const char *name)
912 std::string findname = name;
913 SetCase(findname, false);
914 std::vector<Sound*> soundlist;
915 for (int i = 0; i < (int)sounds.size(); i++)
919 std::string name2 = sounds[i]->GetName();
920 SetCase(name2, false);
921 if (findname == name2)
922 soundlist.push_back(sounds[i]);
928 void Floor::Report(std::string message)
930 //general reporting function
931 sbs->Report("Floor " + ToString2(Number) + ": " + message);
934 bool Floor::ReportError(std::string message)
936 //general reporting function
937 return sbs->ReportError("Floor " + ToString2(Number) + ": " + message);
940 float Floor::GetBase(bool relative)
942 //returns the base of the floor
943 //if Interfloor is on the bottom of the level (by default), the base is GetBase()
944 //otherwise the base is just altitude
945 if (relative == false)
947 if (sbs->InterfloorOnTop == false)
948 return Altitude + InterfloorHeight;
954 if (sbs->InterfloorOnTop == false)
955 return InterfloorHeight;
961 Object* Floor::AddDirectionalIndicator(int elevator, bool relative, bool active_direction, 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)
963 //create a directional indicator on the specified floor, associated with a given elevator
966 Report("adding directional indicator");
968 Elevator *elev = sbs->GetElevator(elevator);
973 if (relative == true)
975 x = elev->GetPosition().x + CenterX;
976 z = elev->GetPosition().z + CenterZ;
984 if (active_direction == false)
986 //if active_direction is false, only create indicator if the elevator serves the floor
987 if (elev->IsServicedFloor(Number) == false)
991 DirectionalIndicator *indicator = new DirectionalIndicator(this, elevator, Number, active_direction, single, vertical, BackTexture, uptexture, uptexture_lit, downtexture, downtexture_lit, x, z, GetBase(true) + voffset, direction, BackWidth, BackHeight, ShowBack, tw, th);
992 DirIndicatorArray.push_back(indicator);
996 void Floor::SetDirectionalIndicators(int elevator, bool UpLight, bool DownLight)
998 //set light status of all standard (non active-direction) directional indicators associated with the given elevator
1000 for (int i = 0; i < (int)DirIndicatorArray.size(); i++)
1002 DirectionalIndicator *indicator = DirIndicatorArray[i];
1006 if (indicator->elevator == elevator && indicator->ActiveDirection == false)
1008 indicator->DownLight(DownLight);
1009 indicator->UpLight(UpLight);
1015 void Floor::UpdateDirectionalIndicators(int elevator)
1017 //updates the active-direction indicators associated with the given elevator
1019 SBS_PROFILE("Floor::UpdateDirectionalIndicators1");
1020 for (int i = 0; i < (int)DirIndicatorArray.size(); i++)
1022 DirectionalIndicator *indicator = DirIndicatorArray[i];
1026 if (indicator->elevator == elevator && indicator->ActiveDirection == true)
1028 Elevator *elev = sbs->GetElevator(elevator);
1033 if (elev->ActiveDirection == 1)
1035 indicator->UpLight(true);
1036 indicator->DownLight(false);
1038 if (elev->ActiveDirection == 0)
1040 indicator->UpLight(false);
1041 indicator->DownLight(false);
1043 if (elev->ActiveDirection == -1)
1045 indicator->UpLight(false);
1046 indicator->DownLight(true);
1053 void Floor::UpdateDirectionalIndicators()
1055 //updates all active-direction indicators
1057 SBS_PROFILE("Floor::UpdateDirectionalIndicators2");
1059 for (int i = 0; i < (int)DirIndicatorArray.size(); i++)
1061 DirectionalIndicator *indicator = DirIndicatorArray[i];
1065 if (indicator->ActiveDirection == true)
1067 Elevator *elev = sbs->GetElevator(indicator->elevator);
1072 if (elev->ActiveDirection == 1)
1074 indicator->UpLight(true);
1075 indicator->DownLight(false);
1077 if (elev->ActiveDirection == 0)
1079 indicator->UpLight(false);
1080 indicator->DownLight(false);
1082 if (elev->ActiveDirection == -1)
1084 indicator->UpLight(false);
1085 indicator->DownLight(true);
1092 Door* Floor::GetDoor(int number)
1095 if (number < (int)DoorArray.size())
1097 if (DoorArray[number])
1098 return DoorArray[number];
1104 void Floor::RemoveCallButton(CallButton *callbutton)
1106 //remove a call button object from the array
1107 //this does not delete the object
1108 for (int i = 0; i < (int)CallButtonArray.size(); i++)
1110 if (CallButtonArray[i] == callbutton)
1112 CallButtonArray.erase(CallButtonArray.begin() + i);
1118 void Floor::RemoveFloorIndicator(FloorIndicator *indicator)
1120 //remove a floor indicator from the array
1121 //this does not delete the object
1122 for (int i = 0; i < (int)FloorIndicatorArray.size(); i++)
1124 if (FloorIndicatorArray[i] == indicator)
1126 FloorIndicatorArray.erase(FloorIndicatorArray.begin() + i);
1132 void Floor::RemoveDirectionalIndicator(DirectionalIndicator *indicator)
1134 //remove a directional indicator from the array
1135 //this does not delete the object
1136 for (int i = 0; i < (int)DirIndicatorArray.size(); i++)
1138 if (DirIndicatorArray[i] == indicator)
1140 DirIndicatorArray.erase(DirIndicatorArray.begin() + i);
1146 void Floor::RemoveDoor(Door *door)
1148 //remove a door from the array
1149 //this does not delete the object
1150 for (int i = 0; i < (int)DoorArray.size(); i++)
1152 if (DoorArray[i] == door)
1154 DoorArray.erase(DoorArray.begin() + i);
1160 void Floor::RemoveSound(Sound *sound)
1162 //remove a sound from the array
1163 //this does not delete the object
1164 for (int i = 0; i < (int)sounds.size(); i++)
1166 if (sounds[i] == sound)
1168 sounds.erase(sounds.begin() + i);
1174 void Floor::RemoveLight(Light *light)
1176 //remove a light reference (does not delete the object itself)
1177 for (int i = 0; i < (int)lights.size(); i++)
1179 if (lights[i] == light)
1181 lights.erase(lights.begin() + i);
1187 void Floor::RemoveModel(Model *model)
1189 //remove a model reference (does not delete the object itself)
1190 for (int i = 0; i < (int)ModelArray.size(); i++)
1192 if (ModelArray[i] == model)
1194 ModelArray.erase(ModelArray.begin() + i);
1200 void Floor::RemoveControl(Control *control)
1202 //remove a control reference (does not delete the object itself)
1203 for (int i = 0; i < (int)ControlArray.size(); i++)
1205 if (ControlArray[i] == control)
1207 ControlArray.erase(ControlArray.begin() + i);
1213 void Floor::RemoveTrigger(Trigger *trigger)
1215 //remove a trigger reference (does not delete the object itself)
1216 for (int i = 0; i < (int)TriggerArray.size(); i++)
1218 if (TriggerArray[i] == trigger)
1220 TriggerArray.erase(TriggerArray.begin() + i);
1226 void Floor::RemoveCameraTexture(CameraTexture *cameratexture)
1228 //remove a camera texture reference (does not delete the object itself)
1229 for (int i = 0; i < (int)CameraTextureArray.size(); i++)
1231 if (CameraTextureArray[i] == cameratexture)
1233 CameraTextureArray.erase(CameraTextureArray.begin() + i);
1239 Object* Floor::AddLight(const char *name, int type, Ogre::Vector3 position, Ogre::Vector3 direction, float color_r, float color_g, float color_b, float spec_color_r, float spec_color_g, float spec_color_b, float spot_inner_angle, float spot_outer_angle, float spot_falloff, float att_range, float att_constant, float att_linear, float att_quadratic)
1243 Light* light = new Light(this, name, type, position + Ogre::Vector3(0, GetBase(true), 0), direction, color_r, color_g, color_b, spec_color_r, spec_color_g, spec_color_b, spot_inner_angle, spot_outer_angle, spot_falloff, att_range, att_constant, att_linear, att_quadratic);
1244 lights.push_back(light);
1248 Object* Floor::AddModel(const char *name, const char *filename, bool center, Ogre::Vector3 position, Ogre::Vector3 rotation, float max_render_distance, float scale_multiplier, bool enable_physics, float restitution, float friction, float mass)
1251 Model* model = new Model(this, name, filename, center, position + Ogre::Vector3(0, GetBase(true), 0), rotation, max_render_distance, scale_multiplier, enable_physics, restitution, friction, mass);
1252 if (model->load_error == true)
1257 ModelArray.push_back(model);
1261 void Floor::ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
1263 //change all instances of oldtexture in all meshes to newtexture
1264 Level->ReplaceTexture(oldtexture, newtexture);
1265 Interfloor->ReplaceTexture(oldtexture, newtexture);
1266 ColumnFrame->ReplaceTexture(oldtexture, newtexture);
1269 Object* Floor::AddControl(const char *name, const char *sound, const char *direction, float CenterX, float CenterZ, float width, float height, float voffset, std::vector<std::string> &action_names, std::vector<std::string> &textures)
1272 std::vector<Action*> actionnull; //not used
1273 Control* control = new Control(this, name, false, sound, action_names, actionnull, textures, direction, width, height, true);
1274 control->Move(CenterX, GetBase(true) + voffset, CenterZ);
1275 ControlArray.push_back(control);
1279 Object* Floor::AddTrigger(const char *name, const char *sound_file, Ogre::Vector3 &area_min, Ogre::Vector3 &area_max, std::vector<std::string> &action_names)
1282 Trigger* trigger = new Trigger(this, name, false, sound_file, area_min, area_max, action_names);
1283 TriggerArray.push_back(trigger);
1284 trigger->Move(0, GetBase(true), 0);
1288 Object* Floor::AddCameraTexture(const char *name, bool enabled, int quality, float fov, Ogre::Vector3 position, bool use_rotation, Ogre::Vector3 rotation)
1290 //add a camera texture
1291 CameraTexture* cameratexture = new CameraTexture(this, name, enabled, quality, fov, GetBase(true) + position, use_rotation, rotation);
1292 CameraTextureArray.push_back(cameratexture);
1293 return cameratexture;
1296 Object* Floor::AddEscalator(const char *name, const char *texture, const char *direction, float CenterX, float CenterZ, float width, float risersize, float treadsize, int num_steps, float voffset, float tw, float th)
1299 Escalator* escalator = new Escalator(this, name, texture, direction, CenterX, CenterZ, width, risersize, treadsize, num_steps, GetBase(true) + voffset, tw, th);
1300 EscalatorArray.push_back(escalator);
1304 void Floor::SetAltitude(float altitude)
1306 //position object at altitude
1307 SetPositionY(altitude);
1308 Altitude = altitude;
1311 void Floor::ShowInfo(bool detailed, bool display_header)
1313 //show information about this floor on the console
1315 //if detailed is true (default), show detailed information for this floor
1316 //otherwise, show a single-line listing suitable for showing in a list with other floors
1318 //if display_header is true, show header/key along with listing
1320 if (display_header == true)
1321 sbs->Report("\n--- Floor Information ---\n");
1323 if (detailed == true)
1325 sbs->Report("Number: " + ToString2(Number));
1326 sbs->Report("ID: " + ID);
1327 sbs->Report("Name: " + Name);
1328 sbs->Report("Type: " + FloorType);
1329 sbs->Report("Description: " + Description);
1330 sbs->Report("Height: " + ToString2(Height));
1331 sbs->Report("InterfloorHeight: " + ToString2(InterfloorHeight));
1332 sbs->Report("FullHeight: " + ToString2(FullHeight()));
1333 sbs->Report("Altitude: " + ToString2(Altitude));
1334 sbs->Report("Base: " + ToString2(GetBase()));
1336 std::vector<int> elevator_list, stairs_list, shaft_list;
1337 GetElevatorList(elevator_list);
1338 GetStairsList(stairs_list);
1339 GetShaftList(shaft_list);
1342 for (int i = 0; i < (int)elevator_list.size(); i++)
1344 elevs += ToString2(elevator_list[i]);
1345 if (i < (int)elevator_list.size() - 1)
1348 sbs->Report("Elevators servicing: " + elevs);
1351 for (int i = 0; i < (int)stairs_list.size(); i++)
1353 stairs += ToString2(stairs_list[i]);
1354 if (i < (int)stairs_list.size() - 1)
1357 sbs->Report("Stairwells spanning: " + stairs);
1360 for (int i = 0; i < (int)shaft_list.size(); i++)
1362 shafts += ToString2(shaft_list[i]);
1363 if (i < (int)shaft_list.size() - 1)
1366 sbs->Report("Shafts spanning: " + shafts);
1368 if (display_header == true)
1373 if (display_header == true)
1374 sbs->Report("Number(ID)\t----\tName\t----\tType\t----\tHeight\t----\tIFloorHeight\t----\tAltitude\t----\tBase\t----\tDescription");
1376 sbs->Report(ToString2(Number) + "(" + ID + ")\t----\t" + Name + "\t----\t" + FloorType + "\t----\t" + ToString2(Height) + "\t----\t" + ToString2(InterfloorHeight) + "\t----\t" + ToString2(Altitude) + "\t----\t" + ToString2(GetBase()) + "\t----\t" + Description);
1380 void Floor::GetElevatorList(std::vector<int> &listing)
1382 //return a list of elevators that service this floor
1384 for (int i = 1; i <= sbs->Elevators(); i++)
1386 Elevator *elev = sbs->GetElevator(i);
1389 if (elev->IsServicedFloor(Number) == true)
1390 listing.push_back(elev->Number);
1395 void Floor::GetStairsList(std::vector<int> &listing)
1397 //return a list of stairwells that span this floor
1399 for (int i = 1; i <= sbs->StairsNum(); i++)
1401 Stairs *stairs = sbs->GetStairs(i);
1404 if (stairs->IsValidFloor(Number) == true)
1405 listing.push_back(stairs->StairsNum);
1410 void Floor::GetShaftList(std::vector<int> &listing)
1412 //return a list of shafts that span this floor
1414 for (int i = 1; i <= sbs->Shafts(); i++)
1416 Shaft *shaft = sbs->GetShaft(i);
1419 if (shaft->IsValidFloor(Number) == true)
1420 listing.push_back(shaft->ShaftNumber);