Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Copper Buttons #3

Merged
merged 7 commits into from
Oct 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ Clients need to have the mod installed to see the golems. If they do not have th

## Features

## Copper Buttons
* Waxed and unwaxed variants
* Lower redstone signal and breaking strengths when oxidised

### Spawning
* The spawning combo is a bottom __Copper Block__, middle __Carved Pumpkin__ Block and top __Lightning Rod__.
* In creative, you can use the Copper Golem spawn egg
Expand All @@ -37,7 +41,7 @@ Clients need to have the mod installed to see the golems. If they do not have th
* Random ticks will cause oxidation to increment, of which are 4 levels (0-3)
* Interacting with the mob with Honeycomb to Wax it
* Interacting with the mob with an any Axe will unwax it, if waxed, otherwise if not at first oxidation level will deoxidise it by 1 level
* Lightning strikes will set oxidation level to 0 (min level)
* Lightning strikes will set oxidation level to 0 (min level) if not waxed

## Animations
* Spinning head randomly
Expand Down
70 changes: 63 additions & 7 deletions src/main/java/com/mrjoshuat/coppergolem/ModInit.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
package com.mrjoshuat.coppergolem;

import com.mrjoshuat.coppergolem.block.OxidizableButtonBlock;
import com.mrjoshuat.coppergolem.block.WaxedOxidizableButtonBlock;
import com.mrjoshuat.coppergolem.entity.CopperGolemEntity;

import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder;
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;

import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.block.Oxidizable;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.SpawnEggItem;
import net.minecraft.item.*;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;

Expand All @@ -23,16 +35,60 @@ public class ModInit implements ModInitializer {
public static final EntityType<CopperGolemEntity> COPPER_GOLEM_ENTITY_TYPE = Registry.register(
Registry.ENTITY_TYPE,
new Identifier("minecraft", "copper_golem"),
FabricEntityTypeBuilder.create(SpawnGroup.MISC, CopperGolemEntity::new)
.dimensions(EntityDimensions.fixed(0.75f, 1.15f)).build()
FabricEntityTypeBuilder.create(SpawnGroup.MISC, CopperGolemEntity::new).dimensions(EntityDimensions.fixed(0.75f, 1.15f)).build()
);

public static final Item IRON_GOLEM_SPAWN_EGG = new SpawnEggItem(COPPER_GOLEM_ENTITY_TYPE,
13136982, 5805694, new Item.Settings().group(ItemGroup.MISC));
public static final Item IRON_GOLEM_SPAWN_EGG = new SpawnEggItem(COPPER_GOLEM_ENTITY_TYPE,13136982, 5805694, new Item.Settings().group(ItemGroup.MISC));

public static final Identifier COPPER_BUTTON_ID = new Identifier("minecraft", "copper_button");
public static final Identifier EXPOSED_COPPER_BUTTON_ID = new Identifier("minecraft", "exposed_copper_button");
public static final Identifier WEATHERED_COPPER_BUTTON_ID = new Identifier("minecraft", "weathered_copper_button");
public static final Identifier OXIDIZED_COPPER_BUTTON_ID = new Identifier("minecraft", "oxidized_copper_button");

public static final Identifier WAXED_COPPER_BUTTON_ID = new Identifier("minecraft", "waxed_copper_button");
public static final Identifier WAXED_EXPOSED_COPPER_BUTTON_ID = new Identifier("minecraft", "waxed_exposed_copper_button");
public static final Identifier WAXED_WEATHERED_COPPER_BUTTON_ID = new Identifier("minecraft", "waxed_weathered_copper_button");
public static final Identifier WAXED_OXIDIZED_COPPER_BUTTON_ID = new Identifier("minecraft", "waxed_oxidized_copper_button");

public static final Block COPPER_BUTTON = new OxidizableButtonBlock(Oxidizable.OxidizationLevel.UNAFFECTED, buildButtonSettings(0, COPPER_BUTTON_ID));
public static final Block EXPOSED_COPPER_BUTTON = new OxidizableButtonBlock(Oxidizable.OxidizationLevel.EXPOSED, buildButtonSettings(1, EXPOSED_COPPER_BUTTON_ID));
public static final Block WEATHERED_COPPER_BUTTON = new OxidizableButtonBlock(Oxidizable.OxidizationLevel.WEATHERED, buildButtonSettings(2, WEATHERED_COPPER_BUTTON_ID));
public static final Block OXIDIZED_COPPER_BUTTON = new OxidizableButtonBlock(Oxidizable.OxidizationLevel.OXIDIZED, buildButtonSettings(3, OXIDIZED_COPPER_BUTTON_ID));

public static final Block WAXED_COPPER_BUTTON = new WaxedOxidizableButtonBlock(Oxidizable.OxidizationLevel.UNAFFECTED, buildButtonSettings(0, WAXED_COPPER_BUTTON_ID));
public static final Block WAXED_EXPOSED_COPPER_BUTTON = new WaxedOxidizableButtonBlock(Oxidizable.OxidizationLevel.EXPOSED, buildButtonSettings(1, WAXED_EXPOSED_COPPER_BUTTON_ID));
public static final Block WAXED_WEATHERED_COPPER_BUTTON = new WaxedOxidizableButtonBlock(Oxidizable.OxidizationLevel.WEATHERED, buildButtonSettings(2, WAXED_WEATHERED_COPPER_BUTTON_ID));
public static final Block WAXED_OXIDIZED_COPPER_BUTTON = new WaxedOxidizableButtonBlock(Oxidizable.OxidizationLevel.OXIDIZED, buildButtonSettings(3, WAXED_OXIDIZED_COPPER_BUTTON_ID));

@Override
public void onInitialize() {
FabricDefaultAttributeRegistry.register(COPPER_GOLEM_ENTITY_TYPE, CopperGolemEntity.createMobAttributes());
Registry.register(Registry.ITEM, new Identifier("minecraft", "copper_golem_spawn_egg"), IRON_GOLEM_SPAWN_EGG);

registerCopperButton(COPPER_BUTTON_ID, COPPER_BUTTON);
registerCopperButton(EXPOSED_COPPER_BUTTON_ID, EXPOSED_COPPER_BUTTON);
registerCopperButton(WEATHERED_COPPER_BUTTON_ID, WEATHERED_COPPER_BUTTON);
registerCopperButton(OXIDIZED_COPPER_BUTTON_ID, OXIDIZED_COPPER_BUTTON);

registerCopperButton(WAXED_COPPER_BUTTON_ID, WAXED_COPPER_BUTTON);
registerCopperButton(WAXED_EXPOSED_COPPER_BUTTON_ID, WAXED_EXPOSED_COPPER_BUTTON);
registerCopperButton(WAXED_WEATHERED_COPPER_BUTTON_ID, WAXED_WEATHERED_COPPER_BUTTON);
registerCopperButton(WAXED_OXIDIZED_COPPER_BUTTON_ID, WAXED_OXIDIZED_COPPER_BUTTON);
}

private static void registerCopperButton(Identifier identifier, Block block) {
Registry.register(Registry.BLOCK, identifier, block);
Registry.register(Registry.ITEM, identifier, new BlockItem(block, new FabricItemSettings().group(ItemGroup.REDSTONE)));
}

private static final float buttonStrengthBase = 4f;
private static FabricBlockSettings buildButtonSettings(int val, Identifier identifier) {
return FabricBlockSettings.of(Material.DECORATION)
.noCollision()
.requiresTool()
.breakByTool(FabricToolTags.PICKAXES)
.sounds(BlockSoundGroup.COPPER)
.strength(buttonStrengthBase - (buttonStrengthBase * (val * 0.1f)))
.drops(identifier);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.block.BlockState;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;

import java.util.Random;

public interface OxidizableBlockCallback {
Event<OxidizableBlockCallback> EVENT = EventFactory.createArrayBacked(OxidizableBlockCallback.class,
(listeners) -> () -> {
(listeners) -> (BlockState state, ServerWorld world, BlockPos pos, Random random) -> {
for (OxidizableBlockCallback listener : listeners) {
ActionResult result = listener.randomTick();
ActionResult result = listener.randomTick(state, world, pos, random);

if(result != ActionResult.PASS) {
return result;
Expand All @@ -18,5 +23,5 @@ public interface OxidizableBlockCallback {
return ActionResult.PASS;
});

ActionResult randomTick();
ActionResult randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.mrjoshuat.coppergolem.block;

import com.google.common.base.Suppliers;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.mrjoshuat.coppergolem.ModInit;
import net.minecraft.block.*;

import java.util.Optional;
import java.util.function.Supplier;

public interface OxidizableButton extends Degradable<Oxidizable.OxidizationLevel> {
Supplier<BiMap<Block, Block>> BUTTON_OXIDATION_LEVEL_INCREASES = Suppliers.memoize(() -> {
BiMap<Block, Block> map = HashBiMap.create();
map.put(ModInit.COPPER_BUTTON, ModInit.EXPOSED_COPPER_BUTTON);
map.put(ModInit.EXPOSED_COPPER_BUTTON, ModInit.WEATHERED_COPPER_BUTTON);
map.put(ModInit.WEATHERED_COPPER_BUTTON, ModInit.OXIDIZED_COPPER_BUTTON);
return map;
});
Supplier<BiMap<Block, Block>> BUTTON_OXIDATION_LEVEL_DECREASES = Suppliers.memoize(() -> {
return ((BiMap)BUTTON_OXIDATION_LEVEL_INCREASES.get()).inverse();
});

static Optional<Block> getDecreasedOxidationBlock(Block block) {
return Optional.ofNullable((Block)((BiMap) BUTTON_OXIDATION_LEVEL_DECREASES.get()).get(block));
}

static Block getUnaffectedOxidationBlock(Block block) {
Block block2 = block;

for(Block block3 = (Block)((BiMap) BUTTON_OXIDATION_LEVEL_DECREASES.get()).get(block);
block3 != null;
block3 = (Block)((BiMap) BUTTON_OXIDATION_LEVEL_DECREASES.get()).get(block3)) {
block2 = block3;
}

return block2;
}

static Optional<BlockState> getDecreasedOxidationState(BlockState state) {
return getDecreasedOxidationBlock(state.getBlock()).map((block) -> {
return block.getStateWithProperties(state);
});
}

static Optional<Block> getIncreasedOxidationBlock(Block block) {
var x = (BiMap)BUTTON_OXIDATION_LEVEL_INCREASES.get();
var b = (Block)(x).get(block);
return Optional.ofNullable(b);
}

static BlockState getUnaffectedOxidationState(BlockState state) {
return getUnaffectedOxidationBlock(state.getBlock()).getStateWithProperties(state);
}

default Optional<BlockState> getDegradationResult(BlockState state) {
return getIncreasedOxidationBlock(state.getBlock()).map((block) -> {
return block.getStateWithProperties(state);
});
}

default float getDegradationChanceMultiplier() {
return this.getDegradationLevel() == Oxidizable.OxidizationLevel.UNAFFECTED ? 0.75F : 1.0F;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.mrjoshuat.coppergolem.block;

import com.mrjoshuat.coppergolem.OxidizableBlockCallback;

import com.mrjoshuat.coppergolem.handler.RedstonePowerHandler;
import net.minecraft.block.*;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;

import java.util.Random;

public class OxidizableButtonBlock extends AbstractButtonBlock implements OxidizableButton {
private final Oxidizable.OxidizationLevel oxidizationLevel;

public OxidizableButtonBlock(Oxidizable.OxidizationLevel oxidizationLevel, AbstractBlock.Settings settings) {
super(false, settings);
this.oxidizationLevel = oxidizationLevel;
}

public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
this.tickDegradation(state, world, pos, random);
}

public boolean hasRandomTicks(BlockState state) {
return OxidizableButton.getIncreasedOxidationBlock(state.getBlock()).isPresent();
}

@Override
public Oxidizable.OxidizationLevel getDegradationLevel() {
return this.oxidizationLevel;
}

@Override
protected SoundEvent getClickSound(boolean powered) {
// or to use BLOCK_COPPER_STEP?
return powered ? SoundEvents.BLOCK_METAL_PRESSURE_PLATE_CLICK_ON : SoundEvents.BLOCK_METAL_PRESSURE_PLATE_CLICK_OFF;
}

@Override
public int getWeakRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction direction) {
return state.get(POWERED) ? RedstonePowerHandler.getRedstonePower(getDegradationLevel()) : 0;
}

@Override
public int getStrongRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction direction) {
return state.get(POWERED) && getDirection(state) == direction ? RedstonePowerHandler.getRedstonePower(getDegradationLevel()) : 0;
}

@Override
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
if (player.isCreative()) {
return;
}
var itemStack = new ItemStack(state.getBlock(), 1);
var itemEntity = new ItemEntity(world, pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D, itemStack);
world.spawnEntity(itemEntity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.mrjoshuat.coppergolem.block;

import com.mrjoshuat.coppergolem.handler.RedstonePowerHandler;
import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Oxidizable;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;

public class WaxedOxidizableButtonBlock extends AbstractButtonBlock {
private Oxidizable.OxidizationLevel level;

public WaxedOxidizableButtonBlock(Oxidizable.OxidizationLevel level, Settings settings) {
super(false, settings);
this.level = level;
}

@Override
protected SoundEvent getClickSound(boolean powered) {
// or to use BLOCK_COPPER_STEP?
return powered ? SoundEvents.BLOCK_METAL_PRESSURE_PLATE_CLICK_ON : SoundEvents.BLOCK_METAL_PRESSURE_PLATE_CLICK_OFF;
}



@Override
public int getWeakRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction direction) {
return state.get(POWERED) ? RedstonePowerHandler.getRedstonePower(level) : 0;
}

@Override
public int getStrongRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction direction) {
return state.get(POWERED) && getDirection(state) == direction ? RedstonePowerHandler.getRedstonePower(level) : 0;
}

@Override
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
if (player.isCreative()) {
return;
}
var itemStack = new ItemStack(state.getBlock(), 1);
var itemEntity = new ItemEntity(world, pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D, itemStack);
world.spawnEntity(itemEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ protected void tickOxidisationAI() {

private void setupRandomTickListener() {
// TODO: this should be removed, need a better way
OxidizableBlockCallback.EVENT.register(() -> {
OxidizableBlockCallback.EVENT.register((state, world, pos, random) -> {
if (this.getWaxed()) {
return ActionResult.PASS;
}
Expand Down Expand Up @@ -264,11 +264,11 @@ protected ActionResult interactMob(PlayerEntity player, Hand hand) {
Item handItem = stack.getItem();

// debug
/*if (handItem == Items.DIAMOND_AXE) {
if (handItem == Items.DIAMOND_AXE) {
this.incrementOxidisation();
this.tickOxidisationAI();
return ActionResult.success(this.world.isClient);
}*/
}

if (ALL_AXES.contains(handItem)) {
if (this.getWaxed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mrjoshuat.coppergolem.entity.CopperGolemEntity;

import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.entity.ai.goal.Goal;
Expand Down Expand Up @@ -87,10 +88,5 @@ private List<BlockPos> getButtons() {
}

// TODO: what button, so all the buttons?
private boolean isValidBlock(Block block) {
return block == Blocks.ACACIA_BUTTON || block == Blocks.BIRCH_BUTTON || block == Blocks.CRIMSON_BUTTON ||
block == Blocks.DARK_OAK_BUTTON || block == Blocks.JUNGLE_BUTTON || block == Blocks.OAK_BUTTON ||
block == Blocks.SPRUCE_BUTTON || block == Blocks.STONE_BUTTON || block == Blocks.POLISHED_BLACKSTONE_BUTTON ||
block == Blocks.WARPED_BUTTON;
}
private boolean isValidBlock(Block block) { return block instanceof AbstractButtonBlock; }
}