import { CollectionConfig } from "payload"; import { isDeveloper } from "@/utils/access-control/isRole"; import { emitGameEvent } from "@/utils/event-log/emit"; export const GameStructures: CollectionConfig = { slug: "game-structures", admin: { group: "Game", useAsTitle: "name", }, access: { read: ({ req }) => !!req.user, create: isDeveloper, update: isDeveloper, delete: isDeveloper, }, hooks: { afterChange: [ async ({ doc, previousDoc, req }) => { const d = doc as any; const prev = previousDoc as any; if (!prev) return; if (!req.user) return; const oldStored = JSON.stringify(prev.storedResources ?? []); const newStored = JSON.stringify(d.storedResources ?? []); const oldVoid = JSON.stringify(prev.voidStorage ?? []); const newVoid = JSON.stringify(d.voidStorage ?? []); if (oldStored === newStored && oldVoid === newVoid) return; await emitGameEvent(req.payload, { type: "storage:withdraw", message: `Admin updated storage in "${d.name}"`, actor: req.user.id, structure: d.id, targetCollection: "game-structures", targetId: d.id, data: { previousStored: prev.storedResources, newStored: d.storedResources, previousVoid: prev.voidStorage, newVoid: d.voidStorage, }, }); }, ], }, fields: [ { name: "name", type: "text", label: "Display Name", admin: { description: "The name of the structure as displayed in-game and on the frontend.", }, required: true, }, { name: "type", type: "relationship", relationTo: "structures", required: true, admin: { description: "The type of structure this is.", }, }, { name: "faction", type: "relationship", relationTo: "factions", admin: { description: "The faction that owns this structure.", }, }, { label: "Geolocation", type: "group", fields: [ { name: "coordinates", type: "point", }, ], }, { name: "storedResources", type: "array", fields: [ { name: "resource", type: "relationship", relationTo: "resources", required: true, }, { name: "amount", type: "number", required: true, min: 1, }, { name: "gridX", type: "number", required: true, min: 0, admin: { description: "Column position in the inventory grid (0-indexed).", }, }, { name: "gridY", type: "number", required: true, min: 0, admin: { description: "Row position in the inventory grid (0-indexed).", }, }, { name: "rotated", type: "checkbox", defaultValue: false, admin: { description: "Whether this item is rotated 90 degrees (swaps width and height).", }, }, ], }, { name: "voidStorage", type: "array", admin: { description: "Items that no longer fit in the grid after a resize, stored here until retrieved.", }, fields: [ { name: "resource", type: "relationship", relationTo: "resources", required: true, }, { name: "amount", type: "number", required: true, min: 1, }, { name: "gridX", type: "number", required: true, min: 0, }, { name: "gridY", type: "number", required: true, min: 0, }, { name: "rotated", type: "checkbox", defaultValue: false, }, ], }, ], };