@@ -1,53 +0,0 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.capability.inventory; | |||
import net.minecraft.item.ItemStack; | |||
import pl.asie.charset.api.lib.IItemInsertionHandler; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
public class ItemInsertionHandlerWrapper implements Function<List<IItemInsertionHandler>, IItemInsertionHandler> { | |||
@Override | |||
public IItemInsertionHandler apply(List<IItemInsertionHandler> iItemInsertionHandlers) { | |||
return new WrappedInserter(iItemInsertionHandlers); | |||
} | |||
private class WrappedInserter implements IItemInsertionHandler { | |||
private final Collection<IItemInsertionHandler> receivers; | |||
WrappedInserter(Collection<IItemInsertionHandler> receivers) { | |||
this.receivers = receivers; | |||
} | |||
@Override | |||
public ItemStack insertItem(ItemStack stack, boolean simulate) { | |||
ItemStack toInsert = stack; | |||
for (IItemInsertionHandler insertionHandler : receivers) { | |||
toInsert = insertionHandler.insertItem(toInsert, simulate); | |||
if (toInsert.isEmpty()) | |||
break; | |||
} | |||
return toInsert; | |||
} | |||
} | |||
} |
@@ -1,50 +0,0 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.capability.lib; | |||
import net.minecraft.util.EnumFacing; | |||
import pl.asie.charset.api.lib.IAxisRotatable; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
public class AxisRotatableWrapper implements Function<List<IAxisRotatable>, IAxisRotatable> { | |||
@Override | |||
public IAxisRotatable apply(List<IAxisRotatable> iAxisRotatableList) { | |||
return new IAxisRotatable() { | |||
@Override | |||
public boolean rotateAround(EnumFacing axis, boolean simulate) { | |||
for (IAxisRotatable rotatable : iAxisRotatableList) { | |||
if (!rotatable.rotateAround(axis, true)) { | |||
return false; | |||
} | |||
} | |||
if (!simulate) { | |||
for (IAxisRotatable rotatable : iAxisRotatableList) { | |||
rotatable.rotateAround(axis, false); | |||
} | |||
} | |||
return true; | |||
} | |||
}; | |||
} | |||
} |
@@ -1,48 +0,0 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.capability.lib; | |||
import net.minecraftforge.fml.relauncher.Side; | |||
import pl.asie.charset.api.lib.IDebuggable; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
public class DebuggableWrapper implements Function<List<IDebuggable>, IDebuggable> { | |||
@Override | |||
public IDebuggable apply(List<IDebuggable> iDebuggables) { | |||
return new Wrapped(iDebuggables); | |||
} | |||
private class Wrapped implements IDebuggable { | |||
private final Collection<IDebuggable> receivers; | |||
Wrapped(Collection<IDebuggable> receivers) { | |||
this.receivers = receivers; | |||
} | |||
@Override | |||
public void addDebugInformation(List<String> stringList, Side side) { | |||
for (IDebuggable debug : receivers) | |||
debug.addDebugInformation(stringList, side); | |||
} | |||
} | |||
} |
@@ -1,43 +0,0 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.capability.redstone; | |||
import pl.asie.charset.api.wires.IBundledEmitter; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
public class BundledEmitterWrapper implements Function<List<IBundledEmitter>, IBundledEmitter> { | |||
@Override | |||
public IBundledEmitter apply(List<IBundledEmitter> collection) { | |||
byte[] data = new byte[16]; | |||
for (IBundledEmitter emitter : collection) { | |||
byte[] dataIn = emitter.getBundledSignal(); | |||
if (dataIn != null) { | |||
for (int i = 0; i < 16; i++) { | |||
data[i] = (byte) Math.max(0xFF & (int) dataIn[i], 0xFF & (int) data[i]); | |||
} | |||
} | |||
} | |||
return new DefaultBundledEmitter(data); | |||
} | |||
} |
@@ -1,48 +0,0 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.capability.redstone; | |||
import pl.asie.charset.api.wires.IRedstoneReceiver; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
public class RedstoneReceiverWrapper implements Function<List<IRedstoneReceiver>, IRedstoneReceiver> { | |||
@Override | |||
public IRedstoneReceiver apply(List<IRedstoneReceiver> iRedstoneReceivers) { | |||
return new WrappedReceiver(iRedstoneReceivers); | |||
} | |||
private class WrappedReceiver implements IRedstoneReceiver { | |||
private final Collection<IRedstoneReceiver> receiverSet; | |||
public WrappedReceiver(Collection<IRedstoneReceiver> receiverSet) { | |||
this.receiverSet = receiverSet; | |||
} | |||
@Override | |||
public void onRedstoneInputChange() { | |||
for (IRedstoneReceiver r : receiverSet) { | |||
r.onRedstoneInputChange(); | |||
} | |||
} | |||
} | |||
} |
@@ -59,27 +59,26 @@ public class ShiftScrollHandler { | |||
private final Set<Item> items; | |||
public ItemGroup(Collection c) { | |||
ImmutableSet.Builder<Item> builder = new ImmutableSet.Builder<>(); | |||
items = new LinkedHashSet<>(); | |||
for (Object o : c) { | |||
if (o instanceof Block) { | |||
builder.add(Item.getItemFromBlock((Block) o)); | |||
items.add(Item.getItemFromBlock((Block) o)); | |||
} else if (o instanceof Item) { | |||
builder.add((Item) o); | |||
items.add((Item) o); | |||
} | |||
} | |||
this.items = builder.build(); | |||
} | |||
public ItemGroup(Block... blocks) { | |||
ImmutableSet.Builder<Item> builder = new ImmutableSet.Builder<>(); | |||
items = new LinkedHashSet<>(); | |||
for (Block b : blocks) { | |||
builder.add(Item.getItemFromBlock(b)); | |||
items.add(Item.getItemFromBlock(b)); | |||
} | |||
this.items = builder.build(); | |||
} | |||
public ItemGroup(Item... items) { | |||
this.items = ImmutableSet.copyOf(items); | |||
public ItemGroup(Item... its) { | |||
items = new LinkedHashSet<>(); | |||
items.addAll(Arrays.asList(its)); | |||
} | |||
@Override |
@@ -25,6 +25,7 @@ import mcmultipart.api.multipart.IMultipartRegistry; | |||
import pl.asie.charset.lib.handlers.DebugInfoProvider; | |||
import pl.asie.charset.lib.loader.AnnotatedPluginHandler; | |||
import pl.asie.charset.lib.utils.OcclusionUtils; | |||
import pl.asie.charset.lib.utils.redstone.RedstoneUtils; | |||
@MCMPAddon | |||
public class MCMPAddonCharset extends AnnotatedPluginHandler<IMCMPAddon> implements IMCMPAddon { | |||
@@ -36,6 +37,7 @@ public class MCMPAddonCharset extends AnnotatedPluginHandler<IMCMPAddon> impleme | |||
public void registerParts(IMultipartRegistry registry) { | |||
OcclusionUtils.INSTANCE = new OcclusionUtilsMultipart(); | |||
DebugInfoProvider.registerHandler(new DebugInfoProviderMCMP()); | |||
RedstoneUtils.addRedstoneGetter(new RedstoneGetterMultipart()); | |||
for (IMCMPAddon addon : getPlugins()) { | |||
addon.registerParts(registry); |
@@ -19,10 +19,13 @@ | |||
package pl.asie.charset.lib.modcompat.mcmultipart; | |||
import mcmultipart.api.container.IMultipartContainer; | |||
import mcmultipart.api.container.IPartInfo; | |||
import mcmultipart.api.item.ItemBlockMultipart; | |||
import mcmultipart.api.multipart.IMultipart; | |||
import mcmultipart.api.multipart.MultipartHelper; | |||
import mcmultipart.api.slot.EnumEdgeSlot; | |||
import mcmultipart.api.slot.EnumFaceSlot; | |||
import mcmultipart.api.slot.IPartSlot; | |||
import net.minecraft.block.state.IBlockState; | |||
import net.minecraft.entity.player.EntityPlayer; | |||
@@ -32,11 +35,42 @@ import net.minecraft.util.EnumHand; | |||
import net.minecraft.util.math.BlockPos; | |||
import net.minecraft.world.World; | |||
import java.util.Collection; | |||
import java.util.HashSet; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import java.util.stream.Stream; | |||
public final class MCMPUtils { | |||
private MCMPUtils() { | |||
} | |||
private static void addSlot(IPartSlot slot, IMultipartContainer container, Collection<IPartSlot> partSlots, Stream.Builder<IPartInfo> builder) { | |||
if (slot != null) { | |||
partSlots.add(slot); | |||
container.get(slot).ifPresent(builder); | |||
} | |||
} | |||
// FIXME: Hack to work around deficiencies in MCMultiPart 2 as-is | |||
public static Stream<IPartInfo> streamParts(IMultipartContainer container, EnumFacing edge, EnumFacing face) { | |||
Stream.Builder<IPartInfo> streamBuilder = Stream.builder(); | |||
Set<IPartSlot> partSlots = new HashSet<>(); | |||
if (edge != null) addSlot(EnumEdgeSlot.fromFaces(edge, face), container, partSlots, streamBuilder); | |||
addSlot(EnumFaceSlot.fromFace(face), container, partSlots, streamBuilder); | |||
if (edge != null) addSlot(EnumFaceSlot.fromFace(edge), container, partSlots, streamBuilder); | |||
for (IPartSlot slot : container.getParts().keySet()) { | |||
if (partSlots.add(slot)) { | |||
addSlot(slot, container, partSlots, streamBuilder); | |||
} | |||
} | |||
return streamBuilder.build(); | |||
} | |||
public static boolean placePartAt(ItemStack stack, EntityPlayer player, EnumHand hand, World world, BlockPos pos, EnumFacing facing, | |||
float hitX, float hitY, float hitZ, IMultipart multipartBlock, IBlockState state) { | |||
IPartSlot slot = multipartBlock.getSlotForPlacement(world, pos, state, facing, hitX, hitY, hitZ, player); |
@@ -17,28 +17,39 @@ | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.simplelogic.gates; | |||
package pl.asie.charset.lib.modcompat.mcmultipart; | |||
import mcmultipart.api.container.IMultipartContainer; | |||
import mcmultipart.api.multipart.MultipartCapabilityHelper; | |||
import mcmultipart.api.multipart.MultipartHelper; | |||
import mcmultipart.api.multipart.MultipartRedstoneHelper; | |||
import mcmultipart.api.slot.EnumEdgeSlot; | |||
import net.minecraft.util.EnumFacing; | |||
import net.minecraft.util.math.BlockPos; | |||
import net.minecraft.world.IBlockAccess; | |||
import pl.asie.charset.lib.capability.Capabilities; | |||
import pl.asie.charset.lib.utils.redstone.IRedstoneGetter; | |||
import javax.annotation.Nullable; | |||
import java.util.Optional; | |||
public class RedstoneGetterMultipart implements IRedstoneGetter { | |||
@Override | |||
public int get(IBlockAccess world, BlockPos pos, EnumFacing face, EnumFacing edge) { | |||
public int get(IBlockAccess world, BlockPos pos, EnumFacing face, @Nullable EnumFacing edge) { | |||
Optional<IMultipartContainer> container = MultipartHelper.getContainer(world, pos); | |||
//noinspection OptionalIsPresent | |||
if (container.isPresent()) { | |||
if (edge != null) { | |||
return MultipartRedstoneHelper.getWeakPower(container.get(), EnumEdgeSlot.fromFaces(face.getOpposite(), edge), face.getOpposite()); | |||
} else { | |||
return MultipartRedstoneHelper.getWeakPower(container.get(), face.getOpposite()); | |||
} | |||
return MCMPUtils.streamParts(container.get(), edge, face.getOpposite()).map( | |||
(info) -> { | |||
if (info.getTile().hasPartCapability(Capabilities.REDSTONE_EMITTER, face.getOpposite())) { | |||
return info.getTile().getPartCapability(Capabilities.REDSTONE_EMITTER, face.getOpposite()).getRedstoneSignal(); | |||
} else if (info.getState().canProvidePower()) { | |||
return info.getPart().getWeakPower(info.getPartWorld(), info.getPartPos(), info, face); | |||
} else { | |||
return -1; | |||
} | |||
} | |||
).filter((a) -> a >= 0).findFirst().orElse(0); | |||
} else { | |||
return -1; | |||
} |
@@ -17,7 +17,7 @@ | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.simplelogic.gates.modcompat.redstonepaste; | |||
package pl.asie.charset.lib.modcompat.redstonepaste; | |||
import com.google.common.collect.Table; | |||
import com.google.common.collect.Tables; | |||
@@ -31,8 +31,8 @@ import net.minecraftforge.fml.common.Mod; | |||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; | |||
import pl.asie.charset.lib.loader.CharsetModule; | |||
import pl.asie.charset.lib.loader.ModuleProfile; | |||
import pl.asie.simplelogic.gates.IRedstoneGetter; | |||
import pl.asie.simplelogic.gates.RedstoneGetterHandler; | |||
import pl.asie.charset.lib.utils.redstone.IRedstoneGetter; | |||
import pl.asie.charset.lib.utils.redstone.RedstoneUtils; | |||
import java.util.EnumMap; | |||
@@ -44,11 +44,11 @@ import java.util.EnumMap; | |||
* My apologies. | |||
*/ | |||
@CharsetModule( | |||
name = "redstonepaste:simplelogic.gates", | |||
name = "redstonepaste:lib", | |||
profile = ModuleProfile.COMPAT, | |||
dependencies = {"mod:redstonepaste", "simplelogic.gates"} | |||
dependencies = {"mod:redstonepaste"} | |||
) | |||
public class SimpleLogicCompatRedstonePaste { | |||
public class CharsetCompatRedstonePaste { | |||
private static final Table<EnumFacing, EnumFacing, Integer> faceEdgeBit = Tables.newCustomTable( | |||
new EnumMap<>(EnumFacing.class), | |||
() -> new EnumMap<>(EnumFacing.class) | |||
@@ -125,6 +125,6 @@ public class SimpleLogicCompatRedstonePaste { | |||
@Mod.EventHandler | |||
public void onPostInit(FMLPostInitializationEvent event) { | |||
RedstoneGetterHandler.GETTERS.add(new RedstoneGetterPaste()); | |||
RedstoneUtils.addRedstoneGetter(new RedstoneGetterPaste()); | |||
} | |||
} |
@@ -35,12 +35,15 @@ import gnu.trove.set.TIntSet; | |||
import gnu.trove.set.hash.TIntHashSet; | |||
import net.minecraft.init.Blocks; | |||
import net.minecraft.item.EnumDyeColor; | |||
import net.minecraft.item.Item; | |||
import net.minecraft.item.ItemStack; | |||
import net.minecraft.item.crafting.Ingredient; | |||
import net.minecraft.util.JsonUtils; | |||
import net.minecraft.util.NonNullList; | |||
import net.minecraft.util.ResourceLocation; | |||
import net.minecraftforge.common.crafting.IIngredientFactory; | |||
import net.minecraftforge.common.crafting.JsonContext; | |||
import net.minecraftforge.fml.common.registry.ForgeRegistries; | |||
import net.minecraftforge.oredict.OreDictionary; | |||
import pl.asie.charset.lib.recipe.ingredient.IngredientCharset; | |||
import pl.asie.charset.lib.recipe.ingredient.IngredientWrapper; | |||
@@ -74,16 +77,17 @@ public class IngredientGroup extends IngredientCharset { | |||
} | |||
private static final Map<String, Entry> entryMap = new HashMap<>(); | |||
private final String type, nbtTag; | |||
private final String type, nbtTag, itemPrefix; | |||
private final TIntSet blacklistedIds; | |||
private final boolean modifyMeta; | |||
private char dependencyChar; | |||
private Ingredient dependency; | |||
public IngredientGroup(String type, String nbtTag, boolean modifyMeta, TIntSet blacklistedIds, char depChar) { | |||
public IngredientGroup(String type, String nbtTag, String itemPrefix, boolean modifyMeta, TIntSet blacklistedIds, char depChar) { | |||
super(); | |||
this.type = type; | |||
this.nbtTag = nbtTag; | |||
this.itemPrefix = itemPrefix; | |||
this.modifyMeta = modifyMeta; | |||
this.blacklistedIds = blacklistedIds; | |||
this.dependencyChar = depChar; | |||
@@ -201,6 +205,19 @@ public class IngredientGroup extends IngredientCharset { | |||
} else { | |||
ItemUtils.getTagCompound(stack, true).setInteger(nbtTag, id); | |||
} | |||
} else if (itemPrefix != null) { | |||
int id = getId(source); | |||
Entry e = entryMap.get(type); | |||
if (e != null && !e.isStringBased()) { | |||
Item it = ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemPrefix + id)); | |||
if (it == null) { | |||
throw new RuntimeException("Could not find item " + itemPrefix + id + "!"); | |||
} | |||
ItemStack newStack = new ItemStack(it, stack.getCount(), stack.getItemDamage()); | |||
newStack.setTagCompound(stack.getTagCompound()); | |||
stack = newStack; | |||
} | |||
} else if (modifyMeta) { | |||
int id = getId(source); | |||
Entry e = entryMap.get(type); | |||
@@ -291,6 +308,7 @@ public class IngredientGroup extends IngredientCharset { | |||
public Ingredient parse(JsonContext context, JsonObject json) { | |||
String type = JsonUtils.getString(json, "group"); | |||
String tag = json.has("nbtKey") ? JsonUtils.getString(json, "nbtKey") : null; | |||
String itPref = json.has("itemPrefix") ? JsonUtils.getString(json, "itemPrefix") : null; | |||
TIntSet blacklistedIds = new TIntHashSet(); | |||
if (JsonUtils.hasField(json, "blacklist")) { | |||
@@ -306,7 +324,7 @@ public class IngredientGroup extends IngredientCharset { | |||
dep = JsonUtils.getString(json, "depends").charAt(0); | |||
} | |||
return IngredientCharset.wrap(new IngredientGroup(type, tag, json.has("modifyMeta"), blacklistedIds, dep)); | |||
return IngredientCharset.wrap(new IngredientGroup(type, tag, itPref, json.has("modifyMeta"), blacklistedIds, dep)); | |||
} | |||
} | |||
} |
@@ -90,7 +90,7 @@ public class IngredientMatcher implements IRecipeResultBuilder { | |||
} | |||
// TODO: Implement for non-distinct ingredients. | |||
(((IngredientWrapper) entry.getKey()).getIngredientCharset()).transform(stack, entry.getValue(), this); | |||
stack = (((IngredientWrapper) entry.getKey()).getIngredientCharset()).transform(stack, entry.getValue(), this); | |||
} | |||
} | |||
@@ -49,6 +49,10 @@ public class CharsetFaceBakery extends FaceBakery { | |||
public BakedQuad makeBakedQuad(Vector3f min, Vector3f max, int tintIndex, float[] uv, | |||
TextureAtlasSprite icon, EnumFacing facing, ITransformation rot, boolean uvLocked) { | |||
if (icon == null) { | |||
return null; | |||
} | |||
boolean hasColorIndex = tintIndex != -1 && ((tintIndex & 0xFF000000) == 0); | |||
boolean hasColor = tintIndex != -1 && ((tintIndex & 0xFF000000) != 0); | |||
@@ -17,15 +17,18 @@ | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.simplelogic.gates; | |||
package pl.asie.charset.lib.utils.redstone; | |||
import net.minecraft.util.EnumFacing; | |||
import net.minecraft.util.math.BlockPos; | |||
import net.minecraft.world.IBlockAccess; | |||
import javax.annotation.Nullable; | |||
import java.util.OptionalInt; | |||
public interface IRedstoneGetter { | |||
// -1 = don't use, 0-15 = value | |||
int get(IBlockAccess world, BlockPos pos, EnumFacing face, EnumFacing edge); | |||
/** | |||
* @return -1 = ignore result (use next handler), 0-15 - redstone signal value | |||
*/ | |||
int get(IBlockAccess world, BlockPos pos, EnumFacing face, @Nullable EnumFacing edge); | |||
} |
@@ -17,7 +17,7 @@ | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.utils; | |||
package pl.asie.charset.lib.utils.redstone; | |||
import mcmultipart.api.container.IMultipartContainer; | |||
import mcmultipart.api.multipart.MultipartHelper; | |||
@@ -31,6 +31,8 @@ import net.minecraft.world.IBlockAccess; | |||
import net.minecraft.world.World; | |||
import net.minecraftforge.fml.common.Loader; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Optional; | |||
/** | |||
@@ -41,6 +43,23 @@ public final class RedstoneUtils { | |||
} | |||
private static final List<IRedstoneGetter> GETTERS = new ArrayList<>(); | |||
public static void addRedstoneGetter(IRedstoneGetter getter) { | |||
GETTERS.add(getter); | |||
} | |||
public static int getModdedWeakPower(IBlockAccess w, BlockPos p, EnumFacing face, EnumFacing edge) { | |||
for (IRedstoneGetter getter : GETTERS) { | |||
int v = getter.get(w, p, face, edge); | |||
if (v >= 0) { | |||
return v; | |||
} | |||
} | |||
return -1; | |||
} | |||
// TODO: Evaluate me | |||
public static int getRedstonePower(World world, BlockPos pos, EnumFacing facing) { | |||
IBlockState iblockstate = world.getBlockState(pos); |
@@ -19,8 +19,10 @@ | |||
package pl.asie.charset.lib.wires; | |||
import com.google.common.collect.ImmutableSet; | |||
import mcmultipart.api.container.IPartInfo; | |||
import mcmultipart.api.slot.EnumCenterSlot; | |||
import mcmultipart.api.slot.EnumEdgeSlot; | |||
import mcmultipart.api.slot.EnumFaceSlot; | |||
import mcmultipart.api.slot.IPartSlot; | |||
import mcmultipart.api.world.IMultipartWorld; | |||
@@ -37,6 +39,7 @@ import net.minecraft.item.ItemStack; | |||
import net.minecraft.tileentity.TileEntity; | |||
import net.minecraft.util.BlockRenderLayer; | |||
import net.minecraft.util.EnumFacing; | |||
import net.minecraft.util.EnumHand; | |||
import net.minecraft.util.NonNullList; | |||
import net.minecraft.util.math.AxisAlignedBB; | |||
import net.minecraft.util.math.BlockPos; | |||
@@ -56,6 +59,7 @@ import pl.asie.charset.lib.modcompat.mcmultipart.IMultipartBase; | |||
import javax.annotation.Nullable; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Set; | |||
public class BlockWire extends BlockBase implements IMultipartBase, ITileEntityProvider { | |||
protected static final PropertyBool REDSTONE = PropertyBool.create("redstone"); | |||
@@ -65,6 +69,7 @@ public class BlockWire extends BlockBase implements IMultipartBase, ITileEntityP | |||
setHardness(0.0f); | |||
setOpaqueCube(false); | |||
setFullCube(false); | |||
setDefaultState(getDefaultState().withProperty(REDSTONE, false)); | |||
} | |||
@Override | |||
@@ -251,6 +256,20 @@ public class BlockWire extends BlockBase implements IMultipartBase, ITileEntityP | |||
} | |||
} | |||
@Override | |||
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { | |||
IBlockState state = getDefaultState(); | |||
ItemStack stack = placer.getHeldItem(hand); | |||
if (stack.getItem() instanceof ItemWire) { | |||
WireProvider provider = ((ItemWire) stack.getItem()).getWireProvider(); | |||
if (provider != null && provider.canProvidePower()) { | |||
state = state.withProperty(REDSTONE, true); | |||
} | |||
} | |||
return state; | |||
} | |||
@Override | |||
public IPartSlot getSlotForPlacement(World world, BlockPos pos, IBlockState state, EnumFacing facing, float hitX, float hitY, float hitZ, EntityLivingBase placer) { | |||
ItemStack stack = placer.getHeldItemMainhand(); |
@@ -33,6 +33,7 @@ import net.minecraftforge.event.RegistryEvent; | |||
import net.minecraftforge.fml.common.Mod; | |||
import net.minecraftforge.fml.common.event.FMLInitializationEvent; | |||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; | |||
import net.minecraftforge.fml.common.eventhandler.EventPriority; | |||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | |||
import net.minecraftforge.fml.common.registry.ForgeRegistries; | |||
import net.minecraftforge.fml.relauncher.Side; | |||
@@ -42,6 +43,7 @@ import pl.asie.charset.ModCharset; | |||
import pl.asie.charset.lib.loader.CharsetModule; | |||
import pl.asie.charset.lib.loader.ModuleProfile; | |||
import pl.asie.charset.lib.utils.RegistryUtils; | |||
import pl.asie.simplelogic.wires.logic.WireRenderHandlerOverlay; | |||
import javax.annotation.Nullable; | |||
@@ -112,14 +114,16 @@ public class CharsetLibWires { | |||
rendererWire = new RendererWire(); | |||
} | |||
@SubscribeEvent | |||
@SubscribeEvent(priority = EventPriority.LOW) | |||
@SideOnly(Side.CLIENT) | |||
public void onTextureStitchPre(TextureStitchEvent.Pre event) { | |||
WireManager.REGISTRY.unfreeze(); | |||
for (WireProvider provider : WireManager.REGISTRY) { | |||
rendererWire.registerSheet(event.getMap(), provider); | |||
if (rendererWire.getContainer(provider) == null) { | |||
rendererWire.registerContainer(provider, new IWireRenderContainer.Simple(new WireRenderHandlerDefault(provider))); | |||
} | |||
} | |||
rendererWire.reloadTextures(event.getMap()); | |||
} | |||
@SubscribeEvent | |||
@@ -135,4 +139,8 @@ public class CharsetLibWires { | |||
public void initClient(FMLInitializationEvent event) { | |||
MinecraftForge.EVENT_BUS.register(new WireHighlightHandler()); | |||
} | |||
public void registerRenderer(WireProvider provider, IWireRenderContainer container) { | |||
rendererWire.registerContainer(provider, container); | |||
} | |||
} |
@@ -17,22 +17,33 @@ | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.capability.redstone; | |||
package pl.asie.charset.lib.wires; | |||
import pl.asie.charset.api.wires.IRedstoneEmitter; | |||
import net.minecraftforge.fml.relauncher.Side; | |||
import net.minecraftforge.fml.relauncher.SideOnly; | |||
import java.util.List; | |||
import java.util.function.Function; | |||
public interface IWireRenderContainer { | |||
final class Simple implements IWireRenderContainer { | |||
private final WireRenderHandler handler; | |||
public class RedstoneEmitterWrapper implements Function<List<IRedstoneEmitter>, IRedstoneEmitter> { | |||
@Override | |||
public IRedstoneEmitter apply(List<IRedstoneEmitter> collection) { | |||
int data = 0; | |||
public Simple(WireRenderHandler handler) { | |||
this.handler = handler; | |||
} | |||
for (IRedstoneEmitter emitter : collection) { | |||
data = Math.max(data, emitter.getRedstoneSignal()); | |||
@Override | |||
public int getLayerCount() { | |||
return 1; | |||
} | |||
return new DefaultRedstoneEmitter(data); | |||
@Override | |||
public WireRenderHandler get(int layer) { | |||
return handler; | |||
} | |||
} | |||
@SideOnly(Side.CLIENT) | |||
int getLayerCount(); | |||
@SideOnly(Side.CLIENT) | |||
WireRenderHandler get(int layer); | |||
} |
@@ -37,6 +37,7 @@ import net.minecraft.util.text.translation.I18n; | |||
import net.minecraft.world.World; | |||
import pl.asie.charset.api.wires.WireFace; | |||
import pl.asie.charset.lib.CharsetLib; | |||
import pl.asie.charset.lib.modcompat.mcmultipart.MCMPUtils; | |||
import javax.annotation.Nullable; | |||
@@ -111,10 +112,6 @@ public class ItemWire extends ItemBlockMultipart { | |||
return false; | |||
} | |||
if (provider.canProvidePower()) { | |||
newState = newState.withProperty(BlockWire.REDSTONE, true); | |||
} | |||
if (super.placeBlockAtTested(stack, player, world, pos, facing, hitX, hitY, hitZ, newState)) { | |||
TileEntity tileEntity = world.getTileEntity(pos); | |||
if (tileEntity instanceof TileWire) { |
@@ -33,38 +33,13 @@ import pl.asie.charset.api.wires.WireFace; | |||
import pl.asie.charset.lib.render.CharsetFaceBakery; | |||
import pl.asie.charset.lib.render.model.ModelFactory; | |||
import pl.asie.charset.lib.render.model.SimpleBakedModel; | |||
import pl.asie.charset.lib.render.sprite.SpritesheetFactory; | |||
import javax.annotation.Nonnull; | |||
import javax.annotation.Nullable; | |||
import java.util.Collection; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
public class RendererWire extends ModelFactory<Wire> { | |||
public static class WireSheet { | |||
@Nonnull final TextureAtlasSprite[] top; | |||
@Nullable final TextureAtlasSprite side; | |||
@Nullable final TextureAtlasSprite edge; | |||
@Nonnull final TextureAtlasSprite particle; | |||
final int width, height; | |||
private WireSheet(TextureMap map, String domain, String path, WireProvider type) { | |||
top = SpritesheetFactory.register(map, new ResourceLocation(domain, path + "top"), 4, 4); | |||
particle = map.registerSprite(new ResourceLocation(domain, path + "particle")); | |||
if (!type.isFlat()) { | |||
edge = map.registerSprite(new ResourceLocation(domain, path + "edge")); | |||
side = map.registerSprite(new ResourceLocation(domain, path + "side")); | |||
} else { | |||
edge = null; | |||
side = null; | |||
} | |||
width = (int) (type.getWidth() * 16); | |||
height = (int) (type.getHeight() * 16); | |||
} | |||
} | |||
private final ModelRotation[] ROTATIONS = new ModelRotation[]{ | |||
ModelRotation.X0_Y0, | |||
ModelRotation.X180_Y0, | |||
@@ -74,28 +49,21 @@ public class RendererWire extends ModelFactory<Wire> { | |||
ModelRotation.X270_Y90 | |||
}; | |||
private final Map<WireProvider, WireSheet> sheetMap = new HashMap<>(); | |||
private final Map<WireProvider, IWireRenderContainer> containerMap = new HashMap<>(); | |||
public RendererWire() { | |||
super(Wire.PROPERTY, new ResourceLocation("minecraft:blocks/stone")); | |||
super(Wire.PROPERTY, TextureMap.LOCATION_MISSING_TEXTURE); | |||
addDefaultBlockTransforms(); | |||
} | |||
public WireSheet getSheet(WireProvider type) { | |||
return sheetMap.get(type); | |||
private <T> void addNonNull(Collection<T> coll, T object) { | |||
if (object != null) { | |||
coll.add(object); | |||
} | |||
} | |||
public void registerSheet(TextureMap map, WireProvider type) { | |||
ResourceLocation location = type.getTexturePrefix(); | |||
String domain = location.getResourceDomain(); | |||
String path = location.getResourcePath(); | |||
if (!path.endsWith("/")) { | |||
path += "_"; | |||
} | |||
WireSheet sheet = new WireSheet(map, domain, path, type); | |||
sheetMap.put(type, sheet); | |||
public IWireRenderContainer getContainer(WireProvider type) { | |||
return containerMap.get(type); | |||
} | |||
private boolean wc(Wire wire, EnumFacing facing) { | |||
@@ -108,7 +76,7 @@ public class RendererWire extends ModelFactory<Wire> { | |||
return false; | |||
} | |||
private float getCL(Wire wire, WireFace side) { | |||
private float getCL(WireRenderHandler handler, Wire wire, WireFace side) { | |||
// TODO | |||
//float h = wire != null && wire.hasWire(side) ? wire.getWireKind(side).height() : 0; | |||
float h = 0; | |||
@@ -117,95 +85,149 @@ public class RendererWire extends ModelFactory<Wire> { | |||
h = 0; | |||
} | |||
if (!wc(wire, side.facing) && wire.getProvider() != null) { | |||
h = 8.0f - (sheetMap.get(wire.getProvider()).width / 2); // TODO: Replace with WireProvider call? | |||
if (!wc(wire, side.facing)) { | |||
h = 8.0f - (handler.getWidth() * 8); | |||
} | |||
return side.facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? 16.0f - h : h; | |||
} | |||
public void addWireFreestanding(Wire wire, WireSheet sheet, int renderColor, List<BakedQuad> quads) { | |||
float min = 8.0f - (sheet.width / 2); | |||
float max = 8.0f + (sheet.width / 2); | |||
Vector3f minX = new Vector3f(min, getCL(wire, WireFace.DOWN), getCL(wire, WireFace.NORTH)); | |||
Vector3f maxX = new Vector3f(min, getCL(wire, WireFace.UP), getCL(wire, WireFace.SOUTH)); | |||
Vector3f minY = new Vector3f(getCL(wire, WireFace.WEST), min, getCL(wire, WireFace.NORTH)); | |||
Vector3f maxY = new Vector3f(getCL(wire, WireFace.EAST), min, getCL(wire, WireFace.SOUTH)); | |||
Vector3f minZ = new Vector3f(getCL(wire, WireFace.WEST), getCL(wire, WireFace.DOWN), min); | |||
Vector3f maxZ = new Vector3f(getCL(wire, WireFace.EAST), getCL(wire, WireFace.UP), min); | |||
// NORTH SOUTH WEST EAST | |||
protected void addTopFaceCplxInner(WireRenderHandler handler, Wire wire, EnumFacing facing, EnumFacing renderFace, EnumFacing[] dirs, int dirI, Vector3f from, Vector3f to, List<BakedQuad> quads, int connMask, ModelRotation rot) { | |||
float minX = 8.0f - (handler.getWidth() * 8); | |||
float maxX = 16.0f - minX; | |||
float minZ = minX; | |||
float maxZ = maxX; | |||
int dirP = dirI; | |||
switch (dirP) { | |||
case 0: | |||
minZ = 0.0f; | |||
maxZ = minX; | |||
break; | |||
case 1: | |||
minZ = maxZ; | |||
maxZ = 16.0f; | |||
break; | |||
case 2: | |||
minX = 0.0f; | |||
maxX = minZ; | |||
break; | |||
case 3: | |||
minX = maxX; | |||
maxX = 16.0f; | |||
break; | |||
default: | |||
break; | |||
} | |||
switch (renderFace.getAxis()) { | |||
case X: | |||
from = new Vector3f(from.x, minX, minZ); | |||
to = new Vector3f(to.x, maxX, maxZ); | |||
break; | |||
case Y: | |||
from = new Vector3f(minX, from.y, minZ); | |||
to = new Vector3f(maxX, to.y, maxZ); | |||
break; | |||
case Z: | |||
from = new Vector3f(minX, minZ, from.z); | |||
to = new Vector3f(maxX, maxZ, to.z); | |||
break; | |||
} | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
from, to, handler.getColor(WireRenderHandler.TextureType.TOP, wire, dirI < 0 ? null : dirs[dirI]), | |||
new float[] { minX, minZ, maxX, maxZ }, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, dirI < 0 ? null : dirs[dirI], connMask), | |||
renderFace, rot, true | |||
) | |||
); | |||
} | |||
protected void makeTopFace(List<BakedQuad> quads, WireRenderHandler handler, Wire wire, Vector3f from, Vector3f to, int connMask, EnumFacing facing, EnumFacing renderFacing, ModelRotation rot) { | |||
if (!handler.isTopSimple()) { | |||
// Render the top face as up to five quads | |||
EnumFacing[] dirs = WireUtils.getConnectionsForRender(WireFace.get(EnumFacing.getFront(facing.ordinal() & (~1)))); | |||
addTopFaceCplxInner(handler, wire, facing, renderFacing, dirs, -1, from, to, quads, connMask, rot); | |||
if ((connMask & 8) != 0) addTopFaceCplxInner(handler, wire, facing, renderFacing, dirs, 0, from, to, quads, connMask, rot); | |||
if ((connMask & 4) != 0) addTopFaceCplxInner(handler, wire, facing, renderFacing, dirs, 1, from, to, quads, connMask, rot); | |||
if ((connMask & 2) != 0) addTopFaceCplxInner(handler, wire, facing, renderFacing, dirs, 2, from, to, quads, connMask, rot); | |||
if ((connMask & 1) != 0) addTopFaceCplxInner(handler, wire, facing, renderFacing, dirs, 3, from, to, quads, connMask, rot); | |||
return; | |||
} | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
from, to, handler.getColor(WireRenderHandler.TextureType.TOP, wire, null), | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, connMask), | |||
renderFacing, rot, true | |||
) | |||
); | |||
} | |||
public void addWireFreestanding(WireRenderHandler handler, Wire wire, List<BakedQuad> quads) { | |||
float min = 8.0f - (handler.getWidth() * 8); | |||
float max = 16.0f - min; | |||
Vector3f minX = new Vector3f(min, getCL(handler, wire, WireFace.DOWN), getCL(handler, wire, WireFace.NORTH)); | |||
Vector3f maxX = new Vector3f(min, getCL(handler, wire, WireFace.UP), getCL(handler, wire, WireFace.SOUTH)); | |||
Vector3f minY = new Vector3f(getCL(handler, wire, WireFace.WEST), min, getCL(handler, wire, WireFace.NORTH)); | |||
Vector3f maxY = new Vector3f(getCL(handler, wire, WireFace.EAST), min, getCL(handler, wire, WireFace.SOUTH)); | |||
Vector3f minZ = new Vector3f(getCL(handler, wire, WireFace.WEST), getCL(handler, wire, WireFace.DOWN), min); | |||
Vector3f maxZ = new Vector3f(getCL(handler, wire, WireFace.EAST), getCL(handler, wire, WireFace.UP), min); | |||
int cmcX = (wc(wire, EnumFacing.UP) ? 8 : 0) | (wc(wire, EnumFacing.DOWN) ? 4 : 0) | (wc(wire, EnumFacing.NORTH) ? 2 : 0) | (wc(wire, EnumFacing.SOUTH) ? 1 : 0); | |||
int cmcY = (wc(wire, EnumFacing.NORTH) ? 4 : 0) | (wc(wire, EnumFacing.SOUTH) ? 8 : 0) | (wc(wire, EnumFacing.WEST) ? 2 : 0) | (wc(wire, EnumFacing.EAST) ? 1 : 0); | |||
int cmcZ = (wc(wire, EnumFacing.UP) ? 8 : 0) | (wc(wire, EnumFacing.DOWN) ? 4 : 0) | (wc(wire, EnumFacing.WEST) ? 1 : 0) | (wc(wire, EnumFacing.EAST) ? 2 : 0); | |||
for (int i = 0; i < 2; i++) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
minX, maxX, renderColor, | |||
sheet.top[cmcX], i == 0 ? EnumFacing.WEST : EnumFacing.EAST, | |||
ModelRotation.X0_Y0, true | |||
) | |||
); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
minY, maxY, renderColor, | |||
sheet.top[cmcY], i == 0 ? EnumFacing.DOWN : EnumFacing.UP, | |||
ModelRotation.X0_Y0, true | |||
) | |||
); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
minZ, maxZ, renderColor, | |||
sheet.top[cmcZ], i == 0 ? EnumFacing.NORTH : EnumFacing.SOUTH, | |||
ModelRotation.X0_Y0, true | |||
) | |||
); | |||
if (i == 0) { | |||
// set to max | |||
minX.setX(max); | |||
maxX.setX(max); | |||
minY.setY(max); | |||
maxY.setY(max); | |||
minZ.setZ(max); | |||
maxZ.setZ(max); | |||
// swap | |||
cmcY = (cmcY & 0x3) | ((cmcY & 0x8) >> 1) | ((cmcY & 0x4) << 1); | |||
cmcZ = (cmcZ & 0xC) | ((cmcZ & 0x2) >> 1) | ((cmcZ & 0x1) << 1); | |||
cmcX = (cmcX & 0xC) | ((cmcX & 0x2) >> 1) | ((cmcX & 0x1) << 1); | |||
} | |||
} | |||
if (sheet.edge != null) { | |||
for (EnumFacing f : EnumFacing.VALUES) { | |||
if (wc(wire, f)) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0.0F, min), new Vector3f(max, 0.0f, max), | |||
renderColor, | |||
f.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? new float[]{max, min, min, max} : new float[]{min, min, max, max}, | |||
sheet.edge, EnumFacing.DOWN, ROTATIONS[f.ordinal()], true | |||
) | |||
); | |||
} | |||
makeTopFace(quads, handler, wire, minX, maxX, cmcX, EnumFacing.WEST, EnumFacing.WEST, ModelRotation.X0_Y0); | |||
makeTopFace(quads, handler, wire, minY, maxY, cmcY, EnumFacing.DOWN, EnumFacing.DOWN, ModelRotation.X0_Y0); | |||
makeTopFace(quads, handler, wire, minZ, maxZ, cmcZ, EnumFacing.NORTH, EnumFacing.NORTH, ModelRotation.X0_Y0); | |||
// set to max | |||
minX.setX(max); | |||
maxX.setX(max); | |||
minY.setY(max); | |||
maxY.setY(max); | |||
minZ.setZ(max); | |||
maxZ.setZ(max); | |||
// swap | |||
cmcY = (cmcY & 0x3) | ((cmcY & 0x8) >> 1) | ((cmcY & 0x4) << 1); | |||
cmcZ = (cmcZ & 0xC) | ((cmcZ & 0x2) >> 1) | ((cmcZ & 0x1) << 1); | |||
cmcX = (cmcX & 0xC) | ((cmcX & 0x2) >> 1) | ((cmcX & 0x1) << 1); | |||
makeTopFace(quads, handler, wire, minX, maxX, cmcX, EnumFacing.EAST, EnumFacing.EAST, ModelRotation.X0_Y0); | |||
makeTopFace(quads, handler, wire, minY, maxY, cmcY, EnumFacing.UP, EnumFacing.UP, ModelRotation.X0_Y0); | |||
makeTopFace(quads, handler, wire, minZ, maxZ, cmcZ, EnumFacing.SOUTH, EnumFacing.SOUTH, ModelRotation.X0_Y0); | |||
for (EnumFacing f : EnumFacing.VALUES) { | |||
if (wc(wire, f)) { | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0.0F, min), new Vector3f(max, 0.0f, max), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, f), | |||
f.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? new float[]{max, min, min, max} : new float[]{min, min, max, max}, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, f, 15), | |||
EnumFacing.DOWN, ROTATIONS[f.ordinal()], true | |||
) | |||
); | |||
} | |||
} | |||
} | |||
public void addCorner(Wire wire, WireSheet sheet, EnumFacing dir, int renderColor, List<BakedQuad> quads) { | |||
public void addCorner(WireRenderHandler handler, Wire wire, EnumFacing dir, List<BakedQuad> quads) { | |||
if (wire.getProvider().isFlat()) { | |||
return; | |||
} | |||
int width = sheet.width; | |||
int height = sheet.height; | |||
int width = (int) (handler.getWidth() * 16.0f); | |||
int height = (int) (handler.getHeight() * 16.0f); | |||
ModelRotation rot = ROTATIONS[wire.getLocation().ordinal()]; | |||
float min = 8.0f - (width / 2); | |||
float max = 8.0f + (width / 2); | |||
float max = 16.0f - min; | |||
// Edge faces | |||
@@ -215,186 +237,177 @@ public class RendererWire extends ModelFactory<Wire> { | |||
if (dir == EnumFacing.NORTH) { | |||
float[] topUV = new float[]{min, 16 - height, max, 16}; | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0, -height), new Vector3f(max, height, -height), | |||
renderColor, edgeUVFlipped, | |||
sheet.top[15], EnumFacing.NORTH, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.NORTH), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, height, -height), new Vector3f(max, height, 0), | |||
renderColor, topUV, | |||
sheet.top[15], EnumFacing.UP, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.UP), topUV, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.UP, rot, false | |||
) | |||
); | |||
if (sheet.edge != null) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0, -height), new Vector3f(min, height, 0), | |||
renderColor, edgeUV, | |||
sheet.edge, EnumFacing.WEST, rot, false | |||
) | |||
); | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0, -height), new Vector3f(min, height, 0), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.WEST, rot, false | |||
) | |||
); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(max, 0, -height), new Vector3f(max, height, 0), | |||
renderColor, edgeUVFlipped, | |||
sheet.edge, EnumFacing.EAST, rot, false | |||
) | |||
); | |||
} | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(max, 0, -height), new Vector3f(max, height, 0), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.EAST, rot, false | |||
) | |||
); | |||
} else if (dir == EnumFacing.SOUTH) { | |||
float[] topUV = new float[]{min, 0, max, height}; | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0, 16 + height), new Vector3f(max, height, 16 + height), | |||
renderColor, edgeUVFlipped, | |||
sheet.top[15], EnumFacing.SOUTH, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.SOUTH), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, height, 16), new Vector3f(max, height, 16 + height), | |||
renderColor, topUV, | |||
sheet.top[15], EnumFacing.UP, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.UP), topUV, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.UP, rot, false | |||
) | |||
); | |||
if (sheet.edge != null) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0, 16), new Vector3f(min, height, 16 + height), | |||
renderColor, edgeUV, | |||
sheet.edge, EnumFacing.WEST, rot, false | |||
) | |||
); | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, 0, 16), new Vector3f(min, height, 16 + height), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.WEST, rot, false | |||
) | |||
); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(max, 0, 16), new Vector3f(max, height, 16 + height), | |||
renderColor, edgeUVFlipped, | |||
sheet.edge, EnumFacing.EAST, rot, false | |||
) | |||
); | |||
} | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(max, 0, 16), new Vector3f(max, height, 16 + height), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.EAST, rot, false | |||
) | |||
); | |||
} else if (dir == EnumFacing.WEST) { | |||
float[] topUV = new float[]{16 - height, min, 16, max}; | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(-height, height, min), new Vector3f(0, height, max), | |||
renderColor, topUV, | |||
sheet.top[15], EnumFacing.UP, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.UP), topUV, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.UP, rot, false | |||
) | |||
); | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(-height, 0, min), new Vector3f(-height, height, max), | |||
renderColor, edgeUV, | |||
sheet.top[15], EnumFacing.WEST, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.WEST), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.WEST, rot, false | |||
) | |||
); | |||
if (sheet.edge != null) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(-height, 0, min), new Vector3f(0, height, min), | |||
renderColor, edgeUVFlipped, | |||
sheet.edge, EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(-height, 0, min), new Vector3f(0, height, min), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(-height, 0, max), new Vector3f(0, height, max), | |||
renderColor, edgeUV, | |||
sheet.edge, EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
} | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(-height, 0, max), new Vector3f(0, height, max), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
} else if (dir == EnumFacing.EAST) { | |||
float[] topUV = new float[]{0, min, height, max}; | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16, height, min), new Vector3f(16 + height, height, max), | |||
renderColor, topUV, | |||
sheet.top[15], EnumFacing.UP, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.UP), topUV, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.UP, rot, false | |||
) | |||
); | |||
quads.add( | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16 + height, 0, min), new Vector3f(16 + height, height, max), | |||
renderColor, edgeUV, | |||
sheet.top[15], EnumFacing.EAST, rot, false | |||
handler.getColor(WireRenderHandler.TextureType.TOP, wire, EnumFacing.EAST), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.TOP, wire, null, 15), EnumFacing.EAST, rot, false | |||
) | |||
); | |||
if (sheet.edge != null) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16, 0, min), new Vector3f(16 + height, height, min), | |||
renderColor, edgeUVFlipped, | |||
sheet.edge, EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16, 0, min), new Vector3f(16 + height, height, min), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16, 0, max), new Vector3f(16 + height, height, max), | |||
renderColor, edgeUV, | |||
sheet.edge, EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
} | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16, 0, max), new Vector3f(16 + height, height, max), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, null), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, null, 15), EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
} | |||
} | |||
public void addWire(Wire wire, WireSheet sheet, List<BakedQuad> quads) { | |||
public void addWire(WireRenderHandler handler, Wire wire, List<BakedQuad> quads) { | |||
WireFace side = wire.getLocation(); | |||
int renderColor = wire.getRenderColor(); | |||
if (side == WireFace.CENTER) { | |||
addWireFreestanding(wire, sheet, renderColor, quads); | |||
addWireFreestanding(handler, wire, quads); | |||
return; | |||
} | |||
float min = 8.0f - (sheet.width / 2); | |||
float max = 8.0f + (sheet.width / 2); | |||
float min = 8.0f - (handler.getWidth() * 8f); | |||
float max = 16.0f - min; | |||
float minH = 0.0f; | |||
float maxH = sheet.height; | |||
float maxH = handler.getHeight() * 16f; | |||
EnumFacing[] dirs = WireUtils.getConnectionsForRender(side); | |||
boolean[] connectionMatrix = new boolean[]{ | |||
wire == null || wire.connectsAny(dirs[0]), | |||
wire == null || wire.connectsAny(dirs[1]), | |||
wire == null || wire.connectsAny(dirs[2]), | |||
wire == null || wire.connectsAny(dirs[3]) | |||
wire.connectsAny(dirs[0]), | |||
wire.connectsAny(dirs[1]), | |||
wire.connectsAny(dirs[2]), | |||
wire.connectsAny(dirs[3]) | |||
}; | |||
int cmc = (connectionMatrix[0] ? 8 : 0) | (connectionMatrix[1] ? 4 : 0) | (connectionMatrix[2] ? 2 : 0) | (connectionMatrix[3] ? 1 : 0); | |||
boolean[] cornerConnectionMatrix = new boolean[]{ | |||
wire == null || wire.connectsCorner(dirs[0]), | |||
wire == null || wire.connectsCorner(dirs[1]), | |||
wire == null || wire.connectsCorner(dirs[2]), | |||
wire == null || wire.connectsCorner(dirs[3]) | |||
wire.connectsCorner(dirs[0]), | |||
wire.connectsCorner(dirs[1]), | |||
wire.connectsCorner(dirs[2]), | |||
wire.connectsCorner(dirs[3]) | |||
}; | |||
ModelRotation rot = ROTATIONS[side.ordinal()]; | |||
// Center face | |||
Vector3f from = new Vector3f(min, sheet.height, min); | |||
Vector3f to = new Vector3f(max, sheet.height, max); | |||
Vector3f from = new Vector3f(min, maxH, min); | |||
Vector3f to = new Vector3f(max, maxH, max); | |||
if (connectionMatrix[0]) { | |||
from.setZ(0.0f); | |||
@@ -409,56 +422,43 @@ public class RendererWire extends ModelFactory<Wire> { | |||
to.setX(16.0f); | |||
} | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
from, to, | |||
renderColor, new float[]{from.getX(), from.getZ(), to.getX(), to.getZ()}, | |||
sheet.top[cmc], EnumFacing.UP, | |||
rot, true | |||
) | |||
); | |||
makeTopFace(quads, handler, wire, from, to, cmc, wire.getLocation().facing, EnumFacing.UP, rot); | |||
if (!wire.getProvider().isFlat()) { | |||
from.setY(0.0F); | |||
to.setY(0.0F); | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
from, to, | |||
renderColor, new float[]{from.getX(), from.getZ(), to.getX(), to.getZ()}, | |||
sheet.top[cmc], EnumFacing.DOWN, rot, true | |||
) | |||
); | |||
makeTopFace(quads, handler, wire, from, to, cmc, wire.getLocation().facing, EnumFacing.DOWN, rot); | |||
// Side faces | |||
Vector3f fromZ = new Vector3f(from.getX(), 0.0f, min); | |||
Vector3f toZ = new Vector3f(to.getX(), sheet.height, min); | |||
Vector3f toZ = new Vector3f(to.getX(), maxH, min); | |||
Vector3f fromX = new Vector3f(min, 0.0f, from.getZ()); | |||
Vector3f toX = new Vector3f(min, sheet.height, to.getZ()); | |||
Vector3f toX = new Vector3f(min, maxH, to.getZ()); | |||
// Should we render a faux side wire on this side? (For bundled) | |||
boolean crossroadsX = connectionMatrix[2] && !connectionMatrix[3]; | |||
boolean crossroadsZ = connectionMatrix[0] && !connectionMatrix[1]; | |||
boolean renderSideX = connectionMatrix[0] || connectionMatrix[1]; | |||
boolean renderSideZ = connectionMatrix[2] || connectionMatrix[3]; | |||
// getIcon(false, cmc == 1, crossroadsX, EnumFacing.WEST) | |||
if (sheet.side != null) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromX, toX, | |||
renderColor, new float[]{fromX.getZ(), fromX.getY(), toX.getZ(), toX.getY()}, | |||
sheet.side, EnumFacing.WEST, rot, false | |||
) | |||
); | |||
if (!connectionMatrix[2] || renderSideX) addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromX, toX, | |||
handler.getColor(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.WEST), new float[]{fromX.getZ(), fromX.getY(), toX.getZ(), toX.getY()}, | |||
handler.getTexture(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.WEST, cmc), EnumFacing.WEST, rot, false | |||
) | |||
); | |||
// getIcon(false, cmc == 0 || cmc == 4, crossroadsZ, EnumFacing.NORTH) | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromZ, toZ, | |||
renderColor, new float[]{toZ.getX(), fromZ.getY(), fromZ.getX(), toZ.getY()}, | |||
sheet.side, EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
} | |||
// getIcon(false, cmc == 0 || cmc == 4, crossroadsZ, EnumFacing.NORTH) | |||
if (!connectionMatrix[0] || renderSideZ) addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromZ, toZ, | |||
handler.getColor(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.NORTH), new float[]{toZ.getX(), fromZ.getY(), fromZ.getX(), toZ.getY()}, | |||
handler.getTexture(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.NORTH, cmc), EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
fromX.setX(max); | |||
toX.setX(max); | |||
@@ -466,94 +466,90 @@ public class RendererWire extends ModelFactory<Wire> { | |||
fromZ.setZ(max); | |||
toZ.setZ(max); | |||
if (sheet.side != null) { | |||
// getIcon(false, cmc == 2, crossroadsX, EnumFacing.EAST) | |||
quads.add( | |||
// getIcon(false, cmc == 2, crossroadsX, EnumFacing.EAST) | |||
if (!connectionMatrix[3] || renderSideX) addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromX, toX, | |||
handler.getColor(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.EAST), new float[]{toX.getZ(), fromX.getY(), fromX.getZ(), toX.getY()}, | |||
handler.getTexture(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.EAST, cmc), EnumFacing.EAST, rot, false | |||
) | |||
); | |||
// getIcon(false, cmc == 0 || cmc == 8, crossroadsZ, EnumFacing.SOUTH) | |||
if (!connectionMatrix[1] || renderSideZ) addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromZ, toZ, | |||
handler.getColor(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.SOUTH), new float[]{fromZ.getX(), fromZ.getY(), toZ.getX(), toZ.getY()}, | |||
handler.getTexture(WireRenderHandler.TextureType.SIDE, wire, EnumFacing.SOUTH, cmc), EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
// Edge faces | |||
float[] edgeUV = new float[]{min, minH, max, maxH}; | |||
float[] edgeUVFlipped = new float[]{max, minH, min, maxH}; | |||
if (connectionMatrix[0]) { | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromX, toX, | |||
renderColor, new float[]{toX.getZ(), fromX.getY(), fromX.getZ(), toX.getY()}, | |||
sheet.side, EnumFacing.EAST, rot, false | |||
new Vector3f(min, minH, 0.0F), new Vector3f(max, maxH, 0.0F), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.NORTH), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.NORTH, 15), EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
} | |||
// getIcon(false, cmc == 0 || cmc == 8, crossroadsZ, EnumFacing.SOUTH) | |||
quads.add( | |||
if (connectionMatrix[1]) { | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
fromZ, toZ, | |||
renderColor, new float[]{fromZ.getX(), fromZ.getY(), toZ.getX(), toZ.getY()}, | |||
sheet.side, EnumFacing.SOUTH, rot, false | |||
new Vector3f(min, minH, 16.0F), new Vector3f(max, maxH, 16.0F), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.SOUTH), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.SOUTH, 15), EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
} | |||
// Edge faces | |||
float[] edgeUV = new float[]{min, minH, max, maxH}; | |||
float[] edgeUVFlipped = new float[]{max, minH, min, maxH}; | |||
if (sheet.edge != null) { | |||
if (connectionMatrix[0]) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, minH, 0.0F), new Vector3f(max, maxH, 0.0F), | |||
renderColor, edgeUVFlipped, | |||
sheet.edge, EnumFacing.NORTH, rot, false | |||
) | |||
); | |||
} | |||
if (connectionMatrix[1]) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(min, minH, 16.0F), new Vector3f(max, maxH, 16.0F), | |||
renderColor, edgeUV, | |||
sheet.edge, EnumFacing.SOUTH, rot, false | |||
) | |||
); | |||
} | |||
if (connectionMatrix[2]) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(0.0F, minH, min), new Vector3f(0.0F, maxH, max), | |||
renderColor, edgeUV, | |||
sheet.edge, EnumFacing.WEST, rot, false | |||
) | |||
); | |||
} | |||
if (connectionMatrix[2]) { | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(0.0F, minH, min), new Vector3f(0.0F, maxH, max), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.WEST), edgeUV, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.WEST, 15), EnumFacing.WEST, rot, false | |||
) | |||
); | |||
} | |||
if (connectionMatrix[3]) { | |||
quads.add( | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16.0F, minH, min), new Vector3f(16.0F, maxH, max), | |||
renderColor, edgeUVFlipped, | |||
sheet.edge, EnumFacing.EAST, rot, false | |||
) | |||
); | |||
} | |||
if (connectionMatrix[3]) { | |||
addNonNull(quads, | |||
CharsetFaceBakery.INSTANCE.makeBakedQuad( | |||
new Vector3f(16.0F, minH, min), new Vector3f(16.0F, maxH, max), | |||
handler.getColor(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.EAST), edgeUVFlipped, | |||
handler.getTexture(WireRenderHandler.TextureType.EDGE, wire, EnumFacing.EAST, 15), EnumFacing.EAST, rot, false | |||
) | |||
); | |||
} | |||
EnumFacing[] dirs0 = WireUtils.getConnectionsForRender(WireFace.DOWN); | |||
for (int i = 0; i < 4; i++) { | |||
if (cornerConnectionMatrix[i]) { | |||
addCorner(wire, sheet, dirs0[i], renderColor, quads); | |||
addCorner(handler, wire, dirs0[i], quads); | |||
} | |||
} | |||
} | |||
} | |||
@Override | |||
public IBakedModel bake(Wire wire, boolean isItem, BlockRenderLayer layer) { | |||
public IBakedModel bake(Wire wire, boolean isItem, BlockRenderLayer blockLayer) { | |||
SimpleBakedModel model = new SimpleBakedModel(this); | |||
if (wire != null) { | |||
WireSheet sheet = sheetMap.get(wire.getProvider()); | |||
if (sheet != null) { | |||
//if (sheet.particle.getIconName().endsWith("missingno")) { | |||
//} else { | |||
// model.setParticle(sheet.particle); | |||
//} | |||
model.setParticle(sheet.top[sheet.top.length - 1]); | |||
addWire(wire, sheet, model.getQuads(null, null, 0)); | |||
IWireRenderContainer container = containerMap.get(wire.getProvider()); | |||
if (container != null) { | |||
for (int i = 0; i < container.getLayerCount(); i++) { | |||
WireRenderHandler handler = container.get(i); | |||
if (i == 0) { | |||
model.setParticle(handler.getTexture(WireRenderHandler.TextureType.PARTICLE, wire,null, 15)); | |||
} | |||
addWire(handler, wire, model.getQuads(null, null, 0)); | |||
} | |||
} | |||
} | |||
@@ -568,4 +564,17 @@ public class RendererWire extends ModelFactory<Wire> { | |||
} | |||
return wire; | |||
} | |||
public void registerContainer(WireProvider provider, IWireRenderContainer container) { | |||
containerMap.put(provider, container); | |||
} | |||
protected void reloadTextures(TextureMap map) { | |||
for (IWireRenderContainer container : containerMap.values()) { | |||
for (int i = 0; i < container.getLayerCount(); i++) { | |||
WireRenderHandler handler = container.get(i); | |||
handler.refresh(map); | |||
} | |||
} | |||
} | |||
} |
@@ -387,15 +387,17 @@ public abstract class Wire implements ITickable, ICapabilityProvider, IRenderCom | |||
} | |||
} | |||
if (validSides.contains(WireFace.CENTER)) { | |||
// TODO: Fix CENTER occlusion | |||
/* if (validSides.contains(WireFace.CENTER)) { | |||
AxisAlignedBB mask = factory.getBox(WireFace.CENTER, 1 + location.ordinal()); | |||
if (mask != null) { | |||
if (OcclusionUtils.INSTANCE.intersects(Collections.singletonList(mask), container.world(), container.pos())) { | |||
occludedSides |= 1 << 6; | |||
System.out.println("removing"); | |||
validSides.remove(WireFace.CENTER); | |||
} | |||
} | |||
} | |||
} */ | |||
// Connection test | |||
for (WireFace facing : validSides) { |
@@ -0,0 +1,71 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.wires; | |||
import net.minecraft.client.renderer.texture.TextureAtlasSprite; | |||
import net.minecraft.client.renderer.texture.TextureMap; | |||
import net.minecraft.util.BlockRenderLayer; | |||
import net.minecraft.util.EnumFacing; | |||
import net.minecraftforge.fml.relauncher.Side; | |||
import net.minecraftforge.fml.relauncher.SideOnly; | |||
import javax.annotation.Nullable; | |||
public abstract class WireRenderHandler { | |||
public enum TextureType { | |||
TOP, | |||
SIDE, | |||
EDGE, | |||
PARTICLE | |||
} | |||
protected final WireProvider provider; | |||
public WireRenderHandler(WireProvider provider) { | |||
this.provider = provider; | |||
} | |||
@SideOnly(Side.CLIENT) | |||
public abstract boolean isTranslucent(); | |||
@SideOnly(Side.CLIENT) | |||
public float getWidth() { | |||
return provider.getWidth(); | |||
} | |||
@SideOnly(Side.CLIENT) | |||
public float getHeight() { | |||
return provider.getHeight(); | |||
} | |||
@SideOnly(Side.CLIENT) | |||
public abstract void refresh(TextureMap map); | |||
@SideOnly(Side.CLIENT) | |||
public abstract TextureAtlasSprite getTexture(TextureType type, Wire wire, EnumFacing facing, int connMask); | |||
@SideOnly(Side.CLIENT) | |||
public abstract int getColor(TextureType type, Wire wire, @Nullable EnumFacing direction); | |||
@SideOnly(Side.CLIENT) | |||
public boolean isTopSimple() { | |||
return true; | |||
} | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.charset.lib.wires; | |||
import net.minecraft.client.renderer.texture.TextureAtlasSprite; | |||
import net.minecraft.client.renderer.texture.TextureMap; | |||
import net.minecraft.util.BlockRenderLayer; | |||
import net.minecraft.util.EnumFacing; | |||
import net.minecraft.util.ResourceLocation; | |||
import net.minecraftforge.fml.relauncher.Side; | |||
import net.minecraftforge.fml.relauncher.SideOnly; | |||
import pl.asie.charset.lib.render.sprite.SpritesheetFactory; | |||
import javax.annotation.Nonnull; | |||
import javax.annotation.Nullable; | |||
public class WireRenderHandlerDefault extends WireRenderHandler { | |||
private final String domain, path; | |||
@Nonnull private TextureAtlasSprite[] top; | |||
@Nullable private TextureAtlasSprite side; | |||
@Nullable private TextureAtlasSprite edge; | |||
public WireRenderHandlerDefault(WireProvider provider) { | |||
super(provider); | |||
ResourceLocation location = provider.getTexturePrefix(); | |||
this.domain = location.getResourceDomain(); | |||
if (!location.getResourcePath().endsWith("/")) { | |||
this.path = location.getResourcePath() + "_"; | |||
} else { | |||
this.path = location.getResourcePath(); | |||
} | |||
} | |||
@Override | |||
public boolean isTranslucent() { | |||
return false; | |||
} | |||
@Override | |||
@SideOnly(Side.CLIENT) | |||
public void refresh(TextureMap map) { | |||
top = SpritesheetFactory.register(map, new ResourceLocation(domain, path + "top"), 4, 4); | |||
if (!provider.isFlat()) { | |||
edge = map.registerSprite(new ResourceLocation(domain, path + "edge")); | |||
side = map.registerSprite(new ResourceLocation(domain, path + "side")); | |||
} else { | |||
edge = null; | |||
side = null; | |||
} | |||
} | |||
@Override | |||
public TextureAtlasSprite getTexture(TextureType type, Wire wire, @Nullable EnumFacing facing, int connMask) { | |||
switch (type) { | |||
case TOP: | |||
return top[connMask & 15]; | |||
case SIDE: | |||
return side; | |||
case EDGE: | |||
return edge; | |||
default: | |||
return top[15]; | |||
} | |||
} | |||
@Override | |||
public int getColor(TextureType type, Wire wire, @Nullable EnumFacing direction) { | |||
return wire.getRenderColor(); | |||
} | |||
} |
@@ -38,6 +38,7 @@ import net.minecraftforge.common.capabilities.Capability; | |||
import net.minecraftforge.common.capabilities.ICapabilityProvider; | |||
import pl.asie.charset.api.wires.WireFace; | |||
import pl.asie.charset.lib.capability.CapabilityHelper; | |||
import pl.asie.charset.lib.modcompat.mcmultipart.MCMPUtils; | |||
import pl.asie.charset.lib.utils.OcclusionUtils; | |||
import javax.annotation.Nullable; | |||
@@ -70,7 +71,7 @@ public final class WireUtils { | |||
if (wire.getLocation() != WireFace.CENTER) { | |||
Optional<IMultipartContainer> container = MultipartHelper.getContainer(wire.getContainer().world(), pos); | |||
if (container.isPresent()) { | |||
boolean result = MultipartCapabilityHelper.hasCapability(container.get(), capability, EnumEdgeSlot.fromFaces(wire.getLocation().facing, face), face); | |||
boolean result = MCMPUtils.streamParts(container.get(), wire.getLocation().facing, face).anyMatch((info) -> info.getTile().hasPartCapability(capability, face)); | |||
TileWire.isWireCheckingForCaps = false; | |||
return result; | |||
} | |||
@@ -98,13 +99,15 @@ public final class WireUtils { | |||
if (searcher.getLocation() != WireFace.CENTER) { | |||
Optional<IMultipartContainer> container = MultipartHelper.getContainer(searcher.getContainer().world(), pos); | |||
if (container.isPresent()) { | |||
T result = MultipartCapabilityHelper.getCapability(container.get(), capability, EnumEdgeSlot.fromFaces(searcher.getLocation().facing, face), face); | |||
T result = MCMPUtils.streamParts(container.get(), searcher.getLocation().facing, face).filter((info) -> info.getTile().hasPartCapability(capability, face)) | |||
.map((info) -> info.getTile().getPartCapability(capability, face)).findFirst().orElse(null); | |||
TileWire.isWireCheckingForCaps = false; | |||
return result; | |||
} | |||
} | |||
T result = CapabilityHelper.get(searcher.getContainer().world(), pos, capability, face, true, true, false); | |||
TileEntity tile = searcher.getContainer().world().getTileEntity(pos); | |||
T result = tile != null ? tile.getCapability(capability, face) : null; | |||
TileWire.isWireCheckingForCaps = false; | |||
return result; | |||
} | |||
@@ -184,7 +187,7 @@ public final class WireUtils { | |||
} | |||
TileEntity tile = access.getTileEntity(pos); | |||
if (tile != null && tile instanceof TileWire && ((TileWire) tile).wire != null && ((TileWire) tile).wire.getLocation() == face) { | |||
if (tile instanceof TileWire && ((TileWire) tile).wire != null && ((TileWire) tile).wire.getLocation() == face) { | |||
return ((TileWire) tile).wire; | |||
} else { | |||
return null; | |||
@@ -193,11 +196,13 @@ public final class WireUtils { | |||
public static @Nullable Wire getAnyWire(IBlockAccess access, BlockPos pos) { | |||
if (access instanceof IMultipartBlockAccess) { | |||
TileWire tileWire = (TileWire) ((IMultipartBlockAccess) access).getPartInfo().getTile().getTileEntity(); | |||
return tileWire.wire; | |||
} else { | |||
return getAnyWire(access.getTileEntity(pos)); | |||
IPartInfo info = ((IMultipartBlockAccess) access).getPartInfo(); | |||
if (info.getPartPos().equals(pos)) { | |||
return getAnyWire(info.getTile().getTileEntity()); | |||
} | |||
} | |||
return getAnyWire(access.getTileEntity(pos)); | |||
} | |||
public static Collection<Wire> getAllWires(IBlockAccess access, BlockPos pos) { |
@@ -34,8 +34,6 @@ import net.minecraft.util.*; | |||
import net.minecraft.util.math.BlockPos; | |||
import net.minecraft.util.math.RayTraceResult; | |||
import net.minecraft.util.math.Vec3d; | |||
import net.minecraft.util.text.TextComponentString; | |||
import net.minecraft.util.text.TextComponentTranslation; | |||
import net.minecraftforge.common.ForgeHooks; | |||
import net.minecraftforge.common.capabilities.Capability; | |||
import net.minecraftforge.common.util.Constants; | |||
@@ -44,10 +42,8 @@ import net.minecraftforge.items.IItemHandler; | |||
import net.minecraftforge.items.ItemHandlerHelper; | |||
import pl.asie.charset.api.lib.IAxisRotatable; | |||
import pl.asie.charset.api.lib.ICacheable; | |||
import pl.asie.charset.api.lib.ISimpleInstantiatingRegistry; | |||
import pl.asie.charset.api.locks.Lockable; | |||
import pl.asie.charset.api.storage.IBarrel; | |||
import pl.asie.charset.lib.CharsetLib; | |||
import pl.asie.charset.lib.block.ITileWrenchRotatable; | |||
import pl.asie.charset.lib.block.TileBase; | |||
import pl.asie.charset.lib.capability.CapabilityCache; | |||
@@ -61,6 +57,7 @@ import pl.asie.charset.lib.notify.component.NotificationComponentString; | |||
import pl.asie.charset.lib.scheduler.Scheduler; | |||
import pl.asie.charset.lib.utils.*; | |||
import pl.asie.charset.lib.utils.Orientation; | |||
import pl.asie.charset.lib.utils.redstone.RedstoneUtils; | |||
import javax.annotation.Nullable; | |||
import java.util.*; |
@@ -45,6 +45,7 @@ import pl.asie.charset.api.wires.IBundledEmitter; | |||
import pl.asie.charset.api.wires.IBundledReceiver; | |||
import pl.asie.charset.api.wires.IRedstoneEmitter; | |||
import pl.asie.charset.api.wires.IRedstoneReceiver; | |||
import pl.asie.charset.lib.utils.redstone.RedstoneUtils; | |||
import pl.asie.simplelogic.gates.logic.GateLogic; | |||
import pl.asie.simplelogic.gates.logic.GateLogicDummy; | |||
import pl.asie.charset.lib.block.TileBase; | |||
@@ -274,7 +275,7 @@ public class PartGate extends TileBase implements IRenderComparable<PartGate>, I | |||
EnumFacing real = gateToReal(facing); | |||
World w = getWorld(); | |||
BlockPos p = getPos().offset(real); | |||
int mpValue = RedstoneGetterHandler.getWeakPower(w, p, real, getSide()); | |||
int mpValue = RedstoneUtils.getModdedWeakPower(w, p, real, getSide()); | |||
if (mpValue >= 0) { | |||
values[i] = (byte) mpValue; | |||
} else { |
@@ -1,45 +0,0 @@ | |||
/* | |||
* Copyright (c) 2015, 2016, 2017, 2018 Adrian Siekierka | |||
* | |||
* This file is part of Charset. | |||
* | |||
* Charset is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Lesser General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Charset is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with Charset. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
package pl.asie.simplelogic.gates; | |||
import mcmultipart.api.container.IMultipartContainer; | |||
import mcmultipart.api.multipart.MultipartHelper; | |||
import mcmultipart.api.multipart.MultipartRedstoneHelper; | |||
import net.minecraft.util.EnumFacing; | |||
import net.minecraft.util.math.BlockPos; | |||
import net.minecraft.world.IBlockAccess; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Optional; | |||
public class RedstoneGetterHandler { | |||
public static final List<IRedstoneGetter> GETTERS = new ArrayList<>(); | |||
public static int getWeakPower(IBlockAccess w, BlockPos p, EnumFacing face, EnumFacing edge) { | |||
for (IRedstoneGetter getter : GETTERS) { | |||
int v = getter.get(w, p, face, edge); | |||
if (v >= 0) { | |||
return v; | |||
} | |||
} | |||
return -1; | |||
} | |||
} |
@@ -48,6 +48,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; | |||
import pl.asie.charset.ModCharset; | |||
import pl.asie.charset.lib.config.CharsetLoadConfigEvent; | |||
import pl.asie.charset.lib.handlers.ShiftScrollHandler; | |||
import pl.asie.charset.lib.modcompat.mcmultipart.RedstoneGetterMultipart; | |||
import pl.asie.charset.shared.SimpleLogicShared; | |||
import pl.asie.simplelogic.gates.logic.*; | |||
import pl.asie.charset.lib.loader.CharsetModule; | |||
@@ -108,10 +109,6 @@ public class SimpleLogicGates { | |||
@EventHandler | |||
public void preInit(FMLPreInitializationEvent event) { | |||
if (Loader.isModLoaded("mcmultipart")) { | |||
RedstoneGetterHandler.GETTERS.add(new RedstoneGetterMultipart()); | |||
} | |||
blockGate = new BlockGate(); | |||
itemGate = new ItemGate(blockGate); | |||