2021-05-17 03:02:24 +08:00
|
|
|
package com.gtnewhorizon.structurelib.structure;
|
|
|
|
|
|
2022-08-08 17:40:12 +08:00
|
|
|
import java.util.ArrayList;
|
2026-05-23 09:42:20 +02:00
|
|
|
import java.util.LinkedHashSet;
|
2022-08-08 17:40:12 +08:00
|
|
|
import java.util.List;
|
2026-05-23 09:42:20 +02:00
|
|
|
import java.util.Set;
|
2022-08-08 17:40:12 +08:00
|
|
|
import java.util.function.Consumer;
|
2022-09-13 21:22:34 +08:00
|
|
|
import java.util.function.Predicate;
|
2023-01-30 12:52:27 +00:00
|
|
|
|
2022-09-13 21:22:34 +08:00
|
|
|
import javax.annotation.Nullable;
|
2023-01-30 12:52:27 +00:00
|
|
|
|
2022-08-08 17:40:12 +08:00
|
|
|
import net.minecraft.entity.player.EntityPlayerMP;
|
2021-05-17 03:02:24 +08:00
|
|
|
import net.minecraft.item.ItemStack;
|
2022-08-08 17:40:12 +08:00
|
|
|
import net.minecraft.util.IChatComponent;
|
2021-05-17 03:02:24 +08:00
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
|
2022-09-13 21:22:34 +08:00
|
|
|
import com.google.common.collect.Iterables;
|
2023-01-30 12:52:27 +00:00
|
|
|
|
2021-05-17 03:02:24 +08:00
|
|
|
/**
|
|
|
|
|
* Use StructureUtility to instantiate
|
|
|
|
|
*/
|
|
|
|
|
public interface IStructureElementChain<T> extends IStructureElement<T> {
|
2023-01-30 12:52:27 +00:00
|
|
|
|
2026-05-28 01:08:27 -05:00
|
|
|
IStructureElement<? super T>[] fallbacks();
|
2021-05-17 03:02:24 +08:00
|
|
|
|
2022-07-08 17:14:18 +08:00
|
|
|
@Override
|
|
|
|
|
default boolean check(T t, World world, int x, int y, int z) {
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2022-07-08 17:14:18 +08:00
|
|
|
if (fallback.check(t, world, x, y, z)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-05-17 03:02:24 +08:00
|
|
|
|
2024-12-14 13:13:34 -05:00
|
|
|
@Override
|
|
|
|
|
default boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2024-12-14 13:13:34 -05:00
|
|
|
if (fallback.couldBeValid(t, world, x, y, z, trigger)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 17:14:18 +08:00
|
|
|
@Override
|
|
|
|
|
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2022-07-08 17:14:18 +08:00
|
|
|
if (fallback.spawnHint(t, world, x, y, z, trigger)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-05-17 03:02:24 +08:00
|
|
|
|
2022-07-08 17:14:18 +08:00
|
|
|
@Override
|
|
|
|
|
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2022-07-08 17:14:18 +08:00
|
|
|
if (fallback.placeBlock(t, world, x, y, z, trigger)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-09-13 21:22:34 +08:00
|
|
|
|
2026-05-23 09:42:20 +02:00
|
|
|
@Nullable
|
|
|
|
|
@Override
|
2026-05-24 07:35:25 +02:00
|
|
|
default List<String> getDescription(T context) {
|
2026-05-23 09:42:20 +02:00
|
|
|
Set<String> descriptions = new LinkedHashSet<>();
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2026-05-24 07:35:25 +02:00
|
|
|
List<String> desc = fallback.getDescription(context);
|
2026-05-23 09:42:20 +02:00
|
|
|
if (desc != null) {
|
|
|
|
|
descriptions.addAll(desc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return descriptions.isEmpty() ? null : new ArrayList<>(descriptions);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-13 21:22:34 +08:00
|
|
|
@Nullable
|
|
|
|
|
@Override
|
|
|
|
|
default BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger,
|
|
|
|
|
AutoPlaceEnvironment env) {
|
|
|
|
|
Predicate<ItemStack> predicate = null;
|
|
|
|
|
List<Iterable<ItemStack>> is = new ArrayList<>();
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2022-09-13 21:22:34 +08:00
|
|
|
BlocksToPlace e = fallback.getBlocksToPlace(t, world, x, y, z, trigger, env);
|
|
|
|
|
if (e == null) continue;
|
|
|
|
|
if (predicate == null) predicate = e.getPredicate();
|
|
|
|
|
else predicate = predicate.or(e.getPredicate());
|
2024-11-09 15:46:49 +01:00
|
|
|
Iterable<ItemStack> stacks = e.getStacks();
|
|
|
|
|
if (stacks != null) is.add(stacks);
|
2022-09-13 21:22:34 +08:00
|
|
|
}
|
|
|
|
|
if (predicate == null) return null;
|
|
|
|
|
return new BlocksToPlace(predicate, Iterables.concat(is));
|
|
|
|
|
}
|
2022-08-08 17:40:12 +08:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s,
|
|
|
|
|
EntityPlayerMP actor, Consumer<IChatComponent> chatter) {
|
2026-06-06 18:10:11 +02:00
|
|
|
boolean allContinue = true;
|
2022-08-08 17:40:12 +08:00
|
|
|
List<IChatComponent> bufferedNoise = new ArrayList<>();
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2022-08-08 17:40:12 +08:00
|
|
|
PlaceResult result = fallback.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, bufferedNoise::add);
|
|
|
|
|
switch (result) {
|
2026-06-06 18:10:11 +02:00
|
|
|
case REJECT_CONTINUE:
|
|
|
|
|
break;
|
2022-08-08 17:40:12 +08:00
|
|
|
case REJECT:
|
2026-06-06 18:10:11 +02:00
|
|
|
allContinue = false;
|
2022-08-08 17:40:12 +08:00
|
|
|
break;
|
|
|
|
|
case SKIP:
|
2026-06-06 18:10:11 +02:00
|
|
|
bufferedNoise.forEach(chatter);
|
|
|
|
|
return PlaceResult.SKIP;
|
2022-08-08 17:40:12 +08:00
|
|
|
default:
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// dump all that noise back into upstream
|
|
|
|
|
bufferedNoise.forEach(chatter);
|
2026-06-06 18:10:11 +02:00
|
|
|
return allContinue ? PlaceResult.REJECT_CONTINUE : PlaceResult.REJECT;
|
2022-08-08 17:40:12 +08:00
|
|
|
}
|
2022-09-11 02:54:11 +08:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
|
|
|
|
|
AutoPlaceEnvironment env) {
|
2026-06-06 18:10:11 +02:00
|
|
|
boolean allContinue = true;
|
2022-09-11 02:54:11 +08:00
|
|
|
List<IChatComponent> bufferedNoise = new ArrayList<>();
|
2026-05-28 01:08:27 -05:00
|
|
|
for (IStructureElement<? super T> fallback : fallbacks()) {
|
2022-09-11 02:54:11 +08:00
|
|
|
PlaceResult result = fallback
|
|
|
|
|
.survivalPlaceBlock(t, world, x, y, z, trigger, env.withChatter(bufferedNoise::add));
|
|
|
|
|
switch (result) {
|
2026-06-06 18:10:11 +02:00
|
|
|
case REJECT_CONTINUE:
|
|
|
|
|
break;
|
2022-09-11 02:54:11 +08:00
|
|
|
case REJECT:
|
2026-06-06 18:10:11 +02:00
|
|
|
allContinue = false;
|
2022-09-11 02:54:11 +08:00
|
|
|
break;
|
|
|
|
|
case SKIP:
|
2026-06-06 18:10:11 +02:00
|
|
|
bufferedNoise.forEach(env.getChatter());
|
|
|
|
|
return PlaceResult.SKIP;
|
2022-09-11 02:54:11 +08:00
|
|
|
default:
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// dump all that noise back into upstream
|
|
|
|
|
bufferedNoise.forEach(env.getChatter());
|
2026-06-06 18:10:11 +02:00
|
|
|
return allContinue ? PlaceResult.REJECT_CONTINUE : PlaceResult.REJECT;
|
2022-09-11 02:54:11 +08:00
|
|
|
}
|
2021-05-17 03:02:24 +08:00
|
|
|
}
|