Skip to content

Commit

Permalink
Custom townblock types (#5388)
Browse files Browse the repository at this point in the history
* Initial custom townblock types draft

* Other fixes & javadocs

* Fix up PlayerCacheUtil

* Nuke the TownBlockType enum

* Reduce diff & fixes

* Migration start & fixes

* Finish migration code

* Re-add inventory support

* Add custom types to /plot set completions

* Fix up registration event

* Fix item orders in GUIs

* Fix up converting from old dbs

* Fix compile

* Fix towny gui regression

Fixes items not being added to the page if one was newly created.

* Fix wilds plots not working as intended

* Fix migrator NPE

* Add embassy to config

* Fix tax collection in the DailyTimerTask

* Replaces Towny's own usages of the deprecated getType() methods.

* Fix Config section creating in wrong place.

Moves it to just above the jail plot section.
Moves comments into the config section header, add more explanations.

* Cleanup on custom_types branch.

Mainly comments and javadocs, but also undoing a variable change in
PlotCommand.

* Separate UnclaimedZoneIgnoreIDs from Wilds plots.

Wilds plots get their own list, so that the /towny allowedblocks command
returns a proper list.

Updates the vastly out-of-date unclaimedZoneIgnoreIds list in the
config.

Removes wilds plot special case in PlayerCacheUtil.

* Add back plot set prices to /towny prices

* Add default values to the loading process

* Adjust version in deprecation notice

* Fix spacing, colouring and missing claimedat values in ascii map
hovering.

* Alter the GUI titles to more accurately reflect what is being asked and
represented.

* Adjust version reference from 0.97.5.3 to 0.97.5.4.

Co-authored-by: Llm Dl <LlmDlio@gmail.com>
  • Loading branch information
Warriorrrr and LlmDl authored Dec 21, 2021
1 parent 371dd8e commit d43780d
Show file tree
Hide file tree
Showing 31 changed files with 1,026 additions and 401 deletions.
11 changes: 6 additions & 5 deletions resources/lang/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1110,10 +1110,9 @@ towny_prices_price_shop: '&c &2Shop: &a%s &8| &2Embassy: &a%s'
towny_prices_taxes_plot: '&c [Taxes] &2Resident: &a%s &8| &2Plot: &a%s'
towny_prices_taxes_shop: '&c &2Shop: &a%s &8| &2Embassy: &a%s'
towny_prices_town_neutral_tax: '&c &2Peace: &a%s'
towny_prices_plots_shop: '&c [Setting Plots] &2Shop: &a%s &8| &2Embassy: &a%s'
towny_prices_plots_wilds: '&c &2Wilds: &a%s &8| &2Inn: &a%s'
towny_prices_plots_jail: '&c &2Jail: &a%s &8| &2Farm: &a%s'
towny_prices_plots_bank: '&c &2Bank: &a%s'
towny_prices_plots: '&c [Setting Plots]'
towny_prices_type_single: ' &2%s: &a%s'
towny_prices_type_double: ' &2%s: &a%s &8| &2%s: &a%s'
towny_prices_nationname: '&cNation: &6%s'
towny_prices_nation_tax: '&c [Taxes] &2Town: &a%s &8| &2Peace: &a%s'

Expand All @@ -1132,7 +1131,9 @@ msg_bankrupt: '&c(Bankrupt)'
#Added in 0.98
msg_del_town2: '&bThe town of %s has been deleted!'
msg_ruin_town: '&bThe town of %s fell into ruin!'
gui_title_towny_farmblocks: 'Towny FarmBlocks List'
gui_title_select_plot_type: 'Select PlotType'
gui_title_no_restrictions: 'No restrictions for this plottype.'
gui_title_towny_allowedblocks: '%s AllowedBlocks List'
gui_title_towny_wildsblocks: 'Towny WildsBlocks List'
gui_title_towny_itemuse: 'Towny ItemUse List'
gui_title_towny_switch: 'Towny Switch List'
Expand Down
86 changes: 39 additions & 47 deletions src/com/palmergames/bukkit/config/ConfigNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -720,13 +720,6 @@ public enum ConfigNodes {
"# Automatically precludes towns from one world joining a nation in another world.",
"# If the number is 0, towns will not a proximity to a nation."
),
GTOWN_FARM_PLOT_ALLOW_BLOCKS(
"global_town_settings.farm_plot_allow_blocks",
"BAMBOO,BAMBOO_SAPLING,JUNGLE_LOG,JUNGLE_SAPLING,JUNGLE_LEAVES,OAK_LOG,OAK_SAPLING,OAK_LEAVES,BIRCH_LOG,BIRCH_SAPLING,BIRCH_LEAVES,ACACIA_LOG,ACACIA_SAPLING,ACACIA_LEAVES,DARK_OAK_LOG,DARK_OAK_SAPLING,DARK_OAK_LEAVES,SPRUCE_LOG,SPRUCE_SAPLING,SPRUCE_LEAVES,BEETROOTS,COCOA,CHORUS_PLANT,CHORUS_FLOWER,SWEET_BERRY_BUSH,KELP,SEAGRASS,TALL_SEAGRASS,GRASS,TALL_GRASS,FERN,LARGE_FERN,CARROTS,WHEAT,POTATOES,PUMPKIN,PUMPKIN_STEM,ATTACHED_PUMPKIN_STEM,NETHER_WART,COCOA,VINE,MELON,MELON_STEM,ATTACHED_MELON_STEM,SUGAR_CANE,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,CRIMSON_STEM,CRIMSON_HYPHAE,CRIMSON_ROOTS,MUSHROOM_STEM,NETHER_WART_BLOCK,BROWN_MUSHROOM,BROWN_MUSHROOM_BLOCK,RED_MUSHROOM,RED_MUSHROOM_BLOCK,SHROOMLIGHT,WARPED_FUNGUS,WARPED_HYPHAE,WARPED_ROOTS,WARPED_STEM,WARPED_WART_BLOCK,WEEPING_VINES_PLANT,WEEPING_VINES,NETHER_SPROUTS,SHEARS",
"",
"# List of blocks which can be modified on farm plots, as long as player is also allowed in the plot's '/plot perm' line.",
"# Not included by default but some servers add GRASS_BLOCK,FARMLAND,DIRT,NETHERRACK,CRIMSON_NYLIUM,WARPED_NYLIUM to their list."
),
GTOWN_FARM_ANIMALS(
"global_town_settings.farm_animals",
"PIG,COW,CHICKEN,SHEEP,MOOSHROOM",
Expand Down Expand Up @@ -1448,10 +1441,10 @@ public enum ConfigNodes {
UNCLAIMED_ZONE_SWITCH("unclaimed.unclaimed_zone_switch",
"false",
"",
"# Can players interact with switch blocks listed in the above protectection.switch_ids in the wilderness without restriction?"),
"# Can players interact with switch blocks listed in the above protection.switch_ids in the wilderness without restriction?"),
UNCLAIMED_ZONE_IGNORE(
"unclaimed.unclaimed_zone_ignore",
"SAPLING,GOLD_ORE,IRON_ORE,COAL_ORE,LOG,LEAVES,LAPIS_ORE,LONG_GRASS,YELLOW_FLOWER,RED_ROSE,BROWN_MUSHROOM,RED_MUSHROOM,TORCH,DIAMOND_ORE,LADDER,RAILS,REDSTONE_ORE,GLOWING_REDSTONE_ORE,CACTUS,CLAY,SUGAR_CANE_BLOCK,PUMPKIN,GLOWSTONE,LOG_2,VINE,NETHER_WARTS,COCOA",
"GOLD_ORE,IRON_ORE,COAL_ORE,COPPER_ORE,REDSTONE_ORE,EMERALD_ORE,LAPIS_ORE,DIAMOND_ORE,DEEPSLATE_COAL_ORE,DEEPSLATE_IRON_ORE,DEEPSLATE_COPPER_ORE,DEEPSLATE_GOLD_ORE,DEEPSLATE_EMERALD_ORE,DEEPSLATE_REDSTONE_ORE,DEEPSLATE_LAPIS_ORE,DEEPSLATE_DIAMOND_ORE,NETHER_GOLD_ORE,NETHER_QUARTZ_ORE,ANCIENT_DEBRIS,OAK_LOG,SPRUCE_LOG,BIRCH_LOG,JUNGLE_LOG,ACACIA_LOG,DARK_OAK_LOG,CRIMSON_STEM,WARPED_STEM,ACACIA_LEAVES,OAK_LEAVES,DARK_OAK_LEAVES,JUNGLE_LEAVES,BIRCH_LEAVES,SPRUCE_LEAVES,CRIMSON_HYPHAE,WARPED_HYPHAE,ACACIA_SAPLING,BAMBOO_SAPLING,BIRCH_SAPLING,DARK_OAK_SAPLING,JUNGLE_SAPLING,OAK_SAPLING,SPRUCE_SAPLING,TALL_GRASS,BROWN_MUSHROOM,RED_MUSHROOM,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,LARGE_FERN,TORCH,LADDER,CLAY,PUMPKIN,GLOWSTONE,VINE,NETHER_WART_BLOCK,COCOA",
"",
"# A list of blocks that will bypass the above settings and do not require the towny.wild.* permission node.",
"# These blocks are also used in determining which blocks can be interacted with in Towny Wilds plots in towns."),
Expand Down Expand Up @@ -2221,43 +2214,6 @@ public enum ConfigNodes {
"false",
"",
"# Does a conquered town which cannot pay the nation tax get deleted?"),

ECO_PLOT_TYPE_COSTS("economy.plot_type_costs","",""),
ECO_PLOT_TYPE_COSTS_COMMERCIAL("economy.plot_type_costs.set_commercial",
"0.0",
"",
"# Cost to use /plot set shop to change a normal plot to a shop plot."),
ECO_PLOT_TYPE_COSTS_ARENA("economy.plot_type_costs.set_arena",
"0.0",
"",
"# Cost to use /plot set arena to change a normal plot to a arena plot."),
ECO_PLOT_TYPE_COSTS_EMBASSY("economy.plot_type_costs.set_embassy",
"0.0",
"",
"# Cost to use /plot set embassy to change a normal plot to a embassy plot."),
ECO_PLOT_TYPE_COSTS_WILDS("economy.plot_type_costs.set_wilds",
"0.0",
"",
"# Cost to use /plot set wilds to change a normal plot to a wilds plot."),
ECO_PLOT_TYPE_COSTS_INN("economy.plot_type_costs.set_inn",
"0.0",
"",
"# Cost to use /plot set inn to change a normal plot to a inn plot."),
ECO_PLOT_TYPE_COSTS_JAIL("economy.plot_type_costs.set_jail",
"0.0",
"",
"# Cost to use /plot set jail to change a normal plot to a jail plot."),
ECO_PLOT_TYPE_COSTS_FARM("economy.plot_type_costs.set_farm",
"0.0",
"",
"# Cost to use /plot set farm to change a normal plot to a farm plot."),
ECO_PLOT_TYPE_COSTS_BANK("economy.plot_type_costs.set_bank",
"0.0",
"",
"# Cost to use /plot set bank to change a normal plot to a bank plot."),
// ECO_PLOT_TYPE_COSTS_OUTPOST("economy.plot_type_costs.set_outpost",
// "0.0",
// "# Cost to use /plot set outpost to change a normal plot to a outpost plot."),

BANKHISTORY(
"bank_history",
Expand All @@ -2277,7 +2233,43 @@ public enum ConfigNodes {
"",
"# This allows you to modify the style displayed via bankhistory commands."
),

TOWNBLOCKTYPES(
"townblocktypes",
"",
"",
"",
"############################################################",
"# +------------------------------------------------------+ #",
"# | Town Block Types | #",
"# | | #",
"# | You may add your own custom townblocks to this | #",
"# | section of the config. Removing the townblocks | #",
"# | supplied by Towny from this configuration is not | #",
"# | recommended. | #",
"# | | #",
"# | name: The name used for this townblock, in-game and | #",
"# | in the database. | #",
"# | cost: Cost a player pays to set a townblock to the | #",
"# | type. If tax is set to 0, the towns' plot tax will| #",
"# | be used instead. | #",
"# | tax: The amount a player has to pay city each day to | #",
"# | continue owning the plot. | #",
"# | mapKey: The character that shows on the //towny map | #",
"# | commands. | #",
"# | itemUseIds: If empty, will use values defined in | #",
"# | protection.item_use_ids. If not empty this defines| #",
"# | what items are considered item_use. | #",
"# | switchIds: If empty, will use values defined in | #",
"# | protection.switch_ids. If not empty this defines | #",
"# | what blocks are considered switches in the type. | #",
"# | allowedBlocks: will make it so players with build or | #",
"# | destroy permissions are only able to affect those | #",
"# | blocks, see the farm type for an example. | #",
"# | | #",
"# +------------------------------------------------------+ #",
"############################################################",
""),
TOWNBLOCKTYPES_TYPES("townblocktypes.types", ""),
JAIL(
"jail",
"",
Expand Down
18 changes: 8 additions & 10 deletions src/com/palmergames/bukkit/config/migration/ConfigMigrator.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
import com.palmergames.bukkit.towny.object.TownyWorld;
import com.palmergames.bukkit.towny.permissions.TownyPerms;
import com.palmergames.bukkit.util.Version;
import java.io.InputStream;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* An object which manages the procces of migrating towny config versions to
* An object which manages the process of migrating towny config versions to
* up-to-date ones.
*/
public class ConfigMigrator {
Expand Down Expand Up @@ -107,15 +108,12 @@ private void addPermissions(String key, String value) {
}

private List<Migration> readMigrator() {
InputStream file = Towny.getPlugin().getResource(migrationFilename);

if (file == null) {
throw new UnsupportedOperationException(migrationFilename + " was not found cannot upgrade config");
try (Reader reader = new InputStreamReader(Towny.getPlugin().getResource(migrationFilename))) {

return GSON.fromJson(reader, new TypeToken<List<Migration>>(){}.getType());
} catch (IOException ignored) {
return null;
}

Reader reader = new InputStreamReader(file);

return GSON.fromJson(reader, new TypeToken<List<Migration>>(){}.getType());
}

public void addTownLevelProperty(String key, String value) {
Expand Down
4 changes: 2 additions & 2 deletions src/com/palmergames/bukkit/towny/ChunkNotification.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ public String getGroupNotification() {

public String getPlotTypeNotification() {

if (fromPlotType != toPlotType && toPlotType != null && toPlotType != TownBlockType.RESIDENTIAL)
return String.format(plotTypeNotificationFormat, toPlotType.toString());
if (toPlotType != null && !toPlotType.equals(fromPlotType) && !TownBlockType.RESIDENTIAL.equals(toPlotType))
return String.format(plotTypeNotificationFormat, StringMgmt.capitalize(toPlotType.getName()));
return null;
}
}
17 changes: 17 additions & 0 deletions src/com/palmergames/bukkit/towny/Towny.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.palmergames.bukkit.towny.object.Coord;
import com.palmergames.bukkit.towny.object.PlayerCache;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownBlockTypeHandler;
import com.palmergames.bukkit.towny.object.Translatable;
import com.palmergames.bukkit.towny.object.Translation;
import com.palmergames.bukkit.towny.object.WorldCoord;
Expand Down Expand Up @@ -230,6 +231,9 @@ public void onEnable() {
public void loadFoundation(boolean reload) {
// Before anything can continue we must load the databaseconfig, config
// file, language and permissions, setting the foundation for Towny.

// Handle any legacy config settings.
handleLegacyConfigs();

// Load the database config first, so any conversion happens before the config is loaded.
loadDatabaseConfig(reload);
Expand All @@ -240,6 +244,9 @@ public void loadFoundation(boolean reload) {
// Then load permissions
loadPermissions(reload);

// Initialize the type handler after the config is loaded and before the database is.
TownBlockTypeHandler.initialize();

// Initialize the special log4j hook logger.
TownyLogger.getInstance();

Expand Down Expand Up @@ -332,6 +339,16 @@ private void loadTownAndNationLevels() {
}
}

/**
* Handle any legacy config settings before we load the config and database.
*/
private void handleLegacyConfigs() {
// Old configs stored various TownBlock settings throughout the config.
// This will migrate the old settings into the TownBlockType config section.
// Since 0.97.5.4.
TownBlockTypeHandler.Migrator.checkForLegacyOptions();
}

/**
* Converts the older config.yml's database settings into the database.yml file.
* @return true if successful
Expand Down
48 changes: 30 additions & 18 deletions src/com/palmergames/bukkit/towny/TownyAsciiMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,44 +133,56 @@ else if (nation.hasEnemy(town.getNation()))
else
townyMap[y][x] = townyMap[y][x].content(townblock.getType().getAsciiMapKey());

TextComponent residentComponent = Component.empty();
TextComponent forSaleComponent = Component.empty();
TextComponent claimedAtComponent = Component.empty();
TextComponent groupComponent = Component.empty();

if (TownyEconomyHandler.isActive()) {
double cost;
if (townblock.hasPlotObjectGroup())
cost = townblock.getPlotObjectGroup().getPrice();
else
cost = townblock.getPlotPrice();

double cost = townblock.hasPlotObjectGroup()
? townblock.getPlotObjectGroup().getPrice()
: townblock.getPlotPrice();
if (cost > -1)
forSaleComponent = Component.text(String.format(ChunkNotification.forSaleNotificationFormat, TownyEconomyHandler.getFormattedBalance(cost)).replaceAll("[\\[\\]]", "") + " " + Translatable.of("msg_click_purchase").forLocale(player)).color(NamedTextColor.YELLOW).append(Component.newline());
}

if (townblock.getClaimedAt() > 0)
claimedAtComponent = Component.text(Translatable.of("msg_plot_perm_claimed_at", TownyFormatter.registeredFormat.format(townblock.getClaimedAt())).forLocale(player)).append(Component.newline());

if (townblock.hasPlotObjectGroup()) {
claimedAtComponent = Component.text(Translatable.of("msg_plot_perm_claimed_at").forLocale(player)).color(NamedTextColor.DARK_GREEN)
.append(Component.space())
.append(Component.text(TownyFormatter.registeredFormat.format(townblock.getClaimedAt())).color(NamedTextColor.GREEN))
.append(Component.newline());

if (townblock.hasPlotObjectGroup())
groupComponent = Component.text(Translatable.of("map_hover_plot_group").forLocale(player)).color(NamedTextColor.DARK_GREEN)
.append(Component.text(townblock.getPlotObjectGroup().getFormattedName()).color(NamedTextColor.GREEN)
.append(Component.text(Translatable.of("map_hover_plot_group_size").forLocale(player)).color(NamedTextColor.DARK_GREEN)
.append(Component.text(Translatable.of("map_hover_plots", townblock.getPlotObjectGroup().getTownBlocks().size()).forLocale(player)).color(NamedTextColor.GREEN)
.append(Component.newline()))));
}


TextComponent hoverComponent = Component.text(Translatable.of("status_town").forLocale(player) + town.getName() + (townblock.hasResident() ? " (" + townblock.getResidentOrNull().getName() + ")" : "")).color(NamedTextColor.GREEN).append(Component.text(" (" + tby + ", " + tbx + ")").color(NamedTextColor.WHITE)).append(Component.newline())
.append(Component.text(Translatable.of("status_plot_type").forLocale(player)).color(NamedTextColor.DARK_GREEN).append(Component.text(townblock.getType().getName()).color(NamedTextColor.GREEN).append(Component.newline())
if (townblock.hasResident())
residentComponent = Component.text(" (" + townblock.getResidentOrNull().getName() + ")");

TextComponent townComponent = Component.text(Translatable.of("status_town").forLocale(player)).color(NamedTextColor.DARK_GREEN)
.append(Component.space())
.append(Component.text(town.getName()).color(NamedTextColor.GREEN))
.append(residentComponent.color(NamedTextColor.GREEN))
.append(Component.text(" (" + tby + ", " + tbx + ")").color(NamedTextColor.WHITE)).append(Component.newline());

TextComponent plotTypeComponent = Component.text(Translatable.of("status_plot_type").forLocale(player)).color(NamedTextColor.DARK_GREEN)
.append(Component.space())
.append(Component.text(townblock.getType().getName()).color(NamedTextColor.GREEN).append(Component.newline()));

TextComponent hoverComponent = townComponent
.append(plotTypeComponent)
.append(groupComponent)
.append(forSaleComponent)
.append(claimedAtComponent)
.append(Component.text(Translatable.of("towny_map_detailed_information").forLocale(player)).color(NamedTextColor.DARK_GREEN))));
.append(Component.text(Translatable.of("towny_map_detailed_information").forLocale(player)).color(NamedTextColor.DARK_GREEN));

ClickEvent clickEvent = forSaleComponent.equals(Component.empty())
? ClickEvent.runCommand("/towny:plot info " + tby + " " + tbx)
: ClickEvent.runCommand("/towny:plot claim " + world.getName() + " x" + tby + " z" + tbx);

ClickEvent clickEvent = ClickEvent.runCommand("/towny:plot info " + tby + " " + tbx);
if (!forSaleComponent.equals(Component.empty()))
clickEvent = ClickEvent.runCommand("/towny:plot claim " + world.getName() + " x" + tby + " z" + tbx);

townyMap[y][x] = townyMap[y][x].hoverEvent(HoverEvent.showText(hoverComponent)).clickEvent(clickEvent);
} catch (TownyException e) {
// Unregistered town block (Wilderness)
Expand Down
Loading

0 comments on commit d43780d

Please sign in to comment.