package nova.core.block.component;
import nova.core.component.Component;
import nova.core.component.SidedComponent;
import nova.core.component.UnsidedComponent;
import nova.core.sound.Sound;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Block properties.
*
* @author soniex2
*/
public interface BlockProperty {
/**
* The breaking difficulty of a block, or how long it takes to break a block.
* Tools and armour may make the block break faster or slower than this.
* <p>
* The standard, regular block hardness is 1. {@code Double.POSITIVE_INFINITY} is unbreakable.
* </p>
*/
@UnsidedComponent
public static class Hardness extends Component implements BlockProperty {
private double hardness = 1.0;
/**
* Sets the breaking difficulty.
*
* @param hardness The breaking difficulty.
* @return This instance for chaining if desired.
*/
public Hardness setHardness(double hardness) {
this.hardness = hardness;
return this;
}
/**
* Gets the breaking difficulty.
*
* @return The breaking difficulty.
*/
public double getHardness() {
return hardness;
}
}
/**
* The blast resistance of a block.
* <p>
* The standard, regular block resistance is 1. {@link Double#POSITIVE_INFINITY} is unexplodable.
* </p>
*/
@UnsidedComponent
public static class Resistance extends Component implements BlockProperty {
private double resistance = 1.0;
/**
* Sets the blast resistance
*
* @param resistance The blast resistance.
* @return This instance for chaining if desired.
*/
public Resistance setResistance(double resistance) {
this.resistance = resistance;
return this;
}
/**
* Gets the blast resistance.
*
* @return The blast resistance.
*/
public double getResistance() {
return resistance;
}
}
/**
* The block sounds associated with a block.
*
* @author winsock
*/
@UnsidedComponent
public static class BlockSound extends Component implements BlockProperty {
private final Map<BlockSoundTrigger, Sound> blockSounds = new HashMap<>();
private final Map<String, Sound> customSounds = new HashMap<>();
/**
* Sets a sound to play on a specified trigger. Note to set a {@link BlockSoundTrigger#CUSTOM_TRIGGER} use {@link BlockSound#setCustomBlockSound(String,Sound)}
*
* @param trigger The trigger to set the sound for
* @param sound The sound to play on the triggering of the trigger
* @return This instance for chaining if desired.
*/
public BlockSound setBlockSound(BlockSoundTrigger trigger, Sound sound) {
if (trigger != BlockSoundTrigger.CUSTOM_TRIGGER)
blockSounds.put(trigger, sound);
return this;
}
/**
* Sets a sound to an id of choice
*
* @param customTrigger The custom id for the sound
* @param sound The sound to associate with the id
* @return This instance for chaining if desired.
*/
public BlockSound setCustomBlockSound(String customTrigger, Sound sound) {
customSounds.put(customTrigger, sound);
return this;
}
/**
* Get the sound associated with a trigger
*
* @param trigger The trigger to get the sound for
* @return The sound object associated with the trigger
*/
public Optional<Sound> getSound(BlockSoundTrigger trigger) {
if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER)
return Optional.empty();
return Optional.ofNullable(blockSounds.get(trigger));
}
/**
* Get the sound associated with a custom Id
*
* @param customTrigger The custom id of the sound
* @return The sound object associated with the custom Id
*/
public Optional<Sound> getCustomSound(String customTrigger) {
return Optional.ofNullable(customSounds.get(customTrigger));
}
/**
* Triggers for sounds to play on the location of a block
*/
public enum BlockSoundTrigger {
BREAK,
PLACE,
WALK,
CUSTOM_TRIGGER
}
}
/**
* The opacity associated with a block.
*
* @author winsock
*/
@SidedComponent
public static class Opacity extends Component implements BlockProperty {
/**
* This value determines if the block should allow light through itself or not.
*/
public double opacity = 1;
/**
* Sets that the block should allow light through
*
* @return This instance for chaining if desired.
*/
public Opacity setTransparent() {
opacity = 0;
return this;
}
/**
* Sets if light should be transmitted through this block
*
* @param opacity The block's opacity
* @return This instance for chaining if desired.
*/
public Opacity setOpacity(double opacity) {
this.opacity = opacity;
return this;
}
}
/**
* Indicates whether the block is replaceable.
*/
@UnsidedComponent
public static final class Replaceable extends Component implements BlockProperty {
private static final Replaceable instance = new Replaceable();
/**
* Gets the singleton for Replaceable.
*
* @return The singleton for Replaceable.
*/
public static Replaceable instance() {
return instance;
}
private Replaceable() {
}
@Override
public boolean equals(Object o) {
return this == o || o instanceof Replaceable;
}
@Override
public int hashCode() {
return Replaceable.class.hashCode();
}
}
}