Skyscraper 2.0
control.cpp
Go to the documentation of this file.
1/*
2 Scalable Building Simulator - Control 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 "action.h"
27#include "floor.h"
28#include "elevatorcar.h"
29#include "shaft.h"
30#include "stairs.h"
31#include "buttonpanel.h"
32#include "texture.h"
33#include "sound.h"
34#include "mesh.h"
35#include "control.h"
36
37namespace SBS {
38
39Control::Control(Object *parent, const std::string &name, bool permanent, const std::string &sound_file, const std::vector<std::string> &action_names, const std::vector<Action*> &actions, std::vector<std::string> &textures, const std::string &direction, Real width, Real height, bool center, int selection_position) : Object(parent), Lock(this)
40{
41 //create a control at the specified location
42
43 //actions can either be given as a name list (dynamic action lists) or pointer list (static action lists) - don't use both
44
45 //set up SBS object
46 SetValues("Control", name, permanent);
47
48 std::string name2 = name;
49 if (name.find("Control", 0) == std::string::npos)
50 name2 = "Control " + name;
51
52 ActionNames = action_names;
53 Actions = actions;
54 Direction = direction;
55 is_enabled = true;
56 TextureArray = textures;
57 light_status = false;
58 sound = 0;
59 action_hold = false;
60
61 SetCase(Direction, false);
63
64 //create object mesh
65 ControlMesh = new MeshObject(this, name2, 0, "", "", sbs->GetConfigFloat("Skyscraper.SBS.MaxSmallRenderDistance", 100));
66
67 //set selection position to starting value
68 SetSelectPosition(selection_position);
69
70 std::string texture = GetTexture(selection_position);
71
72 sbs->TexelOverride = true;
73 Wall *wall;
74 if (Direction == "front")
75 {
76 Real x = 0, y = width;
77 if (center == true)
78 {
79 x = -width / 2;
80 y = width / 2;
81 }
82 sbs->DrawWalls(true, false, false, false, false, false);
83 wall = ControlMesh->CreateWallObject(name);
84 sbs->AddWallMain(wall, name, texture, 0, x, 0, y, 0, height, height, 0, 0, 1, 1, false);
85 }
86 if (Direction == "back")
87 {
88 Real x = 0, y = -width;
89 if (center == true)
90 {
91 x = width / 2;
92 y = -width / 2;
93 }
94 sbs->DrawWalls(false, true, false, false, false, false);
95 wall = ControlMesh->CreateWallObject(name);
96 sbs->AddWallMain(wall, name, texture, 0, x, 0, y, 0, height, height, 0, 0, 1, 1, false);
97 }
98 if (Direction == "left")
99 {
100 Real x = 0, y = -width;
101 if (center == true)
102 {
103 x = width / 2;
104 y = -width / 2;
105 }
106 sbs->DrawWalls(true, false, false, false, false, false);
107 wall = ControlMesh->CreateWallObject(name);
108 sbs->AddWallMain(wall, name, texture, 0, 0, x, 0, y, height, height, 0, 0, 1, 1, false);
109 }
110 if (Direction == "right")
111 {
112 Real x = 0, y = width;
113 if (center == true)
114 {
115 x = -width / 2;
116 y = width / 2;
117 }
118 sbs->DrawWalls(false, true, false, false, false, false);
119 wall = ControlMesh->CreateWallObject(name);
120 sbs->AddWallMain(wall, name, texture, 0, 0, x, 0, y, height, height, 0, 0, 1, 1, false);
121 }
122 sbs->ResetWalls();
123 sbs->TexelOverride = false;
124
125 //create sound object
126 if (sound_file != "")
127 {
128 sound = new Sound(this, name, true);
129 sound->Load(sound_file);
130 }
131
132 //register control
133 sbs->RegisterControl(this);
134}
135
137{
138 if (sound)
139 {
140 sound->parent_deleting = true;
141 delete sound;
142 }
143 sound = 0;
144
145 if (ControlMesh)
146 {
148 delete ControlMesh;
149 }
150 ControlMesh = 0;
151
152 //unregister from parent
153 if (sbs->FastDelete == false)
154 {
155 //unregister control
156 sbs->UnregisterControl(this);
157
158 //unregister from parent
159 if (parent_deleting == false)
160 {
161 std::string type = GetParent()->GetType();
162
163 if (type == "ButtonPanel")
164 static_cast<ButtonPanel*>(GetParent())->RemoveControl(this);
165 else if (type == "ElevatorCar")
166 static_cast<ElevatorCar*>(GetParent())->RemoveControl(this);
167 else if (type == "Floor")
168 static_cast<Floor*>(GetParent())->RemoveControl(this);
169 else if (type == "Shaft Level")
170 static_cast<Shaft::Level*>(GetParent())->RemoveControl(this);
171 else if (type == "Stairwell Level")
172 static_cast<Stairwell::Level*>(GetParent())->RemoveControl(this);
173 else if (type == "SBS")
174 sbs->RemoveControl(this);
175 }
176 }
177}
178
179void Control::Enabled(bool value)
180{
181 //enable or disable control
182
183 if (is_enabled == value)
184 return;
185
186 ControlMesh->Enabled(value);
187 is_enabled = value;
188}
189
191{
192 //set selection position without checking state
193
194 if (position < 1 || position > GetPositions())
195 return false;
196
197 current_position = position;
198
199 return ControlMesh->ChangeTexture(GetTexture(position));
200}
201
203{
204 //set selection position
205
206 if (position == current_position)
207 return false;
208
209 return SetSelectPosition(position);
210}
211
212bool Control::NextSelectPosition(bool check_state)
213{
214 //change to the next available control selection position
215
216 int position = GetNextSelectPosition();
217
218 if (check_state == false)
219 return SetSelectPosition(position);
220 else
221 return ChangeSelectPosition(position);
222}
223
225{
226 //determine next selection position
227 int pos = current_position;
228 pos++;
229 if (pos > GetPositions())
230 pos = 1;
231 return pos;
232}
233
235{
236 //change to the next available control selection position
237
238 int position = GetPreviousSelectPosition();
239
240 if (check_state == false)
241 return SetSelectPosition(position);
242 else
243 return ChangeSelectPosition(position);
244}
245
247{
248 //determine previous selection position
249 int pos = current_position;
250 pos--;
251 if (pos < 1)
252 pos = GetPositions();
253 return pos;
254}
255
257{
258 //play associated button sound
259
260 if (sound)
261 {
262 sound->SetLoopState(false);
263 sound->Play();
264 }
265}
266
268{
269 //return control selection position
270 return current_position;
271}
272
273std::string Control::GetPositionAction(int position)
274{
275 //return action's command name associated with the specified selection position
276
277 std::vector<Action*> actionlist;
278
279 if (ActionNames.empty() == false)
280 actionlist = sbs->GetAction(ActionNames[position - 1]);
281 else if (Actions.empty() == false)
282 actionlist.emplace_back(Actions[position - 1]);
283 else
284 return "";
285
286 //return command of first action in list
287 if (actionlist.empty() == false)
288 {
289 if (actionlist[0])
290 return actionlist[0]->GetCommandName();
291 }
292 return "";
293}
294
296{
297 //return action name associated with current selection position
299}
300
301void Control::SetTexture(int position, const std::string &texture)
302{
303 //bind a texture to a specific position
304
305 if (position < 1 || position > GetPositions())
306 return;
307
308 TextureArray[position - 1] = texture;
309}
310
311std::string Control::GetTexture(int position)
312{
313 //get texture for specified position
314
315 if (position < 1 || position > GetPositions())
316 return "";
317
318 return TextureArray[position - 1];
319}
320
322{
323 //return number of available positions, based on size of Actions array
324 if (ActionNames.empty() == false)
325 return (int)ActionNames.size();
326 else
327 return (int)Actions.size();
328}
329
330int Control::FindActionPosition(const std::string &name)
331{
332 //returns the position number that the specified action name is associated with.
333 //otherwise 0 if not found
334
335 for (int i = 1; i <= GetPositions(); i++)
336 {
337 if (GetPositionAction(i) == name)
338 return i;
339 }
340
341 return 0;
342}
343
345{
346 //returns the position number that the first numeric action
347 //otherwise 0 if not found
348
349 for (int i = 1; i <= GetPositions(); i++)
350 {
352 return i;
353 }
354
355 return 0;
356}
357
359{
360 //perform object's action
361 //result is true if at least one action in the list succeeded
362
363 std::vector<Action*> actionlist;
364
365 if (ActionNames.empty() == false)
366 actionlist = sbs->GetAction(ActionNames[current_position - 1]);
367 else if (Actions.empty() == false)
368 actionlist.emplace_back(Actions[current_position - 1]);
369 else
370 return ReportError("No available actions");
371
372 bool result = false;
373 for (size_t i = 0; i < actionlist.size(); i++)
374 {
375 bool result2 = false;
376
377 if (actionlist[i])
378 result2 = actionlist[i]->DoAction(this, action_hold);
379
380 if (result2 == true)
381 result = true;
382 }
383 return result;
384}
385
386bool Control::Press(bool reverse)
387{
388 //press button/control
389 //if reverse is true, select in opposite direction
390
391 //check lock state
392 if (IsLocked() == true)
393 return ReportError("Is locked");
394
395 //get action name of next position state
396 std::string name;
397 if (reverse == false)
399 else
401
402 //exit without changing position if floor button is currently selected
403 if (name == "off" && IsNumeric(GetSelectPositionAction()) == true)
404 return true;
405
406 //change to next control position
407 if (reverse == false)
409 else
411
412 //run action
414
415 //play sound if action succeeded
416 //or always if the name is numeric (elevator is on the same floor, and doors are reopened)
417 if (action_result == true || IsNumeric(name))
418 PlaySound();
419
420 //change back to original selection if result is false
421 if (action_result == false)
422 {
423 if (reverse == false)
425 else
427 }
428
429 return action_result;
430}
431
432void Control::ChangeFloorLight(int floor, bool value)
433{
434 //change light status on control if it calls the specified floor
435
436 if (light_status == value)
437 return;
438
439 std::string floornum = ToString(floor);
440 int index = FindActionPosition(floornum);
441 int index2 = FindActionPosition("off");
442 if (index > 0 && index2 > 0)
443 {
444 if (value == false)
445 ChangeSelectPosition(index2);
446 else
448
449 light_status = value;
450 }
451}
452
453void Control::ChangeLight(bool value)
454{
455 //change light status on control
456
457 if (light_status == value)
458 return;
459
460 int index = FindNumericActionPosition();
461 int index2 = FindActionPosition("off");
462 if (index > 0 && index2 > 0)
463 {
464 if (value == false)
465 ChangeSelectPosition(index2);
466 else
468 }
469 light_status = value;
470}
471
473{
474 for (size_t i = 0; i < Actions.size(); i++)
475 {
476 if (Actions[i] == action)
477 {
478 Actions.erase(Actions.begin() + i);
479 return;
480 }
481 }
482}
483
484void Control::OnClick(Vector3 &position, bool shift, bool ctrl, bool alt, bool right)
485{
486 //toggle lock status if ctrl and shift are pressed
487 if (ctrl == true && shift == true)
488 ToggleLock();
489 else
490 Press(right);
491}
492
493void Control::OnUnclick(bool right)
494{
495 //exit if not in Hold mode
496 if (action_hold == false)
497 return;
498
499 //exit if previous action failed
500 if (action_result == false)
501 return;
502
503 if (right == false)
505 else
507
508 action_hold = false;
509}
510
511void Control::Report(const std::string &message)
512{
513 //general reporting function
514 Object::Report("Control " + GetName() + ": " + message);
515}
516
517bool Control::ReportError(const std::string &message)
518{
519 //general error reporting function
520 return Object::ReportError("Control " + GetName() + ": " + message);
521}
522
523}
void Report(const std::string &message)
Definition control.cpp:511
bool DoAction()
Definition control.cpp:358
int current_position
Definition control.h:69
bool light_status
Definition control.h:75
bool ReportError(const std::string &message)
Definition control.cpp:517
Control(Object *parent, const std::string &name, bool permanent, const std::string &sound, const std::vector< std::string > &action_names, const std::vector< Action * > &actions, std::vector< std::string > &textures, const std::string &direction, Real width, Real height, bool center, int selection_position)
Definition control.cpp:39
void ChangeLight(bool value)
Definition control.cpp:453
std::string GetTexture(int position)
Definition control.cpp:311
int GetPreviousSelectPosition()
Definition control.cpp:246
bool action_hold
Definition control.h:77
int FindActionPosition(const std::string &name)
Definition control.cpp:330
void PlaySound()
Definition control.cpp:256
std::string GetPositionAction(int position)
Definition control.cpp:273
std::string GetSelectPositionAction()
Definition control.cpp:295
void Enabled(bool value)
Definition control.cpp:179
std::vector< std::string > ActionNames
Definition control.h:71
bool ChangeSelectPosition(int position)
Definition control.cpp:202
std::vector< std::string > TextureArray
Definition control.h:70
void ChangeFloorLight(int floor, bool value)
Definition control.cpp:432
int GetNextSelectPosition()
Definition control.cpp:224
bool Press(bool reverse=false)
Definition control.cpp:386
std::vector< Action * > Actions
Definition control.h:72
Sound * sound
Definition control.h:74
void OnUnclick(bool right)
Definition control.cpp:493
void OnClick(Vector3 &position, bool shift, bool ctrl, bool alt, bool right)
Definition control.cpp:484
bool is_enabled
Definition control.h:76
int GetPositions()
Definition control.cpp:321
bool action_result
Definition control.h:78
std::string Direction
Definition control.h:34
bool SetSelectPosition(int position)
Definition control.cpp:190
MeshObject * ControlMesh
Definition control.h:68
int GetSelectPosition()
Definition control.cpp:267
int FindNumericActionPosition()
Definition control.cpp:344
void SetTexture(int position, const std::string &texture)
Definition control.cpp:301
void RemoveAction(Action *action)
Definition control.cpp:472
bool PreviousSelectPosition(bool check_state=true)
Definition control.cpp:234
bool NextSelectPosition(bool check_state=true)
Definition control.cpp:212
bool IsLocked()
Definition lock.cpp:66
bool ToggleLock(bool force=false)
Definition lock.cpp:44
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
const std::string & GetName()
Definition object.cpp:53
virtual bool ReportError(const std::string &message)
Definition object.cpp:84
Object * GetParent()
Definition object.cpp:42
virtual void Report(const std::string &message)
Definition object.cpp:78
bool parent_deleting
Definition object.h:64
void SetValues(const std::string &type, const std::string &name, bool is_permanent, bool is_movable=true)
Definition object.cpp:144
const std::string & GetType()
Definition object.cpp:177
void RemoveControl(Control *control)
Definition sbs.cpp:2883
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
bool TexelOverride
Definition sbs.h:427
void ResetWalls(bool ToDefaults=false)
Definition sbs.cpp:1854
bool FastDelete
Definition sbs.h:188
void RegisterControl(Control *control)
Definition sbs.cpp:3936
std::vector< Action * > GetAction(std::string name)
Definition sbs.cpp:3431
void UnregisterControl(Control *control)
Definition sbs.cpp:3942
void DrawWalls(bool MainN, bool MainP, bool SideN, bool SideP, bool Top, bool Bottom)
Definition sbs.cpp:1833
bool Load(const std::string &filename, bool force=false)
Definition sound.cpp:386
bool Play(bool reset=true)
Definition sound.cpp:321
void SetLoopState(bool value)
Definition sound.cpp:204
Ogre::Vector3 Vector3
Definition globals.h:58
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
bool IsNumeric(char character)
Definition globals.cpp:48
void TrimString(std::string &string)
Definition globals.cpp:188