Skip to content

Commit

Permalink
Fix banner placement bug (#844)
Browse files Browse the repository at this point in the history
* Bug fix related to banner placement

* formatting

* Remove unused imports

* Simplified some logic

* Cleanups

---------

Co-authored-by: Goosius1 <[email protected]>
  • Loading branch information
Goosius1 and Goosius1 authored Jun 2, 2023
1 parent 4e8decf commit 57f1920
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 63 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.goosius</groupId>
<artifactId>SiegeWar</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
<name>siegewar</name> <!-- Leave lower-cased -->

<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@
import org.bukkit.Tag;
import org.bukkit.block.Banner;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;

import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
Expand Down Expand Up @@ -133,10 +132,10 @@ private static boolean evaluatePlaceStandingBanner(Player player, Block block) t
//Get resident's town and possibly their nation
Town residentsTown = resident.getTownOrNull();
Nation residentsNation = resident.getNationOrNull();
//Ensure there is at least 1 adjacent town
Map<BlockFace, TownBlock> adjacentCardinalTownBlocks = SiegeWarBlockUtil.getCardinalAdjacentTownBlocks(block);
Map<BlockFace, TownBlock> adjacentNonCardinalTownBlocks = SiegeWarBlockUtil.getNonCardinalAdjacentTownBlocks(block);

//On the COORD grid, find any townblocks adjacent to the COORD which this block is in
List<TownBlock> adjacentCardinalTownBlocks = SiegeWarBlockUtil.getCardinalAdjacentTownBlocks(block);
List<TownBlock> adjacentNonCardinalTownBlocks = SiegeWarBlockUtil.getNonCardinalAdjacentTownBlocks(block);
if(adjacentCardinalTownBlocks.size() == 0 && adjacentNonCardinalTownBlocks.size() == 0)
return false;

Expand All @@ -158,25 +157,25 @@ private static boolean evaluatePlaceStandingBanner(Player player, Block block) t
//This
if (adjacentCardinalTownBlocks.size() > 1)
throw new TownyException(translator.of("msg_err_siege_war_too_many_adjacent_towns"));

//Get 1st nearby townblock
TownBlock townBlock = null;
BlockFace directionToTownBlock = null;
Map<BlockFace,TownBlock> allNearbyTownBlocks = new HashMap<>();
allNearbyTownBlocks.putAll(adjacentCardinalTownBlocks);
allNearbyTownBlocks.putAll(adjacentNonCardinalTownBlocks);
for(Map.Entry<BlockFace,TownBlock> mapEntry: allNearbyTownBlocks.entrySet()) {
directionToTownBlock = mapEntry.getKey();
townBlock = mapEntry.getValue();
break;

TownBlock townBlock;
if(SiegeWarSettings.isBesiegedTownTownTrapWarfareMitigationEnabled()
&& SiegeWarSettings.isBannerAtTownBorderEnabled()) {
/*
* Ensure the banner is just one block away from the target townblock
* On the minecraft LOCATION GRID, find the first adjacent townblock, if any
*/
townBlock = SiegeWarDistanceUtil.findFirstValidTownBlockAdjacentToMinecraftBlock(block);
if(townBlock == null)
throw new TownyException(translator.of("msg_err_banner_cannot_be_more_than_one_block_away"));
} else {
//Just get one of the adjacent townblocks
List<TownBlock> allTownBlocks = new ArrayList<>();
allTownBlocks.addAll(adjacentCardinalTownBlocks);
allTownBlocks.addAll(adjacentNonCardinalTownBlocks);
townBlock = allTownBlocks.get(0);
}

//Ensure the banner is just one block away from the target townblock
if(SiegeWarSettings.isBesiegedTownTownTrapWarfareMitigationEnabled()
&& SiegeWarSettings.isBannerAtTownBorderEnabled()
&& !SiegeWarDistanceUtil.isDistanceToTownBlockOne(block.getLocation(), townBlock, directionToTownBlock))
throw new TownyException(translator.of("msg_err_banner_cannot_be_more_than_one_block_away"));

if (isWhiteBanner(block)) {
evaluatePlaceWhiteBannerNearTown(player, residentsTown, residentsNation, townBlock.getTownOrNull());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -35,8 +34,8 @@ public class SiegeWarBlockUtil {
*/
public static List<TownBlock> getAllAdjacentTownBlocks(Block block) {
List<TownBlock> result = new ArrayList<>();
result.addAll(getCardinalAdjacentTownBlocks(block).values());
result.addAll(getNonCardinalAdjacentTownBlocks(block).values());
result.addAll(getCardinalAdjacentTownBlocks(block));
result.addAll(getNonCardinalAdjacentTownBlocks(block));
return result;
}

Expand All @@ -59,13 +58,13 @@ public static Set<Siege> getAllAdjacentSieges(Block block) {
* @param block the block to start from
* @return list of adjacent cardinal townblocks
*/
public static Map<BlockFace, TownBlock> getCardinalAdjacentTownBlocks(Block block) {
Map<BlockFace, WorldCoord> coOrdinates = new HashMap<>();
public static List<TownBlock> getCardinalAdjacentTownBlocks(Block block) {
Set<WorldCoord> coOrdinates = new HashSet<>();
WorldCoord startingCoOrdinate = WorldCoord.parseWorldCoord(block);
coOrdinates.put(BlockFace.NORTH,startingCoOrdinate.add(0,-1));
coOrdinates.put(BlockFace.SOUTH,startingCoOrdinate.add(0,1));
coOrdinates.put(BlockFace.EAST,startingCoOrdinate.add(1,0));
coOrdinates.put(BlockFace.WEST,startingCoOrdinate.add(-1,0));
coOrdinates.add(startingCoOrdinate.add(0,-1));
coOrdinates.add(startingCoOrdinate.add(0,1));
coOrdinates.add(startingCoOrdinate.add(1,0));
coOrdinates.add(startingCoOrdinate.add(-1,0));
return getTownBlocks(coOrdinates);
}

Expand All @@ -75,21 +74,22 @@ public static Map<BlockFace, TownBlock> getCardinalAdjacentTownBlocks(Block bloc
* @param block the block to start from
* @return list of adjacent noncardinal townblocks
*/
public static Map<BlockFace, TownBlock> getNonCardinalAdjacentTownBlocks(Block block) {
Map<BlockFace, WorldCoord> coOrdinates = new HashMap<>();
public static List<TownBlock> getNonCardinalAdjacentTownBlocks(Block block) {
Set<WorldCoord> coOrdinates = new HashSet<>();
WorldCoord startingCoOrdinate = WorldCoord.parseWorldCoord(block);
coOrdinates.put(BlockFace.SOUTH_WEST, startingCoOrdinate.add(-1,1));
coOrdinates.put(BlockFace.SOUTH_EAST, startingCoOrdinate.add(1,1));
coOrdinates.put(BlockFace.NORTH_EAST, startingCoOrdinate.add(1,-1));
coOrdinates.put(BlockFace.NORTH_WEST, startingCoOrdinate.add(-1,-1));
coOrdinates.add(startingCoOrdinate.add(-1,1));
coOrdinates.add(startingCoOrdinate.add(1,1));
coOrdinates.add(startingCoOrdinate.add(1,-1));
coOrdinates.add(startingCoOrdinate.add(-1,-1));
return getTownBlocks(coOrdinates);
}

private static Map<BlockFace, TownBlock> getTownBlocks(Map<BlockFace, WorldCoord> coords) {
Map<BlockFace, TownBlock> result = new HashMap<>();
for(Map.Entry<BlockFace, WorldCoord> mapEntry: coords.entrySet()) {
if(mapEntry.getValue().hasTownBlock()) {
result.put(mapEntry.getKey(), mapEntry.getValue().getTownBlockOrNull());
//Get any valid townblocks at the given coords
private static List<TownBlock> getTownBlocks(Set<WorldCoord> coords) {
List<TownBlock> result = new ArrayList<>();
for(WorldCoord worldCoord: coords) {
if(worldCoord.hasTownBlock() && worldCoord.getTownBlockOrNull().hasTown()) {
result.add(worldCoord.getTownBlockOrNull());
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.bukkit.towny.object.TownyWorld;
import com.palmergames.bukkit.towny.object.Translatable;
import com.palmergames.bukkit.towny.object.WorldCoord;
import com.palmergames.util.MathUtil;

import org.bukkit.Bukkit;
Expand Down Expand Up @@ -326,22 +327,21 @@ && areTownBlocksClose(town.getHomeBlockOrNull(), townBlock, radiusInTownBlocks))
return result;
}

/**
*
* @param location location
* @param townBlock townblock
* @param directionToTownBlock direction from the location to the townblock
*
* @return true if the location is a distance of 1 from the townblock
*/
public static boolean isDistanceToTownBlockOne(Location location, TownBlock townBlock, BlockFace directionToTownBlock) {
Coord coordOfLocation = Coord.parseCoord(location);
if (coordOfLocation.equals(townBlock.getCoord()))
return false; //Location is in the target townblock

//Move location in the given direction, and return true if it ends up in the target townblock
Location transposedLocation = location.add(directionToTownBlock.getModX(), 0, directionToTownBlock.getModZ());
Coord coordOfTransposedLocation = Coord.parseCoord(transposedLocation);
return coordOfTransposedLocation.equals(townBlock.getCoord());
public static TownBlock findFirstValidTownBlockAdjacentToMinecraftBlock(Block block) {
int[] x = new int[]{-1,0,1,-1,1,-1,0,1};
int[] z = new int[]{-1,-1,-1,0,0,1,1,1};
Block adjacentBlock;
for(int i = 0; i < 8; i ++) {
adjacentBlock = block.getRelative(x[i], 0, z[i]);
if(!TownyAPI.getInstance().isWilderness(adjacentBlock)) {
//Adjacent townblock found
WorldCoord adjacentWorldCoord = WorldCoord.parseWorldCoord(adjacentBlock);
TownBlock adjacentTownBlock = TownyAPI.getInstance().getTownBlock(adjacentWorldCoord);
if(adjacentTownBlock != null && adjacentTownBlock.hasTown()) {
return adjacentTownBlock;
}
}
}
return null;
}
}

0 comments on commit 57f1920

Please sign in to comment.