// ── Dynamic PVP's zones (protocol 14, PLAN_REDESIGNS §14.3.3) ────────────── // // HunterZ's Dynamic PVP opens its own temporary PvP zones around a downed // patrol helicopter, a Bradley, a locked crate, an airdrop, the cargo ship and // the rest. They are the plugin's own: there is no step and no trigger here, // only the feed's lines (`pvp.zone.created`, public; `pvp.zone.deleted`, // staff's) and the map's `pvp` layer. // // ── Who may read what ────────────────────────────────────────────────────── // // As a world event is read (`worldEvents.js`, D353): the zone and its grid are // public, and its position is staff's, because the map has its own audience for // where things are (D111). A zone names nobody. // // **Only Dynamic PVP's own vanilla events carry their name to the public.** Its // monument zones are named after the monument and an operator's own events by // whatever the operator typed into its config; those reach staff as written and // everyone else as "A PvP zone opened at G7". const { gridOf } = require('./worldEvents') /** Dynamic PVP 5.2.0's own events (its `GeneralEventType`), as its hooks name them. */ const GENERAL_EVENTS = Object.freeze([ 'Bradley', 'Helicopter', 'Satellite', 'TimedSupply', 'SupplySignal', 'CargoShip', 'HackableCrate', 'ExcavatorIgnition', 'GhostShip', 'DeepSeaIsland', 'IslandCannon', ]) const KINDS = Object.freeze(['pvp.zone.created', 'pvp.zone.deleted']) function isGeneral(event) { return GENERAL_EVENTS.includes(event) } /** * One `pvp.zone.*` frame for one viewer: `{ staff, geometry }`. Passes * `kind`, `type`, `t`, `serverId`, `wipeId`, `radius`, `shape`, `durationSec`, * adds `grid`, and `event` when it is one of Dynamic PVP's own or the viewer is * staff. Staff also get `x`, `z` and `zoneId`. Any other frame is returned as is. */ function shapeFor(frame, { staff = false, geometry = null } = {}) { if (!frame || !KINDS.includes(frame.kind)) return frame const out = {} for (const key of ['kind', 'type', 't', 'serverId', 'wipeId', 'radius', 'shape', 'durationSec']) { if (frame[key] !== undefined) out[key] = frame[key] } const grid = gridOf(geometry, frame.x, frame.z) if (grid) out.grid = grid if (typeof frame.event === 'string' && frame.event && (staff || isGeneral(frame.event))) out.event = frame.event if (staff) { for (const key of ['x', 'z', 'zoneId']) { if (frame[key] !== undefined) out[key] = frame[key] } } return out } module.exports = { GENERAL_EVENTS, KINDS, isGeneral, shapeFor }