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%
<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>
<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>
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;
startpos = 0;
getfloordata = false;
setshaftdoors = false;
- int returncode = 0;
MinExtent = 0;
MaxExtent = 0;
InFunction = false;
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())
{
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
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;
}
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;
}
{
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;
}
#ifndef FILEIO_H
#define FILEIO_H
-class ScriptProcessor;
-
class ScriptProcessor
{
public:
bool getfloordata;
bool setshaftdoors;
std::vector<std::string> BuildingData;
- std::vector<std::string> UserVariable;
Ogre::Vector3 MinExtent;
Ogre::Vector3 MaxExtent;
bool InFunction;
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;
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);
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)
{
}
//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)
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)
{
//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)
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)
{
//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)))
//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
};
//parking timer object
- Timer *timer;
+ Timer *parking_timer;
//random call timer object
Timer *random_timer;