OSDN Git Service

e1bfb11b0057ca449f370a6a8d0e514cbb17fd6a
[skyscrapersim/skyscraper.git] / src / buttonpanel.cpp
1 /* $Id$ */
2
3 /*
4         Scalable Building Simulator - Elevator Button Panel Class
5         The Skyscraper Project - Version 1.5 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 "buttonpanel.h"
28 #include "elevator.h"
29 #include "sbs.h"
30 #include "camera.h"
31 #include "unix.h"
32
33 extern SBS *sbs; //external pointer to the SBS engine
34
35 ButtonPanel::ButtonPanel(int _elevator, int index, const char *texture, int rows, int columns, const char *direction, float CenterX, float CenterZ, float buttonwidth, float buttonheight, float spacingX, float spacingY, float voffset, float tw, float th)
36 {
37         //Create an elevator button panel
38         //index is for specifying multiple panels within the same elevator
39
40         elevator = _elevator;
41         Direction = direction;
42         Origin.x = sbs->GetElevator(elevator)->Origin.x + CenterX;
43         Origin.z = sbs->GetElevator(elevator)->Origin.z + CenterZ;
44         ButtonWidth = buttonwidth;
45         ButtonHeight = buttonheight;
46         Rows = rows;
47         Columns = columns;
48         SpacingX = ButtonWidth * spacingX;
49         SpacingY = ButtonHeight * spacingY;
50
51         //total spacing plus total button widths
52         Width = ((Columns + 1) * SpacingX) + (Columns * ButtonWidth);
53         Height = ((Rows + 1) * SpacingY) + (Rows * ButtonHeight);
54
55         //get vertical
56         Origin.y = voffset - (Height / 2);
57
58         //create mesh
59         csString buffer, buffer2, buffer3;
60         buffer2 = elevator;
61         buffer3 = index;
62         buffer = "Button Panel " + buffer2 + ":" + buffer3;
63         buffer.Trim();
64         ButtonPanelMesh = sbs->engine->CreateSectorWallsMesh (sbs->area, buffer.GetData());
65         ButtonPanel_state = scfQueryInterface<iThingFactoryState> (ButtonPanelMesh->GetMeshObject()->GetFactory());
66         ButtonPanelMesh->SetZBufMode(CS_ZBUF_USE);
67         ButtonPanelMesh->SetRenderPriority(sbs->engine->GetObjectRenderPriority());
68         ButtonPanelMesh->GetMeshObject()->SetMixMode(CS_FX_ALPHA);
69
70         //move
71         SetToElevatorAltitude();
72
73         //create panel back
74         sbs->ResetTextureMapping(true);
75         if (Direction == "front")
76         {
77                 sbs->DrawWalls(true, false, false, false, false, false);
78                 AddWall("Panel", texture, 0, -(Width / 2), 0, Width / 2, 0, Height, Height, 0, 0, tw, th);
79         }
80         if (Direction == "back")
81         {
82                 sbs->DrawWalls(false, true, false, false, false, false);
83                 AddWall("Panel", texture, 0, -(Width / 2), 0, Width / 2, 0, Height, Height, 0, 0, tw, th);
84         }
85         if (Direction == "left")
86         {
87                 sbs->DrawWalls(true, false, false, false, false, false);
88                 AddWall("Panel", texture, 0, 0, -(Width / 2), 0, Width / 2, Height, Height, 0, 0, tw, th);
89         }
90         if (Direction == "right")
91         {
92                 sbs->DrawWalls(false, true, false, false, false, false);
93                 AddWall("Panel", texture, 0, 0, -(Width / 2), 0, Width / 2, Height, Height, 0, 0, tw, th);
94         }
95         sbs->ResetWalls();
96         sbs->ResetTextureMapping();
97         Enabled(false); //disable mesh at startup
98 }
99
100 ButtonPanel::~ButtonPanel()
101 {
102
103 }
104
105 void ButtonPanel::AddFloorButton(const char *texture, int row, int column, int floor, float width, float height, float hoffset, float voffset)
106 {
107         //create a standard floor button at specified row/column position
108         //width and height are the button size percentage that the button should be (divided by 100); default is 1 for each, aka 100%.
109         //hoffset and voffset are the optional horizontal and vertical offsets to place the button (in order to place it outside of the default grid position)
110
111         csString floornum;
112         floornum = floor;
113         AddButton(floornum, texture, row, column, width, height, hoffset, voffset);
114 }
115
116 void ButtonPanel::AddControlButton(const char *texture, int row, int column, const char *type, float width, float height, float hoffset, float voffset)
117 {
118         //create a control button at specified row/column position
119         //width and height are the button size percentage that the button should be (divided by 100); default is 1 for each, aka 100%
120         //hoffset and voffset are the optional horizontal and vertical offsets to place the button (in order to place it outside of the default grid position)
121
122         //type is one of these:
123         //open = Open Doors
124         //close = Close Doors
125         //cancel = Call Cancel
126         //stop = Stop
127         //alarm = Alarm
128
129         csString name = type;
130         name.Downcase();
131
132         AddButton(name.GetData(), texture, row, column, width, height, hoffset, voffset);
133 }
134
135 void ButtonPanel::AddButton(const char *name, const char *texture, int row, int column, float bwidth, float bheight, float hoffset, float voffset)
136 {
137         //create the button polygon
138         float xpos, ypos, zpos;
139
140         //set to default if value is 0
141         if (bwidth == 0)
142                 bwidth = 1;
143
144         if (bheight == 0)
145                 bheight = 1;
146
147         //vertical position is the top of the panel, minus the total spacing above it,
148         //minus the total button spaces above (and including) it, minus half of the extra height
149         ypos = (Origin.y + Height) - (SpacingY * row) - (ButtonHeight * row) - ((bheight - 1) / 2);
150         sbs->ResetTextureMapping(true);
151         if (Direction == "front" || Direction == "back")
152         {
153                 if (Direction == "front")
154                 {
155                         sbs->DrawWalls(true, false, false, false, false, false);
156                         //hoizontal position is the left-most edge of the panel (origin aka center minus
157                         //half the width), plus total spacing to the left of it, plus total button spaces
158                         //to the left of it, plus half of the extra width
159                         xpos = (Origin.x - (Width / 2)) + (SpacingX * column) + (ButtonWidth * (column - 1)) + ((bwidth - 1) / 2);
160                         zpos = Origin.z - 0.001;
161                         sbs->AddWallMain(ButtonPanel_state, name, texture, 0, xpos + (hoffset * ButtonWidth), zpos, xpos + (hoffset * ButtonWidth) + (ButtonWidth * bwidth), zpos, ButtonHeight * bheight, ButtonHeight * bheight, ypos + (voffset * ButtonHeight), ypos + (voffset * ButtonHeight), 1, 1);
162                 }
163                 else
164                 {
165                         //back
166                         sbs->DrawWalls(false, true, false, false, false, false);
167                         xpos = (Origin.x + (Width / 2)) - (SpacingX * column) - (ButtonWidth * (column - 1)) - ((bwidth - 1) / 2);
168                         zpos = Origin.z + 0.001;
169                         sbs->AddWallMain(ButtonPanel_state, name, texture, 0, xpos - (hoffset * ButtonWidth), zpos, xpos - (hoffset * ButtonWidth) - (ButtonWidth * bwidth), zpos, ButtonHeight * bheight, ButtonHeight * bheight, ypos + (voffset * ButtonHeight), ypos + (voffset * ButtonHeight), 1, 1);
170                 }
171         }
172         else
173         {
174                 if (Direction == "left")
175                 {
176                         sbs->DrawWalls(true, false, false, false, false, false);
177                         xpos = Origin.x - 0.001;
178                         zpos = (Origin.z + (Width / 2))  - (SpacingX * column) - (ButtonWidth * (column - 1)) - ((bwidth - 1) / 2);
179                         sbs->AddWallMain(ButtonPanel_state, name, texture, 0, xpos, zpos - (hoffset * ButtonWidth), xpos, zpos - (hoffset * ButtonWidth) - (ButtonWidth * bwidth), ButtonHeight * bheight, ButtonHeight * bheight, ypos + (voffset * ButtonHeight), ypos + (voffset * ButtonHeight), 1, 1);
180                 }
181                 else
182                 {
183                         //right
184                         sbs->DrawWalls(false, true, false, false, false, false);
185                         xpos = Origin.x + 0.001;
186                         zpos = (Origin.z - (Width / 2)) + (SpacingX * column) + (ButtonWidth * (column - 1)) + ((bwidth - 1) / 2);
187                         sbs->AddWallMain(ButtonPanel_state, name, texture, 0, xpos, zpos + (hoffset * ButtonWidth), xpos, zpos + (hoffset * ButtonWidth) + (ButtonWidth * bwidth), ButtonHeight * bheight, ButtonHeight * bheight, ypos + (voffset * ButtonHeight), ypos + (voffset * ButtonHeight), 1, 1);
188                 }
189         }
190         sbs->ResetWalls();
191         sbs->ResetTextureMapping();
192 }
193
194 void ButtonPanel::DeleteButton(int row, int column)
195 {
196
197 }
198
199 void ButtonPanel::Press(int index)
200 {
201         //Press selected button
202
203         if (index == -1)
204                 return;
205
206         //exit if in inspection mode or in fire service phase 1 mode
207         if (sbs->GetElevator(elevator)->InspectionService == true || sbs->GetElevator(elevator)->FireServicePhase1 == 1)
208                 return;
209
210         csString name = ButtonPanel_state->GetPolygonName(index);
211         csString name2 = name;
212
213         //strip off any text after and including a colon
214         int colon = name.Find(":");
215         if (colon > 0)
216                 name = name2.Slice(0, colon);
217
218         if (IsNumeric(name) == true)
219         {
220                 int floor = atoi(name.GetData());
221                 int elev_floor = sbs->GetElevator(elevator)->GetFloor();
222
223                 //elevator is above floor
224                 if (elev_floor > floor)
225                         sbs->GetElevator(elevator)->AddRoute(floor, -1);
226
227                 //elevator is below floor
228                 if (elev_floor < floor)
229                         sbs->GetElevator(elevator)->AddRoute(floor, 1);
230
231                 //elevator is on floor
232                 if (elev_floor == floor)
233                 {
234                         if (sbs->GetElevator(elevator)->Direction == 0)
235                         {
236                                 //stopped - play chime and open doors
237                                 if (sbs->GetElevator(elevator)->QueuePositionDirection == -1 || sbs->GetElevator(elevator)->LastQueueDirection == -1)
238                                         sbs->GetElevator(elevator)->Chime(0, floor, false);
239                                 else if (sbs->GetElevator(elevator)->QueuePositionDirection == 1 || sbs->GetElevator(elevator)->LastQueueDirection == 1)
240                                         sbs->GetElevator(elevator)->Chime(0, floor, true);
241                                 sbs->GetElevator(elevator)->OpenDoors();
242                         }
243                         else if (sbs->GetElevator(elevator)->Direction == -1)
244                         {
245                                 //elevator is on floor but already moving down; add an upward route
246                                 sbs->GetElevator(elevator)->AddRoute(floor, 1);
247                         }
248                         else if (sbs->GetElevator(elevator)->Direction == 1)
249                         {
250                                 //elevator is on floor but already moving up; add a downward route
251                                 sbs->GetElevator(elevator)->AddRoute(floor, -1);
252                         }
253                 }
254         }
255         else
256         {
257                 name.Downcase();
258                 if (name == "open" && sbs->GetElevator(elevator)->Direction == 0)
259                         sbs->GetElevator(elevator)->OpenDoors();
260                 if (name == "close" && sbs->GetElevator(elevator)->Direction == 0)
261                         sbs->GetElevator(elevator)->CloseDoors();
262                 if (name == "cancel")
263                         sbs->GetElevator(elevator)->CancelLastRoute();
264                 if (name == "stop")
265                         sbs->GetElevator(elevator)->StopElevator();
266                 if (name == "alarm")
267                         sbs->GetElevator(elevator)->Alarm();
268         }
269 }
270
271 void ButtonPanel::Move(const csVector3 &position)
272 {
273         //relative movement
274         ButtonPanelMesh->GetMovable()->MovePosition(position);
275         ButtonPanelMesh->GetMovable()->UpdateMove();
276 }
277
278 void ButtonPanel::SetToElevatorAltitude()
279 {
280         csVector3 pos = ButtonPanelMesh->GetMovable()->GetPosition();
281         ButtonPanelMesh->GetMovable()->SetPosition(csVector3(pos.x, sbs->GetElevator(elevator)->GetPosition().y, pos.z));
282         ButtonPanelMesh->GetMovable()->UpdateMove();
283 }
284
285 void ButtonPanel::Enabled(bool value)
286 {
287         //enable or disable button panel
288
289         sbs->EnableMesh(ButtonPanelMesh, value);
290 }
291
292 int ButtonPanel::AddWall(const char *name, const char *texture, float thickness, float x1, float z1, float x2, float z2, float height1, float height2, float voffset1, float voffset2, float tw, float th)
293 {
294         //Adds a wall with the specified dimensions
295         float tw2 = tw;
296         float th2;
297         float tempw1;
298         float tempw2;
299
300         //Set horizontal scaling
301         x1 = x1 * sbs->HorizScale;
302         x2 = x2 * sbs->HorizScale;
303         z1 = z1 * sbs->HorizScale;
304         z2 = z2 * sbs->HorizScale;
305
306         //Call texture autosizing formulas
307         if (z1 == z2)
308                 tw2 = sbs->AutoSize(x1, x2, true, tw);
309         if (x1 == x2)
310                 tw2 = sbs->AutoSize(z1, z2, true, tw);
311         if ((z1 != z2) && (x1 != x2))
312         {
313                 //calculate diagonals
314                 if (x1 > x2)
315                         tempw1 = x1 - x2;
316                 else
317                         tempw1 = x2 - x1;
318                 if (z1 > z2)
319                         tempw2 = z1 - z2;
320                 else
321                         tempw2 = z2 - z1;
322                 tw2 = sbs->AutoSize(0, sqrt(pow(tempw1, 2) + pow(tempw2, 2)), true, tw);
323         }
324         th2 = sbs->AutoSize(0, height1, false, th);
325
326         return sbs->AddWallMain(ButtonPanel_state, name, texture, thickness, Origin.x + x1, Origin.z + z1, Origin.x + x2, Origin.z + z2, height1, height2, Origin.y + voffset1, Origin.y + voffset2, tw2, th2);
327 }