Beispiel #1
0
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;
    }