scummvm/engines/asylum/puzzles/pipes.cpp
2021-05-17 15:37:54 +02:00

653 lines
22 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <common/math.h>
#include "asylum/puzzles/pipes.h"
#include "asylum/resources/worldstats.h"
#include "asylum/system/cursor.h"
#include "asylum/system/graphics.h"
#include "asylum/system/screen.h"
#include "asylum/views/scene.h"
#include "asylum/asylum.h"
namespace Asylum {
const Common::Point connectorPoints[] = {
Common::Point(158, 59),
Common::Point(163, 172),
Common::Point(168, 272),
Common::Point(202, 59),
Common::Point(205, 132),
Common::Point(206, 172),
Common::Point(271, 60),
Common::Point(272, 131),
Common::Point(273, 262),
Common::Point(318, 169),
Common::Point(319, 206),
Common::Point(318, 261),
Common::Point(380, 72),
Common::Point(360, 171),
Common::Point(360, 206),
Common::Point(428, 172),
Common::Point(401, 242),
Common::Point(399, 295),
Common::Point(469, 119),
Common::Point(466, 171),
Common::Point(460, 294),
};
const Common::Point peepholePoints[] = {
Common::Point(140, 65),
Common::Point(311, 44),
Common::Point(387, 48),
Common::Point(475, 72),
Common::Point(189, 67),
Common::Point(246, 66),
Common::Point(169, 113),
Common::Point(215, 106),
Common::Point(280, 105),
Common::Point(336, 95),
Common::Point(434, 80),
Common::Point(248, 136),
Common::Point(303, 154),
Common::Point(407, 125),
Common::Point(470, 151),
Common::Point(193, 180),
Common::Point(347, 176),
Common::Point(401, 177),
Common::Point(245, 201),
Common::Point(325, 196),
Common::Point(347, 212),
Common::Point(406, 213),
Common::Point(431, 218),
Common::Point(174, 228),
Common::Point(217, 234),
Common::Point(280, 227),
Common::Point(325, 239),
Common::Point(370, 244),
Common::Point(467, 239),
Common::Point(303, 267),
Common::Point(405, 273),
Common::Point(356, 293),
Common::Point(436, 294),
Common::Point(182, 317),
Common::Point(277, 299),
Common::Point(324, 291),
Common::Point(461, 323)
};
const uint32 peepholeResources[] = {15, 15, 15, 15, 32, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 32, 32, 15,
15, 32, 32, 15, 15, 15, 15, 15, 15, 15, 15, 32, 15, 15, 15, 15, 15, 15, 15};
static BinNum calcStateFromPos(uint32 ind, ConnectorType type, uint32 position) {
uint32 shift = (uint32)Common::intLog2(position);
return BinNum((type >> shift | type << (4 - shift)) & 0xF);
}
//////////////////////////////////////////////////////////////////////////
// Peephole
//////////////////////////////////////////////////////////////////////////
bool Peephole::marks[peepholesCount];
void Peephole::startUpWater(bool flag) {
if (flag)
memset(marks, false, sizeof(marks));
marks[_id] = true;
for (Common::List<Connector *>::iterator iter = _connectors.begin(); iter != _connectors.end(); ++iter) {
for (Common::List<Peephole *>::iterator iter1 = (*iter)->_connectedNodes.begin(); iter1 != (*iter)->_connectedNodes.end(); ++iter1) {
if (!marks[(*iter1)->getId()]) {
for (uint32 i = 0; i < 4; ++i) {
if (isConnected(i) && (*iter1)->getId() > 3)
(*iter1)->_flowValues[i] += _flowValues[i];
}
(*iter1)->startUpWater();
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// Connector
//////////////////////////////////////////////////////////////////////////
void Connector::init(Peephole *n, Peephole *e, Peephole *s, Peephole *w, uint32 pos, ConnectorType type, Connector *nextConnector, Direction nextConnectorPosition) {
_nodes[0] = n;
_nodes[1] = e;
_nodes[2] = s;
_nodes[3] = w;
*_position = pos;
_type = type;
_state = calcStateFromPos(_id, _type, *_position);
_nextConnector = nextConnector;
_nextConnectorPosition = nextConnectorPosition;
_isConnected = false;
for (uint32 i = 0; i < 4; ++i) {
if (_state & ((uint32)1 << i) && _nodes[i]) {
_nodes[i]->connect(this);
_connectedNodes.push_back(_nodes[i]);
}
}
}
void Connector::initGroup() {
if (!_isConnected && isReadyForConnection() && _nextConnector->isReadyForConnection())
connect(_nextConnector);
}
void Connector::turn(bool updpos) {
if (updpos)
*_position = (*_position == 8) ? 1 : *_position << 1;
BinNum newState = BinNum(_state >> 1 | (_state & 1) << 3);
uint32 delta = _state ^ newState;
uint32 newIndex[2], oldIndex[2];
if (delta == kBinNum1111) {
if (newState == kBinNum0101) {
newIndex[0] = 0;
newIndex[1] = 2;
oldIndex[0] = 1;
oldIndex[1] = 3;
} else {
newIndex[0] = 1;
newIndex[1] = 3;
oldIndex[0] = 0;
oldIndex[1] = 2;
}
} else {
newIndex[0] = (uint32)Common::intLog2(newState & delta);
oldIndex[0] = (uint32)Common::intLog2(_state & delta);
}
for (uint32 i = 0; i < (uint32)(delta == kBinNum1111 ? 2 : 1); ++i) {
if (_nodes[oldIndex[i]]) {
_nodes[oldIndex[i]]->disconnect(this);
_connectedNodes.remove(_nodes[oldIndex[i]]);
}
if (_nodes[newIndex[i]]) {
_nodes[newIndex[i]]->connect(this);
_connectedNodes.push_back(_nodes[newIndex[i]]);
}
}
_state = newState;
if (_nextConnector) {
if (_isConnected) {
if (!(_nextConnectorPosition & _state))
disconnect(_nextConnector);
} else if (_nextConnectorPosition & _state && _nextConnector->isReadyForConnection()) {
connect(_nextConnector);
}
}
}
void Connector::connect(Connector *connector) {
for (Common::List<Peephole *>::iterator iter = _connectedNodes.begin(); iter != _connectedNodes.end(); ++iter) {
(*iter)->connect(connector);
connector->_connectedNodes.push_back(*iter);
}
for (Common::List<Peephole *>::iterator iter = connector->_connectedNodes.begin(); iter != connector->_connectedNodes.end(); ++iter) {
(*iter)->connect(this);
_connectedNodes.push_back(*iter);
}
_isConnected = connector->_isConnected = true;
}
void Connector::disconnect(Connector *connector) {
uint32 i;
Common::List<Common::List<Peephole *>::iterator> markedForDeletion;
bool flag;
for (i = 0; i < 4; ++i)
if (_nodes[i]) {
_nodes[i]->disconnect(connector);
connector->_connectedNodes.remove(_nodes[i]);
}
for (Common::List<Peephole *>::iterator iter = _connectedNodes.begin(); iter != _connectedNodes.end(); ++iter) {
flag = true;
for (i = 0; i < 4; ++i) {
if (*iter == _nodes[i]) {
flag = false;
break;
}
}
if (flag)
markedForDeletion.push_back(iter);
}
for (Common::List<Common::List<Peephole *>::iterator>::iterator iter1 = markedForDeletion.begin(); iter1 != markedForDeletion.end(); ++iter1) {
(*(*iter1))->disconnect(this);
_connectedNodes.remove(*(*iter1));
}
_isConnected = connector->_isConnected = false;
}
//////////////////////////////////////////////////////////////////////////
// Spider
//////////////////////////////////////////////////////////////////////////
Spider::Spider(const Common::Rect &rect, Common::String id) {
_boundingBox = rect;
_rnd = new Common::RandomSource(Common::String("pipes_spider") + id);
_isAlive = true;
_location.x = (int16)_rnd->getRandomNumber((uint16)(_boundingBox.right - _boundingBox.left)) + _boundingBox.left;
_location.y = (int16)_rnd->getRandomNumber((uint16)(_boundingBox.bottom - _boundingBox.top)) + _boundingBox.top;
_direction = Direction((uint32)1 << _rnd->getRandomNumber(3));
_stepsNumber = 0;
_steps = 0;
randomize();
}
void Spider::randomize(Direction excluded) {
if (_rnd->getRandomNumber(5) == 5)
_delta = Common::Point(0, 0);
else {
while (_direction == excluded)
_direction = Direction((uint32)1 << _rnd->getRandomNumber(3));
_delta = Common::Point((_direction & kBinNum0010 ? 1 : 0) - (_direction & kBinNum1000 ? 1 : 0), (_direction & kBinNum0100 ? 1 : 0) - (_direction & kBinNum0001 ? 1 : 0));
}
_stepsNumber = _rnd->getRandomNumber(maxStepsNumber - minStepsNumber) + minStepsNumber;
_steps = 0;
}
Common::Point Spider::move() {
Common::Point previousLocation(_location);
if (_isAlive) {
if (_steps++ > _stepsNumber)
randomize();
if (!_boundingBox.contains(_location + _delta))
randomize(_direction);
else
_location += _delta;
}
return previousLocation;
}
//////////////////////////////////////////////////////////////////////////
// PuzzlePipes
//////////////////////////////////////////////////////////////////////////
PuzzlePipes::PuzzlePipes(AsylumEngine *engine) : Puzzle(engine) {
_previousMusicVolume = 0;
_rectIndex = -2;
_frameIndex = _frameIndexLever = 0;
memset(&_levelFlags, false, sizeof(_levelFlags));
_levelFlags[4] = true;
memset(&_levelValues, 0, sizeof(_levelValues));
memset(&_previousLevels, 0, sizeof(_previousLevels));
_isLeverReady = false;
memset(&_sinks, 0, sizeof(_sinks));
memset(&_sources, 0, sizeof(_sources));
_frameIndexSpider = NULL;
initResources();
setup();
}
PuzzlePipes::~PuzzlePipes() {
for (uint32 i = 0; i < _spiders.size(); ++i)
delete _spiders[i];
if (_frameIndexSpider)
delete[] _frameIndexSpider;
}
void PuzzlePipes::saveLoadWithSerializer(Common::Serializer &s) {
s.skip(16);
for (uint32 i = 0; i < connectorsCount; i++) {
s.syncAsUint32LE(_positions[i]);
}
s.skip(16);
}
//////////////////////////////////////////////////////////////////////////
// Event Handling
//////////////////////////////////////////////////////////////////////////
bool PuzzlePipes::init(const AsylumEvent &) {
_previousMusicVolume = getSound()->getMusicVolume();
if (_previousMusicVolume >= -1000)
getSound()->setMusicVolume(-1000);
getSound()->playSound(getWorld()->graphicResourceIds[41], true, Config.ambientVolume);
getScreen()->setPalette(getWorld()->graphicResourceIds[0]);
getScreen()->setGammaLevel(getWorld()->graphicResourceIds[0]);
_rectIndex = -2;
checkConnections();
startUpWater();
(void)checkFlags();
return true;
}
bool PuzzlePipes::update(const AsylumEvent &) {
getScreen()->clear();
getScreen()->clearGraphicsInQueue();
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[1], 0, Common::Point(0, 0), kDrawFlagNone, 0, 4);
for (uint32 i = 0; i < ARRAYSIZE(_connectors); ++i)
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[_connectorResources[_connectors[i].getState()]], 0, connectorPoints[i], kDrawFlagNone, 0, 1);
uint32 filled = 0;
for (uint32 i = 0; i < 4; ++i) {
if (fabs(_levelValues[i] - _previousLevels[i]) > 0.005)
_previousLevels[i] += _levelValues[i] > _previousLevels[i] ? 0.01f : -0.01f;
else
++filled;
}
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[18], 0, Common::Point(210, 444 - int16(_previousLevels[0] * 52)), kDrawFlagNone, 0, 3);
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[18], 0, Common::Point(276, 455 - int16(_previousLevels[1] * 52)), kDrawFlagNone, 0, 3);
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[18], 0, Common::Point(376, 448 - int16(_previousLevels[2] * 52)), kDrawFlagNone, 0, 3);
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[18], 0, Common::Point(458, 442 - int16(_previousLevels[3] * 52)), kDrawFlagNone, 0, 3);
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[33], 0, Common::Point(204, 377), kDrawFlagNone, 0, 1);
_frameIndex = (_frameIndex + 1) % GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[15]);
for (uint32 i = 0; i < ARRAYSIZE(_peepholes); ++i)
if (_peepholes[i].isConnected())
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[peepholeResources[i]], _frameIndex, peepholePoints[i], kDrawFlagNone, 0, 1);
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[2], _frameIndexLever, Common::Point(540, 90), kDrawFlagNone, 0, 1);
_isLeverReady = false;
if (_frameIndexLever) {
_frameIndexLever = (_frameIndexLever + 1) % GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[2]);
if (!_frameIndexLever) {
_isLeverReady = true;
getCursor()->show();
}
}
if (filled == 4) {
if (_levelFlags[0])
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[40], 0, Common::Point(233, 416), kDrawFlagNone, 0, 1);
else if (_levelFlags[1])
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[40], 0, Common::Point(299, 431), kDrawFlagNone, 0, 1);
else if (_levelFlags[2])
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[40], 0, Common::Point(398, 421), kDrawFlagNone, 0, 1);
else if (_levelFlags[3])
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[40], 0, Common::Point(481, 417), kDrawFlagNone, 0, 1);
if (!_levelFlags[4])
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[45], 0, Common::Point(518, 108), kDrawFlagNone, 0, 2);
}
for (uint32 i = 0; i < _spiders.size(); ++i) {
uint32 spiderResourceId = 0;
switch (_spiders[i]->getDirection()) {
default:
error("[PuzzlePipes::update] Invalid spider direction (%d)", _spiders[i]->getDirection());
case kDirectionNh:
spiderResourceId = _spiders[i]->isAlive() ? 34 : 37;
break;
case kDirectionEt:
spiderResourceId = _spiders[i]->isAlive() ? 35 : 38; // FIXME
break;
case kDirectionSh:
spiderResourceId = _spiders[i]->isAlive() ? 36 : 39;
break;
case kDirectionWt:
spiderResourceId = _spiders[i]->isAlive() ? 35 : 38;
break;
}
if (_spiders[i]->isVisible(Common::Rect(-10, -10, 650, 490))) {
uint32 frameCountSpider = GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[spiderResourceId]);
_frameIndexSpider[i] = _spiders[i]->isActive() ? (_frameIndexSpider[i] + 1) % frameCountSpider : 0;
getScreen()->addGraphicToQueue(getWorld()->graphicResourceIds[spiderResourceId], _frameIndexSpider[i], _spiders[i]->move(), kDrawFlagNone, 0, 1);
}
}
getScreen()->drawGraphicsInQueue();
getScreen()->copyBackBufferToScreen();
updateCursor();
if (_isLeverReady) {
if (!_levelFlags[4])
_vm->setGameFlag((GameFlag)(96 + checkFlags()));
getScreen()->clear();
getSound()->stop(getWorld()->graphicResourceIds[41]);
getSound()->setMusicVolume(_previousMusicVolume);
_vm->switchEventHandler(getScene());
}
return true;
}
bool PuzzlePipes::mouseLeftDown(const AsylumEvent &) {
Common::Point mousePos = getCursor()->position();
if (Common::Rect(540, 90, 590, 250).contains(mousePos)) {
if (!_frameIndexLever)
++_frameIndexLever;
getCursor()->hide();
getSound()->playSound(getWorld()->graphicResourceIds[43], false, Config.sfxVolume - 10);
} else {
if (_rectIndex != -1) {
if (_rectIndex < ARRAYSIZE(connectorPoints)) {
getSound()->playSound(getWorld()->graphicResourceIds[42], false, Config.sfxVolume - 10);
_connectors[_rectIndex].turn();
startUpWater();
memset(_levelFlags, false, sizeof(_levelFlags));
_levelFlags[checkFlags()] = true;
} else {
getSound()->playSound(getWorld()->graphicResourceIds[44], false, Config.sfxVolume - 10);
_spiders[_rectIndex - ARRAYSIZE(connectorPoints)]->smash();
_frameIndexSpider[_rectIndex - ARRAYSIZE(connectorPoints)] = 0;
}
}
}
return true;
}
bool PuzzlePipes::mouseRightDown(const AsylumEvent &) {
getScreen()->clear();
getSound()->stop(getWorld()->graphicResourceIds[41]);
getSound()->setMusicVolume(_previousMusicVolume);
_vm->switchEventHandler(getScene());
return true;
}
//////////////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////////////
void PuzzlePipes::initResources() {
_connectorResources[kBinNum0011] = 4;
_connectorResources[kBinNum0110] = 3;
_connectorResources[kBinNum1100] = 6;
_connectorResources[kBinNum1001] = 5;
_connectorResources[kBinNum0111] = 7;
_connectorResources[kBinNum1110] = 10;
_connectorResources[kBinNum1101] = 9;
_connectorResources[kBinNum1011] = 8;
_connectorResources[kBinNum0101] = 11;
_connectorResources[kBinNum1010] = 12;
}
void PuzzlePipes::setup() {
memset(&_levelValues, 0, sizeof(_levelValues));
for (uint32 i = 0; i < peepholesCount; ++i)
_peepholes[i].setId(i);
for (uint32 i = 0; i < connectorsCount; ++i) {
_connectors[i].setId(i);
_connectors[i].setPos(&_positions[i]);
}
for (uint32 i = 0; i < 4; ++i) {
_sinks[i] = &_peepholes[(peepholesCount - 4) + i];
_sources[i] = &_peepholes[i];
memset(&_sources[i]->_flowValues, 0, sizeof(_sources[i]->_flowValues));
_sources[i]->_flowValues[i] = 1;
}
_connectors[ 0].init( NULL, _peepholes + 4, _peepholes + 6, _peepholes + 0, 1, kConnectorTypeL);
_connectors[ 1].init(_peepholes + 6, _peepholes + 15, _peepholes + 23, NULL, 1, kConnectorTypeL);
_connectors[ 2].init(_peepholes + 23, _peepholes + 24, _peepholes + 33, NULL, 2, kConnectorTypeL);
_connectors[ 3].init( NULL, _peepholes + 5, _peepholes + 7, _peepholes + 4, 1, kConnectorTypeL);
_connectors[ 4].init(_peepholes + 7, _peepholes + 11, NULL, NULL, 2, kConnectorTypeL, _connectors + 5, kDirectionSh);
_connectors[ 5].init( NULL, _peepholes + 18, _peepholes + 24, _peepholes + 15, 1, kConnectorTypeT, _connectors + 4, kDirectionNh);
_connectors[ 6].init( NULL, _peepholes + 1, _peepholes + 8, _peepholes + 5, 1, kConnectorTypeL);
_connectors[ 7].init(_peepholes + 8, _peepholes + 12, _peepholes + 25, _peepholes + 11, 1, kConnectorTypeT);
_connectors[ 8].init(_peepholes + 25, _peepholes + 29, _peepholes + 34, _peepholes + 18, 2, kConnectorTypeT);
_connectors[ 9].init(_peepholes + 9, _peepholes + 16, _peepholes + 19, _peepholes + 12, 8, kConnectorTypeT);
_connectors[10].init(_peepholes + 19, _peepholes + 20, _peepholes + 26, NULL, 2, kConnectorTypeL);
_connectors[11].init(_peepholes + 26, _peepholes + 31, _peepholes + 35, _peepholes + 29, 2, kConnectorTypeT);
_connectors[12].init(_peepholes + 2, _peepholes + 10, NULL, _peepholes + 9, 2, kConnectorTypeL);
_connectors[13].init(_peepholes + 13, _peepholes + 17, NULL, _peepholes + 16, 1, kConnectorTypeT, _connectors + 14, kDirectionSh);
_connectors[14].init( NULL, _peepholes + 21, _peepholes + 27, _peepholes + 20, 8, kConnectorTypeT, _connectors + 13, kDirectionNh);
_connectors[15].init(_peepholes + 10, NULL, _peepholes + 22, _peepholes + 17, 1, kConnectorTypeI, _connectors + 19, kDirectionEt);
_connectors[16].init(_peepholes + 21, _peepholes + 22, _peepholes + 30, _peepholes + 27, 2, kConnectorTypeT);
_connectors[17].init(_peepholes + 30, _peepholes + 32, NULL, _peepholes + 31, 2, kConnectorTypeL);
_connectors[18].init(_peepholes + 3, NULL, _peepholes + 14, _peepholes + 13, 8, kConnectorTypeL);
_connectors[19].init(_peepholes + 14, NULL, _peepholes + 28, NULL, 4, kConnectorTypeL, _connectors + 15, kDirectionWt);
_connectors[20].init(_peepholes + 28, NULL, _peepholes + 36, _peepholes + 32, 4, kConnectorTypeL);
_connectors[ 4].initGroup();
_connectors[13].initGroup();
_connectors[15].initGroup();
uint32 i = rnd(kBinNum0111);
if (i & kBinNum0001)
_spiders.push_back(new Spider(Common::Rect(-10, 45, 92, 315), "1"));
if (i & kBinNum0010)
_spiders.push_back(new Spider(Common::Rect(-10, 389, 149, 476), "2"));
if (i & kBinNum0100)
_spiders.push_back(new Spider(Common::Rect(544, 225, 650, 490), "3"));
if (i) {
_frameIndexSpider = new uint32[_spiders.size()];
memset(_frameIndexSpider, 0, _spiders.size()*sizeof(uint32));
}
}
void PuzzlePipes::updateCursor() {
int32 index = findRect();
if (_rectIndex == index)
return;
_rectIndex = index;
// FIXME
if (index > -1 || Common::Rect(540, 90, 590, 250).contains(getCursor()->position()))
getCursor()->set(getWorld()->graphicResourceIds[16]);
else
getCursor()->set(getWorld()->graphicResourceIds[16], 0, kCursorAnimationNone);
}
int32 PuzzlePipes::findRect() {
for (uint32 i = 0; i < ARRAYSIZE(connectorPoints); ++i)
if (Common::Rect(connectorPoints[i].x - 5, connectorPoints[i].y - 5, connectorPoints[i].x + 30, connectorPoints[i].y + 30).contains(getCursor()->position()))
return i;
for (uint32 i = 0; i < _spiders.size(); ++i)
if (_spiders[i]->getPolygon(Common::Rect(10, 10, 30, 30)).contains(getCursor()->position()))
return ARRAYSIZE(connectorPoints) + i;
return -1;
}
uint32 PuzzlePipes::checkFlags() {
uint32 total = _sinks[0]->getLevel1() + _sinks[1]->getLevel1() +_sinks[2]->getLevel1() + _sinks[3]->getLevel1();
float temp;
uint32 val = 4;
if (total)
for (uint32 i = 0; i < 4; ++i) {
temp = _sinks[i]->getLevel1() / float(total);
_levelValues[i] = temp * _sinks[i]->getLevel() / 4;
if (_levelValues[i] == 1.0)
val = i;
}
else
memset(_levelValues, 0, sizeof(_levelValues));
return val;
}
void PuzzlePipes::checkConnections() {
for (uint32 i = 0; i < connectorsCount; i++) {
uint32 oldState = _connectors[i].getState(),
newState = calcStateFromPos(i, _connectors[i].getType(), _positions[i]);
if (oldState != newState) {
do {
_connectors[i].turn(false);
} while (_connectors[i].getState() != newState);
}
}
}
void PuzzlePipes::startUpWater() {
for (uint32 i = 4; i < peepholesCount; ++i)
memset(_peepholes[i]._flowValues, 0, sizeof(_peepholes[i]._flowValues));
_sources[0]->startUpWater(true);
_sources[1]->startUpWater(true);
_sources[2]->startUpWater(true);
_sources[3]->startUpWater(true);
}
} // End of namespace Asylum