Adds bonus range elements to Island object. (#1921)

* Adds bonus range elements to Island object.

Admin commands still need to be adjusted or added to support management
of the bonus ranges.

* Changed to mutable class

Fixed bugs.
This commit is contained in:
tastybento 2022-01-28 18:35:55 -08:00 committed by GitHub
parent 54869a400a
commit 7b94aa0ea2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 185 additions and 12 deletions

View File

@ -270,6 +270,11 @@
<artifactId>GitHubWebAPI4Java</artifactId> <artifactId>GitHubWebAPI4Java</artifactId>
<version>${githubapi.version}</version> <version>${githubapi.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.Marcono1234</groupId>
<artifactId>gson-record-type-adapter-factory</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Static analysis --> <!-- Static analysis -->
<!-- We are using Eclipse's annotations. If you're using IDEA, update <!-- We are using Eclipse's annotations. If you're using IDEA, update
your project settings to take these into account for in real time static your project settings to take these into account for in real time static

View File

@ -56,7 +56,7 @@ public class AdminRangeAddCommand extends CompositeCommand {
Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID));
int newRange = island.getProtectionRange() + Integer.parseInt(args.get(1)); int newRange = island.getProtectionRange() + Integer.parseInt(args.get(1));
if (newRange > island.getRange() * 2) { if (newRange > island.getRange()) {
user.sendMessage("commands.admin.range.invalid-value.too-high", TextVariables.NUMBER, String.valueOf(island.getRange())); user.sendMessage("commands.admin.range.invalid-value.too-high", TextVariables.NUMBER, String.valueOf(island.getRange()));
return false; return false;
} else if (newRange == island.getProtectionRange()) { } else if (newRange == island.getProtectionRange()) {

View File

@ -0,0 +1,67 @@
package world.bentobox.bentobox.database.objects;
import com.google.gson.annotations.Expose;
/**
* Record for bonus ranges
* @author tastybento
* @param id an id to identify this bonus
* @param range the additional bonus range
* @param message the reference key to a locale message related to this bonus. May be blank.
*/
public class BonusRangeRecord {
@Expose
private String uniqueId;
@Expose
private int range;
@Expose
private String message;
/**
* @param uniqueId
* @param range
* @param message
*/
public BonusRangeRecord(String uniqueId, int range, String message) {
this.uniqueId = uniqueId;
this.range = range;
this.message = message;
}
/**
* @return the uniqueId
*/
public String getUniqueId() {
return uniqueId;
}
/**
* @param uniqueId the uniqueId to set
*/
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
/**
* @return the range
*/
public int getRange() {
return range;
}
/**
* @param range the range to set
*/
public void setRange(int range) {
this.range = range;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
/**
* @param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -1,6 +1,7 @@
package world.bentobox.bentobox.database.objects; package world.bentobox.bentobox.database.objects;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -91,6 +92,13 @@ public class Island implements DataObject, MetaDataAble {
@Expose @Expose
private int protectionRange; private int protectionRange;
/**
* Bonuses to protection range
* @since 1.20.0
*/
@Expose
private List<BonusRangeRecord> bonusRanges = new ArrayList<>();
// Maximum ever protection range - used in island deletion // Maximum ever protection range - used in island deletion
@Expose @Expose
private int maxEverProtectionRange; private int maxEverProtectionRange;
@ -272,6 +280,7 @@ public class Island implements DataObject, MetaDataAble {
this.uniqueId = island.getUniqueId(); this.uniqueId = island.getUniqueId();
this.updatedDate = island.getUpdatedDate(); this.updatedDate = island.getUpdatedDate();
this.world = island.getWorld(); this.world = island.getWorld();
this.bonusRanges.addAll(island.getBonusRanges());
this.setChanged(); this.setChanged();
} }
@ -534,12 +543,22 @@ public class Island implements DataObject, MetaDataAble {
} }
/** /**
* Returns the protection range of this Island. * Returns the protection range of this Island plus any bonuses. Will not be greater than getRange().
* This represents half of the length of the side of a theoretical square around the island center inside which flags are enforced. * This represents half of the length of the side of a theoretical square around the island center inside which flags are enforced.
* @return the protection range of this island, strictly positive integer. * @return the protection range of this island, strictly positive integer.
* @see #getRange() * @see #getRange()
*/ */
public int getProtectionRange() { public int getProtectionRange() {
return Math.min(this.getRange(), getRawProtectionRange() + this.getBonusRanges().stream().mapToInt(BonusRangeRecord::getRange).sum());
}
/**
* Returns the protection range of this Island without any bonuses
* This represents half of the length of the side of a theoretical square around the island center inside which flags are enforced.
* @return the protection range of this island, strictly positive integer.
* @since 1.20.0
*/
public int getRawProtectionRange() {
return protectionRange; return protectionRange;
} }
@ -549,15 +568,21 @@ public class Island implements DataObject, MetaDataAble {
public int getMaxEverProtectionRange() { public int getMaxEverProtectionRange() {
if (maxEverProtectionRange > this.range) { if (maxEverProtectionRange > this.range) {
maxEverProtectionRange = this.range; maxEverProtectionRange = this.range;
setChanged();
} }
return Math.max(protectionRange, maxEverProtectionRange); return Math.max(protectionRange, maxEverProtectionRange);
} }
/** /**
* Sets the maximum protection range. This can be used to optimize
* island deletion. Setting this values to a lower value than the current value
* will have no effect.
* @param maxEverProtectionRange the maxEverProtectionRange to set * @param maxEverProtectionRange the maxEverProtectionRange to set
*/ */
public void setMaxEverProtectionRange(int maxEverProtectionRange) { public void setMaxEverProtectionRange(int maxEverProtectionRange) {
this.maxEverProtectionRange = maxEverProtectionRange; if (maxEverProtectionRange > this.maxEverProtectionRange) {
this.maxEverProtectionRange = maxEverProtectionRange;
}
if (maxEverProtectionRange > this.range) { if (maxEverProtectionRange > this.range) {
this.maxEverProtectionRange = this.range; this.maxEverProtectionRange = this.range;
} }
@ -1354,7 +1379,7 @@ public class Island implements DataObject, MetaDataAble {
} }
/** /**
* Indicates the class has been changed * Indicates the fields have been changed. Used to optimize saving on shutdown.
*/ */
public void setChanged() { public void setChanged() {
this.changed = true; this.changed = true;
@ -1534,6 +1559,73 @@ public class Island implements DataObject, MetaDataAble {
getMaxMembers().put(rank, maxMembers); getMaxMembers().put(rank, maxMembers);
} }
/**
* @return the bonusRanges
*/
public List<BonusRangeRecord> getBonusRanges() {
if (bonusRanges == null) {
this.setBonusRanges(new ArrayList<>());
}
return bonusRanges;
}
/**
* @param bonusRanges the bonusRanges to set
*/
public void setBonusRanges(List<BonusRangeRecord> bonusRanges) {
this.bonusRanges = bonusRanges;
setChanged();
}
/**
* Get the bonus range provided by all settings of the range giver
* @param id an id to identify this bonus
* @return bonus range, or 0 if unknown
*/
public int getBonusRange(String id) {
return this.getBonusRanges().stream().filter(r -> r.getUniqueId().equals(id)).mapToInt(BonusRangeRecord::getRange).sum();
}
/**
* Get the BonusRangeRecord for uniqueId
* @param uniqueId a unique id to identify this bonus
* @return optional BonusRangeRecord
*/
public Optional<BonusRangeRecord> getBonusRangeRecord(String uniqueId) {
return this.getBonusRanges().stream().filter(r -> r.getUniqueId().equals(uniqueId)).findFirst();
}
/**
* Add a bonus range amount to the island for this addon or plugin.
* Note, this will not replace any range set already with the same id
* @param id an id to identify this bonus
* @param range range to add to the island protected range
* @param message the reference key to a locale message related to this bonus. May be blank.
*/
public void addBonusRange(String id, int range, String message) {
this.getBonusRanges().add(new BonusRangeRecord(id, range, message));
setMaxEverProtectionRange(this.getProtectionRange());
setChanged();
}
/**
* Clear the bonus ranges for a unique ID
* @param id id to identify this bonus
*/
public void clearBonusRange(String id) {
this.getBonusRanges().removeIf(r -> r.getUniqueId().equals(id));
setChanged();
}
/**
* Clear all bonus ranges for this island
*/
public void clearAllBonusRanges() {
this.getBonusRanges().clear();
setChanged();
}
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */

View File

@ -219,20 +219,17 @@ public class JoinLeaveListener implements Listener {
Island island = plugin.getIslands().getIsland(world, user); Island island = plugin.getIslands().getIsland(world, user);
if (island != null) { if (island != null) {
// Check if new owner has a different range permission than the island size // Check if new owner has a different range permission than the island size
int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.range", island.getProtectionRange()); int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.range", island.getRawProtectionRange());
// Range cannot be greater than the island distance // Range cannot be greater than the island distance
range = Math.min(range, plugin.getIWM().getIslandDistance(island.getWorld())); range = Math.min(range, plugin.getIWM().getIslandDistance(island.getWorld()));
// Range can go up or down // Range can go up or down
if (range != island.getProtectionRange()) { if (range != island.getRawProtectionRange()) {
user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range)); user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range));
plugin.log("Island protection range changed from " + island.getProtectionRange() + " to "
+ range + " for " + user.getName() + " due to permission.");
// Get old range for event
int oldRange = island.getProtectionRange(); int oldRange = island.getProtectionRange();
island.setProtectionRange(range); island.setProtectionRange(range);
plugin.log("Island protection range changed from " + oldRange + " to "
+ island.getProtectionRange() + " for " + user.getName() + " due to permission.");
// Call Protection Range Change event. Does not support canceling. // Call Protection Range Change event. Does not support canceling.
IslandEvent.builder() IslandEvent.builder()
.island(island) .island(island)
@ -240,7 +237,7 @@ public class JoinLeaveListener implements Listener {
.reason(IslandEvent.Reason.RANGE_CHANGE) .reason(IslandEvent.Reason.RANGE_CHANGE)
.involvedPlayer(user.getUniqueId()) .involvedPlayer(user.getUniqueId())
.admin(true) .admin(true)
.protectionRange(range, oldRange) .protectionRange(island.getProtectionRange(), oldRange)
.build(); .build();
} }
} }

View File

@ -74,6 +74,16 @@ public class IslandInfo {
user.sendMessage("commands.admin.info.island-center", TextVariables.XYZ, Util.xyz(island.getCenter().toVector())); user.sendMessage("commands.admin.info.island-center", TextVariables.XYZ, Util.xyz(island.getCenter().toVector()));
user.sendMessage("commands.admin.info.island-coords", "[xz1]", Util.xyz(new Vector(island.getMinX(), 0, island.getMinZ())), "[xz2]", Util.xyz(new Vector(island.getMaxX(), 0, island.getMaxZ()))); user.sendMessage("commands.admin.info.island-coords", "[xz1]", Util.xyz(new Vector(island.getMinX(), 0, island.getMinZ())), "[xz2]", Util.xyz(new Vector(island.getMaxX(), 0, island.getMaxZ())));
user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(island.getProtectionRange())); user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(island.getProtectionRange()));
if (!island.getBonusRanges().isEmpty()) {
user.sendMessage("commands.admin.info.protection-range-bonus-title");
}
island.getBonusRanges().forEach(brb -> {
if (brb.getMessage().isBlank()) {
user.sendMessage("commands.admin.info.protection-range-bonus", TextVariables.NUMBER, String.valueOf(brb.getRange()));
} else {
user.sendMessage(brb.getMessage(), TextVariables.NUMBER, String.valueOf(brb.getRange()));
}
});
user.sendMessage("commands.admin.info.max-protection-range", "[range]", String.valueOf(island.getMaxEverProtectionRange())); user.sendMessage("commands.admin.info.max-protection-range", "[range]", String.valueOf(island.getMaxEverProtectionRange()));
user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX() - 1, 0, island.getMaxProtectedZ() - 1))); user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX() - 1, 0, island.getMaxProtectedZ() - 1)));
if (island.isSpawn()) { if (island.isSpawn()) {

View File

@ -199,6 +199,8 @@ commands:
island-coords: "Island coordinates: [xz1] to [xz2]" island-coords: "Island coordinates: [xz1] to [xz2]"
islands-in-trash: "&d Player has islands in trash." islands-in-trash: "&d Player has islands in trash."
protection-range: "Protection range: [range]" protection-range: "Protection range: [range]"
protection-range-bonus-title: "&b Includes these bonues:"
protection-range-bonus: "Bonus: [number]"
purge-protected: "Island is purge protected" purge-protected: "Island is purge protected"
max-protection-range: "Largest historical protection range: [range]" max-protection-range: "Largest historical protection range: [range]"
protection-coords: "Protection coordinates: [xz1] to [xz2]" protection-coords: "Protection coordinates: [xz1] to [xz2]"