Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,30 @@ public void setUseBankAccount(boolean useBankAccount)
}


/**
* Is acid island aware boolean.
*
* @return {@code true} if the addon must not replace blocks that AcidIsland reverts to water.
* @since 2.10.0
*/
public boolean isAcidIslandAware()
{
return acidIslandAware;
}


/**
* Sets acid island aware.
*
* @param acidIslandAware new value for this object.
* @since 2.10.0
*/
public void setAcidIslandAware(boolean acidIslandAware)
{
this.acidIslandAware = acidIslandAware;
}


/**
* Gets the default number of blocks a generator is allowed to generate during a single exhaustion period.
*
Expand Down Expand Up @@ -558,6 +582,17 @@ public enum GuiAction
@ConfigEntry(path = "use-bank-account")
private boolean useBankAccount = false;

@ConfigComment("")
@ConfigComment("This indicates if the addon should respect AcidIsland acid water.")
@ConfigComment("AcidIsland turns stone, that is created when lava pours into its acid water, back")
@ConfigComment("into water. If this option is enabled, the addon will not process such blocks, so")
@ConfigComment("a single lava bucket cannot be used to convert an entire ocean into generator")
@ConfigComment("blocks. Normal cobblestone generators are not affected by this option.")
@ConfigComment("This option does nothing in worlds that are not managed by AcidIsland, or if acid")
@ConfigComment("damage is disabled in the AcidIsland config.")
@ConfigEntry(path = "acid-island-aware")
private boolean acidIslandAware = true;

@ConfigComment("")
@ConfigComment("This list stores GameModes in which the addon should not work.")
@ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.magiccobblestonegenerator.StoneGeneratorAddon;
import world.bentobox.magiccobblestonegenerator.utils.AcidIslandHelper;
import world.bentobox.magiccobblestonegenerator.utils.CustomBlocks;
import world.bentobox.magiccobblestonegenerator.utils.Why;

Expand Down Expand Up @@ -70,6 +71,19 @@ public void onBlockFormEvent(BlockFormEvent event)

Island island = islandOptional.get();

if (this.addon.getSettings().isAcidIslandAware() &&
event.getNewState().getType() == Material.STONE &&
eventSourceBlock.getType() == Material.WATER &&
AcidIslandHelper.revertsStoneFormedInWater(this.addon, eventSourceBlock.getWorld()))
{
// Lava poured into acid water. AcidIsland turns this stone back into water on the next
// tick, but only if it is still stone. Replacing it would defeat that protection and
// allow whole oceans to be converted into generator blocks.
Why.report(island, eventSourceBlock.getLocation(),
"AcidIsland reverts stone that is formed in acid water!");
return;
}

if (!island.isAllowed(StoneGeneratorAddon.MAGIC_COBBLESTONE_GENERATOR))
{
// Currently addon is not working outside island protection ranges.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
//
// Created by BONNe
// Copyright - 2020
//


package world.bentobox.magiccobblestonegenerator.utils;


import java.lang.reflect.Method;
import java.util.Optional;

import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.magiccobblestonegenerator.StoneGeneratorAddon;


/**
* Helper that detects if AcidIsland is going to undo a block that this addon is about to replace.
* <p>
* AcidIsland water is acid, so its LavaCheck listener turns stone that vanilla creates when lava
* pours into water back into water again. It does that by checking, one tick later, if the block is
* stone. If this addon replaces the forming stone with a generator block, that check no longer
* matches and the block survives, which lets a single lava bucket turn an entire ocean into
* generator blocks.
* <p>
* AcidIsland is only a soft dependency, so the game mode is recognised by its name and the acid
* damage value is read reflectively. That also keeps this working if AcidIsland is not installed at
* all.
*
* @since 2.10.0
*/
public final class AcidIslandHelper
{
/**
* Private constructor. This is a utility class.
*/
private AcidIslandHelper()
{
// Utility class.
}


/**
* This method returns if AcidIsland manages the given world and will revert stone that is formed
* inside its acid water back to water.
*
* @param addon Instance of this addon.
* @param world World where the block is formed.
* @return {@code true} if AcidIsland will revert the formed stone, {@code false} otherwise.
*/
public static boolean revertsStoneFormedInWater(@NotNull StoneGeneratorAddon addon, @NotNull World world)
{
Optional<GameModeAddon> gameMode = addon.getPlugin().getIWM().getAddon(world);

if (gameMode.isEmpty() || !ACID_ISLAND.equals(gameMode.get().getDescription().getName()))
{
// Not an AcidIsland world.
return false;
}

// AcidIsland reverts the stone only if acid actually does damage.
return getAcidDamage(gameMode.get().getWorldSettings()) > 0;
}


/**
* This method returns the acid damage value from AcidIsland world settings.
*
* @param worldSettings World settings of the AcidIsland game mode.
* @return Acid damage value or 0 if it could not be read.
*/
private static int getAcidDamage(@Nullable WorldSettings worldSettings)
{
if (worldSettings == null)
{
return 0;
}

Method method = getAcidDamageMethod(worldSettings.getClass());

if (method == null)
{
return 0;
}

try
{
return ((Number) method.invoke(worldSettings)).intValue();
}
catch (ReflectiveOperationException | ClassCastException | NullPointerException e)
{
return 0;
}
}


/**
* This method returns the cached acid damage getter for the given world settings class.
*
* @param settingsClass Class of the AcidIsland world settings.
* @return The getter method or {@code null} if the class does not have one.
*/
@Nullable
private static Method getAcidDamageMethod(@NotNull Class<?> settingsClass)
{
if (settingsClass.equals(cachedSettingsClass))
{
return cachedAcidDamageMethod;
}

Method method;

try
{
method = settingsClass.getMethod(ACID_DAMAGE_GETTER);
}
catch (NoSuchMethodException | SecurityException e)
{
method = null;
}

cachedSettingsClass = settingsClass;
cachedAcidDamageMethod = method;

return method;
}


// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------

/**
* Name of the AcidIsland game mode addon.
*/
private static final String ACID_ISLAND = "AcidIsland";

/**
* Name of the method that returns player acid damage in AcidIsland settings.
*/
private static final String ACID_DAMAGE_GETTER = "getAcidDamage";

/**
* Class for which the acid damage getter is cached.
*/
private static Class<?> cachedSettingsClass;

/**
* Cached acid damage getter.
*/
private static Method cachedAcidDamageMethod;
}
9 changes: 9 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ notify-on-unlock: true
# Requires Bank Addon
use-bank: false
#
# This indicates if the addon should respect AcidIsland acid water.
# AcidIsland turns stone, that is created when lava pours into its acid water, back
# into water. If this option is enabled, the addon will not process such blocks, so
# a single lava bucket cannot be used to convert an entire ocean into generator
# blocks. Normal cobblestone generators are not affected by this option.
# This option does nothing in worlds that are not managed by AcidIsland, or if acid
# damage is disabled in the AcidIsland config.
acid-island-aware: true
#
# This list stores GameModes in which the addon should not work.
# To disable addon it is necessary to write its name in new line that starts with -. Example:
# disabled-gamemodes:
Expand Down
Loading
Loading