More rune types
This commit is contained in:
parent
a2ef7e870c
commit
2cb6007d16
@ -8,7 +8,8 @@ import info.shylie.ashes.entity.AshenGolemEntity;
|
||||
import info.shylie.ashes.item.RuneItem;
|
||||
import info.shylie.ashes.rune.param.BlockPosRune;
|
||||
import info.shylie.ashes.rune.param.ItemRune;
|
||||
import info.shylie.ashes.rune.task.*;
|
||||
import info.shylie.ashes.rune.task.composite.*;
|
||||
import info.shylie.ashes.rune.task.leaf.*;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@ -49,8 +50,14 @@ public class AshesRegistry {
|
||||
public static final RegistryObject<RuneType<SelectorRune>> SELECTOR_RUNE;
|
||||
public static final RegistryObject<RuneType<StepSequenceRune>> STEP_SEQUENCE_RUNE;
|
||||
public static final RegistryObject<RuneType<StepSelectorRune>> STEP_SELECTOR_RUNE;
|
||||
public static final RegistryObject<RuneType<InverterRune>> INVERTER_RUNE;
|
||||
|
||||
public static final RegistryObject<RuneType<MoveRune>> MOVE_RUNE;
|
||||
public static final RegistryObject<RuneType<TakeItemRune>> TAKE_ITEM_RUNE;
|
||||
public static final RegistryObject<RuneType<PutItemRune>> PUT_ITEM_RUNE;
|
||||
public static final RegistryObject<RuneType<InteractRune>> INTERACT_RUNE;
|
||||
|
||||
public static final RegistryObject<RuneType<HasItemRune>> HAS_ITEM_RUNE;
|
||||
|
||||
static {
|
||||
HEATED_ASHY_INGOT = ITEMS.register(
|
||||
@ -89,8 +96,13 @@ public class AshesRegistry {
|
||||
SELECTOR_RUNE = RUNES.register("selector", RuneType.Builder.of(SelectorRune::new)::build);
|
||||
STEP_SEQUENCE_RUNE = RUNES.register("step_sequence", RuneType.Builder.of(StepSequenceRune::new)::build);
|
||||
STEP_SELECTOR_RUNE = RUNES.register("step_selector", RuneType.Builder.of(StepSelectorRune::new)::build);
|
||||
INVERTER_RUNE = RUNES.register("inverter", RuneType.Builder.of(InverterRune::new)::build);
|
||||
|
||||
MOVE_RUNE = RUNES.register("move", RuneType.Builder.of(MoveRune::new)::build);
|
||||
TAKE_ITEM_RUNE = RUNES.register("take_item", RuneType.Builder.of(TakeItemRune::new)::build);
|
||||
PUT_ITEM_RUNE = RUNES.register("put_item", RuneType.Builder.of(PutItemRune::new)::build);
|
||||
INTERACT_RUNE = RUNES.register("interact", RuneType.Builder.of(InteractRune::new)::build);
|
||||
HAS_ITEM_RUNE = RUNES.register("has_item", RuneType.Builder.of(HasItemRune::new)::build);
|
||||
}
|
||||
|
||||
public static RegistryObject<ForgeSpawnEggItem> registerSpawnEgg(RegistryObject<? extends EntityType<? extends Mob>> type, int bg, int fg) {
|
||||
|
14
src/main/java/info/shylie/ashes/Utils.java
Normal file
14
src/main/java/info/shylie/ashes/Utils.java
Normal file
@ -0,0 +1,14 @@
|
||||
package info.shylie.ashes;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
public class Utils {
|
||||
public static <T> T[] concat(T[] b, T... a) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] c = (T[])Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
|
||||
System.arraycopy(a, 0, c, 0, a.length);
|
||||
System.arraycopy(b, 0, c, a.length, b.length);
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
package info.shylie.ashes.api.golem;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import info.shylie.ashes.api.rune.TaskRune;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.animal.AbstractGolem;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
|
||||
public interface IGolem {
|
||||
float MAX_INTERACT_DISTANCE = 2;
|
||||
|
||||
AbstractGolem asEntity();
|
||||
|
||||
TaskRune getTask();
|
||||
@ -16,4 +22,15 @@ public interface IGolem {
|
||||
task.update(this);
|
||||
}
|
||||
}
|
||||
|
||||
default FakePlayer getFakePlayer() {
|
||||
return FakePlayerFactory.get((ServerLevel)asEntity().level(), new GameProfile(
|
||||
asEntity().getUUID(),
|
||||
asEntity().getDisplayName().getString()
|
||||
));
|
||||
}
|
||||
|
||||
default boolean canInteract(BlockPos pos) {
|
||||
return pos != null && asEntity().distanceToSqr(pos.getX(), pos.getY(), pos.getZ()) <= 3;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public abstract class CompositeTaskRune extends TaskRune {
|
||||
}
|
||||
|
||||
public void add(TaskRune rune) {
|
||||
if (rune == null) { return; }
|
||||
if (rune == null || children.size() >= maxChildren()) { return; }
|
||||
children.add(rune);
|
||||
}
|
||||
|
||||
@ -74,7 +74,12 @@ public abstract class CompositeTaskRune extends TaskRune {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Status updateImpl2(IGolem golem);
|
||||
protected int maxChildren() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
protected void saveImpl2(CompoundTag tag) { }
|
||||
protected void loadImpl2(CompoundTag tag) { }
|
||||
|
||||
protected abstract Status updateImpl2(IGolem golem);
|
||||
}
|
||||
|
@ -14,6 +14,11 @@ public abstract class ParameterRune<T> extends Rune {
|
||||
super(type);
|
||||
}
|
||||
|
||||
public ParameterRune(RuneType<? extends ParameterRune<?>> type, T data) {
|
||||
this(type);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public record UseContext(Level level, Player player, InteractionHand hand) {
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,8 @@ public abstract class Rune {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTypeID() {
|
||||
return type.toString();
|
||||
public ResourceLocation getTypeID() {
|
||||
return AshesRegistry.RUNE_REGISTRY.get().getKey(type);
|
||||
}
|
||||
|
||||
public Component getTooltip() {
|
||||
|
@ -0,0 +1,31 @@
|
||||
package info.shylie.ashes.api.rune.leaf;
|
||||
|
||||
import info.shylie.ashes.Utils;
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.LeafTaskRune;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public abstract class BEInteractRune extends LeafTaskRune {
|
||||
protected BEInteractRune(RuneType<? extends BEInteractRune> type, Class<?>... extra) {
|
||||
super(type, Utils.concat(extra, BlockPos.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean startImpl(IGolem golem) {
|
||||
return golem.canInteract(getValue(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status updateImpl(IGolem golem) {
|
||||
BlockEntity be = golem.asEntity().level().getBlockEntity(getValue(0));
|
||||
if (be != null) {
|
||||
return interact(golem, be);
|
||||
}
|
||||
|
||||
return Status.SUCCESS;
|
||||
}
|
||||
|
||||
protected abstract Status interact(IGolem golem, BlockEntity be);
|
||||
}
|
@ -64,11 +64,13 @@ public class AshenGolemEntity extends AbstractGolem implements IGolem {
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag tag) {
|
||||
super.addAdditionalSaveData(tag);
|
||||
if (task != null) { task.save(tag); }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag tag) {
|
||||
super.readAdditionalSaveData(tag);
|
||||
task = Rune.of(tag, TaskRune.class);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package info.shylie.ashes.item;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.*;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@ -102,6 +103,15 @@ public class RuneItem extends Item {
|
||||
components.add(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescriptionId(ItemStack stack) {
|
||||
Rune rune = Rune.of(stack.getTag());
|
||||
if (rune == null) {
|
||||
return super.getDescriptionId(stack);
|
||||
}
|
||||
return Util.makeDescriptionId("rune", rune.getTypeID());
|
||||
}
|
||||
|
||||
private boolean setParameter(UseOnContext context) {
|
||||
ParameterRune<?> rune = Rune.of(context.getItemInHand().getTag(), ParameterRune.class);
|
||||
if (rune == null) { return false; }
|
||||
|
@ -7,19 +7,20 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.inventory.tooltip.TooltipComponent;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class ItemRune extends ParameterRune<Item> {
|
||||
private static final String ITEM_TAG = "item";
|
||||
|
||||
public ItemRune(RuneType<? extends ItemRune> type) {
|
||||
super(type);
|
||||
super(type, Items.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TooltipComponent getTooltipImage() {
|
||||
Item item = getValue();
|
||||
if (item == null) { return null; }
|
||||
if (item == Items.AIR) { return null; }
|
||||
|
||||
return new SingleItemTooltip(item);
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package info.shylie.ashes.rune.task.composite;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.CompositeTaskRune;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
||||
|
||||
public class InverterRune extends CompositeTaskRune {
|
||||
public InverterRune(RuneType<? extends InverterRune> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status updateImpl2(IGolem golem) {
|
||||
Status status = children.get(0).update(golem);
|
||||
|
||||
return switch (status) {
|
||||
case SUCCESS -> Status.FAILURE;
|
||||
case FAILURE -> Status.SUCCESS;
|
||||
default -> Status.ONGOING;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package info.shylie.ashes.rune.task;
|
||||
package info.shylie.ashes.rune.task.composite;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.CompositeTaskRune;
|
@ -1,4 +1,4 @@
|
||||
package info.shylie.ashes.rune.task;
|
||||
package info.shylie.ashes.rune.task.composite;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
@ -1,4 +1,4 @@
|
||||
package info.shylie.ashes.rune.task;
|
||||
package info.shylie.ashes.rune.task.composite;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.CompositeTaskRune;
|
@ -1,4 +1,4 @@
|
||||
package info.shylie.ashes.rune.task;
|
||||
package info.shylie.ashes.rune.task.composite;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.CompositeTaskRune;
|
@ -0,0 +1,17 @@
|
||||
package info.shylie.ashes.rune.task.leaf;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.LeafTaskRune;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public class HasItemRune extends LeafTaskRune {
|
||||
public HasItemRune(RuneType<? extends HasItemRune> type) {
|
||||
super(type, Item.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status updateImpl(IGolem golem) {
|
||||
return golem.asEntity().getMainHandItem().getItem() == getValue(0) ? Status.SUCCESS : Status.FAILURE;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package info.shylie.ashes.rune.task.leaf;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.LeafTaskRune;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
|
||||
public class InteractRune extends LeafTaskRune {
|
||||
public InteractRune(RuneType<? extends InteractRune> type) {
|
||||
super(type, BlockPos.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status updateImpl(IGolem golem) {
|
||||
BlockPos pos = getValue(0);
|
||||
if (golem.canInteract(pos)) {
|
||||
FakePlayer player = golem.getFakePlayer();
|
||||
player.setItemInHand(InteractionHand.MAIN_HAND, golem.asEntity().getMainHandItem());
|
||||
golem.asEntity().level().getBlockState(pos).use(
|
||||
golem.asEntity().level(),
|
||||
player,
|
||||
InteractionHand.MAIN_HAND,
|
||||
new BlockHitResult(
|
||||
Vec3.atCenterOf(pos),
|
||||
Direction.UP,
|
||||
pos,
|
||||
false
|
||||
)
|
||||
);
|
||||
golem.asEntity().setItemInHand(InteractionHand.MAIN_HAND, player.getMainHandItem());
|
||||
|
||||
return Status.SUCCESS;
|
||||
}
|
||||
|
||||
return Status.FAILURE;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package info.shylie.ashes.rune.task;
|
||||
package info.shylie.ashes.rune.task.leaf;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.LeafTaskRune;
|
||||
@ -36,22 +36,22 @@ public class MoveRune extends LeafTaskRune {
|
||||
e.move(MoverType.SELF, e.getDeltaMovement());
|
||||
|
||||
if (e.getNavigation().isDone()) {
|
||||
BlockPos pos = getValue(0);
|
||||
if (e.position().distanceToSqr(new Vec3(pos.getX(), pos.getY() + 1, pos.getZ())) < 1) {
|
||||
return Status.SUCCESS;
|
||||
}
|
||||
|
||||
return Status.FAILURE;
|
||||
return golem.canInteract(getValue(0)) ? Status.SUCCESS : Status.FAILURE;
|
||||
}
|
||||
|
||||
return Status.ONGOING;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopImpl(IGolem golem) {
|
||||
golem.asEntity().getNavigation().stop();
|
||||
}
|
||||
|
||||
private boolean path(IGolem golem) {
|
||||
BlockPos pos = getValue(0);
|
||||
return pos != null && golem.asEntity().getNavigation().moveTo(
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getY() + 1,
|
||||
pos.getZ(),
|
||||
1.0
|
||||
);
|
@ -0,0 +1,43 @@
|
||||
package info.shylie.ashes.rune.task.leaf;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
||||
import info.shylie.ashes.api.rune.leaf.BEInteractRune;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
|
||||
public class PutItemRune extends BEInteractRune {
|
||||
public PutItemRune(RuneType<? extends PutItemRune> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status interact(IGolem golem, BlockEntity be) {
|
||||
ItemStack handItem = golem.asEntity().getMainHandItem().copy();
|
||||
|
||||
if (handItem.isEmpty()) {
|
||||
return Status.FAILURE;
|
||||
}
|
||||
|
||||
final Status[] status = { Status.FAILURE };
|
||||
|
||||
be.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(handler -> {
|
||||
for (int i = 0; i < handler.getSlots() && !handItem.isEmpty(); i++) {
|
||||
int putCount = handItem.getCount() - handler.insertItem(i, handItem, true).getCount();
|
||||
if (putCount > 0) {
|
||||
handler.insertItem(i, handItem.copy(), false);
|
||||
handItem.shrink(putCount);
|
||||
status[0] = Status.SUCCESS;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (status[0] == Status.SUCCESS) {
|
||||
golem.asEntity().setItemInHand(InteractionHand.MAIN_HAND, handItem);
|
||||
}
|
||||
|
||||
return status[0];
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package info.shylie.ashes.rune.task.leaf;
|
||||
|
||||
import info.shylie.ashes.api.golem.IGolem;
|
||||
import info.shylie.ashes.api.rune.RuneType;
|
||||
import info.shylie.ashes.api.rune.leaf.BEInteractRune;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class TakeItemRune extends BEInteractRune {
|
||||
public TakeItemRune(RuneType<? extends TakeItemRune> type) {
|
||||
super(type, Item.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Status interact(IGolem golem, BlockEntity be) {
|
||||
final Status[] status = { Status.FAILURE };
|
||||
|
||||
be.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(handler -> {
|
||||
Item type = getValue(1);
|
||||
ItemStack totalExtracted = golem.asEntity().getMainHandItem().copy();
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
ItemStack stack = handler.getStackInSlot(i);
|
||||
|
||||
if (!totalExtracted.isEmpty() && !ItemHandlerHelper.canItemStacksStack(totalExtracted, stack)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type == null || stack.getItem() == type) {
|
||||
int count = Math.min(stack.getCount(), stack.getMaxStackSize());
|
||||
if (!totalExtracted.isEmpty()) {
|
||||
count = Math.min(totalExtracted.getMaxStackSize() - totalExtracted.getCount(), count);
|
||||
}
|
||||
ItemStack extracted = handler.extractItem(i, count, false);
|
||||
if (!extracted.isEmpty()) {
|
||||
if (totalExtracted.isEmpty()) {
|
||||
totalExtracted = extracted;
|
||||
}
|
||||
else {
|
||||
totalExtracted.grow(extracted.getCount());
|
||||
}
|
||||
status[0] = Status.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status[0] == Status.SUCCESS) {
|
||||
golem.asEntity().setItemInHand(InteractionHand.MAIN_HAND, totalExtracted);
|
||||
}
|
||||
});
|
||||
|
||||
return status[0];
|
||||
}
|
||||
}
|
@ -1,7 +1,20 @@
|
||||
{
|
||||
"rune.ashes.blockpos": "Position Rune",
|
||||
"rune.ashes.item": "Item Rune",
|
||||
"rune.ashes.sequence": "Sequence Rune",
|
||||
"rune.ashes.selector": "Selector Rune",
|
||||
"rune.ashes.step_sequence": "Step Sequence Rune",
|
||||
"rune.ashes.step_selector": "Step Selector Rune",
|
||||
"rune.ashes.inverter":"Inverter Rune",
|
||||
"rune.ashes.move": "Move Rune",
|
||||
"rune.ashes.take_item": "Take Item Rune",
|
||||
"rune.ashes.put_item": "Put Item Rune",
|
||||
"rune.ashes.interact": "Interact Rune",
|
||||
"rune.ashes.has_item": "Has Item Rune",
|
||||
|
||||
"rune.ashes.blockpos.default": "No position set",
|
||||
|
||||
"item.ashes.rune": "Rune",
|
||||
"item.ashes.rune": "Invalid Rune",
|
||||
|
||||
"itemgroup.ashes": "Ashes"
|
||||
}
|
Loading…
Reference in New Issue
Block a user