1
0
Fork 0
polaris-task-force/src/collections/world/MapZones.ts
Z8MB1E 5f06039697 feat(world): game map collections with basemaps, map permissions, and meter proximity
Add maps basemap config (world size, image/tiles mode, zoom defaults, isActive), map-roads, map-zones, and resource-nodes collections with maps:* permissions. Track game-structures map placement, meter coordinates, and label visibility/priority. Bump proximityThreshold to meters and adapt side-op map creation plus test fixtures to the new required fields.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-16 23:13:57 -04:00

121 lines
3.1 KiB
TypeScript

import { CollectionConfig } from "payload";
import { requirePermission } from "@/utils/access-control/hasPermission";
import { validateHexColor } from "@/lib/map/style";
import { validatePolygon } from "@/lib/map/points";
/**
* GM-drawn terrain zones. Land blueprints cannot be placed inside water
* polygons; water blueprints require one. Default terrain (no zones on the
* map) accepts everything.
*/
export const MapZones: CollectionConfig = {
slug: "map-zones",
admin: {
group: "World",
useAsTitle: "name",
},
access: {
read: ({ req }) => !!req.user,
create: requirePermission("maps:create"),
update: requirePermission("maps:update"),
delete: requirePermission("maps:delete"),
},
fields: [
{
name: "name",
type: "text",
admin: {
description: 'Zone label (e.g. "Altis bay", "Flood plain").',
},
},
{
name: "description",
type: "textarea",
admin: {
description: "Shown in the zone's tooltip and popup on the map.",
},
},
{
name: "map",
type: "relationship",
relationTo: "maps",
required: true,
},
{
name: "type",
type: "select",
required: true,
options: [
{ label: "Water", value: "water" },
{ label: "Land", value: "land" },
],
admin: {
description:
"Water zones block land-blueprint placement. Land zones are informational; default terrain is buildable land.",
},
},
{
name: "fillColor",
type: "text",
validate: validateHexColor,
admin: {
description: "Polygon fill as hex (e.g. #38bdf8). Empty = default color for the type.",
},
},
{
name: "strokeColor",
type: "text",
validate: validateHexColor,
admin: {
description: "Outline color as hex. Empty = default color for the type.",
},
},
{
name: "fillOpacity",
type: "number",
min: 0,
max: 1,
admin: {
description: "Fill opacity 0-1. Empty = default (0.25 water, 0.08 land).",
},
},
{
name: "strokeWeight",
type: "number",
min: 0,
max: 10,
defaultValue: 1,
admin: {
description: "Outline thickness in pixels. 0 hides the outline.",
},
},
{
name: "resources",
type: "relationship",
relationTo: "resources",
hasMany: true,
admin: {
description:
"Resources contained in this zone (e.g. an oil field). A zone with resources satisfies blueprint resourcesInRange requirements for any site inside it.",
},
},
{
name: "labelVisible",
type: "checkbox",
defaultValue: true,
label: "Show Name Label",
admin: {
description: "Renders the zone's name at the polygon's center.",
},
},
{
name: "points",
type: "json",
required: true,
validate: validatePolygon,
admin: {
description: "Polygon ring as an array of [x, y] meter tuples (need not repeat the first point).",
},
},
],
};