mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-03 18:24:12 +02:00
115 lines
5.6 KiB
TypeScript
115 lines
5.6 KiB
TypeScript
import {Player as PlayerDot} from './Render/Player';
|
|
import {Building as BuildingDot} from './Render/Building';
|
|
import {Projectile as ProjectileDot} from './Render/Projectile';
|
|
import {findMapAlias} from './MapBoundries';
|
|
import {PlayerState, Header, WorldBoundaries, BuildingState, ProjectileState, CartState} from "./Data/Parser";
|
|
import {Show} from "solid-js";
|
|
import {Projectile} from "./Render/Cart";
|
|
import {HealBeam} from "./Render/HealBeam";
|
|
import {medics} from "./Render/PlayerSpec";
|
|
|
|
export interface MapRenderProps {
|
|
header: Header;
|
|
players: PlayerState[];
|
|
buildings: BuildingState[];
|
|
projectiles: ProjectileState[];
|
|
cart: CartState | null;
|
|
size: {
|
|
width: number;
|
|
height: number;
|
|
},
|
|
world: WorldBoundaries;
|
|
scale: number;
|
|
onHover: (userId: number) => void;
|
|
highlighted: number;
|
|
}
|
|
|
|
const map_root = document.querySelector('[data-maps]').getAttribute('data-maps');
|
|
|
|
export function MapRender(props: MapRenderProps) {
|
|
const mapAlias = findMapAlias(props.header.map);
|
|
const image = `${map_root}images/${mapAlias}.webp`;
|
|
const background = `url(${image})`;
|
|
const medicPlayers = () => medics(props.players);
|
|
|
|
return (
|
|
<svg class="map-background" width={props.size.width} height={props.size.height}
|
|
style={{"background-image": background}}>
|
|
<defs>
|
|
<pattern id="diagonalHatchRed" patternUnits="userSpaceOnUse" width="8" height="8"
|
|
patternTransform="rotate(45 0 0)">
|
|
<line x1="0" y1="0" x2="0" y2="10" style="stroke:#a75d50; stroke-width:10"/>
|
|
</pattern>
|
|
<pattern id="diagonalHatchBlue" patternUnits="userSpaceOnUse" width="8" height="8"
|
|
patternTransform="rotate(45 0 0)">
|
|
<line x1="0" y1="0" x2="0" y2="10" style="stroke:#5b818f; stroke-width:10"/>
|
|
</pattern>
|
|
<pattern id="diagonalHatchRedBlue" patternUnits="userSpaceOnUse" width="8" height="8"
|
|
patternTransform="rotate(45 0 0)">
|
|
<line x1="0" y1="0" x2="0" y2="10" style="stroke:#a75d50; stroke-width:12"/>
|
|
<line x1="8" y1="0" x2="8" y2="10" style="stroke:#5b818f; stroke-width:4"/>
|
|
</pattern>
|
|
<pattern id="diagonalHatchBlueRed" patternUnits="userSpaceOnUse" width="8" height="8"
|
|
patternTransform="rotate(45 0 0)">
|
|
<line x1="0" y1="0" x2="0" y2="10" style="stroke:#5b818f; stroke-width:12"/>
|
|
<line x1="8" y1="0" x2="8" y2="10" style="stroke:#a75d50; stroke-width:4"/>
|
|
</pattern>
|
|
|
|
|
|
<filter id="sofGlowRed" height="300%" width="300%" x="-75%" y="-75%">
|
|
<feMorphology operator="dilate" radius="4" in="SourceAlpha" result="thicken"/>
|
|
<feGaussianBlur in="thicken" stdDeviation="5" result="blurred"/>
|
|
<feFlood flood-color="rgb(255,52,0)" result="glowColor"/>
|
|
<feComposite in="glowColor" in2="blurred" operator="in" result="softGlow_colored"/>
|
|
<feMerge>
|
|
<feMergeNode in="softGlow_colored"/>
|
|
<feMergeNode in="SourceGraphic"/>
|
|
</feMerge>
|
|
</filter>
|
|
<filter id="sofGlowBlue" height="300%" width="300%" x="-75%" y="-75%">
|
|
<feMorphology operator="dilate" radius="4" in="SourceAlpha" result="thicken"/>
|
|
<feGaussianBlur in="thicken" stdDeviation="5" result="blurred"/>
|
|
<feFlood flood-color="rgb(0,186,255)" result="glowColor"/>
|
|
<feComposite in="glowColor" in2="blurred" operator="in" result="softGlow_colored"/>
|
|
<feMerge>
|
|
<feMergeNode in="softGlow_colored"/>
|
|
<feMergeNode in="SourceGraphic"/>
|
|
</feMerge>
|
|
</filter>
|
|
</defs>
|
|
|
|
<For each={medicPlayers()}>{(player) =>
|
|
<Show when={player.health}>
|
|
<HealBeam player={player} mapBoundary={props.world} targetSize={props.size} scale={props.scale}
|
|
players={props.players}
|
|
/>
|
|
</Show>
|
|
}</For>
|
|
<For each={props.players}>{(player) =>
|
|
<Show when={player.health}>
|
|
<PlayerDot player={player} mapBoundary={props.world} targetSize={props.size} scale={props.scale}
|
|
onHover={props.onHover}
|
|
players={props.players}
|
|
highlighted={props.highlighted === player.info.userId}
|
|
/>
|
|
</Show>
|
|
}</For>
|
|
<For each={props.buildings}>{(building) =>
|
|
<Show when={building.position.x}>
|
|
<BuildingDot building={building} mapBoundary={props.world} targetSize={props.size}
|
|
scale={props.scale}/>
|
|
</Show>
|
|
}</For>
|
|
<For each={props.projectiles}>{(projectile) =>
|
|
<Show when={projectile.position.x}>
|
|
<ProjectileDot projectile={projectile} mapBoundary={props.world} targetSize={props.size}
|
|
scale={props.scale}/>
|
|
</Show>
|
|
}</For>
|
|
<Show when={props.cart}>
|
|
<Projectile cart={props.cart} mapBoundary={props.world} targetSize={props.size}
|
|
scale={props.scale}/>
|
|
</Show>
|
|
</svg>
|
|
);
|
|
}
|