void Level::replaceSquare(Vec2 pos, PSquare square, bool storePrevious) { squares[pos]->onConstructNewSquare(square.get()); Creature* c = squares[pos]->getCreature(); if (c) squares[pos]->removeCreature(); for (Item* it : copyOf(squares[pos]->getItems())) square->dropItem(squares[pos]->removeItem(it)); addLightSource(pos, squares[pos]->getLightEmission(), -1); square->setPosition(pos); square->setLevel(this); for (PTrigger& t : squares[pos]->removeTriggers()) square->addTrigger(std::move(t)); square->setBackground(squares[pos].get()); if (const Tribe* tribe = squares[pos]->getForbiddenTribe()) square->forbidMovementForTribe(tribe); if (storePrevious) oldSquares[pos] = std::move(squares[pos]); squares[pos] = std::move(square); if (c) { squares[pos]->setCreature(c); } addLightSource(pos, squares[pos]->getLightEmission(), 1); updateVisibility(pos); squares[pos]->updateSunlightMovement(isInSunlight(pos)); updateConnectivity(pos); }
void Level::addDarknessSource(Vec2 pos, double radius, int numDarkness) { if (radius > 0) { for (Vec2 v : getVisibleTilesNoDarkness(pos, VisionId::NORMAL)) { double dist = (v - pos).lengthD(); if (dist <= radius) lightCapAmount[v] -= min(1.0, 1 - (dist) / radius) * numDarkness; squares[v]->updateSunlightMovement(isInSunlight(v)); updateConnectivity(v); } } }
void IntersectBed::processFirstBedRecord() { if (options.verbosity >= 2) { std::cerr << "processFirstBedRecord()\n"; if (!bedRecords.empty()) { std::cerr << " "; writeRecord(std::cerr, bedRecords.front(), seqan::Bed()); } } // When computing symmetric difference, we write out the BED record as ROI if there is no overlapping ROI record. if (options.mode == IntersectBedOptions::DIFF) { if (roiRecords.empty() || roiRecords.front().beginPos >= bedRecords.front().endPos) { writeEmptyBed(bedRecords.front()); return; } } if (roiRecords.empty()) return; // When in DIFF mode: Mark all ROI records overlapping with current front BED record as such and stop. typedef std::list<TRoiRecord>::/*const_*/iterator TRoiIter; if (options.mode == IntersectBedOptions::DIFF) { for (TRoiIter it = roiRecords.begin(); it != roiRecords.end(); ++it) if (overlap(*it, bedRecords.front())) back(it->data)[0] = '*'; // Mark as overlapping with BED. return; } // Get range of ROI records overlapping with BED record. TRoiIter rangeBegin = roiRecords.begin(); TRoiIter rangeEnd = rangeBegin; for (; rangeEnd != roiRecords.end() && overlap(*rangeEnd, bedRecords.front()); ++rangeEnd) { if (options.verbosity >= 2) { std::cerr << "ROI RECORD\t"; writeRecord(std::cerr, *rangeEnd, seqan::Roi()); } continue; } // ------------------------------------------------------------------------ // Create a result ROI from that depending on the configuration. // ------------------------------------------------------------------------ // Compute the smallest begin position and the largest end position of BED and all ROI objects. TBedRecord const & bedRecord = bedRecords.front(); int beginPos = bedRecord.beginPos; int endPos = bedRecord.endPos; if (options.verbosity >= 2) std::cerr << "beginPos, endPos == " << beginPos << ", " << endPos << "\n"; for (TRoiIter it = rangeBegin; it != rangeEnd; ++it) { if (options.verbosity >= 2) std::cerr << "it->beginPos, it->endPos == " << it->beginPos << ", " << it->endPos << "\n"; beginPos = std::min(it->beginPos, beginPos); endPos = std::max(it->endPos, endPos); if (options.verbosity >= 2) std::cerr << "beginPos, endPos == " << beginPos << ", " << endPos << "\n"; } // Create bitmap marking positions as connected/covered. seqan::String<bool> connected; resize(connected, endPos - beginPos, false); updateConnectivity(connected, beginPos, bedRecord, rangeBegin, rangeEnd); // Create array with counts. seqan::String<int> counts; resize(counts, endPos - beginPos, 0); for (TRoiIter it = rangeBegin; it != rangeEnd; ++it) for (unsigned j = it->beginPos - beginPos, i = 0; i < length(it->count); ++i, ++j) counts[j] += it->count[i]; // TODO(holtgrew): Increment or simply set? // Write resulting intervals to output file. writeRois(connected, counts, beginPos, bedRecord); }