bool Shape::isHappy( const Neighborhood &n, unsigned int pos_x, unsigned int pos_y) const{ if (n.get(pos_x, pos_y).getType() == "empty") return true; // find the min and max coordinates of possible neighbors unsigned int x_min = (pos_x == 0) ? pos_x : pos_x - 1; unsigned int y_min = (pos_y == 0) ? pos_y : pos_y - 1; unsigned int x_max = (pos_x == n.size_x-1) ? pos_x : pos_x + 1; unsigned int y_max = (pos_y == n.size_y-1) ? pos_y : pos_y + 1; double alike = 0; double different = 0; // evaluate each neighbor to deteremine likeness for (int x=x_min; x <= x_max; x++) { for (int y=y_min; y <= y_max; y++) { if (x == pos_x && y == pos_y) continue; else if (n.get(x, y).getType() == "empty") continue; else if (n.get(x, y).getType() == n.get(pos_x, pos_y).getType()) alike++; else different++; } } // returns true if the shape is happy return ( different || alike ) && ( different == 0 || alike / different >= RATIO_ALIKE_HAPPY ) && ( alike == 0 || different / alike >= RATIO_DIFFERENT_HAPPY); }
void PressureDoor::stopChangingPressure() { Neighborhood *owner; switch (GameState.getNoradSubRoomPressure()) { case 11: _typeMovie.setSegment(kMaxPressureLoopStart * _typeScale, kMaxPressureLoopStop * _typeScale); _typeMovie.setFlags(kLoopTimeBase); _typeMovie.show(); _typeMovie.start(); break; case 10: _typeMovie.setSegment(kCautionLoopStart * _typeScale, kCautionLoopStop * _typeScale); _typeMovie.setFlags(kLoopTimeBase); _typeMovie.show(); _typeMovie.start(); break; case kNormalSubRoomPressure: owner = getOwner(); _typeMovie.setSegment(kOpeningDoorLoopStart * _typeScale, kOpeningDoorLoopStop * _typeScale); _typeMovie.setFlags(kLoopTimeBase); _typeMovie.show(); _gameState = kPlayingDoneMessage; owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag); _typeMovie.start(); break; default: _typeMovie.hide(); break; } }
bool Shape::isHappy(const Neighborhood & n, unsigned int pos_x, unsigned int pos_y) const { if (n.get(pos_x, pos_y).getType() == "Empty") return true; unsigned int x_min = (pos_x == 0) ? pos_x : pos_x - 1; unsigned int y_min = (pos_y == 0) ? pos_y : pos_y - 1; unsigned int x_max = (pos_x == n.size_x - 1) ? pos_x : pos_x + 1; unsigned int y_max = (pos_y == n.size_y - 1) ? pos_y : pos_y + 1; double alike = 0; double different = 0; for (int x = x_min; x <= x_max; x++) { for (int y = y_min; y <= y_max; y++) { if (x == pos_x && y == pos_y) continue; else if (n.get(x, y).getType() == "Empty") continue; else if (n.get(x, y).getType() == n.get(pos_x, pos_y).getType()) alike++; else different++; } } return (different || alike) && (different == 0 || alike / different >= RATIO_ALIKE_HAPPY) && (alike == 0 || different / alike >= RATIO_DIFFERENT_HAPPY); }
/** * Helper method to determine if any cubes are neighboured */ bool Phonemic::noNeighbors() { for(CubeID cube: CubeSet::connected()) { Neighborhood hood = Neighborhood(cube); if(hood.hasCubeAt(LEFT) || hood.hasCubeAt(RIGHT)) return false; } return true; }
Neighborhood br::knnFromSimmat(const QList<cv::Mat> &simmats, int k) { Neighborhood neighborhood; float globalMax = -std::numeric_limits<float>::max(); float globalMin = std::numeric_limits<float>::max(); int numGalleries = (int)sqrt((float)simmats.size()); if (numGalleries*numGalleries != simmats.size()) qFatal("Incorrect number of similarity matrices."); // Process each simmat for (int i=0; i<numGalleries; i++) { QVector<Neighbors> allNeighbors; int currentRows = -1; int columnOffset = 0; for (int j=0; j<numGalleries; j++) { cv::Mat m = simmats[i * numGalleries + j]; if (j==0) { currentRows = m.rows; allNeighbors.resize(currentRows); } if (currentRows != m.rows) qFatal("Row count mismatch."); // Get data row by row for (int k=0; k<m.rows; k++) { Neighbors &neighbors = allNeighbors[k]; neighbors.reserve(neighbors.size() + m.cols); for (int l=0; l<m.cols; l++) { float val = m.at<float>(k,l); if ((i==j) && (k==l)) continue; // Skips self-similarity scores if (val != -std::numeric_limits<float>::max() && val != -std::numeric_limits<float>::infinity() && val != std::numeric_limits<float>::infinity()) { globalMax = std::max(globalMax, val); globalMin = std::min(globalMin, val); } neighbors.append(Neighbor(l+columnOffset, val)); } } columnOffset += m.cols; } // Keep the top matches for (int j=0; j<allNeighbors.size(); j++) { Neighbors &val = allNeighbors[j]; const int cutoff = k; // Number of neighbors to keep int keep = std::min(cutoff, val.size()); std::partial_sort(val.begin(), val.begin()+keep, val.end(), compareNeighbors); neighborhood.append((Neighbors)val.mid(0, keep)); } } return neighborhood; }
bool neighborhoodsOverlap(const Neighborhood &n1, const Neighborhood &n2) { // both neighborhoods are assumed to be in the same frame Neighborhood::const_iterator it1, it2; for (it1 = n1.begin(); it1!=n1.end(); it1++) for (it2 = n2.begin(); it2 != n2.end(); it2++) { if ( *it1 == *it2 ) return true; } return false; }
/** * Helper method to locate the leftmost cube * in a series of neighboured cubes. */ unsigned Phonemic::leftmostNeighbor(unsigned id) { // Find leftmost cube Neighborhood hood = Neighborhood(id); CubeID leftmostID = id; while(hood.hasCubeAt(LEFT)) { leftmostID = hood.cubeAt(LEFT); hood = Neighborhood(leftmostID); } return leftmostID; }
pcl2::Neighborhood pcl2::computeFixedRadiusNeighborhood (Cloud & cloud, const MatF & query, float r) { // Convert point cloud MatF xyz = cloud["xyz"]; assert (xyz.rows () >= 1); assert (xyz.cols () == 3); pcl::PointCloud<pcl::PointXYZ>::Ptr input (new pcl::PointCloud<pcl::PointXYZ>); input->width = cloud.size (); input->height = 1; input->is_dense = false; input->points.resize (cloud.size ()); for (size_t i = 0; i < xyz.rows (); ++i) { input->points[i].x = xyz (i, 0); input->points[i].y = xyz (i, 1); input->points[i].z = xyz (i, 2); } // Convert query point assert (query.rows () == 1); assert (query.cols () == 3); pcl::PointXYZ q; q.x = query (0, 0); q.y = query (0, 1); q.z = query (0, 2); // Perform neighbor search pcl::KdTreeFLANN<pcl::PointXYZ> tree; tree.setInputCloud (input); std::vector<int> idx_vec; std::vector<float> dist_vec; size_t k = (size_t) tree.radiusSearch (q, r, idx_vec, dist_vec); assert (k == idx_vec.size ()); // Convert output EigenMat<int> neighbor_indices (k, 1); EigenMat<float> squared_distances (k, 1); for (size_t i = 0; i < k; ++i) { neighbor_indices (i, 0) = idx_vec[i]; squared_distances (i, 0) = dist_vec[i]; } //Cloud neighborhood = cloud (neighbor_indices); Neighborhood neighborhood (cloud, neighbor_indices); neighborhood.insert ("dist", squared_distances); return (neighborhood); }
static void drawSideIndicator(BG0ROMDrawable &draw, Neighborhood &nb, Int2 topLeft, Int2 size, Side s) { unsigned nbColor = draw.ORANGE; draw.fill(topLeft, size, nbColor | (nb.hasNeighborAt(s) ? draw.SOLID_FG : draw.SOLID_BG)); }
void SoftBody::updateNeighborhoods() { auto kdTree = KdTree(posRest); std::vector<uint32_t> indices; indices.reserve(Neighborhood::MAX_SIZE + 1); auto neighbor_it = neighborhoods.begin(); auto radius_it = radii.begin(); uint32_t index = 0; for (auto& u : posRest) { // // A particle's neighborhood should not include itself. However, this // kdTree will return an index for the current particle. So increment // the neighbor count by 1, and then remove the "self" particle when // we're done. // kdTree.neighbors(posRest, u, Neighborhood::MAX_SIZE + 1, *radius_it, indices); auto selfLocation = std::find(indices.begin(), indices.end(), index); if (selfLocation != indices.end()) { indices.erase(selfLocation); } // If we find a neighbor we didn't already have, add it with an initial // weight of zero. // Neighborhood newNeighbors; for (auto j : indices) { if (neighbor_it->hasNeighbor(j)) { newNeighbors.push_back(neighbor_it->findNeighbor(j)); } else { Vector3d u_ij = posRest[j] - u; Neighbor n(j, u_ij, 0.0); newNeighbors.push_back(n); } } *neighbor_it = newNeighbors; ++neighbor_it; ++radius_it; ++index; } }
void mergeNeighborhoods(Neighborhood &n1, Neighborhood &n2) { Neighborhood::iterator it1, it2; bool present; for (it2 = n2.begin(); it2 != n2.end(); it2++) { present = false; for (it1 = n1.begin(); it1 != n1.end(); it1++) { if ( *it1 == *it2 ) { present = true; break; } } if (!present) { n1.push_back( *it2 ); } } }
/** * Helper method to decide if a series of cubes * spells the current word. */ void Phonemic::checkForWord(unsigned id) { // Find leftmost cube CubeID nextID = leftmostNeighbor(id); Neighborhood hood = Neighborhood(nextID); // Find the sequence of symbols spelled by // the sequence of cubes int wordAttempt[MAX_WORD_SIZE]; wordAttempt[0] = cubes[nextID].symbol; int i = 1; while(hood.hasCubeAt(RIGHT)) { nextID = hood.cubeAt(RIGHT); hood = Neighborhood(nextID); wordAttempt[i] = cubes[nextID].symbol; i++; } wordAttempt[i] = -1; // Check for a match bool match = true; for(int i = 0; i < /*MAX_WORD_SIZE*/ length; i++) { if(/*order[i]*/ wordFamilies[level].phonemes[word][i] != wordAttempt[i]) { match = false; break; } //if(wordFamilies[level].phonemes[word][i] == -1) break; } // Recognize match if(match) { //sounding.play(SfxChime); //sounding.play(SfxCat); sounding.play(/*SfxChime*/ *wordFamilies[level].words[word].sound); allSmiles(); System::paint(); state = WORD_FOUND; } }
void Application::connectedComponents(SparseGraph &G, Vector<Neighborhood> &components) { int N=G.getNumVertices(), componentId=1; Array1D<bool> mark(N); mark.setAllTo(false); for(VertexId i=0 ; i<N ; ++i) { if(mark[i]) continue; Neighborhood component; dfs(G,i,mark,component); components.push_back(component); int size=component.size(); cout<<"Component #"<<componentId++<<" "<<size<<" vertices:"<<endl; for(Neighborhood::iterator cur=component.begin(), end=component.end() ; cur!=end ; ++cur) { VertexId id=*cur; cout<<G.getLabel(id)<<"\t"; } cout<<endl; } }
/** * Helper method to sounds out the sequence of cubes. */ void Phonemic::soundOut(unsigned id) { // Wait for audio channel to be clear if(sounding.isPlaying()) return; // Highlight the current cube cubes[id].vid.bg0.image(vec(0,0), *cubes[id].images[1]); System::paint(); System::finish(); // Play the current cube's sound sounding.play(*cubes[id].sound); while(sounding.isPlaying()) { System::yield(); } // Return the cube to its normal appearance cubes[id].vid.bg0.image(vec(0,0), *cubes[id].images[0]); // Play any cube connected to the right Neighborhood hood = Neighborhood(id); if(hood.hasCubeAt(RIGHT)) soundOut(hood.cubeAt(RIGHT)); }
void PressureDoor::doSolve() { if (_playingAgainstRobot) { GameState.setNoradSubRoomPressure(11); _levelsMovie.setTime((11 + kPressureBase) * _levelsScale); _levelsMovie.redrawMovieWorld(); _typeMovie.setSegment(kMaxPressureLoopStart * _typeScale, kMaxPressureLoopStop * _typeScale); _typeMovie.setFlags(kLoopTimeBase); _typeMovie.show(); _typeMovie.start(); g_AIArea->checkMiddleArea(); } else { GameState.setNoradSubRoomPressure(kNormalSubRoomPressure); _levelsMovie.setTime((kNormalSubRoomPressure + kPressureBase) * _levelsScale); _levelsMovie.redrawMovieWorld(); _typeMovie.setSegment(kOpeningDoorLoopStart * _typeScale, kOpeningDoorLoopStop * _typeScale); _typeMovie.setFlags(kLoopTimeBase); _typeMovie.show(); Neighborhood *owner = getOwner(); owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag); _gameState = kPlayingDoneMessage; _typeMovie.start(); g_AIArea->checkMiddleArea(); } }
void Application::dfs(SparseGraph &G,VertexId v,Array1D<bool> &mark, Neighborhood &component) { Stack<VertexId> S; S.push(v); mark[v]=true; while(!S.isEmpty()) { VertexId v=S.pop(); component.insert(v); bool shouldDelete; Neighborhood &children=*G.getNeighborsOf(v,shouldDelete); for(Neighborhood::iterator cur=children.begin(), end=children.end() ; cur!=end ; ++cur) { VertexId child=*cur; if(mark[child]) continue; S.push(child); mark[child]=true; //component.insert(child); } } }
// Zhu et al. "A Rank-Order Distance based Clustering Algorithm for Face Tagging", CVPR 2011 br::Clusters br::ClusterGallery(const QStringList &simmats, float aggressiveness, const QString &csv) { qDebug("Clustering %d simmat(s)", simmats.size()); // Read in gallery parts, keeping top neighbors of each template Neighborhood neighborhood = getNeighborhood(simmats); const int cutoff = neighborhood.first().size(); const float threshold = 3*cutoff/4 * aggressiveness/5; // Initialize clusters Clusters clusters(neighborhood.size()); for (int i=0; i<neighborhood.size(); i++) clusters[i].append(i); bool done = false; while (!done) { // nextClusterIds[i] = j means that cluster i is set to merge into cluster j QVector<int> nextClusterIDs(neighborhood.size()); for (int i=0; i<neighborhood.size(); i++) nextClusterIDs[i] = i; // For each cluster for (int clusterID=0; clusterID<neighborhood.size(); clusterID++) { const Neighbors &neighbors = neighborhood[clusterID]; int nextClusterID = nextClusterIDs[clusterID]; // Check its neighbors foreach (const Neighbor &neighbor, neighbors) { int neighborID = neighbor.first; int nextNeighborID = nextClusterIDs[neighborID]; // Don't bother if they have already merged if (nextNeighborID == nextClusterID) continue; // Flag for merge if similar enough if (normalizedROD(neighborhood, clusterID, neighborID) < threshold) { if (nextClusterID < nextNeighborID) nextClusterIDs[neighborID] = nextClusterID; else nextClusterIDs[clusterID] = nextNeighborID; } } } // Transitive merge for (int i=0; i<neighborhood.size(); i++) { int nextClusterID = i; while (nextClusterID != nextClusterIDs[nextClusterID]) { assert(nextClusterIDs[nextClusterID] < nextClusterID); nextClusterID = nextClusterIDs[nextClusterID]; } nextClusterIDs[i] = nextClusterID; } // Construct new clusters QHash<int, int> clusterIDLUT; QList<int> allClusterIDs = QSet<int>::fromList(nextClusterIDs.toList()).values(); for (int i=0; i<neighborhood.size(); i++) clusterIDLUT[i] = allClusterIDs.indexOf(nextClusterIDs[i]); Clusters newClusters(allClusterIDs.size()); Neighborhood newNeighborhood(allClusterIDs.size()); for (int i=0; i<neighborhood.size(); i++) { int newID = clusterIDLUT[i]; newClusters[newID].append(clusters[i]); newNeighborhood[newID].append(neighborhood[i]); } // Update indices and trim for (int i=0; i<newNeighborhood.size(); i++) { Neighbors &neighbors = newNeighborhood[i]; int size = qMin(neighbors.size(),cutoff); std::partial_sort(neighbors.begin(), neighbors.begin()+size, neighbors.end(), compareNeighbors); for (int j=0; j<size; j++) neighbors[j].first = clusterIDLUT[j]; neighbors = neighbors.mid(0, cutoff); } // Update results done = true; //(newClusters.size() >= clusters.size()); clusters = newClusters; neighborhood = newNeighborhood; }
Neighborhood getNeighborhood(const QStringList &simmats) { Neighborhood neighborhood; float globalMax = -std::numeric_limits<float>::max(); float globalMin = std::numeric_limits<float>::max(); int numGalleries = (int)sqrt((float)simmats.size()); if (numGalleries*numGalleries != simmats.size()) qFatal("Incorrect number of similarity matrices."); // Process each simmat for (int i=0; i<numGalleries; i++) { QVector<Neighbors> allNeighbors; int currentRows = -1; int columnOffset = 0; for (int j=0; j<numGalleries; j++) { QScopedPointer<br::Format> format(br::Factory<br::Format>::make(simmats[i*numGalleries+j])); br::Template t = format->read(); cv::Mat m = t.m(); if (j==0) { currentRows = m.rows; allNeighbors.resize(currentRows); } if (currentRows != m.rows) qFatal("Row count mismatch."); // Get data row by row for (int k=0; k<m.rows; k++) { Neighbors &neighbors = allNeighbors[k]; neighbors.reserve(neighbors.size() + m.cols); for (int l=0; l<m.cols; l++) { float val = m.at<float>(k,l); if ((i==j) && (k==l)) continue; // Skips self-similarity scores if (val != -std::numeric_limits<float>::max() && val != -std::numeric_limits<float>::infinity() && val != std::numeric_limits<float>::infinity()) { globalMax = std::max(globalMax, val); globalMin = std::min(globalMin, val); } neighbors.append(Neighbor(l+columnOffset, val)); } } columnOffset += m.cols; } // Keep the top matches for (int j=0; j<allNeighbors.size(); j++) { Neighbors &val = allNeighbors[j]; const int cutoff = 20; // Somewhat arbitrary number of neighbors to keep int keep = std::min(cutoff, val.size()); std::partial_sort(val.begin(), val.begin()+keep, val.end(), compareNeighbors); neighborhood.append((Neighbors)val.mid(0, keep)); } } // Normalize scores for (int i=0; i<neighborhood.size(); i++) { Neighbors &neighbors = neighborhood[i]; for (int j=0; j<neighbors.size(); j++) { Neighbor &neighbor = neighbors[j]; if (neighbor.second == -std::numeric_limits<float>::infinity()) neighbor.second = 0; else if (neighbor.second == std::numeric_limits<float>::infinity()) neighbor.second = 1; else neighbor.second = (neighbor.second - globalMin) / (globalMax - globalMin); } } return neighborhood; }
int main(int argc, char *argv[]) { int p = 2; double beta = 10; int neighbors = 8; double sigma = 10.0; double rho = 10.0; double gamma = 10000.0; int c; /* Read command line parameters beta and p. */ while ((c = getopt(argc, argv, "b:p:r:s:g:n:fh")) != -1) { switch (c) { case 'p': p = atoi(optarg); break; case 'b': beta = atof(optarg); break; case 'g': gamma = atof(optarg); break; case 'r': rho = atof(optarg); break; case 's': sigma = atof(optarg); break; case 'n': neighbors = atoi(optarg); break; case '?': if (optopt == 'p' || optopt == 'b' || optopt == 'g' || optopt == 'n' || optopt == 'r' || optopt == 's') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); } else if (isprint(optopt)) { fprintf(stderr, "Unknown option `-%c'.\n", optopt); } else { fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); } return 1; default: exit(1); } } /* * Non-option arguments are now in argv from index optind * to index argc-1 */ Mat image; image = imread(argv[optind], CV_LOAD_IMAGE_GRAYSCALE); if (!image.data) { cout << "Loading image failed" << endl; return -1; } cout << "Using gamma = " << gamma << endl; cout << "Using rho = " << rho << endl; cout << "Using sigma = " << sigma << endl; Mat_<Tensor> tensors = Mat_<Tensor>::zeros(image.rows, image.cols); Mat blur, edge, structure, color; createAnisotropyTensor(tensors, image, sigma, rho, gamma, blur, edge, structure, color); imwrite(argv[optind + 1], blur); imwrite(argv[optind + 2], edge); imwrite(argv[optind + 3], structure); imwrite(argv[optind + 4], color); /* * Network only handles integer edges, so we increase the scale a bit. */ int a; int b; a = 100; b = beta; /* * Specify the neighbors of a pixel. */ cout << "Creating size " << neighbors << " neighborhood." << endl; Neighborhood neigh; if (neighbors >= 4) { neigh.add( 1, 0, b * 1.0); neigh.add( 0, 1, b * 1.0); neigh.add(-1, 0, b * 1.0); neigh.add( 0,-1, b * 1.0); } if (neighbors >= 8) { neigh.add( 1, 1, b * 1.0/sqrt(2.0)); neigh.add(-1, 1, b * 1.0/sqrt(2.0)); neigh.add( 1,-1, b * 1.0/sqrt(2.0)); neigh.add(-1,-1, b * 1.0/sqrt(2.0)); } if (neighbors >= 16) { neigh.add8(1, 2, 1.0); } if (neighbors >= 32) { neigh.add8(3, 1, 1.0); neigh.add8(3, 2, 1.0); } if (neighbors >= 48) { neigh.add8(1, 4, 1.0); neigh.add8(3, 4, 1.0); } if (neighbors >= 72) { neigh.add8(1, 5, 1.0); neigh.add8(2, 5, 1.0); neigh.add8(3, 5, 1.0); } cout << "Neighborhood: " << endl; neigh.setupAngles(); for (Neighborhood::iterator it = neigh.begin(); it != neigh.end(); ++it) { cout << it->x << ", " << it->y << ": " << it->dt * 180 / M_PI << endl; } Mat out = image.clone(); restoreAnisotropicTV(image, out, tensors, neigh, a, b, p); cout << "Writing output to " << argv[optind + 5] << endl; imwrite(argv[optind + 5], out); return 0; }
void PressureDoor::receiveNotification(Notification *notification, const NotificationFlags flags) { Neighborhood *owner = getOwner(); if (notification == _neighborhoodNotification) { if (_playingAgainstRobot && (flags & kExtraCompletedFlag) != 0) { ExtraTable::Entry entry; switch (_robotState) { case kPlayingRobotApproaching: _utilityTimer.stop(); if (GameState.getNoradSubRoomPressure() == kMaxPressure) { owner->getExtraEntry(kN59PlayerWins1, entry); _utilityTimer.setSegment(entry.movieStart, entry.movieEnd); _utilityTimer.setTime(entry.movieStart); _utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag); _punchInTime = kLoopPunchInTime + entry.movieStart; _utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale); owner->startExtraSequence(kN59PlayerWins1, kExtraCompletedFlag, kFilterNoInput); _utilityTimer.start(); _robotState = kRobotDying; } else { owner->getExtraEntry(kN59RobotPunchLoop, entry); _utilityTimer.setSegment(entry.movieStart, entry.movieEnd); _utilityTimer.setTime(entry.movieStart); _utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag); _punchInTime = kLoopPunchInTime + entry.movieStart; _utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale); owner->startSpotLoop(entry.movieStart, entry.movieEnd, kExtraCompletedFlag); _utilityTimer.start(); _robotState = kRobotPunching; _punchCount = 1; } break; case kRobotPunching: if (GameState.getNoradSubRoomPressure() == kMaxPressure) { owner->startExtraSequence(kN59PlayerWins1, kExtraCompletedFlag, kFilterNoInput); _robotState = kRobotDying; } else if (++_punchCount >= kMaxPunches) { _robotState = kRobotComingThrough; owner->getExtraEntry(kN59RobotWins, entry); _utilityTimer.stop(); _utilityTimer.setSegment(entry.movieStart, entry.movieEnd); _utilityTimer.setTime(entry.movieStart); _utilityCallBack.cancelCallBack(); _utilityCallBack.setCallBackFlag(kDoorCrushedFlag); _utilityCallBack.scheduleCallBack(kTriggerTimeFwd, kPunchThroughTime + entry.movieStart, kNavTimeScale); owner->startExtraSequence(kN59RobotWins, kExtraCompletedFlag, kFilterNoInput); _utilityTimer.start(); } else { _utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag); _utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale); owner->scheduleNavCallBack(kExtraCompletedFlag); } break; case kRobotComingThrough: g_system->delayMillis(2 * 1000); ((PegasusEngine *)g_engine)->die(kDeathRobotThroughNoradDoor); break; case kRobotDying: _robotState = kRobotDead; _levelsMovie.stop(); _levelsMovie.setSegment((kNormalSubRoomPressure + kPressureBase) * _levelsScale, (GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale + 1); _levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale); _pressureCallBack.setCallBackFlag(kPressureDroppingFlag); _pressureCallBack.scheduleCallBack(kTriggerAtStart, 0, 0); _typeMovie.stop(); _typeMovie.setSegment(0, _typeMovie.getDuration()); _typeMovie.setTime(kDecreasingPressureTime * _typeScale); _typeMovie.redrawMovieWorld(); _typeMovie.show(); _downButton.show(); _downButton.setCurrentFrameIndex(1); _gameState = kGameOver; allowInput(false); _levelsMovie.setRate(Common::Rational(-4, 3)); // Should match door tracker. break; case kRobotDead: allowInput(true); ((NoradDelta *)owner)->playerBeatRobotWithDoor(); owner->requestDeleteCurrentInteraction(); break; } } if ((flags & (kDelayCompletedFlag | kSpotSoundCompletedFlag)) != 0) { switch (_gameState) { case kPlayingPressureMessage: _typeMovie.setTime(kEqualizeTime * _typeScale); _typeMovie.redrawMovieWorld(); owner->requestDelay(1, 5, kFilterNoInput, 0); owner->requestSpotSound(_equalizeSoundIn, _equalizeSoundOut, kFilterNoInput, 0); owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag); _gameState = kPlayingEqualizeMessage; break; case kPlayingEqualizeMessage: _gameState = kWaitingForPlayer; stopChangingPressure(); break; case kPlayingDoneMessage: _gameState = kWaitingForPlayer; _typeMovie.stop(); _typeMovie.setFlags(0); _typeMovie.hide(); if (!_playingAgainstRobot) ((Norad *)_owner)->doneWithPressureDoor(); break; } } } else if (notification == &_pressureNotification) { switch (flags) { case kSplashFinished: _levelsMovie.stop(); _levelsMovie.setSegment(0, _levelsMovie.getDuration()); _levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale); _levelsMovie.redrawMovieWorld(); if (GameState.getNoradSubRoomPressure() != kNormalSubRoomPressure) { _typeMovie.show(); owner->requestDelay(1, 5, kFilterNoInput, 0); owner->requestSpotSound(_pressureSoundIn, _pressureSoundOut, kFilterNoInput, 0); owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag); _gameState = kPlayingPressureMessage; } else { _gameState = kWaitingForPlayer; } break; case kPressureDroppingFlag: _levelsMovie.stop(); _levelsMovie.hide(); _typeMovie.stop(); _typeMovie.hide(); _upButton.hide(); _downButton.hide(); owner->startExtraSequence(kN59PlayerWins2, kExtraCompletedFlag, kFilterNoInput); break; } } else if (notification == &_utilityNotification) { switch (flags) { case kDoorJumpsUpFlag: _utilityCallBack.setCallBackFlag(kDoorJumpsBackFlag); _utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime + kNavTimePerFrame, kNavTimeScale); _levelsMovie.hide(); _typePunched = _typeMovie.isVisible(); if (_typePunched == true) _typeMovie.hide(); _upButton.hide(); _downButton.hide(); break; case kDoorJumpsBackFlag: _levelsMovie.show(); _upButton.show(); _downButton.show(); if (_typePunched) _typeMovie.show(); break; case kDoorCrushedFlag: _levelsMovie.hide(); _typeMovie.hide(); _upButton.hide(); _downButton.hide(); break; } } }