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>
121 lines
3.1 KiB
TypeScript
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).",
|
|
},
|
|
},
|
|
],
|
|
};
|