mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
ASYLUM: Pipes puzzle: add spiders
This commit is contained in:
@@ -103,19 +103,13 @@ const Common::Point peepholePoints[] = {
|
||||
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};
|
||||
|
||||
const double LOG2 = 0.6931471;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Peephole
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool Peephole::marks[peepholesCount];
|
||||
|
||||
void Peephole::connect(Connector *connector) {
|
||||
_connectors.push_back(connector);
|
||||
}
|
||||
|
||||
void Peephole::disconnect(Connector *connector) {
|
||||
_connectors.remove(connector);
|
||||
}
|
||||
|
||||
void Peephole::startUpWater(bool flag) {
|
||||
if (flag)
|
||||
memset(marks, false, sizeof(marks));
|
||||
@@ -183,8 +177,8 @@ void Connector::turn() {
|
||||
oldIndex[1] = 2;
|
||||
}
|
||||
} else {
|
||||
newIndex[0] = log((double)(newState & delta)) / log((double)2);
|
||||
oldIndex[0] = log((double)(_state & delta)) / log((double)2);
|
||||
newIndex[0] = log((double)(newState & delta)) / LOG2;
|
||||
oldIndex[0] = log((double)(_state & delta)) / LOG2;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < (uint32)(delta == kBinNum1111 ? 2 : 1); ++i) {
|
||||
@@ -259,6 +253,49 @@ void Connector::disconnect(Connector *connector) {
|
||||
_isConnected = connector->_isConnected = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Spider
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Spider::Spider(Common::Rect rect, Common::String id) {
|
||||
_boundingBox = rect;
|
||||
_rnd = new Common::RandomSource(Common::String("pipes_spider") + id);
|
||||
_isAlive = true;
|
||||
_location.x = _rnd->getRandomNumber(_boundingBox.right - _boundingBox.left) + _boundingBox.left;
|
||||
_location.y = _rnd->getRandomNumber(_boundingBox.bottom - _boundingBox.top) + _boundingBox.top;
|
||||
_direction = Direction(1 << _rnd->getRandomNumber(3));
|
||||
|
||||
randomize();
|
||||
}
|
||||
|
||||
void Spider::randomize(Direction excluded) {
|
||||
if (_rnd->getRandomNumber(5) == 5)
|
||||
_delta = Common::Point(0, 0);
|
||||
else {
|
||||
while (_direction == excluded)
|
||||
_direction = Direction(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
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -272,6 +309,9 @@ PuzzlePipes::PuzzlePipes(AsylumEngine *engine) : Puzzle(engine) {
|
||||
}
|
||||
|
||||
PuzzlePipes::~PuzzlePipes() {
|
||||
for (uint32 i = 0; i < _spiders.size(); ++i)
|
||||
delete _spiders[i];
|
||||
delete [] _frameIndexSpider;
|
||||
}
|
||||
|
||||
void PuzzlePipes::reset() {
|
||||
@@ -324,8 +364,10 @@ bool PuzzlePipes::update(const AsylumEvent &evt) {
|
||||
_isLeverReady = false;
|
||||
if (_frameIndexLever) {
|
||||
_frameIndexLever = (_frameIndexLever + 1) % GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[2]);
|
||||
if (!_frameIndexLever)
|
||||
if (!_frameIndexLever) {
|
||||
_isLeverReady = true;
|
||||
getCursor()->show();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: turn the fountain on
|
||||
@@ -340,6 +382,32 @@ bool PuzzlePipes::update(const AsylumEvent &evt) {
|
||||
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;
|
||||
|
||||
switch (_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;
|
||||
default: ;
|
||||
}
|
||||
|
||||
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();
|
||||
@@ -361,16 +429,22 @@ bool PuzzlePipes::mouseLeftDown(const AsylumEvent &evt) {
|
||||
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) {
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[42], false, Config.sfxVolume - 10);
|
||||
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;
|
||||
_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,6 +521,17 @@ void PuzzlePipes::setup() {
|
||||
_connectors[10].initGroup();
|
||||
_connectors[11].initGroup();
|
||||
|
||||
uint32 i = rnd(7);
|
||||
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"));
|
||||
|
||||
_frameIndexSpider = new uint32[_spiders.size()];
|
||||
memset(_frameIndexSpider, 0, sizeof(_frameIndexSpider));
|
||||
|
||||
startUpWater();
|
||||
}
|
||||
|
||||
@@ -469,6 +554,10 @@ int32 PuzzlePipes::findRect() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/array.h"
|
||||
#include "common/random.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Asylum {
|
||||
|
||||
@@ -76,8 +79,8 @@ public:
|
||||
uint32 getLevel1() { return _flowValues[0] + _flowValues[1] + _flowValues[2] + _flowValues[3]; }
|
||||
bool isConnected() { return isConnected(0) || isConnected(1) || isConnected(2) || isConnected(3); }
|
||||
|
||||
void connect(Connector *connector);
|
||||
void disconnect(Connector *connector);
|
||||
void connect(Connector *connector) { _connectors.push_back(connector); }
|
||||
void disconnect(Connector *connector) { _connectors.remove(connector); }
|
||||
void startUpWater(bool flag = false);
|
||||
|
||||
private:
|
||||
@@ -118,6 +121,34 @@ private:
|
||||
friend void Peephole::startUpWater(bool);
|
||||
};
|
||||
|
||||
class Spider {
|
||||
public:
|
||||
Spider(Common::Rect rect, Common::String id);
|
||||
~Spider() { delete _rnd; }
|
||||
|
||||
bool isAlive() const { return _isAlive; }
|
||||
bool isActive() const { return _delta != Common::Point(0, 0); }
|
||||
bool isVisible(Common::Rect rect) const { return rect.contains(_location); }
|
||||
|
||||
Direction getDirection() const { return _direction; }
|
||||
Common::Rect getPolygon(Common::Rect frame) const { return Common::Rect(_location.x - frame.left, _location.y - frame.top, _location.x + frame.right, _location.y + frame.bottom); }
|
||||
|
||||
Common::Point move();
|
||||
void smash() { _isAlive = false; }
|
||||
private:
|
||||
static const uint32 minStepsNumber = 20, maxStepsNumber = 200;
|
||||
Common::RandomSource *_rnd;
|
||||
bool _isAlive;
|
||||
Common::Point _location;
|
||||
Common::Point _delta;
|
||||
Common::Rect _boundingBox;
|
||||
Direction _direction;
|
||||
uint32 _stepsNumber;
|
||||
uint32 _steps;
|
||||
|
||||
void randomize(Direction excluded = kDirectionNowhere);
|
||||
};
|
||||
|
||||
class PuzzlePipes : public Puzzle {
|
||||
public:
|
||||
PuzzlePipes(AsylumEngine *engine);
|
||||
@@ -136,6 +167,8 @@ private:
|
||||
Connector _connectors[connectorsCount];
|
||||
Peephole _peepholes[peepholesCount];
|
||||
Peephole *_sinks[4], *_sources[4];
|
||||
Common::Array<Spider *> _spiders;
|
||||
uint32 *_frameIndexSpider;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Event Handling
|
||||
|
||||
Reference in New Issue
Block a user