Permalink
Browse files

Merge branch 'restart' of github.com:fabianschuiki/OpenSkyscraper int…

…o restart
  • Loading branch information...
2 parents 32310e7 + 3887835 commit 5f86e685e26f416bf83c04a2ae1c1da9370e0546 @fabianschuiki committed Apr 25, 2012
View
@@ -5,6 +5,10 @@
- In `Route`, keep track of how many stairs and elevators were used. Then make the pathfinder limit
the amount of stairs and elevators that are used per route. Otherwise algorithm complexity will
explode.
+- Modify `Time` so that `absolute` is a day counter that advances evenly. Add some code that
+ calculates the current hour by scaling the absolute time differently for different phases of the
+ day to create the effect of time running at different speeds.
+
Game
----
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -1,21 +1,31 @@
-<tower funds="1100000" rating="0" time="4" paused="0" rainy="0" tool="finger" x="0" y="200">
- <item type="fastfood" x="8" y="2" variant="0" open="1"/>
- <item type="elevator-standard" x="10" y="0" height="16">
- <car altitude="0"/>
+<tower funds="1100000" rating="0" time="0.195" speed="1" rainy="0" tool="finger" x="0" y="200">
+ <item type="fastfood" x="8" y="2" variant="0" open="0"/>
+ <item type="elevator-standard" x="10" y="0" height="6">
+ <car altitude="0.000000"/>
+ <car altitude="0.000000"/>
</item>
- <item type="elevator-standard" x="-12" y="15" height="10">
- <car altitude="0"/>
+ <item type="elevator-standard" x="-12" y="15" height="18">
+ <car altitude="15.000000"/>
</item>
- <item type="fastfood" x="-8" y="24" variant="4" open="1"/>
- <item type="fastfood" x="-8" y="2" variant="4" open="1"/>
- <item type="fastfood" x="-24" y="1" variant="0" open="1"/>
- <item type="fastfood" x="8" y="3" variant="2" open="1"/>
- <item type="fastfood" x="-8" y="1" variant="1" open="1"/>
- <item type="fastfood" x="8" y="1" variant="2" open="1"/>
- <item type="fastfood" x="-24" y="2" variant="3" open="1"/>
- <item type="fastfood" x="-8" y="3" variant="0" open="1"/>
- <item type="fastfood" x="-24" y="3" variant="4" open="1"/>
+ <item type="elevator-express" x="-20" y="0" height="16">
+ <car altitude="0.000000"/>
+ </item>
+ <item type="fastfood" x="-8" y="24" variant="4" open="0"/>
+ <item type="fastfood" x="-8" y="2" variant="4" open="0"/>
+ <item type="fastfood" x="-24" y="1" variant="0" open="0"/>
+ <item type="fastfood" x="8" y="3" variant="2" open="0"/>
+ <item type="fastfood" x="-8" y="1" variant="1" open="0"/>
+ <item type="fastfood" x="8" y="1" variant="2" open="0"/>
+ <item type="fastfood" x="-24" y="2" variant="3" open="0"/>
+ <item type="fastfood" x="-8" y="3" variant="0" open="0"/>
+ <item type="fastfood" x="-24" y="3" variant="4" open="0"/>
<item type="stairs" x="-12" y="0"/>
<item type="escalator" x="0" y="0"/>
<item type="lobby" x="-24" y="0" width="48"/>
+ <item type="stairs" x="-12" y="2"/>
+ <item type="fastfood" x="-24" y="4" variant="2" open="0"/>
+ <item type="fastfood" x="-8" y="4" variant="2" open="0"/>
+ <item type="stairs" x="-12" y="3"/>
+ <item type="stairs" x="-12" y="1"/>
+ <item type="fastfood" x="8" y="4" variant="1" open="0"/>
</tower>
View
@@ -4,22 +4,27 @@
body {
top: 330px;
left: 0px;
- width: 64px;
+ width: 128px;
background-color: #ddd;
}
- button#speed {
- display: block;
- width: 64px;
- height: 32px;
+ div.speed-buttons { display: block; padding: 0px 18px; padding-top: 10px; }
+ div.tool-buttons { display: block; padding: 0px 32px; padding-bottom: 10px; }
+
+ button.speed {
+ display: inline-block;
+ width: 23px;
+ height: 24px;
background-decorator: image;
- background-image: /simtower/ui/toolbox/speed;
+ background-image: /speed.png;
background-image-t: 0 0.5;
}
- button#speed:active { background-image-t: 0.5 1; }
- button#speed.pause { background-image-s: 0 0.5; }
- button#speed.play { background-image-s: 0.5 1; }
+ button.speed:active, button.speed.selected { background-image-t: 0.5 1; }
+ button#speed0 { background-image-s: 0 0.25; }
+ button#speed1 { background-image-s: 0.25 0.5; }
+ button#speed2 { background-image-s: 0.5 0.75; }
+ button#speed3 { background-image-s: 0.75 1; }
button.tool {
display: inline-block;
@@ -49,9 +54,16 @@
</head>
<body>
- <button id="speed" class="play"></button>
- <button id="bulldozer" class="tool"></button>
- <button id="finger" class="tool"></button>
- <button id="inspector" class="tool"></button>
+ <div class="speed-buttons">
+ <button id="speed0" class="speed"></button>
+ <button id="speed1" class="speed"></button>
+ <button id="speed2" class="speed"></button>
+ <button id="speed3" class="speed"></button>
+ </div>
+ <div class="tool-buttons">
+ <button id="bulldozer" class="tool"></button>
+ <button id="finger" class="tool"></button>
+ <button id="inspector" class="tool"></button>
+ </div>
</body>
</rml>
View
@@ -19,8 +19,8 @@ Game::Game(Application & app)
population = 0;
populationNeedsUpdate = false;
- time.set(5);
- paused = false;
+ time.set(7/78.0);
+ speedMode = 1;
selectedTool = "inspector";
itemBelowCursor = NULL;
toolPrototype = NULL;
@@ -85,31 +85,40 @@ bool Game::handleEvent(sf::Event & event)
switch (event.Type) {
case sf::Event::KeyPressed: {
switch (event.Key.Code) {
- case sf::Key::Left: poi.x -= 20; break;
- case sf::Key::Right: poi.x += 20; break;
- case sf::Key::Up: poi.y += 20; break;
- case sf::Key::Down: poi.y -= 20; break;
- case sf::Key::F1: reloadGUI(); break;
- case sf::Key::F3: setRating(1); break;
+ case sf::Key::Left: poi.x -= 20; return true;
+ case sf::Key::Right: poi.x += 20; return true;
+ case sf::Key::Up: poi.y += 20; return true;
+ case sf::Key::Down: poi.y -= 20; return true;
+ case sf::Key::F1: reloadGUI(); return true;
+ case sf::Key::F3: setRating(1); return true;
case sf::Key::F2: {
FILE * f = fopen("default.tower", "w");
tinyxml2::XMLPrinter xml(f);
encodeXML(xml);
fclose(f);
- } break;
- case sf::Key::PageUp: zoom /= 2; break;
- case sf::Key::PageDown: zoom *= 2; break;
+ } return true;
+ case sf::Key::PageUp: zoom /= 2; return true;
+ case sf::Key::PageDown: zoom *= 2; return true;
}
} break;
+ case sf::Event::TextEntered: {
+ switch (event.Text.Unicode) {
+ case '0': setSpeedMode(0); return true;
+ case '1': setSpeedMode(1); return true;
+ case '2': setSpeedMode(2); return true;
+ case '3': setSpeedMode(3); return true;
+ } break;
+ } break;
+
case sf::Event::MouseButtonPressed: {
if (toolPrototype) {
bool handled = false;
if (toolPrototype->id.find("elevator") == 0) {
for (ItemSet::iterator i = items.begin(); i != items.end(); i++) {
if ((*i)->prototype == toolPrototype && (*i)->getRect().containsPoint(toolPosition)) {
LOG(DEBUG, "add car on floor %i to elevator %s", toolPosition.y, (*i)->desc().c_str());
- ((Item::Elevator *)*i)->addCar(toolPosition.y);
+ ((Item::Elevator::Elevator *)*i)->addCar(toolPosition.y);
transferFunds(-80000);
handled = true;
break;
@@ -134,7 +143,7 @@ bool Game::handleEvent(sf::Event & event)
}
else if (selectedTool == "finger") {
if (itemBelowCursor->prototype->id.find("elevator") == 0) {
- Item::Elevator * e = (Item::Elevator *)itemBelowCursor;
+ Item::Elevator::Elevator * e = (Item::Elevator::Elevator *)itemBelowCursor;
draggingMotor = 0;
if (toolPosition.y < itemBelowCursor->position.y) draggingMotor = -1;
@@ -148,6 +157,7 @@ bool Game::handleEvent(sf::Event & event)
if (!e->unservicedFloors.erase(toolPosition.y))
e->unservicedFloors.insert(toolPosition.y);
updateRoutes();
+ e->cleanQueues();
}
}
}
@@ -181,7 +191,6 @@ void Game::advance(double dt)
drawnSprites = 0;
//Advance time.
- if (paused) dt = 0;
time.advance(dt);
timeWindow.updateTime();
@@ -202,10 +211,10 @@ void Game::advance(double dt)
}
//Play sounds.
- if (time.checkHour(5)) cockSound.Play();
- if (time.checkHour(6)) morningSound.Play();
- if (time.checkHour(9)) bellsSound.Play();
- if (time.checkHour(18)) eveningSound.Play();
+ if (time.checkHour(5)) cockSound.Play(this);
+ if (time.checkHour(6)) morningSound.Play(this);
+ if (time.checkHour(9)) bellsSound.Play(this);
+ if (time.checkHour(18)) eveningSound.Play(this);
morningSound.SetLoop(time.hour < 8);
//Constrain the POI.
@@ -294,6 +303,15 @@ void Game::advance(double dt)
}
glEnd();
+ //Adjust pitch of playing sounds.
+ for (SoundSet::iterator s = playingSounds.begin(); s != playingSounds.end(); s++) {
+ if ((*s)->GetStatus() == sf::Sound::Stopped) {
+ playingSounds.erase(s);
+ } else {
+ (*s)->SetPitch(1 + (time.speed_animated-1) * 0.2);
+ }
+ }
+
//Autorelease sounds.
for (SoundSet::iterator s = autoreleaseSounds.begin(); s != autoreleaseSounds.end(); s++) {
if ((*s)->GetStatus() == sf::Sound::Stopped) {
@@ -340,7 +358,7 @@ void Game::encodeXML(tinyxml2::XMLPrinter & xml)
xml.PushAttribute("funds", funds);
xml.PushAttribute("rating", rating);
xml.PushAttribute("time", time.absolute);
- xml.PushAttribute("paused", paused);
+ xml.PushAttribute("speed", speedMode);
xml.PushAttribute("rainy", sky.rainyDay);
xml.PushAttribute("tool", selectedTool.c_str());
@@ -364,7 +382,7 @@ void Game::decodeXML(tinyxml2::XMLDocument & xml)
setFunds(root->IntAttribute("funds"));
setRating(root->IntAttribute("rating"));
time.set(root->DoubleAttribute("time"));
- setPaused(root->BoolAttribute("paused"));
+ setSpeedMode(root->IntAttribute("speed"));
sky.rainyDay = root->BoolAttribute("rainy");
selectTool(root->Attribute("tool"));
@@ -380,11 +398,15 @@ void Game::decodeXML(tinyxml2::XMLDocument & xml)
updateRoutes();
}
-void Game::transferFunds(int f)
+void Game::transferFunds(int f, std::string message)
{
setFunds(funds + f);
playOnce("simtower/cash");
- LOG(DEBUG, "%i", f);
+ if (!message.empty()) {
+ char c[32];
+ snprintf(c, 32, ": $%i", f);
+ timeWindow.showMessage(message + c);
+ }
}
void Game::setFunds(int f)
@@ -435,10 +457,19 @@ void Game::ratingMayIncrease()
}
}
-void Game::setPaused(bool p)
+void Game::setSpeedMode(int sm)
{
- if (paused != p) {
- paused = p;
+ assert(sm >= 0 && sm <= 3);
+ if (speedMode != sm) {
+ speedMode = sm;
+ double speed = 0;
+ switch (speedMode) {
+ case 0: speed = 0; break;
+ case 1: speed = 1; break;
+ case 2: speed = 2; break;
+ case 3: speed = 4; break;
+ }
+ time.speed = speed;
toolboxWindow.updateSpeed();
}
}
@@ -457,9 +488,9 @@ void Game::selectTool(const char * tool)
* internally. */
void Game::playOnce(Path sound)
{
- sf::Sound * snd = new sf::Sound;
+ Sound * snd = new Sound;
snd->SetBuffer(app.sounds[sound]);
- snd->Play();
+ snd->Play(this);
autoreleaseSounds.insert(snd);
}
@@ -474,6 +505,9 @@ void Game::updateRoutes()
}
}
+/** Finds a route from start to destination through the tower. The returned route contains start as
+ * the first and destination as the last node, with transportation in between. If the returned
+ * route is empty(), no path was found through the tower. */
Route Game::findRoute(Item::Item * start, Item::Item * destination)
{
return findRoute(Route(), start->position.y, start, destination);
@@ -492,6 +526,11 @@ Route Game::findRoute(Route route, int floor, Item::Item * current, Item::Item *
Item::Item * i = *it;
if (!i->canHaulPeople() || route.usesItem(i)) continue;
+ //Limit the number of elevators, stairs and escalators to use per route.
+ if (i->isElevator() && route.numElevators >= 2) continue;
+ if (i->prototype->id == "stairs" && route.numStairs >= 3) continue;
+ if (i->prototype->id == "escalator" && route.numEscalators >= 5) continue;
+
//Check whether this item connects to the floor we're currently at.
if (!i->connectsFloor(floor)) continue;
@@ -503,21 +542,24 @@ Route Game::findRoute(Route route, int floor, Item::Item * current, Item::Item *
r.add(destination);
}
- //Otherwise check lobbies for elevators.
+ //For elevators, check the lobbies for connecting transports.
else if (i->isElevator()) {
- for (int f = i->position.y % 15; f < i->size.y; f += 15) {
- Route sr = findRoute(route, f + i->position.y, i, destination);
+ for (int n = i->position.y % 15; n < i->size.y; n += 15) {
+ int f = n + i->position.y;
+ if (!i->connectsFloor(f)) continue;
+ Route sr = findRoute(route, f, i, destination);
if (r.empty() || sr.score() < r.score()) r = sr;
}
}
- //Or the floor above/below for stairs.
+ //For stairlike items, check the floor above/below for connecting transports.
else if (i->isStairlike()) {
int f = i->position.y;
if (f == floor) f += i->size.y-1;
r = findRoute(route, f, i, destination);
}
+ //If r's score is lower (better) than the best we've found so far, make r the current best route.
if (!r.empty() && (best.empty() || r.score() < best.score())) best = r;
}
Oops, something went wrong.

0 comments on commit 5f86e68

Please sign in to comment.