void DefaultPathDrawer::UpdateExtraTexture(int extraTex, int starty, int endy, int offset, unsigned char* texMem) const { switch (extraTex) { case CBaseGroundDrawer::drawPathTraversability: { bool useCurrentBuildOrder = true; if (guihandler->inCommand <= 0) { useCurrentBuildOrder = false; } if (guihandler->inCommand >= guihandler->commands.size()) { useCurrentBuildOrder = false; } if (useCurrentBuildOrder && guihandler->commands[guihandler->inCommand].type != CMDTYPE_ICON_BUILDING) { useCurrentBuildOrder = false; } if (useCurrentBuildOrder) { for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const float3 pos(tx * (SQUARE_SIZE << 1) + SQUARE_SIZE, 0.0f, ty * (SQUARE_SIZE << 1) + SQUARE_SIZE); const int idx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; BuildSquareStatus status = FREE; if (!loshandler->InLos(pos, gu->myAllyTeam)) { status = NOLOS; } else { const UnitDef* ud = unitDefHandler->GetUnitDefByID(-guihandler->commands[guihandler->inCommand].id); const BuildInfo bi(ud, pos, guihandler->buildFacing); CFeature* f = NULL; GML_RECMUTEX_LOCK(quad); // UpdateExtraTexture - testunitbuildsquare accesses features in the quadfield if (uh->TestUnitBuildSquare(bi, f, gu->myAllyTeam, false)) { if (f != NULL) { status = OBJECTBLOCKED; } } else { status = TERRAINBLOCKED; } } const SColor& col = GetBuildColor(status); texMem[idx + CBaseGroundDrawer::COLOR_R] = col.r; texMem[idx + CBaseGroundDrawer::COLOR_G] = col.g; texMem[idx + CBaseGroundDrawer::COLOR_B] = col.b; texMem[idx + CBaseGroundDrawer::COLOR_A] = col.a; } } } else { const MoveDef* md = GetSelectedMoveDef(); if (md != NULL) { const bool los = (gs->cheatEnabled || gu->spectating); for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const int sqx = (tx << 1); const int sqy = (ty << 1); const int texIdx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; const bool losSqr = loshandler->InLos(sqx, sqy, gu->myAllyTeam); float scale = 1.0f; if (los || losSqr) { if (CMoveMath::IsBlocked(*md, sqx, sqy , NULL) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } if (CMoveMath::IsBlocked(*md, sqx + 1, sqy , NULL) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } if (CMoveMath::IsBlocked(*md, sqx, sqy + 1, NULL) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } if (CMoveMath::IsBlocked(*md, sqx + 1, sqy + 1, NULL) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } } // NOTE: raw speedmods are not necessarily clamped to [0, 1] const float sm = CMoveMath::GetPosSpeedMod(*md, sqx, sqy); const SColor& smc = GetSpeedModColor(sm * scale); texMem[texIdx + CBaseGroundDrawer::COLOR_R] = smc.r; texMem[texIdx + CBaseGroundDrawer::COLOR_G] = smc.g; texMem[texIdx + CBaseGroundDrawer::COLOR_B] = smc.b; texMem[texIdx + CBaseGroundDrawer::COLOR_A] = smc.a; } } } else { // we have nothing to show -> draw a dark red overlay for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const int texIdx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; texMem[texIdx + CBaseGroundDrawer::COLOR_R] = 100; texMem[texIdx + CBaseGroundDrawer::COLOR_G] = 0; texMem[texIdx + CBaseGroundDrawer::COLOR_B] = 0; texMem[texIdx + CBaseGroundDrawer::COLOR_A] = 255; } } } } } break;
void DefaultPathDrawer::UpdateExtraTexture(int extraTex, int starty, int endy, int offset, unsigned char* texMem) const { switch (extraTex) { case CBaseGroundDrawer::drawPathTraversability: { bool useCurrentBuildOrder = true; if (guihandler->inCommand <= 0) { useCurrentBuildOrder = false; } if (guihandler->inCommand >= guihandler->commands.size()) { useCurrentBuildOrder = false; } if (useCurrentBuildOrder && guihandler->commands[guihandler->inCommand].type != CMDTYPE_ICON_BUILDING) { useCurrentBuildOrder = false; } if (useCurrentBuildOrder) { for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const float3 pos(tx * (SQUARE_SIZE << 1) + SQUARE_SIZE, 0.0f, ty * (SQUARE_SIZE << 1) + SQUARE_SIZE); const int idx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; BuildSquareStatus status = FREE; if (!loshandler->InLos(pos, gu->myAllyTeam)) { status = NOLOS; } else { const UnitDef* ud = unitDefHandler->GetUnitDefByID(-guihandler->commands[guihandler->inCommand].id); const BuildInfo bi(ud, pos, guihandler->buildFacing); CFeature* f = NULL; GML_RECMUTEX_LOCK(quad); // UpdateExtraTexture - testunitbuildsquare accesses features in the quadfield if (uh->TestUnitBuildSquare(bi, f, gu->myAllyTeam, false)) { if (f != NULL) { status = OBJECTBLOCKED; } } else { status = TERRAINBLOCKED; } } const SColor& col = GetBuildColor(status); texMem[idx + CBaseGroundDrawer::COLOR_R] = col.r; texMem[idx + CBaseGroundDrawer::COLOR_G] = col.g; texMem[idx + CBaseGroundDrawer::COLOR_B] = col.b; texMem[idx + CBaseGroundDrawer::COLOR_A] = col.a; } } } else { const MoveData* md = NULL; const CMoveMath* mm = NULL; const bool los = (gs->cheatEnabled || gu->spectating); { GML_RECMUTEX_LOCK(sel); // UpdateExtraTexture const CUnitSet& selUnits = selectedUnits.selectedUnits; const CUnit* selUnit = NULL; // use the first selected unit, if it has the ability to move if (!selUnits.empty()) { selUnit = *selUnits.begin(); md = selUnit->unitDef->movedata; mm = (md != NULL)? md->moveMath: NULL; } } for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const int sqx = (tx << 1); const int sqy = (ty << 1); const int texIdx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; if (md != NULL) { float s = 1.0f; if (los || loshandler->InLos(sqx, sqy, gu->myAllyTeam)) { if (mm->IsBlocked(*md, sqx, sqy ) & CMoveMath::BLOCK_STRUCTURE) { s -= 0.25f; } if (mm->IsBlocked(*md, sqx + 1, sqy ) & CMoveMath::BLOCK_STRUCTURE) { s -= 0.25f; } if (mm->IsBlocked(*md, sqx, sqy + 1) & CMoveMath::BLOCK_STRUCTURE) { s -= 0.25f; } if (mm->IsBlocked(*md, sqx + 1, sqy + 1) & CMoveMath::BLOCK_STRUCTURE) { s -= 0.25f; } } const float& m = GetSpeedMod(md, mm, sqx, sqy); const SColor& c = GetSpeedModColor(m * s); texMem[texIdx + CBaseGroundDrawer::COLOR_R] = c.r; texMem[texIdx + CBaseGroundDrawer::COLOR_G] = c.g; texMem[texIdx + CBaseGroundDrawer::COLOR_B] = c.b; texMem[texIdx + CBaseGroundDrawer::COLOR_A] = c.a; } else { // we have nothing to show // -> draw a dark red overlay texMem[texIdx + CBaseGroundDrawer::COLOR_R] = 100; texMem[texIdx + CBaseGroundDrawer::COLOR_G] = 0; texMem[texIdx + CBaseGroundDrawer::COLOR_B] = 0; texMem[texIdx + CBaseGroundDrawer::COLOR_A] = 255; } } } } } break; case CBaseGroundDrawer::drawPathHeat: { for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const int texIdx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; texMem[texIdx + CBaseGroundDrawer::COLOR_R] = Clamp(8 * pm->GetHeatOnSquare(tx << 1, ty << 1), 32, 255); texMem[texIdx + CBaseGroundDrawer::COLOR_G] = 32; texMem[texIdx + CBaseGroundDrawer::COLOR_B] = 32; texMem[texIdx + CBaseGroundDrawer::COLOR_A] = 255; } } } break; case CBaseGroundDrawer::drawPathCost: { const PathNodeStateBuffer& maxResStates = pm->maxResPF->squareStates; const PathNodeStateBuffer& medResStates = pm->medResPE->blockStates; const PathNodeStateBuffer& lowResStates = pm->lowResPE->blockStates; const unsigned int medResBlockSize = pm->medResPE->BLOCK_SIZE, medResBlocksX = pm->medResPE->nbrOfBlocksX; const unsigned int lowResBlockSize = pm->lowResPE->BLOCK_SIZE, lowResBlocksX = pm->lowResPE->nbrOfBlocksX; const float gCostMax[3] = { std::max(1.0f, maxResStates.GetMaxGCost()), std::max(1.0f, medResStates.GetMaxGCost()), std::max(1.0f, lowResStates.GetMaxGCost()), }; for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < gs->hmapx; ++tx) { const unsigned int texIdx = ((ty * (gs->pwr2mapx >> 1)) + tx) * 4 - offset; // NOTE: // tx is in [0, gs->hmapx> // ty is in [0, gs->hmapy> (highResInfoTexWanted == false) const unsigned int hx = tx << 1; const unsigned int hy = ty << 1; float gCost[3] = { maxResStates.gCost[hy * gs->mapx + hx], medResStates.gCost[(hy / medResBlockSize) * medResBlocksX + (hx / medResBlockSize)], lowResStates.gCost[(hy / lowResBlockSize) * lowResBlocksX + (hx / lowResBlockSize)], }; if (math::isinf(gCost[0])) { gCost[0] = gCostMax[0]; } if (math::isinf(gCost[1])) { gCost[1] = gCostMax[1]; } if (math::isinf(gCost[2])) { gCost[2] = gCostMax[2]; } // NOTE: // the normalisation means each extraTextureUpdate block // of rows gets assigned different colors when units are // moving (so view it while paused) texMem[texIdx + CBaseGroundDrawer::COLOR_R] = (gCost[0] / gCostMax[0]) * 255; texMem[texIdx + CBaseGroundDrawer::COLOR_G] = (gCost[1] / gCostMax[1]) * 255; texMem[texIdx + CBaseGroundDrawer::COLOR_B] = (gCost[2] / gCostMax[2]) * 255; texMem[texIdx + CBaseGroundDrawer::COLOR_A] = 255; } } } break; default: { } break; }