OSDN Git Service

-added additional check to elevator service modes to prevent random activity
authorryan <>
Mon, 1 Apr 2013 22:46:06 +0000 (22:46 +0000)
committerryan <>
Mon, 1 Apr 2013 22:46:06 +0000 (22:46 +0000)
-elevator parking is no longer run while in a service mode
-fixed elevator availability check for LimitQueue
-added elevator queue reversal when arriving at top/bottom floor; fixes call quirks on those floors
-fixed issue in elevator_doors.txt script that prevented dual-speed left doors from closing properly
-switched user variable system over to named variables

data/scripts/elevator_doors.txt
designguide.html
src/frontend/fileio.cpp
src/frontend/fileio.h
src/sbs/elevator.cpp
src/sbs/elevator.h

index 6fef81a..777ecc4 100644 (file)
     if[%param9% = front | %param9% = left] WallOrientation = right
     if[%param9% = back | %param9% = right] WallOrientation = left
     if[%param11% = false] AddDoorComponent %param1%, Door1, %param2%, %param3%, %param4% / 2, left, %param10%, %param10% * 0.75, %204%, %206%, %205%, %207%, %param8%, 0, -1, 0, 0, 0
-    if[%param11% = true] AddShaftDoorsComponent %param1%, Door2, %param2%, %param3%, %param4% / 2, left, %param10% / 2, (%param10% * 0.75) * 2, %200%, %202%, %201%, %203%, %param8%, 0, 1, 0, 0, 0
+    if[%param11% = true] AddShaftDoorsComponent %param1%, Door2, %param2%, %param3%, %param4% / 2, left, %param10% / 2, (%param10% * 0.75) / 2, %200%, %202%, %201%, %203%, %param8%, 0, 1, 0, 0, 0
 
     if[%param9% = front | %param9% = left] WallOrientation = left
     if[%param9% = back | %param9% = right] WallOrientation = right
-    if[%param11% = false] AddDoorComponent %param1%, Door1, %param2%, %param3%, %param4% / 2, left, %param10% / 2, (%param10% * 0.75) * 2, %200%, %202%, %201%, %203%, %param8%, 0, -1, 0, 0, 0
+    if[%param11% = false] AddDoorComponent %param1%, Door1, %param2%, %param3%, %param4% / 2, left, %param10% / 2, (%param10% * 0.75) / 2, %200%, %202%, %201%, %203%, %param8%, 0, -1, 0, 0, 0
     if[%param11% = true] AddShaftDoorsComponent %param1%, Door2, %param2%, %param3%, %param4% / 2, left, %param10%, %param10% * 0.75, %204%, %206%, %205%, %207%, %param8%, 0, 1, 0, 0, 0
     if[%param11% = false] FinishDoors %param1%
     if[%param11% = true] FinishShaftDoors %param1%
index 779cbad..ca38093 100644 (file)
@@ -82,13 +82,13 @@ at the top of your building file. The Triton Center file has this header:<br>
 <strong>2. Variables</strong></p>
 
 <p align="left">Variables are marked with percent signs (%), and most system
-variables will be described later. There are 256 user variables (0-255) which
-can be set using the Set command:<font face="Courier New, Courier, mono"
-size="2"><br>
-Set 2 = 100<br>
+variables will be described later. Variables can be set using the Set
+command:<font face="Courier New, Courier, mono" size="2"><br>
+Set myvariable = 100<br>
 </font>and then can be used later:<font face="Courier New, Courier, mono"
 size="2"><br>
-Height = %2%<br>
+Height = %myvariable%<br>
+<br>
 </font></p>
 
 <p align="left"><strong>3. IF statements</strong></p>
@@ -115,6 +115,7 @@ less than 82:<br>
 <p align="left">In the above example, the statement will be true if the
 <em>floor</em> value is less than 82 and if the <em>height</em> value is either
 3 or 5.<br>
+<br>
 </p>
 
 <p align="left"><strong>4. Inline calculations</strong></p>
index 8ec1443..746b520 100644 (file)
@@ -52,19 +52,6 @@ extern Skyscraper *skyscraper;
 
 ScriptProcessor::ScriptProcessor()
 {
-       //set variable array size
-       UserVariable.resize(256);
-}
-
-ScriptProcessor::~ScriptProcessor()
-{
-
-}
-
-bool ScriptProcessor::LoadBuilding()
-{
-       //building loader/script interpreter
-
        line = 0; //line number
        LineData = "";  //line contents
        Current = 0;
@@ -83,7 +70,6 @@ bool ScriptProcessor::LoadBuilding()
        startpos = 0;
        getfloordata = false;
        setshaftdoors = false;
-       int returncode = 0;
        MinExtent = 0;
        MaxExtent = 0;
        InFunction = false;
@@ -102,10 +88,22 @@ bool ScriptProcessor::LoadBuilding()
        cache_interfloorheight_s = "";
        cache_base = 0;
        cache_base_s = "";
-       int progress_marker = 0;
        setkey = false;
        keyvalue = 0;
        lockvalue = 0;
+}
+
+ScriptProcessor::~ScriptProcessor()
+{
+
+}
+
+bool ScriptProcessor::LoadBuilding()
+{
+       //building loader/script interpreter
+
+       int returncode = 0;
+       int progress_marker = 0;
 
        while (line < (int)BuildingData.size())
        {
@@ -503,19 +501,22 @@ breakpoint:
                                std::string str = LineData.substr(temp1 + 1, temp3 - temp1 - 1);
                                TrimString(str);
                                temp2 = str;
-                               if (IsNumeric(temp2.c_str()) == true)
+
+                               bool found = false;
+                               for (int i = 0; i < variables.size(); i++)
                                {
-                                       temp4 = atoi(temp2.c_str());
-                                       if (temp4 < 0 || temp4 > (int)UserVariable.size() - 1)
+                                       if (variables[i].name == temp2)
                                        {
-                                               ScriptError("Invalid variable number");
-                                               return false;
+                                               found = true;
+
+                                               //replace all occurrences of the variable with it's value
+                                               ReplaceAll(LineData, std::string("%" + temp2 + "%").c_str(), variables[i].value.c_str());
+                                               startpos = temp1;
+                                               break;
                                        }
-                                       //replace all occurrences of the variable with it's value
-                                       ReplaceAll(LineData, std::string("%" + temp2 + "%").c_str(), UserVariable[temp4].c_str());
-                                       startpos = temp1;
                                }
-                               else
+
+                               if (found == false)
                                        startpos = temp3 + 1;
                        }
                        else
@@ -1322,17 +1323,51 @@ int ScriptProcessor::ProcCommands()
        if (linecheck.substr(0, 4) == "set " && Section != 2 && Section != 4)
        {
                temp1 = LineData.find("=", 0);
-               temp3 = atoi(LineData.substr(4, temp1 - 5).c_str());
+               if (temp1 < 0)
+                       return ScriptError("Syntax Error");
+
+               std::string str = LineData.substr(4, temp1 - 5);
+               TrimString(str);
+
+               //reserved keywords
+               if (str == "base" || str == "floor" || str == "height" || str == "interfloorheight" || str == "fullheight" || str == "elevator" || str == "minx" || str == "maxx" || str == "minz" || str == "maxz" || str == "number" || str.substr(0, 4) == "param")
+                       return ScriptError("Cannot use system variable name");
 
                //get text after equal sign
                temp2 = GetAfterEquals(LineData.c_str());
 
-               if (temp3 < 0 || temp3 > UserVariable.size() - 1)
-                       return ScriptError("Invalid variable number");
+               //find existing variable by name
+               int index = -1;
+               for (int i = 0; i < variables.size(); i++)
+               {
+                       if (variables[i].name == str)
+                       {
+                               index = i;
+                               break;
+                       }
+               }
+
+               std::string value = Calc(temp2.c_str());
+
+               if (index == -1)
+               {
+                       //create new variable
+                       VariableMap variable;
+                       variable.name = str;
+                       variable.value = value;
+                       variables.push_back(variable);
+                       value = variable.value;
+               }
+               else
+               {
+                       //set existing variable
+                       variables[index].name = str;
+                       variables[index].value = value;
+                       value = variables[index].value;
+               }
 
-               UserVariable[temp3] = Calc(temp2.c_str());
                if (Simcore->Verbose == true)
-                       skyscraper->Report("Variable " + ToString2(temp3) + " set to " + UserVariable[temp3]);
+                       skyscraper->Report("Variable '" + str + "' set to " + value);
                return sNextLine;
        }
 
@@ -3320,19 +3355,49 @@ int ScriptProcessor::ProcFloors()
                temp1 = LineData.find("=", 0);
                if (temp1 < 0)
                        return ScriptError("Syntax Error");
+
                std::string str = LineData.substr(4, temp1 - 5);
                TrimString(str);
-               if (!IsNumeric(str.c_str(), temp3))
-                       return ScriptError("Invalid variable number");
+
+               //reserved keywords
+               if (str == "base" || str == "floor" || str == "height" || str == "interfloorheight" || str == "fullheight" || str == "elevator" || str == "minx" || str == "maxx" || str == "minz" || str == "maxz" || str == "number" || str.substr(0, 4) == "param")
+                       return ScriptError("Cannot use system variable name");
 
                //get text after equal sign
                temp2 = GetAfterEquals(LineData.c_str());
 
-               if (temp3 < 0 || temp3 > (int)UserVariable.size() - 1)
-                       return ScriptError("Invalid variable number");
-               UserVariable[temp3] = Calc(temp2.c_str());
+               //find existing variable by name
+               int index = -1;
+               for (int i = 0; i < variables.size(); i++)
+               {
+                       if (variables[i].name == str)
+                       {
+                               index = i;
+                               break;
+                       }
+               }
+
+               std::string value = Calc(temp2.c_str());
+
+               if (index == -1)
+               {
+                       //create new variable
+                       VariableMap variable;
+                       variable.name = str;
+                       variable.value = value;
+                       variables.push_back(variable);
+                       value = variable.value;
+               }
+               else
+               {
+                       //set existing variable
+                       variables[index].name = str;
+                       variables[index].value = value;
+                       value = variables[index].value;
+               }
+
                if (Simcore->Verbose == true)
-                       skyscraper->Report("Variable " + ToString2(temp3) + " set to " + UserVariable[temp3]);
+                       skyscraper->Report("Variable '" + str + "' set to " + value);
                return sNextLine;
        }
 
@@ -6774,22 +6839,50 @@ int ScriptProcessor::ProcElevators()
        {
                temp1 = LineData.find("=", 0);
                if (temp1 < 0)
-                       return ScriptError("Syntax error");
+                       return ScriptError("Syntax Error");
 
                std::string str = LineData.substr(4, temp1 - 5);
                TrimString(str);
-               if (!IsNumeric(str.c_str(), temp3))
-                       return ScriptError("Invalid variable number");
+
+               //reserved keywords
+               if (str == "base" || str == "floor" || str == "height" || str == "interfloorheight" || str == "fullheight" || str == "elevator" || str == "minx" || str == "maxx" || str == "minz" || str == "maxz" || str == "number" || str.substr(0, 4) == "param")
+                       return ScriptError("Cannot use system variable name");
 
                //get text after equal sign
                temp2 = GetAfterEquals(LineData.c_str());
 
-               if (temp3 < 0 || temp3 > (int)UserVariable.size() - 1)
-                       return ScriptError("Invalid variable number");
+               //find existing variable by name
+               int index = -1;
+               for (int i = 0; i < variables.size(); i++)
+               {
+                       if (variables[i].name == str)
+                       {
+                               index = i;
+                               break;
+                       }
+               }
+
+               std::string value = Calc(temp2.c_str());
+
+               if (index == -1)
+               {
+                       //create new variable
+                       VariableMap variable;
+                       variable.name = str;
+                       variable.value = value;
+                       variables.push_back(variable);
+                       value = variable.value;
+               }
+               else
+               {
+                       //set existing variable
+                       variables[index].name = str;
+                       variables[index].value = value;
+                       value = variables[index].value;
+               }
 
-               UserVariable[temp3] = Calc(temp2.c_str());
                if (Simcore->Verbose == true)
-                       skyscraper->Report("Variable " + ToString2(temp3) + " set to " + UserVariable[temp3]);
+                       skyscraper->Report("Variable '" + str + "' set to " + value);
                return sNextLine;
        }
 
index d972442..c4702bf 100644 (file)
@@ -25,8 +25,6 @@
 #ifndef FILEIO_H
 #define FILEIO_H
 
-class ScriptProcessor;
-
 class ScriptProcessor
 {
        public:
@@ -64,7 +62,6 @@ class ScriptProcessor
        bool getfloordata;
        bool setshaftdoors;
        std::vector<std::string> BuildingData;
-       std::vector<std::string> UserVariable;
        Ogre::Vector3 MinExtent;
        Ogre::Vector3 MaxExtent;
        bool InFunction;
@@ -110,6 +107,14 @@ class ScriptProcessor
 
        std::vector<IncludeInfo> includes; //stored include mappings
 
+       struct VariableMap
+       {
+               std::string name;
+               std::string value;
+       };
+
+       std::vector<VariableMap> variables; //named user variables
+
        bool floorcache_firstrun;
        int cache_current;
        std::string cache_current_s;
index 4d9b44e..119f68d 100644 (file)
@@ -185,7 +185,7 @@ Elevator::Elevator(int number)
        LastChimeDirection = 0;
 
        //create timers
-       timer = new Timer(this, 0);
+       parking_timer = new Timer(this, 0);
        random_timer = new Timer(this, 1);
        arrival_delay = new Timer(this, 2);
        departure_delay = new Timer(this,3);
@@ -251,12 +251,12 @@ Elevator::~Elevator()
        if (sbs->Verbose)
                Report("deleting timers");
 
-       if (timer)
+       if (parking_timer)
        {
-               timer->Stop();
-               delete timer;
+               parking_timer->Stop();
+               delete parking_timer;
        }
-       timer = 0;
+       parking_timer = 0;
 
        if (random_timer)
        {
@@ -1350,11 +1350,8 @@ void Elevator::MonitorLoop()
        }
 
        //enable auto-park timer if specified
-       if (ParkingDelay > 0 && Running == true && IsIdle() == true)
-       {
-               if (timer->IsRunning() == false)
-                       timer->Start(ParkingDelay * 1000, true);
-       }
+       if (parking_timer->IsRunning() == false && ParkingDelay > 0 && Running == true && IsIdle() == true && InServiceMode() == false)
+               parking_timer->Start(ParkingDelay * 1000, true);
 
        //enable random call timer
        if (random_timer->IsRunning() == false && RandomActivity == true && Running == true && InServiceMode() == false)
@@ -2161,6 +2158,22 @@ void Elevator::FinishMove()
                                ResetQueue(true, false);
                }
 
+               //reverse queues if at either top or bottom of serviced floors
+               if (QueuePositionDirection == 1 && GotoFloor == GetTopFloor())
+               {
+                       if (sbs->Verbose)
+                               Report("at top floor; setting queue search direction to down");
+                       LastQueueDirection = QueuePositionDirection;
+                       QueuePositionDirection = -1;
+               }
+               else if (QueuePositionDirection == -1 && GotoFloor == GetBottomFloor())
+               {
+                       if (sbs->Verbose)
+                               Report("at bottom floor; setting queue search direction to up");
+                       LastQueueDirection = QueuePositionDirection;
+                       QueuePositionDirection = 1;
+               }
+
                //open doors
                //do not automatically open doors if in fire service phase 2
                if (FireServicePhase2 == 0)
@@ -4101,7 +4114,7 @@ void Elevator::Timer::Notify()
        {
                //parking timer
 
-               if (elevator->ParkingDelay > 0 && elevator->IsIdle() == true)
+               if (elevator->ParkingDelay > 0 && elevator->IsIdle() == true && elevator->InServiceMode() == false)
                {
                        int floor = elevator->GetFloor();
                        if (elevator->ParkingFloor != floor)
@@ -4117,29 +4130,36 @@ void Elevator::Timer::Notify()
 
                        Stop();
                }
+               else if (elevator->InServiceMode() == true)
+                       Stop(); //stop timer if in service mode
        }
-       else if (type == 1 && elevator->RandomActivity == true)
+       else if (type == 1)
        {
                //random call timer
-               
-               RandomGen rnd_main(time(0) + elevator->Number);
-               RandomGen rnd_floor(sbs->GetRunTime() + elevator->Number);
 
-               int num, floor;
+               if (elevator->RandomActivity == true && elevator->InServiceMode() == false)
+               {
+                       RandomGen rnd_main(time(0) + elevator->Number);
+                       RandomGen rnd_floor(sbs->GetRunTime() + elevator->Number);
 
-               //get call probability
-               if (elevator->RandomProbability > 1)
-                       num = rnd_main.Get(elevator->RandomProbability - 1);
-               else
-                       num = 0;
+                       int num, floor;
+
+                       //get call probability
+                       if (elevator->RandomProbability > 1)
+                               num = rnd_main.Get(elevator->RandomProbability - 1);
+                       else
+                               num = 0;
 
-               //get call floor
-               int index = rnd_floor.Get(elevator->ServicedFloors.size());
-               floor = elevator->ServicedFloors[index];
+                       //get call floor
+                       int index = rnd_floor.Get(elevator->ServicedFloors.size());
+                       floor = elevator->ServicedFloors[index];
 
-               //if probability number matched, press selected floor button
-               if (num == 0 && elevator->IsQueued(floor) == false && floor != elevator->GetFloor())
-                       elevator->PressFloorButton(floor);
+                       //if probability number matched, press selected floor button
+                       if (num == 0 && elevator->IsQueued(floor) == false && floor != elevator->GetFloor())
+                               elevator->PressFloorButton(floor);
+               }
+               else if (elevator->InServiceMode() == true)
+                       Stop(); //stop timer if in service mode
        }
        else if (type > 1)
        {
@@ -4895,8 +4915,8 @@ bool Elevator::AvailableForCall(int floor, int direction)
                //and if no queue changes are pending
                if (QueuePending == false)
                {
-                       //and if elevator either has limitqueue off, or has limitqueue on and is eligible
-                       if (LimitQueue == false || (LimitQueue == true && QueuePositionDirection == 0))
+                       //and if elevator either has limitqueue off, or has limitqueue on and queue direction is the same
+                       if (LimitQueue == false || (LimitQueue == true && (QueuePositionDirection == direction || QueuePositionDirection == 0)))
                        {
                                //and if elevator either has queueresets off, or has queueresets on and queue direction is the same
                                if (QueueResets == false || (QueueResets == true && (QueuePositionDirection == direction || QueuePositionDirection == 0)))
@@ -4905,7 +4925,7 @@ bool Elevator::AvailableForCall(int floor, int direction)
                                        //current floor and called up, or on the same floor and not moving, or idle
                                        if ((GetFloor() > floor && direction == -1) || (GetFloor() < floor && direction == 1) || (GetFloor() == floor && MoveElevator == false) || IsIdle())
                                        {
-                                               //and if it's either going the same direction as the call or idle
+                                               //and if it's either going the same direction as the call, on either the highest/lowest (terminal) floor, or idle
                                                if (QueuePositionDirection == direction || IsIdle())
                                                {
                                                        //and if nudge mode is off on all doors
index cc30de5..b13c37d 100644 (file)
@@ -307,7 +307,7 @@ private:
        };
 
        //parking timer object
-       Timer *timer;
+       Timer *parking_timer;
 
        //random call timer object
        Timer *random_timer;