HunterZ
Creates PvP zones upon certain actions/events/monuments

Supported Games
GameServerKingsGameServerKings

Introduction

Dynamic PVP automatically manages creation and deletion of Zone Manager zones and corresponding PVE plugin ruleset mappings, for various events on your server. This allows you to turn a PVE server into a hybrid PVE/PVP server.

The most common setup is to use a PVE plugin to make your entire server PVE by default, and then have Dynamic PVP create "exclusion" zones where the PVE plugin knows to not enforce its rules.

This means that Dynamic PVP requires Zone Manager, and in most cases a compatible PVE plugin such as True PVE.

IMPORTANT NOTE

For increased compatibility with your chosen PVE plugin, it is recommended to add it as a hard dependency in DynamicPVP.cs.

Example:

//Requires: TruePVE
//Requires: ZoneManager
using System;

Event Types

Dynamic PVP can automatically manage zones mappings for the following kinds of events:

General Events

These are dynamic PVP events based on the following vanilla world events:

  • Bradley APC death
  • Patrol Helicopter death
  • Supply Drop (timed airdrops)
  • Supply Signal (called airdrops)
  • Hackable Crates (Chinook - and optionally Cargo Ship and/or Oil Rig - crates)
  • Giant Excavator ignition/activation
  • Cargo Ship

Monument events

These are static PVP events based on monuments defined by the game or custom maps.

Monument event zone geometry can be automatically calculated based on "prevent building" volumes.

NOTE: Dynamic PVP will automatically add disabled events to the config file for vanilla monuments, Train Tunnel sections, and any named monuments from the currently loaded map.

Custom events

These are user-defined automatic or timed events managed via the dynpvp command and configured in Dynamic PVP's data file.

Please edit the data file after unloading the plugin to avoid losing changes.

PVP Delays

Dynamic PVP supports per-event configuration of PVP exit delays (or "PVP delays" for short). This is a mechanism that causes players to be considered still in PVP status for a configured amount of time after exiting a PVP zone, in order to prevent them from exploiting PVE/PVP zone boundaries during a fight.

As of Dynamic PVP 4.3.0, True PVE 2.2.3's ExcludePlayer API can be used to implement PVP delays instead of the built-in CanEntityTakeDamage hook handler. This is highly recommended because allowing True PVE to perform all damage calculations is both more efficient, and allows for damage rules to be resolved across zones/delays created by multiple PVP plugins.

True PVE ExcludePlayer support can be explicitly activated in the config file, but it will also activate automatically when True PVE 2.2.3 is detected and all PVP delay damage types are enabled in the config file.

Permissions

  • dynamicpvp.admin -- Allows player to use dynpvp commands

Commands

  • dynpvp help or dynpvp h -- View help
  • dynpvp add <eventName> [timed] -- Create custom event record. If timed is specified, it will be a timed event
  • dynpvp remove <eventName> -- Remove custom event record
  • dynpvp start <eventName> -- Start custom event
  • dynpvp stop <eventName> -- Stop custom event
  • dynpvp edit <eventName> true or dynpvp edit <eventName> false -- Enable or disable (respectively) auto-start state of auto event
  • dynpvp edit <eventName> move -- Move custom event to your current location
  • dynpvp edit <eventName> <time> -- Changes the duration (in seconds) of a timed event
  • dynpvp list -- Display all custom events
  • dynpvp show -- Temporarily show geometries in-game for all active zones

Note: Geometries are shown for the commanding admin only. Duration can be changed in the config file.

Configuration

IMPORTANT NOTES

  • For each enabled event, you must define a Zone Radius or Zone Size that is greater than zero. If you do not do this, zone creation will fail with an error log as of 4.3.0. Radius takes precedence over size, so set radius to zero if you want to create a rectangular box zone.

  • Player-visible domes and colored rings can only be created for "sphere" zones defined by a radius. "Box" zones defined by a size have no dome/ring support. This is a game limitation. Admins can visualize both kinds of zones via the /dynpvp show command.

  • PVP Delay flags:

    • ZonePlayersCanDamageDelayedPlayers -- Players in PVP zone can damage players in PVP delay
    • DelayedPlayersCanDamageDelayedPlayers -- Players in PVP delay can damage players in PVP zone
    • DelayedPlayersCanDamageZonePlayers -- Players in PVP delay can damage players in PVP delay
  • Fixed Rotation:

    • This is generally only useful for monument events with box-shaped zones. If true, the zone will be rotated relative to the world; if false, it will be rotated relative to the monument. Generally you will want to set this to false since it's usually most important that the box cover the monument regardless of its world orientation.

Example Configuration File

{
  "Global Settings": {
    "Enable Debug Mode": true,
    "Log Debug To File": false,
    "Compare Radius (Used to determine if it is a SupplySignal)": 50.0, // Used to distinguish whether supply drops originate from a Supply Signal or a timed drop
    "If the entity has an owner, don't create a PVP zone": true, // "Entity" refers to the one that triggered the event, such as Bradley or Heli
    "Use TruePVE PVP Delay API (more efficient and cross-plugin, but supersedes PVP Delay Flags)": false,
    "PVP Delay Flags": "ZonePlayersCanDamageDelayedPlayers, DelayedPlayersCanDamageZonePlayers, DelayedPlayersCanDamageDelayedPlayers"
  },
  "Chat Settings": {
    "Command": "dynpvp",
    "Chat Prefix": "[DynamicPVP]: ",
    "Chat Prefix Color": "#00FFFF",
    "Chat SteamID Icon": 0,
    "Zone Show Distance": 1000.0,
    "Zone Show Duration (in seconds)": 15.0
  },
  "General Event Settings": {
    "Bradley event settings": {
      "Enable Event": true,
      "Delay In Starting Event": 0.0,
      "Delay In Stopping Event": 0.0,
      "Holster Time On Enter (In seconds, or 0 to disable)": 0.0,
      "Enable PVP Delay": true, // When a player leaves the area for a period of time, they can still be hurt by other players
      "PVP Delay Time": 10.0,
      "TruePVE Mapping": "exclude", // Tells PVE plugin to exclude this from PVE rules, making it a PVP zone
      "Use Blacklist Commands (If false, a whitelist is used)": true,
      "Command works for PVP delayed players": false,
      "Command List (If there is a '/' at the front, it is a chat command)": [
        "kill",
        "/god"
      ],
      "Drop plugin Backpacks on death (null disables override)": null, // true to force drop on player deaths in this event's zones, false to force keep, null to take no special action
      "Bypass Loot Defender locks": false, // whether to force allow looting of containers in this event's zones
      "Block Restore Upon Death": false, // whether to prevent restoring on player deaths in this event's zones
      "Dome Settings": { // This will be ignored for cube zones
        "Dome Darkness (0 to disable)": 8,
        "Enable Red Ring": false,
        "Enable Green Ring": false,
        "Enable Blue Ring": false,
        "Enable Purple Ring": false
      },
      "Enable Bots (Need BotSpawn Plugin)": false,
      "BotSpawn Profile Name": "",
      "Event Duration": 600.0,
      "Dynamic PVP Zone Settings": {
        "Zone Comfort": 0.0,
        "Zone Radiation": 0.0,
        "Zone Temperature": 0.0,
        "Enable Safe Zone": false,
        "Eject Spawns": "",
        "Zone Parent ID": "",
        "Enter Message": "Entering a PVP area!",
        "Leave Message": "Leaving a PVP area.",
        "Permission Required To Enter Zone": "",
        "Extra Zone Flags": [
          "notp",
          "undestr"
        ],
        "Zone Radius": 100.0, // Defines a spherical zone
        "Zone Size": { // Defines a box zone if Zone Radius is zero, otherwise ignored
          "x": 0.0,
          "y": 0.0,
          "z": 0.0
        },
        "Zone Rotation": 0.0, // Box zone rotation
        "Fixed Rotation": false
      }
    }
  },
  "Monument Event Settings": {
    "Abandoned Cabins": {
      "Enable Event": false,
      "Delay In Starting Event": 0.0,
      "Delay In Stopping Event": 0.0,
      "Holster Time On Enter (In seconds, or 0 to disable)": 0.0,
      "Enable PVP Delay": false,
      "PVP Delay Time": 10.0,
      "TruePVE Mapping": "exclude",
      "Use Blacklist Commands (If false, a whitelist is used)": true,
      "Command works for PVP delayed players": false,
      "Command List (If there is a '/' at the front, it is a chat command)": [],
      "Drop plugin Backpacks on death (null disables override)": null,
      "Bypass Loot Defender locks": false,
      "Block Restore Upon Death": false,
      "Enable Domes": true,
      "Dome Settings": {
        "Dome Darkness (0 to disable)": 0,
        "Enable Red Ring": true,
        "Enable Green Ring": false,
        "Enable Blue Ring": false,
        "Enable Purple Ring": false
      },
      "Dynamic PVP Zone Settings": {
        "Zone Comfort": 0.0,
        "Zone Radiation": 0.0,
        "Zone Temperature": 0.0,
        "Enable Safe Zone": false,
        "Eject Spawns": "",
        "Zone Parent ID": "",
        "Enter Message": "Entering a PVP area!",
        "Leave Message": "Leaving a PVP area.",
        "Permission Required To Enter Zone": "",
        "Extra Zone Flags": [],
        "Zone Radius": 0.0,
        "Zone Size": {
          "x": 0.0,
          "y": 0.0,
          "z": 0.0
        },
        "Zone Rotation": 0.0,
        "Fixed Rotation": false,
        "Auto-calculate zone geometry (overwrites existing values)": false // determines whether Zone Radius, Zone Size, Zone Rotation, Fixed Rotation, and Transform Position should be calculated automatically and overwritten
      },
      "Zone ID": "",
      "Transform Position": { // Move the position of the zone; use `dynpvp show` to see x/y/z for non-fixed rotation zones
        "x": 0.0,
        "y": 0.0,
        "z": 0.0
      }
    }
  }
}

Hooks

The following hooks are used to integrate with and/or provide integration points for other plugins.

PVE rule exclusion

void AddOrUpdateMapping(string zoneId, string mapping)

Called to request a PVE plugin to map the Dynamic PVP zone ID specified via zoneId to the ruleset specified via mapping.

void ExcludePlayer(ulong playerID, float pvpDelayTime, Oxide.Plugins.DynamicPVP)

When support for this feature is active via config file or automatic sensing, it will be called to request a PVE plugin to activate PVE rule exclusion (i.e. PVP delay status) for the given player ID for the given amount of time, on behalf of Dynamic PVP.

void RemoveMapping(string zoneId)

Called to request a PVE plugin to remove the ruleset mapping for the Dyanmic PVP zone ID specified via zoneId.

PVP zone reporting

void OnPlayerEnterPVP(BasePlayer player, string zoneId)

Called to report that the given player has entered a Dyamic PVP zone with the given zone ID.

void OnPlayerExitPVP(BasePlayer player, string zoneId)

Called to report that the given player has exited a Dynamic PVP zone with the given zone ID, and is not subject to a PVP exit delay.

void OnPlayerExitPVP(BasePlayer player, string zoneId, float pvpDelaySeconds)

Called to report that the given player has exited a Dynamic PVP zone with the given zone ID, and is subject to a PVP exit delay of the given length in seconds.

PVP delay reporting

void OnPlayerAddedToPVPDelay(ulong playerID, string zoneId, float pvpDelayTime, BasePlayer player)

Called when a PVP delay is activated for the given player upon entering the given Dynamic PVP zone, for the given amount of time (in seconds).

void OnPlayerRemovedFromPVPDelay(ulong playerId, string leftZoneId, BasePlayer player)

Called when the given player's PVP delay originating from leaving the given zone ID expires or is removed due to entering another Dynamic PVP zone.

Event management

object OnCreateDynamicPVP(string eventName, BaseEntity entity)

Called when a Dynamic PVP zone is about to be created. If another plugin returns a non-null value, zone creation will be aborted.

void OnCreatedDynamicPVP(string zoneId, string eventName, Vector3 position, float duration)

Called after a Dynamic PVP zone creation has completed.

object OnDeleteDynamicPVP(string zoneId, string eventName)

Called when a Dynamic PVP zone is about to be deleted. If another plugin returns a non-null value, zone deletion will be aborted.

void OnDeletedDynamicPVP(string zoneId, string eventName)

Called after a Dynamic PVP zone deletion has completed.

API

The following methods are provided for integration with other plugins via Oxide's Interface.CallHook() or DynamicPVP.Call() APIs.

string[] AllDynamicPVPZones()

Returns an array of strings containing Zone Manager zone IDs for all active Dynamic PVP events.

void AllDynamicPVPZonesNoAlloc(List<string> list)

Populates given list with Zone Manager zone IDs for all active Dynamic PVP events. This is an alternative to AllDynamicPVPZones() that avoids allocating a new array.

bool IsDynamicPVPZone(string zoneID)

Returns true if the given Zone Manager zone ID is recognized by Dynamic PVP as one that it's managing, otherwise returns false.

bool EventDataExists(string eventName)

Returns true if a auto/timed custom event with the given name exists in Dynamic PVP's data records, otherwise returns false.

bool IsPlayerInPVPDelay(ulong playerID)

Returns true if Dynamic PVP is currently tracking a PVP delay status for the given player, otherwise returns false.

string GetPlayerPVPDelayedZoneID(ulong playerId)

If given player has a PVP delay status tracked by Dynamic PVP, returns the Zone Manager zone ID for the zone that the player left in order to trigger the delay; otherwise returns null.

string GetEventName(string zoneId)

If the given Zone Manager zone ID is recognized as a Dynamic PVP event zone, returns the name of the event; otherwise returns null.

bool CreateOrUpdateEventData(string eventName, string eventData, bool isTimed = false)

Creates/recreates an auto (if isTimed is false or not specified) or timed (if isTimed is true) custom event data record with the given name, based on the given event data. Auto events with AutoStart=true will be auto-started. Returns a boolean indicating whether (re)creation was successful. eventData must contain a JSON definition of an event object depending on the value of isTimed:

  • false -- must contain an AutoEvent object
  • true -- must contain a TimedEvent object
bool CreateEventData(string eventName, Vector3 position, bool isTimed)

Creates an auto (if isTimed is false) or timed (if isTimed is true) custom event data record with the given name, at the given location, with default configuration. Does not auto-start events. Returns false if EventDataExists(eventName) returns true (i.e. if a custom event data record already exists for eventName), otherwise returns true.

bool RemoveEventData(string eventName, bool forceClose = true)

Removes the given custom event's data record. Calls ForceCloseZones(eventName) to handle the case of removing data for a started event, unless a forceClose value of false is specified. Returns false if EventDataExists(eventName) returns false (i.e. if no custom event data record exists for eventName).

bool StartEvent(string eventName, Vector3 position)

Starts the given custom event name, at the given location. For AutoEvent events, position can be default, in which case the preconfigured location is used. Returns false if EventDataExists(eventName) returns false (i.e. if no custom event data record exists for eventName), or if zone creation fails.

bool StopEvent(string eventName)

Returns true if EventDataExists(eventName) and ForceCloseZones(eventName) both return true, otherwise returns false.

bool ForceCloseZones(string eventName)

Deletes any Dynamic PVP zone associated with eventName, and returns a boolean indication of whether a closure occurred.

bool IsUsingExcludePlayer()

Returns true if True PVE 2.2.3 ExcludePlayer() PVP delay API is being used, either due to configuration, or due to auto sensing.

Credits

  • HunterZ: Current maintainer of this plugin.
  • CatMeat: Original author of this plugin. (Thanks for this amazing plugin!)
  • Arainrr: Previous maintainer. (Thank you for your hard work)
  • IIIaKa: Hook enhancements.
  • sickness0666: Holster feature.
  • WhiteThunder: Custom monument "prevent building" collider detection.
  • Nivex: Collaboration on many things.
  • beee: Config/data migration.

MIT License


Copyright (c) 2019 Arainrr


Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:


The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.