// The heart and core of StarCraft's unit search engine. // Based on BWAPI's Shared/Templates.h void UnitFinder::search(int left, int top, int right, int bottom) { //0: No match, 1: Passed X iteration, 2: Passed Y iteration //(Necessary because each UnitFinderData array has 2 entries per unit) u8 unitSearchFlags[UNIT_ARRAY_LENGTH + 1] = { 0 }; int r = right, b = bottom; const bool isWidthExtended = right - left - 1 < *MAX_UNIT_WIDTH; const bool isHeightExtended = top - bottom - 1 < *MAX_UNIT_HEIGHT; // Check if the location is smaller than the largest unit if (isWidthExtended) r += *MAX_UNIT_WIDTH; if (isHeightExtended) b += *MAX_UNIT_HEIGHT; // Create UnitFinderData elements for compatibility with stl functions UnitFinderData finderVal; // Search for the values using built-in binary search algorithm and comparator finderVal.position = left; UnitFinderData *pLeft = std::lower_bound(getStartX(), getEndX(), finderVal); finderVal.position = top; UnitFinderData *pTop = std::lower_bound(getStartY(), getEndY(), finderVal); finderVal.position = r; UnitFinderData *pRight = std::lower_bound(pLeft, getEndX(), finderVal); finderVal.position = b; UnitFinderData *pBottom = std::lower_bound(pTop, getEndY(), finderVal); // Iterate the Y entries of the finder for (UnitFinderData *py = pTop; py < pBottom; ++py) { if (unitSearchFlags[py->unitIndex] == 0) { // If height is small, check unit bounds if (!isHeightExtended || CUnit::getFromIndex(py->unitIndex)->getTop() < bottom) unitSearchFlags[py->unitIndex] = 1; } } // Iterate the X entries of the finder this->unitCount = 0; for (UnitFinderData *px = pLeft; px < pRight; ++px) { if (unitSearchFlags[px->unitIndex] == 1) { // If width is small, check unit bounds if (!isWidthExtended || CUnit::getFromIndex(px->unitIndex)->getLeft() < right) { CUnit *unit = CUnit::getFromIndex(px->unitIndex); if (unit) this->units[this->unitCount++] = unit; } unitSearchFlags[px->unitIndex] = 0; //Prevent duplicates } } }
/** * Compares two areas with the == operator. Two uninitialized areas * are equal to each other. * * @param otherArea This is the area we're comparing to, i.e. on * the right hand side of the operator when used * @return True if this area is the same as the given area */ bool Area3D::operator ==(const Area3D &otherArea) const { return getStartX() == otherArea.getStartX() && getStartY() == otherArea.getStartY() && getStartZ() == otherArea.getStartZ() && getEndX() == otherArea.getEndX() && getEndY() == otherArea.getEndY() && getEndZ() == otherArea.getEndZ(); }
void CameraSystem::fixBoundaries() { auto stageSize = Constants::UI::stageSize; if (getEndX() > stageSize.width) { _lookAtX -= getEndX() - stageSize.width; } else if (getStartX() < 0) { _lookAtX -= getStartX(); } if (getEndY() > stageSize.height) { _lookAtY -= getEndY() - stageSize.height; } else if (getStartY() < 0) { _lookAtY -= getStartY(); } }
void cMapCamera::centerAndJumpViewPortToCell(int cell) { // fix any boundaries if (cell < 0) cell = 0; if (cell >= MAX_CELLS) cell = (MAX_CELLS-1); int cellX = cellCalculator->getX(cell); int cellY = cellCalculator->getY(cell); // determine the half of our screen int width = mapCamera->getViewportWidth(); int height = mapCamera->getViewportHeight(); // Half ... int iHalfX = width/2; int iHalfY = height/2; // determine the new X and Y position int newViewPortX = cellX - iHalfX; int newViewPortY = cellY - iHalfY; // now make sure the bottom right does not reach outside the map borders. // first jump to the new coordinates jumpTo(newViewPortX, newViewPortY); int diffX = getEndX() - (game.map_width - 1); int diffY = getEndY() - (game.map_height - 1); // when > 0 then it has overlapped, and should be substracted to the original X if (diffX > 0) { newViewPortX -= diffX; } if (diffY > 0) { newViewPortY -= diffY; } if (newViewPortX < 1) { newViewPortX = 1; } if (newViewPortY < 1) { newViewPortY = 1; } // now the final 'jump' to the correct positions jumpTo(newViewPortX, newViewPortY); }
/** * Returns the intersection of this 3D area with another 3D area. If there is * no intersection, an invalid 3D area will be returned. * * @param otherArea the area to intersect this 3D area with * @return the 3D area that is the intersection */ Area3D Area3D::intersect(const Area3D &otherArea) const { Area3D result; // Check validity because of comparison operators. if (isValid() && otherArea.isValid()) { Displacement startX(std::max(getStartX(), otherArea.getStartX())); Displacement startY(std::max(getStartY(), otherArea.getStartY())); Displacement startZ(std::max(getStartZ(), otherArea.getStartZ())); Displacement endX(std::min(getEndX(), otherArea.getEndX())); Displacement endY(std::min(getEndY(), otherArea.getEndY())); Displacement endZ(std::min(getEndZ(), otherArea.getEndZ())); if (startX <= endX && startY <= endY && startZ <= endZ) result = Area3D(startX, startY, startZ, endX, endY, endZ); } return result; }
void cMapCamera::thinkInteraction() { if (mouse_co_x1 > -1 && mouse_co_y1 > -1) { return; } // thinking for map (scrolling that is) if (mouse_x <= 1 || key[KEY_LEFT]) { if (x > 1) { x--; mouse_tile = MOUSE_LEFT; } } if (mouse_y <= 1 || key[KEY_UP]) { if (y > 1) { y--; mouse_tile = MOUSE_UP; } } if (mouse_x >= (game.screen_x-2) || key[KEY_RIGHT]) { if ((getEndX()) < (game.map_width-1)) { x++; mouse_tile = MOUSE_RIGHT; } } if (mouse_y >= (game.screen_y-2) || key[KEY_DOWN]) { if ((getEndY()) < (game.map_height-1)) { y++; mouse_tile = MOUSE_DOWN; } } }
// doDraw //-------------------------------------------------------------------------- void VehicleSelectionView::doDraw( Surface& dest ) { Objective* obj = ObjectiveInterface::getObjective(CURRENT_SELECTED_OUTPOST_ID); if ( !obj || obj->occupying_player != PlayerInterface::getLocalPlayer() ) { // Desktop::setVisibilityNoDoAnything("VehicleSelectionView", false); changeMade = false; return; } char strBuf[256]; const int color = Color::white; // Draw a line attaching the VehicleSelectionView to its outpost. {if (WorldInputCmdProcessor::isObjectiveSelected()) { // Draw a line connecting the vehicleSelectionView and the objective. iRect gameViewRect; WorldViewInterface::getViewWindow(&gameViewRect); iXY objectivePos(WorldInputCmdProcessor::getSelectedObjectiveWorldPos()); objectivePos -= gameViewRect.getLocation(); iXY a(VehicleSelectionView::getLocation() + VehicleSelectionView::getSize() / 2); iXY b(objectivePos); // Calculate the starting point on the outside of the vehicleSelectionView box. fXY v2oSlope(Math::unitDirection(a, b)); a.x += int(v2oSlope.x * float(VehicleSelectionView::getWidth() / 2)); a.y += int(v2oSlope.y * float(VehicleSelectionView::getHeight() / 2)); // Calculate the starting point on the outside of the objective box. iXY objectiveOutlineSize(3, 3); //fXY o2vSlope(Math::unitDirection(b, a)); //b.x += o2vSlope.x * float(objectiveOutlineSize.x); //b.y += o2vSlope.y * float(objectiveOutlineSize.y); //screen.drawLine(a, b, Color::white); iRect r(objectivePos.x - objectiveOutlineSize.x, objectivePos.y - objectiveOutlineSize.y, objectiveOutlineSize.x, objectiveOutlineSize.y); screen->fillRect(r, Color::white); //int xOffset = (strlen(WorldInputCmdProcessor::getSelectedObjectiveName()) * CHAR_XPIX) / 2; //screen.bltStringShadowed(r.min.x - xOffset, r.min.y - 15, WorldInputCmdProcessor::getSelectedObjectiveName(), Color::white, Color::black); iXY oos(objectiveOutlineSize); iXY cpos; if (v2oSlope.x > 0 && v2oSlope.y > 0) { cpos = iXY(getEndX(), getEndY()); r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y); } if (v2oSlope.x > 0 && v2oSlope.y <= 0) { cpos = iXY(getEndX(), getLocationY()); r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y); } if (v2oSlope.x <= 0 && v2oSlope.y > 0) { cpos = iXY(getLocationX(), getEndY()); r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y); } if (v2oSlope.x <= 0 && v2oSlope.y <= 0) { cpos = iXY(getLocationX(), getLocationY()); r = iRect(cpos.x - oos.x, cpos.y-oos.y, oos.x, oos.y); } // screen->drawLine(cpos, b, Color::white); screen->fillRect(r, Color::white); //screen.bltLookup(r, Palette::darkGray256.getColorArray()); //screen.drawButtonBorder(r, Color::white, Color::gray96); // Draw the name of the outpost. }} bltViewBackground(dest); int remaining_time = 0; int generation_time = 0; if ( obj->unit_generation_on_flag ) { remaining_time = obj->unit_generation_timer.getTimeLeft(); UnitProfile* profile = UnitProfileInterface::getUnitProfile(obj->unit_generation_type); generation_time = profile->regen_time; } if (vsvUnitGenOn) { sprintf(strBuf, "%s", getUnitName(vsvSelectedUnit)); dest.bltString( productionUnitPos.x, productionUnitPos.y, strBuf, color); sprintf(strBuf, "%01d:%02d/%01d:%02d", remaining_time / 60, remaining_time % 60, generation_time / 60, generation_time % 60); dest.bltString( timeRequiredPos.x, timeRequiredPos.y, strBuf, color); } else { sprintf(strBuf, "%s", _("power off")); dest.bltString( productionUnitPos.x, productionUnitPos.y, strBuf, color); dest.bltString( timeRequiredPos.x, timeRequiredPos.y, strBuf, color); } int unitPerPlayer = GameConfig::game_maxunits / GameConfig::game_maxplayers; sprintf(strBuf, "%d/%d", int(UnitInterface::getUnitCount(PlayerInterface::getLocalPlayerIndex())), unitPerPlayer); dest.bltString(unitsBuiltPos.x, unitsBuiltPos.y, strBuf, color); drawUnitProfileInfo(dest, iXY(0, unitProfileDataY), highlightedUnitType); //sprintf(strBuf, "%01d:%02d", ( (int) outpost_status.unit_generation_time_remaining ) / 60, ( (int) outpost_status.unit_generation_time_remaining) % 60 ); //clientArea.bltString(timeRemainingPos, strBuf, color); View::doDraw( dest ); } // end VehicleSelectionView::doDraw
float CameraSystem::getHeight() const { return getEndY() - getStartY(); }
/** * Sets the topmost Y position. This method may change the height of the 3D * area. * * @param startY the new topmost Y position */ void Area3D::setStartY(const Displacement &startY) { setArea(getStartX(), startY, getStartZ(), getEndX(), getEndY(), getEndZ()); }
/** * Sets the X dimension of the 3D area. This method may change the X * positions and the width of the 3D area. * * @param startX the new leftmost X position * @param width the new width of the 3D area */ void Area3D::setXDimension(const Displacement &startX, const Distance &width) { setArea(startX, getStartY(), getStartZ(), startX + width, getEndY(), getEndZ()); }
/** * Moves the backmost Z position of the 3D area. This method will not * change the depth of the 3D area. * * @param endZ the new backmost Z position */ void Area3D::moveEndZ(const Displacement &endZ) { setArea(getStartX(), getStartY(), getStartZ() + (endZ - getEndZ()), getEndX(), getEndY(), endZ); }
/** * Sets the rightmost X position. This method may change the width of the 3D * area. * * @param endX the new rightmost X position */ void Area3D::setEndX(const Displacement &endX) { setArea(getStartX(), getStartY(), getStartZ(), endX, getEndY(), getEndZ()); }
/** * Changes the depth of the 3D area. * * @param depth the new depth of the 3D area */ void Area3D::setDepth(const Distance &depth) { setArea(getStartX(), getStartY(), getStartZ(), getEndX(), getEndY(), getStartZ() + depth); }
/** * Changes the width of the 3D area. * * @param width the new width of the 3D area */ void Area3D::setWidth(const Distance &width) { setArea(getStartX(), getStartY(), getStartZ(), getStartX() + width, getEndY(), getEndZ()); }
/** * Moves the frontmost Z position of the 3D area. This method will not change * the depth of the 3D area. * * @param startZ the new frontmost Z position */ void Area3D::moveStartZ(const Displacement &startZ) { setArea(getStartX(), getStartY(), startZ, getEndX(), getEndY(), getEndZ() + (startZ - getStartZ())); }
/** * Moves the leftmost X position of the 3D area. This method will not change * the width of the 3D area. * * @param startX the new leftmost X position */ void Area3D::moveStartX(const Displacement &startX) { setArea(startX, getStartY(), getStartZ(), getEndX() + (startX - getStartX()), getEndY(), getEndZ()); }
/** * Sets the Z dimension of the 3D area. This method may change the Z * positions and the depth of the 3D area. * * @param startZ the new frontmost Z position * @param depth the new depth of the 3D area */ void Area3D::setZDimension(const Displacement &startZ, const Distance &depth) { setArea(getStartX(), getStartY(), startZ, getEndX(), getEndY(), startZ + depth); }
/** * Returns the height (in the Y dimension) of the 3D area. */ Distance Area3D::getHeight() const { return Distance( (getEndY() - getStartY()).meters(), Distance::Meters); }