Skip to content

Commit

Permalink
Added generateBlock method to the API
Browse files Browse the repository at this point in the history
  • Loading branch information
OmerBenGera committed Feb 26, 2022
1 parent 381d541 commit ee529aa
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 65 deletions.
Expand Up @@ -1679,6 +1679,22 @@ public interface Island extends Comparable<Island>, IMissionsHolder {
*/
void clearGeneratorAmounts(World.Environment environment);

/**
* Generate a block at a specified location.
* The method calculates a block to generate from {@link #getGeneratorAmounts(World.Environment)}.
* It doesn't look for any conditions for generating it - lava, water, etc are not required.
* The method will fail if there are no valid generator rates for the environment.
*
* @param location The location to generate block at.
* @param optimizeCobblestone When set to true and cobblestone needs to be generated, the plugin will
* not play effects, count the block towards the block counts or set the block.
* This is useful when calling the method from BlockFromToEvent, and instead of letting
* the player do the logic of vanilla, the plugin lets the game do it.
* @return The block type that was generated, null if failed.
*/
@Nullable
Key generateBlock(Location location, boolean optimizeCobblestone);

/*
* Schematic methods
*/
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/com/bgsoftware/superiorskyblock/island/SIsland.java
Expand Up @@ -68,6 +68,7 @@
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.WeatherType;
import org.bukkit.World;
import org.bukkit.block.Biome;
Expand Down Expand Up @@ -101,6 +102,7 @@
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -2944,6 +2946,68 @@ public void clearGeneratorAmounts(World.Environment environment) {
}
}

@Override
public Key generateBlock(Location location, boolean optimizeCobblestone) {
Preconditions.checkNotNull(location, "location parameter cannot be null.");
Preconditions.checkNotNull(location.getWorld(), "location's world cannot be null.");

World.Environment environment = location.getWorld().getEnvironment();

int totalGeneratorAmounts = getGeneratorTotalAmount(environment);

if (totalGeneratorAmounts == 0)
return null;

Map<String, Integer> generatorAmounts = getGeneratorAmounts(environment);

String newState = "COBBLESTONE";

if (totalGeneratorAmounts == 1) {
newState = generatorAmounts.keySet().iterator().next();
} else {
int generatedIndex = ThreadLocalRandom.current().nextInt(totalGeneratorAmounts);
int currentIndex = 0;
for (Map.Entry<String, Integer> entry : generatorAmounts.entrySet()) {
currentIndex += entry.getValue();
if (generatedIndex < currentIndex) {
newState = entry.getKey();
break;
}
}
}

Key generatedBlock = Key.of(newState);

String[] typeSections = newState.split(":");

if (optimizeCobblestone && typeSections[0].contains("COBBLESTONE"))
/* Block is being counted in BlocksListener#onBlockFromToMonitor */
return generatedBlock;

// If the block is a custom block, and the event was cancelled - we need to call the handleBlockPlace manually.
handleBlockPlace(generatedBlock, 1);

Material generateBlockType = Material.valueOf(typeSections[0]);
byte blockData = typeSections.length == 2 ? Byte.parseByte(typeSections[1]) : 0;
int combinedId = plugin.getNMSAlgorithms().getCombinedId(generateBlockType, blockData);

if (combinedId == -1) {
SuperiorSkyblockPlugin.log("&cFailed to generate block for type " + generateBlockType + ":" + blockData);
generateBlockType = Material.COBBLESTONE;
blockData = 0;
combinedId = plugin.getNMSAlgorithms().getCombinedId(generateBlockType, blockData);
}

PluginDebugger.debug("Action: Generate Block, Island: " + getOwner().getName() +
", Block: " + generateBlockType + ":" + blockData);

plugin.getNMSWorld().setBlock(location, combinedId);

plugin.getNMSWorld().playGeneratorSound(location);

return generatedBlock;
}

/*
* Settings related methods
*/
Expand Down
Expand Up @@ -1364,6 +1364,12 @@ public void clearGeneratorAmounts(World.Environment environment) {
// Do nothing.
}

@Nullable
@Override
public Key generateBlock(Location location, boolean optimizeCobblestone) {
return null;
}

@Override
public boolean wasSchematicGenerated(World.Environment environment) {
return true;
Expand Down
Expand Up @@ -21,6 +21,8 @@ public final class ConstantKeys {
public static final Key END_PORTAL_FRAME_WITH_EYE = Key.of(Materials.END_PORTAL_FRAME.toBukkitType(), (short) 7);
public static final Key END_PORTAL_FRAME = Key.of(Materials.END_PORTAL_FRAME.toBukkitType().name());
public static final Key WET_SPONGE = Key.of("WET_SPONGE");
public static final Key COBBLESTONE = Key.of("COBBLESTONE");

private ConstantKeys() {

}
Expand Down
Expand Up @@ -2,10 +2,10 @@

import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin;
import com.bgsoftware.superiorskyblock.api.island.Island;
import com.bgsoftware.superiorskyblock.key.Key;
import com.bgsoftware.superiorskyblock.api.key.Key;
import com.bgsoftware.superiorskyblock.key.ConstantKeys;
import com.bgsoftware.superiorskyblock.module.generators.GeneratorsModule;
import com.bgsoftware.superiorskyblock.utils.ServerVersion;
import com.bgsoftware.superiorskyblock.utils.debug.PluginDebugger;
import com.bgsoftware.superiorskyblock.utils.legacy.Materials;
import org.bukkit.Material;
import org.bukkit.World;
Expand All @@ -17,10 +17,6 @@
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockFromToEvent;

import javax.annotation.Nullable;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

@SuppressWarnings("unused")
public final class GeneratorsListener implements Listener {

Expand Down Expand Up @@ -53,7 +49,9 @@ public void onBlockFormEvent(BlockFormEvent e) {
if (e.getBlock().getType() != LAVA_MATERIAL || e.getNewState().getType() != BASALT_MATERIAL)
return;

if (performBlockGeneration(e.getBlock(), island))
Key generatedBlock = island.generateBlock(e.getBlock().getLocation(), true);

if (generatedBlock != null && !generatedBlock.equals(ConstantKeys.COBBLESTONE))
e.setCancelled(true);
}

Expand All @@ -77,65 +75,10 @@ public void onBlockFromToEvent(BlockFromToEvent e) {
if (block.getType().isSolid())
return;

if (performBlockGeneration(block, island))
e.setCancelled(true);
}

private boolean performBlockGeneration(Block block, Island island) {
World.Environment environment = block.getWorld().getEnvironment();
Map<String, Integer> generatorAmounts = island.getGeneratorAmounts(environment);

int totalGeneratorAmounts = island.getGeneratorTotalAmount(environment);

if (totalGeneratorAmounts == 0)
return false;

String newState = "COBBLESTONE";

if (totalGeneratorAmounts == 1) {
newState = generatorAmounts.keySet().iterator().next();
} else {
int generatedIndex = ThreadLocalRandom.current().nextInt(totalGeneratorAmounts);
int currentIndex = 0;
for (Map.Entry<String, Integer> entry : generatorAmounts.entrySet()) {
currentIndex += entry.getValue();
if (generatedIndex < currentIndex) {
newState = entry.getKey();
break;
}
}
}
Key generatedBlock = island.generateBlock(block.getLocation(), true);

String[] typeSections = newState.split(":");

/* Block is being placed in BlocksListener#onBlockFromToMonitor
island.handleBlockPlace(Key.of(newState), 1); */

if (typeSections[0].contains("COBBLESTONE"))
return false;

// If the block is a custom block, and the event was cancelled - we need to call the handleBlockPlace manually.
island.handleBlockPlace(Key.of(newState), 1);

Material generateBlockType = Material.valueOf(typeSections[0]);
byte blockData = typeSections.length == 2 ? Byte.parseByte(typeSections[1]) : 0;
int combinedId = plugin.getNMSAlgorithms().getCombinedId(generateBlockType, blockData);

if (combinedId == -1) {
SuperiorSkyblockPlugin.log("&cFailed to generate block for type " + generateBlockType + ":" + blockData);
generateBlockType = Material.COBBLESTONE;
blockData = 0;
combinedId = plugin.getNMSAlgorithms().getCombinedId(generateBlockType, blockData);
}

PluginDebugger.debug("Action: Generate Block, Island: " + island.getOwner().getName() +
", Block: " + generateBlockType + ":" + blockData);

plugin.getNMSWorld().setBlock(block.getLocation(), combinedId);

plugin.getNMSWorld().playGeneratorSound(block.getLocation());

return true;
if (generatedBlock != null && !generatedBlock.equals(ConstantKeys.COBBLESTONE))
e.setCancelled(true);
}

private boolean canGenerateBlock(Block block) {
Expand Down

0 comments on commit ee529aa

Please sign in to comment.