1
0
Fork 0
polaris-task-force/src/collections/game/GameStructures.ts

170 lines
4 KiB
TypeScript

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,
},
],
},
],
};