215 lines
8.2 KiB
Markdown
215 lines
8.2 KiB
Markdown
# RoseFirefighter
|
|
|
|
RoseFirefighter is a Paper 26.2 companion plugin for **JobsReborn**. It detects legitimate firefighting, runs temporary fire emergencies, integrates with GriefPrevention, and submits JobsReborn actions so JobsReborn remains responsible for job membership, levels, XP, income, bonuses, taxes, payment limits, and progression.
|
|
|
|
## Supported firefighting
|
|
|
|
- Extinguishing `FIRE`.
|
|
- Extinguishing `SOUL_FIRE`.
|
|
- Extinguishing lit `CAMPFIRE` blocks.
|
|
- Extinguishing lit `SOUL_CAMPFIRE` blocks.
|
|
- Water-bucket extinguishing when the affected fire can be attributed to the player who emptied the bucket.
|
|
- Controlled RoseFirefighter emergency fires, including fire that naturally spreads during the incident.
|
|
|
|
Only players currently working the configured JobsReborn `Firefighter` job can receive submitted JobsReborn rewards.
|
|
|
|
## Anti-farming behavior
|
|
|
|
With `rewards.anti-farm: true`, RoseFirefighter rejects payment for player-created fire, including:
|
|
|
|
- Flint-and-steel ignition.
|
|
- Fire-charge/direct player ignition.
|
|
- Fire started by a projectile shot by a player.
|
|
- Fire spread from a player-created fire.
|
|
- Fire caused by player-placed lava or tracked lava flow.
|
|
- Campfires a player relights and then extinguishes.
|
|
|
|
Active player-created fire and player-placed lava stay tainted while their sources remain active. Configurable retention timers remain afterward, and a separate location cooldown prevents duplicate payouts.
|
|
|
|
## Requirements
|
|
|
|
- Paper 26.2
|
|
- Java 25
|
|
- JobsReborn 5.2.6.x
|
|
- CMILib, as required by JobsReborn
|
|
- GriefPrevention 16.18.6+ (optional, but recommended for claim-aware dispatch and protected-property response)
|
|
- A JobsReborn-compatible economy if monetary payouts are desired
|
|
|
|
## Build
|
|
|
|
The repository includes the Gradle 9.6.1 Wrapper. A global Gradle installation is not required.
|
|
|
|
Windows:
|
|
|
|
```text
|
|
gradlew.bat clean build
|
|
```
|
|
|
|
Linux/macOS:
|
|
|
|
```text
|
|
./gradlew clean build
|
|
```
|
|
|
|
The resulting JAR is written to `build/libs/`.
|
|
|
|
## Install
|
|
|
|
1. Copy `jobs/Firefighter.yml` to `plugins/Jobs/jobs/Firefighter.yml`.
|
|
2. Reload JobsReborn or restart the server.
|
|
3. Copy the RoseFirefighter JAR into the server's `plugins/` directory.
|
|
4. Restart Paper.
|
|
5. Players can join with the normal JobsReborn command, for example `/jobs join Firefighter`.
|
|
|
|
## Duty controls
|
|
|
|
Firefighters are **on duty by default**. Duty state is persisted by UUID in `duty-status.yml`.
|
|
|
|
```text
|
|
/firefighter onduty
|
|
/firefighter offduty
|
|
/firefighter status
|
|
```
|
|
|
|
`/firefighter offduty` silences RoseFirefighter dispatch/lifecycle notifications for that Firefighter without forcing them to leave the JobsReborn job. Off-duty players retain emergency capability if they choose to respond manually, but they are not counted toward the minimum on-duty responders required to start an incident.
|
|
|
|
## JobsReborn payouts
|
|
|
|
`jobs/Firefighter.yml` contains the base income and job-XP values. RoseFirefighter does not calculate those amounts itself.
|
|
|
|
| Verified extinguish | JobsReborn action | Base income | Base job XP |
|
|
|---|---|---:|---:|
|
|
| `FIRE` | `BREAK/FIRE` | 1.00 | 1.00 |
|
|
| `SOUL_FIRE` | `BREAK/SOUL_FIRE` | 1.25 | 1.25 |
|
|
| `CAMPFIRE` | `COLLECT/CAMPFIRE` | 0.50 | 0.50 |
|
|
| `SOUL_CAMPFIRE` | `COLLECT/SOUL_CAMPFIRE` | 0.75 | 0.75 |
|
|
|
|
Emergency fires additionally apply `emergencies.reward-multiplier`, which defaults to `5`.
|
|
|
|
## Random incident dispatch
|
|
|
|
Fixed sites are optional. Automatic incidents and `/firefighter emergency start random` can select random locations without any configured sites.
|
|
|
|
When GriefPrevention is installed and `emergencies.random-locations.prefer-griefprevention-claims` is enabled, RoseFirefighter prefers a random top-level player-owned claim. The incident is labeled using the current/known claim owner, for example:
|
|
|
|
```text
|
|
🔥 FIRE ALERT! Fire reported at The_Rose94's home in world near X:123 Y:68 Z:-245.
|
|
```
|
|
|
|
On-duty Firefighters also receive a dispatch-detail line containing:
|
|
|
|
- Exact world and coordinates.
|
|
- Nearby GriefPrevention claim owners.
|
|
- Approximate distance to nearby claims, including `inside` when the incident is within the claim.
|
|
|
|
If no suitable player claim is available, RoseFirefighter can fall back to a random currently loaded world/chunk location and then to a configured fixed site. All of these behaviors are configurable.
|
|
|
|
## Fixed emergency sites
|
|
|
|
Fixed sites remain available for special locations or manual testing:
|
|
|
|
```text
|
|
/firefighter site add RoseGarden 18
|
|
/firefighter site remove <name>
|
|
/firefighter site list
|
|
/firefighter emergency start <site>
|
|
/firefighter emergency start random
|
|
/firefighter emergency stop
|
|
/firefighter reload
|
|
```
|
|
|
|
`rosefirefighter.admin` is required for site, emergency, and reload management and defaults to server operators.
|
|
|
|
## Natural fire spread and instant rollback
|
|
|
|
Emergency fire is allowed to behave naturally **inside the active response radius** when `emergencies.fire-spread` and `emergencies.fire-damage` are enabled.
|
|
|
|
RoseFirefighter treats the incident as a temporary world transaction:
|
|
|
|
- Initial emergency fires are tracked.
|
|
- Every naturally spread fire becomes another tracked emergency fire.
|
|
- Fire spread outside the incident boundary is cancelled.
|
|
- Before emergency fire changes or burns a block, RoseFirefighter captures the first pre-incident `BlockState` for that location.
|
|
- The first snapshot wins, so later changes cannot overwrite the original property state.
|
|
- Tile/block-entity state is retained.
|
|
- Container inventories are copied and protected from becoming duplicate fire loot before rollback.
|
|
- Fire-triggered TNT is blocked by default to prevent explosion chains from escaping the controlled incident boundary.
|
|
- Secondary physics damage is suppressed by default so falling blocks and support-dependent decorations do not create untracked damage or duplicate blocks.
|
|
|
|
When the incident is contained, manually stopped, expires, the plugin disables, or the server performs a normal shutdown, RoseFirefighter immediately:
|
|
|
|
1. Removes all remaining tracked emergency fire, including spread fire.
|
|
2. Removes/restores temporary Firefighter construction.
|
|
3. Restores forced-entry damage.
|
|
4. Restores all captured fire-damaged blocks to their first pre-incident state.
|
|
5. Restores preserved container contents.
|
|
6. Returns eligible temporary response-block items to the Firefighters who placed them.
|
|
|
|
Offline Firefighter item returns are saved in `pending-returns.yml` and delivered on the player's next join.
|
|
|
|
## GriefPrevention integration and forced entry
|
|
|
|
RoseFirefighter never enables `/IgnoreClaims` and never gives Firefighters a global `griefprevention.adminclaims` bypass.
|
|
|
|
Instead, during an active incident it uses GriefPrevention's claim-permission API to allow the temporary response permission only when:
|
|
|
|
- The player is working the JobsReborn Firefighter job.
|
|
- The emergency is active.
|
|
- The affected block is inside the active incident radius.
|
|
|
|
Inside that radius Firefighters can place response blocks, empty water buckets, extinguish fire, and—when `emergencies.forced-entry: true`—make temporary forced entry through protected doors, windows, walls, and other property.
|
|
|
|
Forced-entry blocks:
|
|
|
|
- Produce no item drops.
|
|
- Produce no XP.
|
|
- Are captured in the same first-state rollback ledger.
|
|
- Are automatically restored when the incident ends.
|
|
|
|
Temporary build access uses Bukkit runtime `PermissionAttachment` with `rosefirefighter.emergency.build`; it does not create permanent LuckPerms data.
|
|
|
|
## Emergency configuration highlights
|
|
|
|
`src/main/resources/config.yml` includes controls for:
|
|
|
|
- Emergency enable/disable and scheduling.
|
|
- Minimum **on-duty** Firefighters.
|
|
- Random claim/location dispatch.
|
|
- Fixed-site fallback.
|
|
- Nearby-claim reporting radius/count.
|
|
- Fire spread and fire damage.
|
|
- Instant fire-damage restoration.
|
|
- Fire-triggered TNT prevention.
|
|
- Secondary physics protection.
|
|
- Protected-site building.
|
|
- Forced entry.
|
|
- Temporary response-block cleanup and item return.
|
|
- Emergency duration and initial fire count.
|
|
- Emergency reward multiplier.
|
|
- Permitted worlds.
|
|
- Announcement behavior.
|
|
|
|
## Development dependencies
|
|
|
|
Paper 26.2:
|
|
|
|
```kotlin
|
|
compileOnly("io.papermc.paper:paper-api:26.2.build.+")
|
|
```
|
|
|
|
JobsReborn:
|
|
|
|
```kotlin
|
|
compileOnly("com.github.Zrips:Jobs:v5.2.6.2") {
|
|
isTransitive = false
|
|
}
|
|
```
|
|
|
|
GriefPrevention:
|
|
|
|
```kotlin
|
|
compileOnly("com.github.GriefPrevention:GriefPrevention:16.18.6") {
|
|
isTransitive = false
|
|
}
|
|
```
|