{#if mapImageUrl} {:else} {/if} {#each { length: MAP_W + 1 } as _, i} {/each} {#each { length: MAP_H + 1 } as _, i} {/each} {#each MAP_LANDMARKS as lm} {lm.name} {/each} {#each resources as res} {#if res.resource_type === 'mineral' && res.amount > 0} {:else if res.resource_type === 'geyser'} {/if} {/each} {#each allBuildings as { b, isOwn, colorBg, colorBorder }} {#if b.status !== 'destroyed' && (isOwn || isVisible(b.x, b.y))} {@const size = BUILDING_SIZES[b.building_type]} {@const color = colorBg} {@const border = colorBorder} {@const bx = b.x - size.w / 2} {@const by = b.y - size.h / 2} {#if b.id === $selectedBuilding?.id} {/if} {#if b.status === 'constructing'} {/if} {#if b.production_queue.length > 0} {#each { length: Math.min(b.production_queue.length, 5) } as _, qi} {/each} {/if} {/if} {/each} {#each allUnits as { u, isOwn } (u.id)} {@const op = beamOpacities[u.id] ?? 0} {#if op > 0 && (isOwn || isVisible(u.x, u.y))} {@const beam = UNIT_BEAM[u.unit_type]} {@const isSiegedTank = u.unit_type === 'tank' && u.is_sieged} {@const bw = isSiegedTank ? beam.width * 1.6 : beam.width} {@const srcRs = unitRenderStates[u.id]} {@const srcX = srcRs?.renderX ?? u.x} {@const srcY = srcRs?.renderY ?? u.y} {@const targetPos = u.attack_target_id ? (() => { const t = allUnits.find(a => a.u.id === u.attack_target_id); const trs = unitRenderStates[u.attack_target_id]; return t ? { x: trs?.renderX ?? t.u.x, y: trs?.renderY ?? t.u.y } : null; })() : u.attack_target_building_id ? (buildingPosMap[u.attack_target_building_id] ?? null) : null} {#if targetPos} {/if} {/if} {/each} {#each allUnits as { u, isOwn, color } (u.id)} {#if isOwn || isVisible(u.x, u.y)} {@const rs = unitRenderStates[u.id]} {@const rx = rs?.renderX ?? u.x} {@const ry = rs?.renderY ?? u.y} {@const angle = rs?.angle ?? 0} {@const isSelected = u.id === $selectedUnit?.id} {@const isLargeUnit = u.unit_type === 'goliath' || u.unit_type === 'tank' || u.unit_type === 'wraith'} {@const isTank = u.unit_type === 'tank'} {@const spriteHalf = isTank ? 1.52 : isLargeUnit ? 0.76 : 0.38} {@const spriteSize = isTank ? 3.04 : isLargeUnit ? 1.52 : 0.76} {#if isSelected} {/if} {#if u.is_sieged} {/if} {#if u.is_cloaked} {/if} {/if} {/each} {#if showWalkable} {#each walkablePolygons as pts} {/each} {/if} {#if showNavPoints} {#each navPoints as [nx, ny]} {/each} {/if} {#if !isObserver} {@const _visSrc = getVisibleSources(gs, myId)} {#each exploredSources as s} {/each} {#each _visSrc as s} {/each} {/if} {#if $isTutorial && $gameState?.tutorial_target_x != null && $gameState?.tutorial_target_y != null} {@const bx = $gameState.tutorial_target_x} {@const by = $gameState.tutorial_target_y} OBJECTIVE {/if}