4 Scalable Building Simulator - Escalator Object
5 The Skyscraper Project - Version 1.11 Alpha
6 Copyright (C)2004-2017 Ryan Thoryk
7 http://www.skyscrapersim.com
8 http://sourceforge.net/projects/skyscraper
9 Contact - ryan@skyscrapersim.com
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.
34 #include "dynamicmesh.h"
36 #include "escalator.h"
40 Escalator::Escalator(Object *parent, const std::string &name, int run, float speed, const std::string &sound_file, const std::string &texture, const std::string &direction, float CenterX, float CenterZ, float width, float risersize, float treadsize, int num_steps, float voffset, float tw, float th) : Object(parent)
42 //create a new escalator object
43 //run is either 1 for forward motion, -1 for reverse motion, 0 for stop
44 //direction is where the step base is - front, back, left, or right.
49 SetValues("Escalator", "", false);
51 Floor *floor = dynamic_cast<Floor*>(parent);
53 Name = "Floor" + ToString(floor->Number) + ":"+ name;
61 sbs->IncrementEscalatorCount();
64 buffer_zone_steps = 2;
67 Move(CenterX, voffset, CenterZ);
70 for (int i = 0; i < num_steps; i++)
72 Step *mesh = new Step(this, "Step " + ToString(i + 1), 0, 100);
73 Steps.push_back(mesh);
77 sound = new Sound(this, name, true);
78 sound->Load(sound_file);
79 sound->SetPosition(CenterX, voffset, CenterZ);
82 CreateSteps(texture, direction, width, risersize, treadsize, tw, th);
85 Escalator::~Escalator()
89 sound->parent_deleting = true;
95 for (size_t i = 0; i < Steps.size(); i++)
99 Steps[i]->parent_deleting = true;
105 //unregister from parent
106 if (sbs->FastDelete == false)
108 sbs->DecrementEscalatorCount();
110 //unregister from parent
111 if (parent_deleting == false)
113 std::string type = GetParent()->GetType();
116 static_cast<Floor*>(GetParent())->RemoveEscalator(this);
121 void Escalator::Enabled(bool value)
123 //enable or disable escalator
125 if (is_enabled == value)
130 for (size_t i = 0; i < Steps.size(); i++)
131 Steps[i]->Enabled(value);
133 if (value == false && sound->IsPlaying() == true)
139 void Escalator::SetRun(int value)
143 for (size_t i = 0; i < Steps.size(); i++)
145 Steps[i]->vector = Ogre::Vector3::ZERO;
153 void Escalator::Report(const std::string &message)
155 //general reporting function
156 Object::Report("Escalator " + GetName() + ": " + message);
159 bool Escalator::ReportError(const std::string &message)
161 //general reporting function
162 return Object::ReportError("Escalator " + GetName() + ": " + message);
165 void Escalator::Loop()
169 SBS_PROFILE("Escalator::Loop");
171 if (!IsEnabled() || Run == 0)
173 if (sound->IsPlaying() == true)
178 if (sound->IsPlaying() == false)
180 sound->SetLoopState(true);
187 void Escalator::CreateSteps(const std::string &texture, const std::string &direction, float width, float risersize, float treadsize, float tw, float th)
190 std::string Name = GetName();
192 Direction = direction;
193 this->treadsize = treadsize;
194 this->risersize = risersize;
195 SetCase(Direction, false);
196 int num_steps = (int)Steps.size();
198 sbs->GetTextureManager()->ResetTextureMapping(true);
199 if (Direction == "right" || Direction == "back")
200 sbs->SetWallOrientation("right");
201 if (Direction == "left" || Direction == "front")
202 sbs->SetWallOrientation("left");
204 for (int i = 1; i <= num_steps; i++)
207 std::string base = Name + ":" + ToString(i);
210 Wall *wall = Steps[i - 1]->CreateWallObject(base);
212 float thickness = treadsize;
214 if (Direction == "right")
216 pos = ((treadsize * num_steps + 1) / 2) - (treadsize * i);
217 sbs->DrawWalls(true, true, true, true, false, true);
218 sbs->AddWallMain(wall, base + "-riser", texture, thickness, treadsize, -(width / 2), treadsize, width / 2, risersize, risersize, 0, 0, tw, th, true);
220 sbs->DrawWalls(false, true, false, false, false, false);
221 sbs->AddFloorMain(wall, base + "-tread", texture, 0, 0, -(width / 2), treadsize, width / 2, risersize, risersize, false, false, tw, th, true);
223 if (i < (buffer_zone_steps + 1))
224 Steps[i - 1]->Move(Ogre::Vector3(pos, -risersize, 0));
225 else if (i > num_steps - buffer_zone_steps)
226 Steps[i - 1]->Move(Ogre::Vector3(pos, risersize * (i - (((buffer_zone_steps * 2) + 1) - (num_steps - i))), 0));
228 Steps[i - 1]->Move(Ogre::Vector3(pos, risersize * (i - (buffer_zone_steps * 2)), 0));
229 Steps[i - 1]->vector = Ogre::Vector3::ZERO;
230 Steps[1 - 1]->speed = 0;
233 start = Steps[i - 1]->GetPosition();
235 end = Steps[i - 1]->GetPosition();
236 Steps[i - 1]->start = Steps[i - 1]->GetPosition();
238 if (Direction == "left")
240 pos = -((treadsize * num_steps + 1) / 2) + (treadsize * i);
241 sbs->DrawWalls(true, true, true, true, false, true);
242 sbs->AddWallMain(wall, base + "-riser", texture, thickness, -treadsize, width / 2, -treadsize, -(width / 2), risersize, risersize, 0, 0, tw, th, true);
244 sbs->DrawWalls(false, true, false, false, false, false);
245 sbs->AddFloorMain(wall, base + "-tread", texture, 0, -treadsize, -(width / 2), 0, width / 2, risersize, risersize, false, false, tw, th, true);
247 if (i < (buffer_zone_steps + 1))
248 Steps[i - 1]->Move(Ogre::Vector3(pos, -risersize, 0));
249 else if (i > num_steps - buffer_zone_steps)
250 Steps[i - 1]->Move(Ogre::Vector3(pos, risersize * (i - (((buffer_zone_steps * 2) + 1) - (num_steps - i))), 0));
252 Steps[i - 1]->Move(Ogre::Vector3(pos, risersize * (i - (buffer_zone_steps * 2)), 0));
253 Steps[i - 1]->vector = Ogre::Vector3::ZERO;
254 Steps[1 - 1]->speed = 0;
257 start = Steps[i - 1]->GetPosition();
259 end = Steps[i - 1]->GetPosition();
260 Steps[i - 1]->start = Steps[i - 1]->GetPosition();
262 if (Direction == "back")
264 pos = ((treadsize * num_steps + 1) / 2) - (treadsize * i);
265 sbs->DrawWalls(true, true, true, true, false, true);
266 sbs->AddWallMain(wall, base + "-riser", texture, thickness, width / 2, treadsize, -(width / 2), treadsize, risersize, risersize, 0, 0, tw, th, true);
268 sbs->DrawWalls(false, true, false, false, false, false);
269 sbs->AddFloorMain(wall, base + "-tread", texture, 0, -(width / 2), 0, width / 2, treadsize, risersize, risersize, false, false, tw, th, true);
271 if (i < (buffer_zone_steps + 1))
272 Steps[i - 1]->Move(Ogre::Vector3(0, -risersize, pos));
273 else if (i > num_steps - buffer_zone_steps)
274 Steps[i - 1]->Move(Ogre::Vector3(0, risersize * (i - (((buffer_zone_steps * 2) + 1) - (num_steps - i))), pos));
276 Steps[i - 1]->Move(Ogre::Vector3(0, risersize * (i - (buffer_zone_steps * 2)), pos));
277 Steps[i - 1]->vector = Ogre::Vector3::ZERO;
278 Steps[1 - 1]->speed = 0;
281 start = Steps[i - 1]->GetPosition();
283 end = Steps[i - 1]->GetPosition();
284 Steps[i - 1]->start = Steps[i - 1]->GetPosition();
286 if (Direction == "front")
288 pos = -((treadsize * num_steps + 1) / 2) + (treadsize * i);
289 sbs->DrawWalls(true, true, true, true, false, true);
290 sbs->AddWallMain(wall, base + "-riser", texture, thickness, -(width / 2), -treadsize, width / 2, -treadsize, risersize, risersize, 0, 0, tw, th, true);
292 sbs->DrawWalls(false, true, false, false, false, false);
293 sbs->AddFloorMain(wall, base + "-tread", texture, 0, -(width / 2), -treadsize, width / 2, 0, risersize, risersize, false, false, tw, th, true);
295 if (i < (buffer_zone_steps + 1))
296 Steps[i - 1]->Move(Ogre::Vector3(0, -risersize, pos));
297 else if (i > num_steps - buffer_zone_steps)
298 Steps[i - 1]->Move(Ogre::Vector3(0, risersize * (i - (((buffer_zone_steps * 2) + 1) - (num_steps - i))), pos));
300 Steps[i - 1]->Move(Ogre::Vector3(0, risersize * (i - (buffer_zone_steps * 2)), pos));
301 Steps[i - 1]->vector = Ogre::Vector3::ZERO;
302 Steps[1 - 1]->speed = 0;
305 start = Steps[i - 1]->GetPosition();
307 end = Steps[i - 1]->GetPosition();
308 Steps[i - 1]->start = Steps[i - 1]->GetPosition();
311 sbs->ResetWalls(true);
312 sbs->GetTextureManager()->ResetTextureMapping();
315 void Escalator::MoveSteps()
317 if (GetPosition().distance(sbs->camera->GetPosition()) > 100)
320 for (size_t i = 0; i < Steps.size(); i++)
324 if (Direction == "right")
326 float pos = Steps[i]->GetPosition().x;
327 if (pos < end.x - treadsize)
328 Steps[i]->SetPosition(start);
329 else if (pos >= start.x - (treadsize * 2) || pos <= end.x + treadsize)
330 Steps[i]->Move(Ogre::Vector3(-Run, 0, 0), Speed * sbs->delta);
331 else if (pos > end.x + treadsize)
332 Steps[i]->Move(Ogre::Vector3(-Run, Run * (risersize / treadsize), 0), Speed * sbs->delta);
334 if (Direction == "left")
336 float pos = Steps[i]->GetPosition().x;
337 if (pos > end.x + treadsize)
338 Steps[i]->SetPosition(start);
339 else if (pos <= start.x + (treadsize * 2) || pos >= end.x - treadsize)
340 Steps[i]->Move(Ogre::Vector3(Run, 0, 0), Speed * sbs->delta);
341 else if (pos < end.x - treadsize)
342 Steps[i]->Move(Ogre::Vector3(Run, Run * (risersize / treadsize), 0), Speed * sbs->delta);
344 if (Direction == "back")
346 float pos = Steps[i]->GetPosition().z;
347 if (pos < end.z - treadsize)
348 Steps[i]->SetPosition(start);
349 else if (pos >= start.z - (treadsize * 2) || pos <= end.z + treadsize)
350 Steps[i]->Move(Ogre::Vector3(0, 0, -Run), Speed * sbs->delta);
351 else if (pos > end.z + treadsize)
352 Steps[i]->Move(Ogre::Vector3(0, Run * (risersize / treadsize), -Run), Speed * sbs->delta);
354 if (Direction == "front")
356 float pos = Steps[i]->GetPosition().z;
357 if (pos > end.z + treadsize)
358 Steps[i]->SetPosition(start);
359 else if (pos <= start.z + (treadsize * 2) || pos >= end.z - treadsize)
360 Steps[i]->Move(Ogre::Vector3(0, 0, Run), Speed * sbs->delta);
361 else if (pos < end.z - treadsize)
362 Steps[i]->Move(Ogre::Vector3(0, Run * (risersize / treadsize), Run), Speed * sbs->delta);
367 if (Direction == "right")
369 float pos = Steps[i]->GetPosition().x;
371 Steps[i]->SetPosition(Ogre::Vector3(end.x - treadsize, end.y, end.z));
372 else if (pos <= end.x + treadsize || pos >= start.x - (treadsize * 2))
373 Steps[i]->Move(Ogre::Vector3(-Run, 0, 0), Speed * sbs->delta);
374 else if (pos < start.x - treadsize)
375 Steps[i]->Move(Ogre::Vector3(-Run, Run * (risersize / treadsize), 0), Speed * sbs->delta);
377 if (Direction == "left")
379 float pos = Steps[i]->GetPosition().x;
381 Steps[i]->SetPosition(Ogre::Vector3(end.x + treadsize, end.y, end.z));
382 else if (pos >= end.x - treadsize || pos <= start.x + (treadsize * 2))
383 Steps[i]->Move(Ogre::Vector3(Run, 0, 0), Speed * sbs->delta);
384 else if (pos > start.x + treadsize)
385 Steps[i]->Move(Ogre::Vector3(Run, Run * (risersize / treadsize), 0), Speed * sbs->delta);
387 if (Direction == "back")
389 float pos = Steps[i]->GetPosition().z;
391 Steps[i]->SetPosition(Ogre::Vector3(end.x, end.y, end.z - treadsize));
392 else if (pos <= end.z + treadsize || pos >= start.z - (treadsize * 2))
393 Steps[i]->Move(Ogre::Vector3(0, 0, -Run), Speed * sbs->delta);
394 else if (pos < start.z - treadsize)
395 Steps[i]->Move(Ogre::Vector3(0, Run * (risersize / treadsize), -Run), Speed * sbs->delta);
397 if (Direction == "front")
399 float pos = Steps[i]->GetPosition().z;
401 Steps[i]->SetPosition(Ogre::Vector3(end.x, end.y, end.z + treadsize));
402 else if (pos >= end.z - treadsize || pos <= start.z + (treadsize * 2))
403 Steps[i]->Move(Ogre::Vector3(0, 0, Run), Speed * sbs->delta);
404 else if (pos > start.z + treadsize)
405 Steps[i]->Move(Ogre::Vector3(0, Run * (risersize / treadsize), Run), Speed * sbs->delta);
411 void Escalator::OnClick(Ogre::Vector3 &position, bool shift, bool ctrl, bool alt, bool right)
413 //cycle run stages if shift-click is performed
420 for (size_t i = 0; i < Steps.size(); i++)
422 Steps[i]->vector = 0;
433 void Escalator::ResetState()
435 //reset escalator state
438 for (size_t i = 0; i < Steps.size(); i++)
440 Steps[i]->SetPosition(Steps[i]->start);