Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ Controls player vs player combat mechanics.
### `factions.nonMembersCanInteractWithDoors`
**Type:** Boolean
**Default:** `false`
**Description:** When `true`, non-faction members can open/close doors in faction territory.
**Description:** When `true`, non-faction members can open/close doors, trapdoors, and fence gates in faction territory.

### `factions.maxClaimRadius`
**Type:** Integer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.bukkit.block.DoubleChest
import org.bukkit.block.data.Bisected
import org.bukkit.block.data.Bisected.Half.BOTTOM
import org.bukkit.block.data.type.Door
import org.bukkit.block.data.type.Gate
import org.bukkit.block.data.type.TrapDoor
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
Expand Down Expand Up @@ -154,9 +155,9 @@ class PlayerInteractListener(private val plugin: MedievalFactions) : Listener {
}
}

// Handle door/trapdoor special case
// Handle door/trapdoor/fence gate special case
if (plugin.config.getBoolean("factions.nonMembersCanInteractWithDoors")) {
if (clickedBlock.blockData is Door || clickedBlock.blockData is TrapDoor) {
if (clickedBlock.blockData is Door || clickedBlock.blockData is TrapDoor || clickedBlock.blockData is Gate) {
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: blockData is already read into a local (val blockData = clickedBlock.blockData) earlier in this method. Reusing that variable here would avoid re-fetching clickedBlock.blockData three times and keeps the condition a bit cleaner.

Suggested change
if (clickedBlock.blockData is Door || clickedBlock.blockData is TrapDoor || clickedBlock.blockData is Gate) {
if (blockData is Door || blockData is TrapDoor || blockData is Gate) {

Copilot uses AI. Check for mistakes.
return
}
}
Comment on lines +158 to 163
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nonMembersCanInteractWithDoors early-return happens before the claim/wilderness lookup, so enabling this option currently bypasses wilderness interaction protection as well (and now does so for fence gates too). If the intent is “in faction territory” (per CONFIG.md), consider moving this special-case to after the claim is resolved (only apply it when claim != null).

Copilot uses AI. Check for mistakes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.bukkit.block.Block
import org.bukkit.block.BlockFace
import org.bukkit.block.data.BlockData
import org.bukkit.block.data.type.Door
import org.bukkit.block.data.type.Gate
import org.bukkit.block.data.type.TrapDoor
import org.bukkit.configuration.file.FileConfiguration
import org.bukkit.entity.Player
Expand Down Expand Up @@ -96,6 +97,21 @@ class PlayerInteractListenerTest {
verifyEventNotCancelled()
}

@Test
fun onPlayerInteract_FenceGateWithNonMembersCanInteractWithDoorsEnabled_ShouldAllowInteraction() {
// Arrange
mockBlockData<Gate>()
setupConfigForDoorInteraction(enabled = true)
setupPlayerMocks(fixture.player)
setupClaimAndFaction(fixture.block)

// Act
uut.onPlayerInteract(fixture.event)

// Assert - event should NOT be cancelled because fence gates are allowed
verifyEventNotCancelled()
}

@Test
fun onPlayerInteract_DoorWithNonMembersCanInteractWithDoorsDisabled_ShouldBlockInteraction() {
// Arrange
Expand Down
Loading