diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 1db6be7ea..5f2612681 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -120,6 +120,7 @@ body:
description: Select Immersive Intelligence version.
options:
- 0.3.1
+ - 0.3.1-dev4
- 0.3.1-dev3-test1
- 0.3.1-dev2
- 0.3.1-dev1
diff --git a/gradle.properties b/gradle.properties
index a03e347ea..9b69a0c16 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,7 +15,7 @@ mcmod_Contributors=Pabilo8,Carver,Sch
modForge=1.12.2-14.23.5.2847
modMappings=snapshot_20171003
#Project Data
-modVersion=0.3.1-dev3-test1
+modVersion=0.3.1-dev4
modGroup=pl.pabilo8
modName=immersiveintelligence
# Private Team II Maven
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/LogisticTag.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/LogisticTag.java
index de45699b0..693584d61 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/LogisticTag.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/LogisticTag.java
@@ -211,7 +211,7 @@ public NBTTagCompound serializeNBT()
.withString("origin", origin)
.withString("destination", destination)
.withColor("color", IIColor.fromDye(color))
- .withUUID("owner", owner)
+ .conditionally(owner!=null, tis -> tis.withUUID("owner", owner))
.withInt("batch_number", batchNumber)
.unwrap();
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/ComponentRole.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/ComponentRole.java
index 46a5eeb8b..a34f3730e 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/ComponentRole.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/ComponentRole.java
@@ -1,9 +1,10 @@
package pl.pabilo8.immersiveintelligence.api.ammo.enums;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
-import pl.pabilo8.immersiveintelligence.common.util.ISerializableEnum;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.ILocalizedEnum;
-public enum ComponentRole implements ISerializableEnum
+public enum ComponentRole implements ILocalizedEnum
{
GENERAL_PURPOSE(0xaaaaaa),
SHRAPNEL(0x3f4f57),
@@ -32,4 +33,10 @@ public IIColor getColor()
{
return color;
}
+
+ @Override
+ public String geLocaleKey()
+ {
+ return IIReference.DESCRIPTION_KEY+"bullet_type.";
+ }
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/FuseType.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/FuseType.java
index 57b58daa9..9a9fd2717 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/FuseType.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/enums/FuseType.java
@@ -1,11 +1,9 @@
package pl.pabilo8.immersiveintelligence.api.ammo.enums;
-import pl.pabilo8.immersiveintelligence.common.util.ISerializableEnum;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.ILocalizedEnum;
-import javax.annotation.Nonnull;
-import java.util.Arrays;
-
-public enum FuseType implements ISerializableEnum
+public enum FuseType implements ILocalizedEnum
{
CONTACT('\u29b0'),
TIMED('\u29b1'),
@@ -18,11 +16,9 @@ public enum FuseType implements ISerializableEnum
this.symbol = symbol;
}
- //TODO: 28.05.2024 replace with IIUtils.enumValue
- @Nonnull
- public static FuseType v(String s)
+ @Override
+ public String geLocaleKey()
{
- String ss = s.toUpperCase();
- return Arrays.stream(values()).filter(e -> e.name().equals(ss)).findFirst().orElse(CONTACT);
+ return IIReference.DESCRIPTION_KEY+"bullet_fuse.";
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/parts/IAmmoTypeItem.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/parts/IAmmoTypeItem.java
index 27469762b..5e9d156d0 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/parts/IAmmoTypeItem.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/parts/IAmmoTypeItem.java
@@ -13,6 +13,7 @@
import pl.pabilo8.immersiveintelligence.api.ammo.enums.PropellantType;
import pl.pabilo8.immersiveintelligence.api.utils.ItemTooltipHandler;
import pl.pabilo8.immersiveintelligence.api.utils.ItemTooltipHandler.IAdvancedTooltipItem;
+import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.EntityAmmoBase;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
@@ -183,7 +184,7 @@ default FuseType getFuseType(ItemStack stack)
{
if(!ItemNBTHelper.hasKey(stack, NBT_FUSE))
makeDefault(stack);
- return FuseType.v(ItemNBTHelper.getString(stack, NBT_FUSE));
+ return IIUtils.enumValue(FuseType.class, ItemNBTHelper.getString(stack, NBT_FUSE));
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/utils/AmmoFactory.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/utils/AmmoFactory.java
index 2b51ca690..c44ac8d9b 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/utils/AmmoFactory.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/ammo/utils/AmmoFactory.java
@@ -17,6 +17,7 @@
import pl.pabilo8.immersiveintelligence.common.IILogger;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.EntityAmmoBase;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
+import pl.pabilo8.immersiveintelligence.common.util.gun.GunAimCoordinate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -115,7 +116,21 @@ public AmmoFactory(World world)
public AmmoFactory setStack(ItemStack stack)
{
this.stack = stack;
- this.ammo = ((IAmmoType, E>)stack.getItem());
+ this.ammo = this.ammo==null?((IAmmoType, E>)stack.getItem()): this.ammo;
+ return this;
+ }
+
+ /**
+ * Sets the ammo to create, used when the ammo type can't be determined directly from the stack, f.e. in turrets
+ *
+ * @param ammo The ammo to create
+ * @return The factory
+ */
+ @SuppressWarnings("rawtypes")
+ public AmmoFactory setAmmo(@Nonnull IAmmoType ammo)
+ {
+ //noinspection unchecked
+ this.ammo = (IAmmoType, E>)ammo;
return this;
}
@@ -195,6 +210,12 @@ public AmmoFactory setPositionAndVelocity(Vec3d pos, Vec3d dir, float velocit
return this;
}
+ public AmmoFactory setPositionAndVelocity(Vec3d positionVector, GunAimCoordinate aim, float offset, float velocity)
+ {
+ Vec3d target = aim.getTarget(0);
+ return setPositionAndVelocity(positionVector.add(target.scale(offset)), target, offset);
+ }
+
/**
* Sets the owner of the ammo
*
@@ -252,6 +273,8 @@ public AmmoFactory setUseArtilleryAngles(boolean useArtilleryAngles)
return this;
}
+ //--- Ammo Entity Creation ---//
+
/**
* Builds the ammo based on passed data and spawns it in the world.
*
@@ -272,7 +295,7 @@ public E create()
public E create(@Nullable Consumer action)
{
//Invalid ammo type
- if(ammo==null)
+ if(ammo==null||stack==null||stack.isEmpty())
return null;
//No position or direction passed
@@ -356,4 +379,21 @@ public boolean isValidAmmo(ItemStack stack)
return false;
return stack.getItem()==ammo&&!((IAmmoTypeItem, ?>)ammo).isBulletCore(stack);
}
+
+ //--- Getters ---//
+
+ public World getWorld()
+ {
+ return world.get();
+ }
+
+ public Vec3d getPos()
+ {
+ return pos;
+ }
+
+ public Vec3d getDirection()
+ {
+ return dir;
+ }
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/BulletComponentStack.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/BulletComponentStack.java
index 80af3159d..b29205c67 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/BulletComponentStack.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/BulletComponentStack.java
@@ -1,6 +1,5 @@
package pl.pabilo8.immersiveintelligence.api.crafting;
-import net.minecraft.client.resources.I18n;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.INBTSerializable;
@@ -30,7 +29,7 @@ private BulletComponentStack(String name, int amount, @Nonnull NBTTagCompound ta
{
this.name = name;
this.amount = amount;
- this.tagCompound = tag;
+ this.tagCompound = tag.copy();
Optional first = AmmoRegistry.getAllComponents().stream()
.filter(comp -> this.name.equals(comp.getName()))
@@ -41,7 +40,12 @@ private BulletComponentStack(String name, int amount, @Nonnull NBTTagCompound ta
public BulletComponentStack(AmmoComponent component, @Nullable NBTTagCompound tag)
{
- this(component.getName(), 16, tag==null?new NBTTagCompound(): tag);
+ this(component, 16, tag);
+ }
+
+ public BulletComponentStack(AmmoComponent component, int amount, @Nullable NBTTagCompound tag)
+ {
+ this(component.getName(), amount, tag==null?new NBTTagCompound(): tag);
}
public BulletComponentStack()
@@ -49,13 +53,18 @@ public BulletComponentStack()
this("", 0, new NBTTagCompound());
}
+ public BulletComponentStack copy()
+ {
+ return new BulletComponentStack(name, amount, tagCompound);
+ }
+
@Override
public NBTTagCompound serializeNBT()
{
NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("name", name);
nbt.setInteger("amount", amount);
- nbt.setTag("nbt", tagCompound);
+ nbt.setTag("nbt", tagCompound.copy());
return nbt;
}
@@ -65,7 +74,7 @@ public void deserializeNBT(NBTTagCompound nbt)
{
name = nbt.getString("name");
amount = nbt.getInteger("amount");
- tagCompound = nbt.getCompoundTag("nbt");
+ tagCompound = nbt.getCompoundTag("nbt").copy();
Optional first = AmmoRegistry.getAllComponents().stream()
.filter(comp -> this.name.equals(comp.getName()))
@@ -76,7 +85,7 @@ public void deserializeNBT(NBTTagCompound nbt)
public boolean isEmpty()
{
- return name.isEmpty()||amount==0;
+ return name.isEmpty()||amount==0||component==null;
}
public boolean isFluid()
@@ -86,30 +95,34 @@ public boolean isFluid()
public boolean matches(ItemStack stack)
{
- if(isEmpty()||component==null)
+ if(isEmpty())
return true;
+ if(stack.isEmpty()||component==null)
+ return false;
NBTTagCompound stackTag = stack.getTagCompound();
if(stackTag==null)
stackTag = new NBTTagCompound();
- return component.getName().equals(name)&&this.tagCompound.equals(stackTag);
+ return component.getMaterial().matchesItemStackIgnoringSize(stack)&&this.tagCompound.equals(stackTag);
}
public boolean matches(FluidStack fs)
{
if(isEmpty())
return true;
+ if(fs==null||component==null||component.getMaterial().fluid==null)
+ return false;
NBTTagCompound stackTag = fs.tag==null?new NBTTagCompound(): fs.tag;
- return fs.getFluid().getName().equals(name)&&this.tagCompound.equals(stackTag);
+ return fs.isFluidEqual(component.getMaterial().fluid)&&this.tagCompound.equals(stackTag);
}
public void subtract(int amount)
{
this.amount = Math.max(0, this.amount-amount);
- if(amount==0)
+ if(this.amount==0)
{
tagCompound = new NBTTagCompound();
name = "";
@@ -135,7 +148,7 @@ public float getAmountPercentage()
@SideOnly(Side.CLIENT)
public String getTranslatedName()
{
- return I18n.format("ie.manual.entry.bullet_component."+name);
+ return component!=null?component.getTranslatedName(): "";
}
public AmmoComponent getComponent()
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/ProjectileWorkshopRecipe.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/ProjectileWorkshopRecipe.java
index dbdcbb57a..70656ee0b 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/ProjectileWorkshopRecipe.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/crafting/ProjectileWorkshopRecipe.java
@@ -17,9 +17,27 @@
**/
public class ProjectileWorkshopRecipe extends IIMultiblockRecipe
{
+ public static final String FILLING_RECIPE_NAME = "core_filling";
+ public static final ProjectileWorkshopRecipe CORE_FILLING = new ProjectileWorkshopRecipe();
+
+ @Nullable
public IAmmoTypeItem, ?> ammo;
public boolean isFilling;
- public ItemStack effect, ingredient;
+ public ItemStack effect = ItemStack.EMPTY, ingredient = ItemStack.EMPTY;
+
+ /**
+ * Single hard-coded recipe used by Core Filler mode.
+ */
+ private ProjectileWorkshopRecipe()
+ {
+ super(FILLING_RECIPE_NAME);
+ this.isFilling = true;
+
+ this.setTimeAndEnergy(
+ ProjectileWorkshop.fillingTime,
+ ProjectileWorkshop.fillingEnergyUsage
+ );
+ }
/**
* Production recipe
@@ -42,25 +60,9 @@ public ProjectileWorkshopRecipe(IAmmoTypeItem, ?> ammo, AmmoCore core, CoreTyp
);
}
- //Filling recipe
- /*public ProjectileWorkshopRecipe(ItemStack inputStack, BulletComponentStack component)
- {
- assert inputStack.getItem() instanceof IAmmoTypeItem;
-
- this.ammo = (IAmmoTypeItem, ?>)inputStack.getItem();
- this.isFilling = true;
-
- this.totalProcessTime = ProjectileWorkshop.fillingTime;
- this.energyPerTick = ProjectileWorkshop.fillingEnergyUsage;
-
- this.effect = inputStack.copy();
- this.effect.setCount(1);
- ammo.addComponents(this.effect, component.getComponent(), component.tagCompound);
- }*/
-
public ItemStack getEffect()
{
- return effect;
+ return effect.copy();
}
@Nullable
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/data/IIDataTypeUtils.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/data/IIDataTypeUtils.java
index 0aa392ef2..d5203bffc 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/data/IIDataTypeUtils.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/data/IIDataTypeUtils.java
@@ -38,7 +38,7 @@ public static void registerDataTypes()
//number types
registerType("integer", DataTypeInteger.class, DataTypeInteger::new, IIColor.fromPackedRGB(0x26732e), false);
registerType("float", DataTypeFloat.class, DataTypeFloat::new, IIColor.fromPackedRGB(0x0d6b68), false);
- registerType("vector", DataTypeVector.class, DataTypeVector::new, IIColor.fromPackedRGB(0x9d8900), false);
+ registerType("vector", DataTypeVector.class, DataTypeVector::new, IIColor.fromPackedRGB(0x9d8900), true);
registerGenericType("number", NumericDataType.class);
//text types
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/data/types/DataTypeExpression.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/data/types/DataTypeExpression.java
index 4c914bf44..9edc4ef24 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/data/types/DataTypeExpression.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/data/types/DataTypeExpression.java
@@ -100,7 +100,8 @@ public void valueFromNBT(NBTTagCompound nbt)
{
this.operation = IIDataOperationUtils.getOperationInstance(nbt.getString("Operation"));
this.meta = this.operation.getMeta();
- this.requiredVariable = nbt.getString("requiredVariable").charAt(0);
+ String required = nbt.getString("requiredVariable");
+ this.requiredVariable = required.isEmpty()?' ': required.charAt(0);
this.data = new DataType[meta.allowedTypes().length];
for(int i = 0; i < meta.allowedTypes().length; i++)
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleConstraints.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleConstraints.java
index d2d741a34..4d99d174c 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleConstraints.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleConstraints.java
@@ -10,14 +10,14 @@
public class StyleConstraints
{
private final String defaultStyle;
- private final boolean allowColorCustomization;
+ private final PaintStyleConstraint colorCustomization;
private final Set styles;
private final Set decorations;
- public StyleConstraints(String defaultStyle, boolean allowColorCustomization, Set styles, Set decorations)
+ public StyleConstraints(String defaultStyle, PaintStyleConstraint colorCustomization, Set styles, Set decorations)
{
this.defaultStyle = defaultStyle;
- this.allowColorCustomization = allowColorCustomization;
+ this.colorCustomization = colorCustomization;
this.styles = styles;
this.decorations = decorations;
}
@@ -27,9 +27,9 @@ public String getDefaultStyle()
return defaultStyle;
}
- public boolean allowsColorCustomization()
+ public PaintStyleConstraint getColorCustomization()
{
- return allowColorCustomization;
+ return colorCustomization;
}
public Set getStyles()
@@ -41,4 +41,11 @@ public Set getDecorations()
{
return decorations;
}
+
+ public enum PaintStyleConstraint
+ {
+ NOT_APPLICABLE,
+ ANY_COLOR,
+ PAINTS_COLOR_ONLY
+ }
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleCustomization.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleCustomization.java
index e09c4a84f..4765324ba 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleCustomization.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/style/StyleCustomization.java
@@ -3,6 +3,7 @@
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagString;
import net.minecraftforge.common.util.INBTSerializable;
+import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints.PaintStyleConstraint;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
@@ -62,6 +63,8 @@ public StyleCustomization withStyle(String style)
public StyleCustomization withColor(IIColor color)
{
+ if(constraints.getColorCustomization()==PaintStyleConstraint.PAINTS_COLOR_ONLY)
+ color = color.constraintToPaintSystem();
this.color = color;
return this;
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/Upgrade.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/Upgrade.java
index 13e1b4333..03911d364 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/Upgrade.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/Upgrade.java
@@ -30,6 +30,7 @@ public class Upgrade
private final ResLoc id, icon;
private int progressRequired, progressStages;
private UpgradePurpose purpose;
+ private boolean isWorkInProgress = false;
public Upgrade(String name)
{
@@ -70,24 +71,51 @@ public Upgrade withProgressStages(int progressRequired)
}
+ /**
+ * Sets the required progress, used for calculating the time it takes to install the upgrade. Adjusted by the amount of animated components drawn during the upgrade install.*
+ *
+ * @return this
+ */
public Upgrade withRequiredProgress(int progress)
{
this.progressRequired = progress;
return this;
}
+ /**
+ * Sets the upgrade purpose, used for categorizing upgrades in the tech tree and applying special rules to them.
+ *
+ * @return this
+ */
public Upgrade withType(UpgradePurpose type)
{
this.purpose = type;
return this;
}
+ /**
+ * Adds information about a benefit that this upgrade provides, shown in the upgrade tooltip.
+ * Benefits are purely informational and do not have to be applied in any way.
+ *
+ * @return this
+ */
public Upgrade withBenefit(UpgradeBenefit benefit)
{
this.benefits.add(benefit);
return this;
}
+ /**
+ * Marks the upgrade as Work-In-Progress and does not allow players to install it.
+ *
+ * @return this
+ */
+ public Upgrade withWIPStatus()
+ {
+ this.isWorkInProgress = true;
+ return this;
+ }
+
//--- Getters ---//
public ResourceLocation getId()
@@ -101,6 +129,11 @@ public String getName()
return id.getResourcePath();
}
+ public boolean isWorkInProgress()
+ {
+ return this.isWorkInProgress;
+ }
+
public UpgradePurpose getPurpose()
{
return purpose;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/UpgradeManager.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/UpgradeManager.java
index d16439d79..08ad60027 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/UpgradeManager.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/upgrade/UpgradeManager.java
@@ -1,10 +1,13 @@
package pl.pabilo8.immersiveintelligence.api.upgrade;
+import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagString;
import net.minecraftforge.common.util.INBTSerializable;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradeOperation;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Tools;
+import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
+import pl.pabilo8.immersiveintelligence.common.network.messages.MessageIITileSync;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
@@ -204,5 +207,7 @@ private void sendTileUpdate()
{
if(parent instanceof TileEntityMultiblockIIBase>)
((TileEntityMultiblockIIBase>)parent).updateTileForEvent(SyncEvents.TILE_UPGRADES_MODIFIED);
+ else if(parent instanceof TileEntityIEBase)
+ IIPacketHandler.sendToClient(new MessageIITileSync(((TileEntityIEBase)parent)));
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ICameraEntity.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ICameraEntity.java
index 09fb8068a..b90b3f7ca 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ICameraEntity.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ICameraEntity.java
@@ -1,15 +1,17 @@
package pl.pabilo8.immersiveintelligence.api.utils.camera;
import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Vec3d;
-import net.minecraftforge.fml.relauncher.Side;
-import net.minecraftforge.fml.relauncher.SideOnly;
+import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedZoom;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
/**
* @author Pabilo8 (pabilo@iiteam.net)
* @since 14.02.2023
*/
-@SideOnly(Side.CLIENT)
public interface ICameraEntity
{
/**
@@ -26,6 +28,16 @@ public interface ICameraEntity
*/
float getCameraYaw(EntityPlayer cameraPlayer, float partialTicks);
+ /**
+ * @param cameraPlayer client player
+ * @param partialTicks partial ticks when rendering
+ * @return camera roll angle
+ */
+ default float getCameraRoll(EntityPlayer cameraPlayer, float partialTicks)
+ {
+ return 0;
+ }
+
/**
* @param cameraPlayer client player
* @param partialTicks partial ticks when rendering
@@ -33,8 +45,29 @@ public interface ICameraEntity
*/
Vec3d getCameraPos(EntityPlayer cameraPlayer, float partialTicks);
- default void setCameraParameters(EntityPlayer cameraPlayer, float partialTicks)
+ boolean isCameraEnabled(EntityPlayer player);
+
+ default boolean isThirdPersonAllowed(EntityPlayer cameraPlayer)
{
+ return true;
+ }
+
+ //--- Zooming ---//
+
+ @Nullable
+ default IAdvancedZoom getZoom()
+ {
+ return null;
+ }
+ /**
+ * Allows to use a zoom-providing ItemStack. Used for vehicles, where the player can use inventory items like binoculars.
+ *
+ * @return the ItemStack providing the zoom, or an empty stack if none
+ */
+ @Nonnull
+ default ItemStack getZoomStack()
+ {
+ return ItemStack.EMPTY;
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/IEntityZoomProvider.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/IEntityZoomProvider.java
deleted file mode 100644
index 01316c45d..000000000
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/IEntityZoomProvider.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package pl.pabilo8.immersiveintelligence.api.utils.camera;
-
-import net.minecraft.item.ItemStack;
-import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedZoomTool;
-
-/**
- * @author Pabilo8 (pabilo@iiteam.net)
- * @since 21.01.2021
- */
-public interface IEntityZoomProvider
-{
- IAdvancedZoomTool getZoom();
-
- default ItemStack getZoomStack()
- {
- return ItemStack.EMPTY;
- }
-}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ZoomSettings.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ZoomSettings.java
new file mode 100644
index 000000000..271f79a65
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/camera/ZoomSettings.java
@@ -0,0 +1,51 @@
+package pl.pabilo8.immersiveintelligence.api.utils.camera;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedZoom;
+
+/**
+ * @author Pabilo8 (pabilo@iiteam.net)
+ * @ii-approved 0.3.1
+ * @since 15.05.2026
+ */
+public class ZoomSettings implements IAdvancedZoom
+{
+ private boolean zoomEnabled = false;
+ private final float[] zoomSteps;
+ private final ResourceLocation overlayTexture;
+
+ public ZoomSettings(float[] zoomSteps, ResourceLocation overlayTexture)
+ {
+ this.zoomSteps = zoomSteps;
+ this.overlayTexture = overlayTexture;
+ }
+
+ public ZoomSettings withZoomEnabled(boolean zoomEnabled)
+ {
+ this.zoomEnabled = zoomEnabled;
+ return this;
+ }
+
+ @Override
+ public boolean shouldZoom(ItemStack stack, EntityPlayer player)
+ {
+ return zoomEnabled;
+ }
+
+ @Override
+ public float[] getZoomSteps(ItemStack stack, EntityPlayer player)
+ {
+ return zoomSteps;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public ResourceLocation getZoomOverlayTexture(ItemStack stack, EntityPlayer player)
+ {
+ return overlayTexture;
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/tools/IAdvancedZoomTool.java b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/tools/IAdvancedZoom.java
similarity index 95%
rename from src/main/java/pl/pabilo8/immersiveintelligence/api/utils/tools/IAdvancedZoomTool.java
rename to src/main/java/pl/pabilo8/immersiveintelligence/api/utils/tools/IAdvancedZoom.java
index d8f195c1a..7b251dfaf 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/tools/IAdvancedZoomTool.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/api/utils/tools/IAdvancedZoom.java
@@ -10,7 +10,7 @@
* @author Pabilo8 (pabilo@iiteam.net)
* @since 27.09.2019
*/
-public interface IAdvancedZoomTool
+public interface IAdvancedZoom
{
/**
* @return whether this item is valid for zooming in
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientEventHandler.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientEventHandler.java
index 27400ee6b..64cd5ca7c 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientEventHandler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientEventHandler.java
@@ -22,6 +22,7 @@
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.FogMode;
+import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.resources.IResourceManager;
@@ -31,7 +32,6 @@
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
@@ -57,6 +57,7 @@
import net.minecraftforge.event.GameRuleChangeEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.event.world.WorldEvent.Load;
+import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
@@ -72,7 +73,7 @@
import pl.pabilo8.immersiveintelligence.api.utils.ItemTooltipHandler;
import pl.pabilo8.immersiveintelligence.api.utils.ItemTooltipHandler.IAdvancedTooltipItem;
import pl.pabilo8.immersiveintelligence.api.utils.ItemTooltipHandler.IItemScrollable;
-import pl.pabilo8.immersiveintelligence.api.utils.camera.IEntityZoomProvider;
+import pl.pabilo8.immersiveintelligence.api.utils.camera.ICameraEntity;
import pl.pabilo8.immersiveintelligence.client.fx.ScreenShake;
import pl.pabilo8.immersiveintelligence.client.fx.utils.ParticleSystem;
import pl.pabilo8.immersiveintelligence.client.gui.GuiWidgetAustralianTabs;
@@ -99,18 +100,15 @@
import pl.pabilo8.immersiveintelligence.common.*;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Graphics;
-import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Tools.TripodPeriscope;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityMachinegun;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityMortar;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityTripodPeriscope;
+import pl.pabilo8.immersiveintelligence.common.entity.EntityCamera;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMountedWeapon;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
import pl.pabilo8.immersiveintelligence.common.item.ItemIIPrintedPage.PageType;
import pl.pabilo8.immersiveintelligence.common.item.weapons.ItemIIGunBase;
import pl.pabilo8.immersiveintelligence.common.item.weapons.ItemIIRailgunOverride;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
-import pl.pabilo8.immersiveintelligence.common.network.messages.MessageEntityNBTSync;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageItemScrollableSwitch;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageManualClose;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
@@ -142,11 +140,9 @@ public class ClientEventHandler implements ISelectiveResourceReloadListener
private static final ArrayList TEXT_OVERLAYS = new ArrayList<>();
private static final ArrayList IN_WORLD_OVERLAYS = new ArrayList<>();
private static final ArrayList SCREEN_SHAKE_EFFECTS = new ArrayList<>();
- public static boolean mgAiming = false;
- public static ArrayList aimingPlayers = new ArrayList<>();
public static GuiScreen lastGui = null;
//Whether the Light Engineer Armor is worn
- public static boolean gotTheDrip;
+ public static boolean gotTheDrip = false, nightVisionActive = false;
static
{
@@ -195,13 +191,6 @@ public static void handleBipedRotations(ModelBiped model, Entity entity)
model.bipedHead.rotateAngleZ = 0f;
model.bipedHeadwear.rotateAngleZ = 0f;
-
- if(aimingPlayers.contains(entity))
- {
- model.bipedHead.rotateAngleZ = -0.35f;
- model.bipedHeadwear.rotateAngleZ = -0.35f;
- }
-
//Handle a vehicle's passenger animations
Entity vehicle = living.getRidingEntity();
//Vehicle seats have no renderer, use the vehicle renderer for the action
@@ -279,53 +268,49 @@ else if((item instanceof ItemIIGunBase||item instanceof ItemIIRailgunOverride)&&
model.bipedRightArm.rotationPointZ += IIMath.clampedLerp3Par(0, 2f, 0, v);
}
- else
+ else if(living.isSneaking()&&item==IIContent.itemBinoculars)
{
- // TODO: 19.09.2021 animation for left hand (requires model offset changes)
- }
- else if(living.isSneaking()&&item==IIContent.itemBinoculars)
- {
- model.bipedRightArm.rotateAngleY = model.bipedHead.rotateAngleY-0.25f;
- model.bipedLeftArm.rotateAngleY = model.bipedHead.rotateAngleY+0.25f;
+ model.bipedRightArm.rotateAngleY = model.bipedHead.rotateAngleY-0.25f;
+ model.bipedLeftArm.rotateAngleY = model.bipedHead.rotateAngleY+0.25f;
- model.bipedRightArm.rotateAngleX = model.bipedHead.rotateAngleX-2f;
- model.bipedLeftArm.rotateAngleX = model.bipedRightArm.rotateAngleX;
+ model.bipedRightArm.rotateAngleX = model.bipedHead.rotateAngleX-2f;
+ model.bipedLeftArm.rotateAngleX = model.bipedRightArm.rotateAngleX;
- int id = heldItem.getMetadata();
- BinocularsRenderer.INSTANCE.render(id==1?ItemNBTHelper.getBoolean(heldItem, "wasUsed")?2: 1: id, model.bipedHead, true);
- }
- else if(item==IIContent.itemMineDetector)
- {
- float v = MineDetectorRenderer.instance.renderBase(living, 2.125f, true);
+ int id = heldItem.getMetadata();
+ BinocularsRenderer.INSTANCE.render(id==1?ItemNBTHelper.getBoolean(heldItem, "wasUsed")?2: 1: id, model.bipedHead, true);
+ }
+ else if(item==IIContent.itemMineDetector)
+ {
+ float v = MineDetectorRenderer.instance.renderBase(living, 2.125f, true);
- model.bipedRightArm.rotateAngleY = model.bipedBody.rotateAngleY-0.45f;
- model.bipedLeftArm.rotateAngleY = model.bipedBody.rotateAngleY+0.45f;
+ model.bipedRightArm.rotateAngleY = model.bipedBody.rotateAngleY-0.45f;
+ model.bipedLeftArm.rotateAngleY = model.bipedBody.rotateAngleY+0.45f;
- model.bipedRightArm.rotateAngleX = -1.25f-(1f-v)*0.5f;
- model.bipedLeftArm.rotateAngleX = model.bipedRightArm.rotateAngleX;
- }
- else if(item==IIContent.itemNavalMine)
- if(right)
- {
- model.bipedRightArm.rotateAngleX -= 0.5f;
+ model.bipedRightArm.rotateAngleX = -1.25f-(1f-v)*0.5f;
model.bipedLeftArm.rotateAngleX = model.bipedRightArm.rotateAngleX;
}
- else
- {
- model.bipedLeftArm.rotateAngleX -= 0.5f;
- model.bipedRightArm.rotateAngleX = model.bipedLeftArm.rotateAngleX;
- }
- else if(item==IIContent.itemGrenade)
- {
- float use = 1f-MathHelper.clamp(((EntityLivingBase)entity).getItemInUseCount()/(float)heldItem.getMaxItemUseDuration(), 0, 1);
- if(right)
+ else if(item==IIContent.itemNavalMine)
+ if(right)
+ {
+ model.bipedRightArm.rotateAngleX -= 0.5f;
+ model.bipedLeftArm.rotateAngleX = model.bipedRightArm.rotateAngleX;
+ }
+ else
+ {
+ model.bipedLeftArm.rotateAngleX -= 0.5f;
+ model.bipedRightArm.rotateAngleX = model.bipedLeftArm.rotateAngleX;
+ }
+ else if(item==IIContent.itemGrenade)
{
- model.rightArmPose = ArmPose.EMPTY;
- //model.leftArmPose=ArmPose.EMPTY;
- float hh = -(4.5f-model.bipedHead.rotateAngleX);
- model.bipedRightArm.rotateAngleX = use!=1?use > 0f?use < 0.35f?use/0.35f*hh: hh: 0f: 0f;
+ float use = 1f-MathHelper.clamp(((EntityLivingBase)entity).getItemInUseCount()/(float)heldItem.getMaxItemUseDuration(), 0, 1);
+ if(right)
+ {
+ model.rightArmPose = ArmPose.EMPTY;
+ //model.leftArmPose=ArmPose.EMPTY;
+ float hh = -(4.5f-model.bipedHead.rotateAngleX);
+ model.bipedRightArm.rotateAngleX = use!=1?use > 0f?use < 0.35f?use/0.35f*hh: hh: 0f: 0f;
+ }
}
- }
}
}
@@ -648,12 +633,13 @@ public void onRenderWorldLast(RenderWorldLastEvent event)
@SubscribeEvent(priority = EventPriority.HIGH)
public void onRenderOverlayPre(Pre event)
{
- if(ClientUtils.mc().player==null||event.getType()!=ElementType.CROSSHAIRS)
+ Minecraft mc = ClientUtils.mc();
+ if(mc.player==null||event.getType()!=ElementType.CROSSHAIRS)
return;
for(EnumHand hand : EnumHand.values())
{
- ItemStack stack = ClientUtils.mc().player.getHeldItem(hand);
+ ItemStack stack = mc.player.getHeldItem(hand);
if(stack.getItem().getTileEntityItemStackRenderer() instanceof ISpecificHandRenderer)
if(((ISpecificHandRenderer)stack.getItem().getTileEntityItemStackRenderer()).shouldCancelCrosshair(stack, hand))
{
@@ -662,9 +648,9 @@ public void onRenderOverlayPre(Pre event)
}
}
- RayTraceResult mop = ClientUtils.mc().objectMouseOver;
- EntityPlayer player = ClientUtils.mc().player;
- //
+ RayTraceResult mop = mc.objectMouseOver;
+ EntityPlayer player = mc.player;
+ float partialTicks = event.getPartialTicks();
//Iterate HUD backgrounds
for(GuiOverlayBase hud : HUD_BACKGROUNDS)
@@ -678,99 +664,32 @@ public void onRenderOverlayPre(Pre event)
Entity ridden = player.getRidingEntity();
Entity lowestRidden = ridden==null?null: ridden.getLowestRidingEntity();
- //--- Entity Zoom Handling ---//
-
- if(lowestRidden instanceof IEntityZoomProvider)
- {
- boolean pressed = ClientProxy.keybindZoom.isKeyDown();
- if(pressed^mgAiming&&ridden instanceof EntityMachinegun)
- {
- NBTTagCompound tag = new NBTTagCompound();
- tag.setBoolean("clientMessage", true);
- tag.setBoolean("aiming", pressed);
- IIPacketHandler.sendToServer(new MessageEntityNBTSync(ridden, tag));
- ((EntityMachinegun)ridden).aiming = pressed;
- }
- mgAiming = pressed;
- }
- else mgAiming = false;
-
//--- Camera Handling ---//
- if(mgAiming)
+ if(lowestRidden instanceof ICameraEntity)
{
- ClientUtils.mc().gameSettings.thirdPersonView = 0;
-
- if(lowestRidden instanceof EntityMachinegun)
+ ICameraEntity cameraEntity = (ICameraEntity)lowestRidden;
+ if(!cameraEntity.isCameraEnabled(player))
+ CameraHandler.setEnabled(false);
+ else
{
- EntityMachinegun mg = (EntityMachinegun)lowestRidden;
- float px = (float)mg.posX, py = (float)mg.posY, pz = (float)mg.posZ;
-
- float yaw = mg.gunYaw;
- float pitch = mg.gunPitch;
-
- EntityLivingBase psg = (EntityLivingBase)mg.getPassengers().get(0);
- float true_head_angle = MathHelper.wrapDegrees(psg.prevRotationYawHead-mg.setYaw);
- float true_head_angle2 = MathHelper.wrapDegrees(psg.rotationPitch);
-
- if(mg.gunYaw < true_head_angle)
- yaw += ClientUtils.mc().getRenderPartialTicks()*2f;
- else if(mg.gunYaw > true_head_angle)
- yaw -= ClientUtils.mc().getRenderPartialTicks()*2f;
-
- if(Math.ceil(mg.gunYaw) <= Math.ceil(true_head_angle)+1f&&Math.ceil(mg.gunYaw) >= Math.ceil(true_head_angle)-1f)
- yaw = true_head_angle;
-
- if(mg.gunPitch < true_head_angle2)
- pitch += ClientUtils.mc().getRenderPartialTicks();
- else if(mg.gunPitch > true_head_angle2)
- pitch -= ClientUtils.mc().getRenderPartialTicks();
-
- yaw = mg.tripod?MathHelper.clamp(yaw, -82.5F, 82.5F): MathHelper.clamp(yaw, -45.0F, 45.0F);
- pitch = MathHelper.clamp(pitch, -20, 20);
-
- yaw += mg.recoilYaw;
- pitch += mg.recoilPitch;
-
- double true_angle = Math.toRadians(180-mg.setYaw-yaw);
- double true_angle2 = Math.toRadians(pitch);
-
- boolean hasScope = mg.getZoom().shouldZoom(mg.gun, null);
-
- Vec3d gun_end = IIMath.offsetPosDirection(2.25f-(hasScope?1.25f: 0), true_angle, true_angle2);
- Vec3d gun_height = IIMath.offsetPosDirection(0.25f+(hasScope?0.125f: 0f), true_angle, true_angle2+90);
-
- CameraHandler.setCameraPos(px+0.85*(gun_end.x+gun_height.x), py-1.5f+0.4025+0.85*(gun_end.y+gun_height.y), pz+0.85*(gun_end.z+gun_height.z));
- CameraHandler.setCameraAngle(mg.setYaw+yaw, pitch, 0);
+ if(!cameraEntity.isThirdPersonAllowed(player))
+ mc.gameSettings.thirdPersonView = -1;
+
+ CameraHandler.setCameraPos(cameraEntity.getCameraPos(player, partialTicks));
+ CameraHandler.setCameraAngle(
+ cameraEntity.getCameraYaw(player, partialTicks),
+ cameraEntity.getCameraPitch(player, partialTicks),
+ cameraEntity.getCameraRoll(player, partialTicks)
+ );
CameraHandler.setEnabled(true);
}
- else if(lowestRidden instanceof EntityMortar)
- {
- EntityMortar mg = (EntityMortar)lowestRidden;
- // CameraHandler.isZooming = false;
- if(mg.shootingProgress!=0)
- CameraHandler.fovZoom = 0;
-
- CameraHandler.setCameraPos(mg.posX, mg.posY+0.75, mg.posZ);
- CameraHandler.setCameraAngle(mg.rotationYaw, 1+(1f-mg.rotationPitch/-90f)*-1.5f, 0);
- CameraHandler.setEnabled(mg.shootingProgress==0);
- }
- else if(lowestRidden instanceof EntityTripodPeriscope)
- {
- EntityTripodPeriscope mg = (EntityTripodPeriscope)lowestRidden;
- float px = (float)mg.posX, py = (float)mg.posY, pz = (float)mg.posZ;
-
- CameraHandler.setCameraPos(px, py+1.25, pz);
- ClientUtils.mc().player.rotationPitch = MathHelper.clamp(ClientUtils.mc().player.rotationPitch, -50, 50);
- ClientUtils.mc().player.prevRotationPitch = MathHelper.clamp(ClientUtils.mc().player.prevRotationPitch, -50, 50);
- float y = MathHelper.wrapDegrees(360+mg.periscopeNextYaw-mg.periscopeYaw);
- float currentYaw = MathHelper.wrapDegrees(mg.periscopeYaw+event.getPartialTicks()*(Math.signum(y)*MathHelper.clamp(Math.abs(y), 0, TripodPeriscope.turnSpeed)));
-
- CameraHandler.setCameraAngle(currentYaw, ClientUtils.mc().player.rotationPitch, 0);
- CameraHandler.setEnabled(true);
- }
+//mc.gameSettings.thirdPersonView = -1;
+// CameraHandler.setCameraPos(mg.posX, mg.posY+0.75, mg.posZ);
+// CameraHandler.setCameraAngle(mg.rotationYaw, 1+(1f-mg.rotationPitch/-90f)*-1.5f, 0);
+// CameraHandler.setEnabled(mg.shootingProgress==0);
}
else
CameraHandler.setEnabled(false);
@@ -839,18 +758,15 @@ else if(CameraHandler.zoom!=null)
if(ridingEntity instanceof EntityVehicleSeat)
{
EntityVehicleSeat riding = (EntityVehicleSeat)ridingEntity;
- if(riding.info!=null&&riding.info.passMouseButtonEvent(event))
+ if(riding.info!=null&&riding.info.passMouseButtonEvent(event)&&event.isButtonstate())
event.setCanceled(true);
}
- else if(ridingEntity instanceof EntityMachinegun)
- if(event.getButton()==1)
- {
- NBTTagCompound tag = new NBTTagCompound();
- tag.setBoolean("clientMessage", true);
- tag.setBoolean("shoot", event.isButtonstate());
- IIPacketHandler.sendToServer(new MessageEntityNBTSync(ridingEntity, tag));
+ else if(ridingEntity instanceof EntityMountedWeapon)
+ {
+ EntityMountedWeapon weapon = (EntityMountedWeapon)ridingEntity;
+ if(weapon.controls!=null&&weapon.controls.passMouseButtonEvent(event)&&event.isButtonstate())
event.setCanceled(true);
- }
+ }
}
/**
@@ -963,7 +879,7 @@ public void onRenderHand(RenderSpecificHandEvent event)
{
//Check ridden entity for custom hand rendering
Entity ridden = ClientUtils.mc().player.getRidingEntity();
- if(ridden instanceof EntityVehicleSeat)
+ if(ridden instanceof EntityVehicleSeat||ridden instanceof EntityMountedWeapon)
{
event.setCanceled(true);
return;
@@ -1061,7 +977,6 @@ public void onWorldLoad(Load event)
return;
//Reset static variables
- aimingPlayers.clear();
blockDamageClient.clear();
//Reload the particle system
@@ -1077,16 +992,17 @@ public void onGameRuleChange(GameRuleChangeEvent event)
@SubscribeEvent
public void onPostClientTick(ClientTickEvent event)
{
- if(event.phase==Phase.END)
- {
- if(ParticleSystem.INSTANCE!=null)
- ParticleSystem.INSTANCE.updateParticles();
+ if(event.phase!=Phase.END)
+ return;
+ Minecraft mc = ClientUtils.mc();
- if(!Weapons.bulletsWhistleSound)
- return;
+ if(ParticleSystem.INSTANCE!=null)
+ ParticleSystem.INSTANCE.updateParticles();
+
+ if(mc.world!=null&&mc.player!=null)
+ {
//Make close bullets produce a whistling sound
- Minecraft mc = ClientUtils.mc();
- if(mc.world!=null&&mc.player!=null)
+ if(Weapons.bulletsWhistleSound)
{
List bullets = mc.world.getEntitiesWithinAABB(EntityAmmoProjectile.class, mc.player.getEntityBoundingBox().grow(3));
for(EntityAmmoProjectile bullet : bullets)
@@ -1094,8 +1010,24 @@ public void onPostClientTick(ClientTickEvent event)
//higher the velocity (howitzers), lower the tone
bullet.playSound(IISounds.bulletFlyby, 0.6f, 1.75f-MathHelper.clamp(bullet.getVelocity()/6f, 0.5f, 1.75f));
}
+
+ //Handle nightvision effect
+ if(OpenGlHelper.shadersSupported)
+ {
+ PotionEffect effect = mc.player.getActivePotionEffect(IIPotions.infraredVision);
+ if(effect!=null&&!nightVisionActive)
+ {
+ mc.entityRenderer.loadShader(IIReference.RES_II.with("shaders/post/nightvision.json"));
+ ClientRegistry.registerEntityShader(EntityCamera.class, IIReference.RES_II.with("shaders/post/nightvision.json"));
+ nightVisionActive = true;
+ }
+ else if(effect==null&&nightVisionActive)
+ {
+ mc.entityRenderer.stopUseShader();
+ ClientRegistry.registerEntityShader(EntityCamera.class, null);
+ nightVisionActive = false;
+ }
+ }
}
}
-
-
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientProxy.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientProxy.java
index 08bf350a2..8897e4f2f 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientProxy.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/ClientProxy.java
@@ -57,6 +57,7 @@
import pl.pabilo8.immersiveintelligence.api.ShrapnelHandler;
import pl.pabilo8.immersiveintelligence.api.ShrapnelHandler.Shrapnel;
import pl.pabilo8.immersiveintelligence.api.ammo.AmmoRegistry;
+import pl.pabilo8.immersiveintelligence.api.ammo.parts.AmmoComponent;
import pl.pabilo8.immersiveintelligence.api.ammo.parts.IAmmoTypeItem;
import pl.pabilo8.immersiveintelligence.api.crafting.recipe.IIMultiblockRecipe;
import pl.pabilo8.immersiveintelligence.api.data.IIDataTypeUtils;
@@ -66,8 +67,9 @@
import pl.pabilo8.immersiveintelligence.client.fx.IIParticles;
import pl.pabilo8.immersiveintelligence.client.fx.utils.ParticleRegistry;
import pl.pabilo8.immersiveintelligence.client.fx.utils.ParticleSystem;
-import pl.pabilo8.immersiveintelligence.client.gui.block.GuiUpgrade;
+import pl.pabilo8.immersiveintelligence.client.gui.block.GuiTileUpgrade;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
+import pl.pabilo8.immersiveintelligence.client.gui.entity.GuiEntityUpgrade;
import pl.pabilo8.immersiveintelligence.client.manual.IIManualCategory;
import pl.pabilo8.immersiveintelligence.client.manual.categories.*;
import pl.pabilo8.immersiveintelligence.client.model.IIModelRegistry;
@@ -80,10 +82,7 @@
import pl.pabilo8.immersiveintelligence.client.render.ammunition.NavalMineRenderer.NavalMineItemstackRenderer;
import pl.pabilo8.immersiveintelligence.client.render.entity.*;
import pl.pabilo8.immersiveintelligence.client.render.entity.hans.HansRenderer;
-import pl.pabilo8.immersiveintelligence.client.render.entity.vehicle.FieldGunRenderer;
-import pl.pabilo8.immersiveintelligence.client.render.entity.vehicle.FieldHowitzerRenderer;
-import pl.pabilo8.immersiveintelligence.client.render.entity.vehicle.MotorbikeRenderer;
-import pl.pabilo8.immersiveintelligence.client.render.entity.vehicle.TrackedMotorbikeRenderer;
+import pl.pabilo8.immersiveintelligence.client.render.entity.vehicle.*;
import pl.pabilo8.immersiveintelligence.client.render.entity.weapon.MachinegunRenderer;
import pl.pabilo8.immersiveintelligence.client.render.entity.weapon.MortarRenderer;
import pl.pabilo8.immersiveintelligence.client.render.entity.weapon.TripodPeriscopeRenderer;
@@ -109,13 +108,13 @@
import pl.pabilo8.immersiveintelligence.client.util.font.IIFontRendererCustomGlyphs;
import pl.pabilo8.immersiveintelligence.common.*;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Factions;
+import pl.pabilo8.immersiveintelligence.common.ammo.components.factory.AmmoComponentFluid;
import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger;
import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityRedstoneBuffer;
import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntitySmallDataBuffer;
import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityTimedBuffer;
import pl.pabilo8.immersiveintelligence.common.block.fortification.tileentity.TileEntityMineSign;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.BlockIIMetalDevice.IIBlockTypes_MetalDevice;
-import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.TileEntityLatexCollector;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.conveyors.*;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.gate_multiblock.multiblock.MultiblockAluminiumChainFenceGate.TileEntityAluminiumChainFenceGate;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.gate_multiblock.multiblock.MultiblockAluminiumFenceGate.TileEntityAluminiumFenceGate;
@@ -138,10 +137,14 @@
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.naval_mine.EntityNavalMine;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.naval_mine.EntityNavalMineAnchor;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMachinegun;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMortar;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityTripodPeriscope;
import pl.pabilo8.immersiveintelligence.common.entity.tactile.EntityAMTTactile;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityDrone;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityMotorbike;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityTrackedMotorbike;
+import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldFlak;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldGun;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldHowitzer;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
@@ -180,6 +183,7 @@ public class ClientProxy extends CommonProxy
public static KeyBinding keybindManualReload, keybindArmorHelmet, keybindArmorExosuit, keybindZoom;
public static KeyBinding keybindVehicleEngine, keybindVehicleClutch, keybindVehicleTowing;
public static KeyBinding keybindVehicleGearUp, keybindVehicleGearDown, keybindVehicleReductionSwitch;
+ public static KeyBinding keybindVehicleGunUp, keybindVehicleGunDown, keybindVehicleGunLeft, keybindVehicleGunRight;
private EasyNBT storedGuiData = EasyNBT.newNBT();
private HashMap, Block> TEISRRegistryQueue = new HashMap<>();
@@ -332,13 +336,21 @@ public Object getClientGuiElement(int ID, EntityPlayer player, World world, int
EnumHand hand;
TileEntity te = world.getTileEntity(new BlockPos(x, y, z));
ItemStack stack = player.getHeldItem(hand = (player.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof IGuiItem?EnumHand.MAIN_HAND: EnumHand.OFF_HAND));
+ Entity entity = y==Integer.MIN_VALUE?world.getEntityByID(x): null;
- if(ID==IIGUI.UPGRADE.ordinal()&&te instanceof IUpgradableDevice)
+ if(ID==IIGUI.UPGRADE_TILE.ordinal()&&te instanceof IUpgradableDevice)
{
IUpgradableDevice upgradeMaster = ((IUpgradableDevice)te).master();
if(upgradeMaster!=null)
//noinspection rawtypes,unchecked
- return new GuiUpgrade(player, ((TileEntityIEBase)upgradeMaster));
+ return new GuiTileUpgrade(player, ((TileEntityIEBase)upgradeMaster));
+ }
+ if(ID==IIGUI.UPGRADE_ENTITY.ordinal()&&entity instanceof IUpgradableDevice)
+ {
+ IUpgradableDevice upgradeMaster = ((IUpgradableDevice)entity).master();
+ if(upgradeMaster!=null)
+ //noinspection rawtypes,unchecked
+ return new GuiEntityUpgrade(player, ((Entity)upgradeMaster));
}
GuiScreen gui = null;
@@ -387,6 +399,7 @@ public void preInit(FMLPreInitializationEvent event)
registerEntityRenderer(EntityDrone.class, DroneRenderer::new);
//Towables
registerEntityRenderer(EntityFieldHowitzer.class, FieldHowitzerRenderer::new);
+ registerEntityRenderer(EntityFieldFlak.class, FieldFlakRenderer::new);
registerEntityRenderer(EntityFieldGun.class, FieldGunRenderer::new);
registerEntityRenderer(EntityTripodPeriscope.class, TripodPeriscopeRenderer::new);
@@ -465,14 +478,11 @@ else if(bullet instanceof ItemIIAmmoRevolver)
ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySmallDataBuffer.class, new SmallDataBufferRenderer());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityDataMerger.class, new DataMergerRenderer());
registerTileRenderer(DataDebuggerRenderer.class);
-
- //TODO: 29.12.2023 latex collector renderer
- ClientRegistry.bindTileEntitySpecialRenderer(TileEntityLatexCollector.class, new LatexCollectorRenderer());
+ registerTileRenderer(LatexCollectorRenderer.class);
//Decorations
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMineSign.class, new MineSignRenderer());
-
//Tools
IIContent.itemTripodPeriscope.setTileEntityItemStackRenderer(TripodPeriscopeRenderer.instance);
IIContent.itemMortar.setTileEntityItemStackRenderer(MortarRenderer.instance);
@@ -687,6 +697,16 @@ public void init(FMLInitializationEvent event)
keybindVehicleReductionSwitch = new IIKeybind("vehicle.gear2.toggle", Keyboard.KEY_G, IIKeybind.CATEGORY_VEHICLES)
.withContext(IIKeybind.VEHICLE_KEY_CONTEXT).register();
+ //Vehicle Gun Keybinds
+ keybindVehicleGunUp = new IIKeybind("vehicle.gun.up", Keyboard.KEY_UP, IIKeybind.CATEGORY_VEHICLES)
+ .withContext(IIKeybind.VEHICLE_KEY_CONTEXT).register();
+ keybindVehicleGunDown = new IIKeybind("vehicle.gun.down", Keyboard.KEY_DOWN, IIKeybind.CATEGORY_VEHICLES)
+ .withContext(IIKeybind.VEHICLE_KEY_CONTEXT).register();
+ keybindVehicleGunLeft = new IIKeybind("vehicle.gun.left", Keyboard.KEY_LEFT, IIKeybind.CATEGORY_VEHICLES)
+ .withContext(IIKeybind.VEHICLE_KEY_CONTEXT).register();
+ keybindVehicleGunRight = new IIKeybind("vehicle.gun.right", Keyboard.KEY_RIGHT, IIKeybind.CATEGORY_VEHICLES)
+ .withContext(IIKeybind.VEHICLE_KEY_CONTEXT).register();
+
//Register shaders
ShaderUtil.init();
@@ -727,6 +747,11 @@ public void postInit(FMLPostInitializationEvent event)
ForgeHooksClient.registerTESRItemStack(Item.getItemFromBlock(IIContent.blockMetalDevice), IIBlockTypes_MetalDevice.SMALL_DATA_BUFFER.getMeta(), TileEntitySmallDataBuffer.class);
ForgeHooksClient.registerTESRItemStack(Item.getItemFromBlock(IIContent.blockMetalDevice), IIBlockTypes_MetalDevice.DATA_MERGER.getMeta(), TileEntityDataMerger.class);
+ //Fix colors for fluid ammo components on client
+ for(AmmoComponent component : AmmoRegistry.getAllComponents())
+ if(component instanceof AmmoComponentFluid)
+ ((AmmoComponentFluid)component).setOverrideColor(IIClientUtils.getFluidTextureColor(((AmmoComponentFluid)component).getFluid()));
+
//Load Models
reloadModels();
IIMultiblockRecipe.loadAllClientSideContent();
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleDrawStages.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleDrawStages.java
index 796fc01fc..69623d40a 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleDrawStages.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleDrawStages.java
@@ -102,16 +102,14 @@ public void prepareRender(BufferBuilder buffer, float partialTicks)
else
GlStateManager.disableTexture2D();
+ if(applyLighting)
+ GlStateManager.enableLighting();
+
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, destFactor);
if(this.renderThroughBlocks)
GlStateManager.disableDepth();
if(shader!=null)
ShaderUtil.useShader(shader, shaderParameters.apply(partialTicks));
- if(applyLighting)
- {
- GlStateManager.enableLighting();
-
- }
buffer.begin(GL11.GL_QUADS, vertexFormat);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleRegistry.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleRegistry.java
index bb825de57..9c8228079 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleRegistry.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/fx/utils/ParticleRegistry.java
@@ -2,10 +2,7 @@
import blusunrize.immersiveengineering.client.ClientUtils;
import com.google.gson.JsonObject;
-import net.minecraft.client.particle.Particle;
-import net.minecraft.client.particle.ParticleCloud;
import net.minecraft.util.EnumFacing;
-import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
@@ -16,17 +13,20 @@
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import pl.pabilo8.immersiveintelligence.api.ammo.PenetrationRegistry;
+import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.client.fx.factories.ParticleFactory;
import pl.pabilo8.immersiveintelligence.client.fx.particles.AbstractParticle;
import pl.pabilo8.immersiveintelligence.client.render.IReloadableModelContainer;
-import pl.pabilo8.immersiveintelligence.client.util.tmt.ModelRendererTurbo;
import pl.pabilo8.immersiveintelligence.common.IILogger;
import pl.pabilo8.immersiveintelligence.common.util.*;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
import javax.annotation.Nullable;
import javax.vecmath.Vector2f;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -395,90 +395,25 @@ debrisMotion, new Vector2f(IIParticleUtils.randFloat.get()*4, IIParticleUtils.ra
}
}
-
- }
-
- public static void spawnGunfireFX(Vec3d pos, Vec3d direction, float size)
- {
- ParticleRegistry.spawnParticle("ammo/gunfire", pos, Vec3d.ZERO, IIParticleUtils.toVector2f(direction))
- .withProperty(ParticleProperties.SIZE, size*0.25f);
- /*ParticleGunfire particle = new ParticleGunfire(getWorld(), pos, motion, size);
- ParticleSystem.addEffect(particle);*/
- }
-
- //TODO: 04.05.2024 replace with AMT models
- public static void spawnTMTModelFX(Vec3d pos, Vec3d motion, float size, ModelRendererTurbo model, ResourceLocation texture)
- {
- /*Particle particle = new ParticleTMTModel(getWorld(), pos, motion, size, model, texture);
- Minecraft.getMinecraft().effectRenderer.addEffect(particle);*/
- }
-
- public static void spawnFlameFX(Vec3d pos, Vec3d motion, float size, int lifeTime)
- {
- /*ParticleFlame particle = new ParticleFlame(getWorld(), pos, motion, size, lifeTime);
- ParticleSystem.addEffect(particle);*/
- }
-
- public static void spawnFlameExplosion(Vec3d pos, float size, Random rand)
- {
-
- for(int i = 0; i < 20*size; i += 1)
- {
- Vec3d v = new Vec3d(1, 0, 0).rotateYaw(i/20f*360f);
-
- ParticleCloud particle = (ParticleCloud)spawnVanillaParticle(EnumParticleTypes.CLOUD, pos, IIParticleUtils.withY(v.scale(0.25), 0.125));
- if(particle!=null)
- {
- particle.setRBGColorF(rand.nextFloat()*0.125f, rand.nextFloat()*0.125f, 0);
- particle.multipleParticleScaleBy(2.5f);
- particle.setMaxAge(10);
- }
-
- }
-
-
}
public static void spawnGasCloud(Vec3d pos, float size, Fluid fluid)
{
//Check if fluid is not null
- if(fluid==null) return;
-
- //Get the color of the fluid
- int color = fluid.getColor(); //Assuming the Fluid class has this method
- float red = ((color>>16)&255)/255.0F;
- float green = ((color>>8)&255)/255.0F;
- float blue = (color&255)/255.0F;
-
- //Spawn multiple particles for the gas cloud effect
- for(int i = 0; i < 40*size; i++)
- {
- //Randomly distribute particles in a larger spherical area
- double offsetX = (Math.random()-0.5)*size*3.5; //Increased spread
- double offsetY = (Math.random()-0.5)*size*2; //Increased vertical spread
- double offsetZ = (Math.random()-0.5)*size*3.5; //Increased spread
+ if(fluid==null)
+ return;
- Vec3d particlePos = pos.add(new Vec3d(offsetX, offsetY-1.0, offsetZ)); //Lower spawn point by 1 block
+ IIColor color = IIClientUtils.getFluidTextureColor(fluid);
- ParticleCloud particle = (ParticleCloud)spawnVanillaParticle(EnumParticleTypes.CLOUD, particlePos, Vec3d.ZERO);
- if(particle!=null)
- {
- particle.setRBGColorF(red, green, blue); //Set the color of the particle
- particle.setMaxAge(160); //Adjust lifespan as needed
- particle.multipleParticleScaleBy(5f); //Adjust scale if necessary
- }
- }
+ for(int i = 0; i < 10; i++)
+ spawnParticle("smoke/gas_cloud", pos.add(IIParticleUtils.getRandXZ().scale(size/2)), Vec3d.ZERO, new Vector2f(0, 0))
+ .withProperty(ParticleProperties.SIZE, size*1.5f)
+ .withProperty(ParticleProperties.MAX_LIFETIME, (int)size*55)
+ .withProperty(ParticleProperties.COLOR, color);
}
//--- Utils ---//
- private static Particle spawnVanillaParticle(EnumParticleTypes particle, Vec3d pos, Vec3d motion)
- {
- return ClientUtils.mc().effectRenderer.spawnEffectParticle(particle.getParticleID(),
- pos.x, pos.y, pos.z,
- motion.x, motion.y, motion.z);
- }
-
private static class ParticleFileEntry
{
ResLoc path;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiAmmunitionCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiAmmunitionCrate.java
index c261c2ff7..583e83e5c 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiAmmunitionCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiAmmunitionCrate.java
@@ -2,29 +2,24 @@
import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoResource;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
+import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.effect_crate.TileEntityAmmunitionCrate;
import pl.pabilo8.immersiveintelligence.common.gui.ContainerAmmunitionCrate;
-import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
/**
* @author Pabilo8 (pabilo@iiteam.net)
* @since 17.05.2019
*/
-@DecoTemplate(name = "ammunitioncrate", category = DecoGuiCategory.GENERIC_TILE)
-public class GuiAmmunitionCrate extends DecoGui
+@DecoTemplate(name = "ammunition_crate", category = DecoGuiCategory.GENERIC_TILE)
+public class GuiAmmunitionCrate extends DecoTileGui
{
- @DecoResource
- public static final ResourceLocation TEXTURE_AMMO = IIReference.RES_II.with("gui/ammunition_crate");
-
public GuiAmmunitionCrate(EntityPlayer player, TileEntityAmmunitionCrate tile)
{
super(player, tile, IIGUI.AMMUNITION_CRATE);
@@ -33,23 +28,32 @@ public GuiAmmunitionCrate(EntityPlayer player, TileEntityAmmunitionCrate tile)
@Override
public void onInit()
{
+ final IIColor backgroundColor = IIColor.fromPackedRGB(0xd0ebc2);
startBackground()
- .withBox(null, 0, 0, 176, 76)
- .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 87, 176, 92)
+ .withBox(DecoTextures.BG_STEEL_ROUGH, DecoTextures.TEMPLATE_ROUND, 0, 0, 176, 126+8, backgroundColor)
+ .withTitleBar(tile)
+ .conditionally(tile.isUpgradeInstalled(IIContent.UPGRADE_MG_LOADER), builder -> builder
+ .withNextLayer()
+ .withBox(DecoTextures.BG_STEEL_ROUGH, DecoTextures.TEMPLATE_ROUND, 176, 0, 48, 126+8, backgroundColor)
+ .withInventorySlots(SlotStyle.VANILLA, container.inputMG)
+ )
+ .withNextLayer()
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 126+8, 176, 92)
.withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
- .withInventorySlots(SlotStyle.IE_CUSTOM1, container.slotsInputrevolver)
- .withInventorySlots(SlotStyle.IE_CUSTOM1, container.slotsInputbullet)
- .withInventorySlots(SlotStyle.IE_CUSTOM1, container.slotsInputshell)
+ .withInventorySlots(SlotStyle.VANILLA, container.inputRevolver)
+ .withInventorySlots(SlotStyle.VANILLA, container.inputBullet)
+ .withInventorySlots(SlotStyle.VANILLA, container.inputShell)
.withInventoryTitleBar()
.build();
- addComponents(
+
+ /*addComponents(
new DecoImage(0, -45)
.withSize(175, 132)
.withImageLocation(TEXTURE_AMMO, true)
.withUV(256, 0, 0, 175, 132)
- );
+ );*/
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalBath.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalBath.java
index e45e62457..9a8d77b21 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalBath.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalBath.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.common.Optional.Method;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
@@ -21,7 +21,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "chemical_bath", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiChemicalBath extends DecoGui
+public class GuiChemicalBath extends DecoTileGui
{
@DecoResource
public static ResLoc TEXTURE = IIReference.RES_II.with("gui/chemical_bath");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalPainter.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalPainter.java
index 28fbed2b1..c6d6aa689 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalPainter.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiChemicalPainter.java
@@ -3,7 +3,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Optional.Method;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoColorPickerPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
@@ -27,7 +27,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "chemical_painter", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiChemicalPainter extends DecoGui
+public class GuiChemicalPainter extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE = IIReference.RES_II.with("gui/chemical_painter");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiCoagulator.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiCoagulator.java
index 16b3d32e5..8a1ad49af 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiCoagulator.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiCoagulator.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
@@ -21,7 +21,7 @@
* @since 12.12.2025
*/
@DecoTemplate(name = "coagulator", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiCoagulator extends DecoGui
+public class GuiCoagulator extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE = IIReference.RES_II.with("gui/coagulator");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataMerger.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataMerger.java
deleted file mode 100644
index dcf5c83b1..000000000
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataMerger.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package pl.pabilo8.immersiveintelligence.client.gui.block;
-
-import blusunrize.immersiveengineering.client.ClientUtils;
-import blusunrize.immersiveengineering.client.gui.GuiIEContainerBase;
-import blusunrize.immersiveengineering.client.gui.elements.GuiButtonIE;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.resources.I18n;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.entity.player.InventoryPlayer;
-import net.minecraft.util.math.MathHelper;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
-import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
-import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeInteger;
-import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
-import pl.pabilo8.immersiveintelligence.client.gui.ITabbedGui;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoColors;
-import pl.pabilo8.immersiveintelligence.common.IIUtils;
-import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger;
-import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger.DataMergerSendMode;
-import pl.pabilo8.immersiveintelligence.common.gui.ContainerDataMerger;
-import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
-import pl.pabilo8.immersiveintelligence.common.network.messages.MessageIITileSync;
-import pl.pabilo8.immersiveintelligence.common.util.IIReference;
-import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * @author Pabilo8 (pabilo@iiteam.net)
- * @since 30.06.2019
- */
-public class GuiDataMerger extends GuiIEContainerBase implements ITabbedGui
-{
- public static final String texture = ImmersiveIntelligence.MODID+":textures/gui/data_merger.png";
-
- public TileEntityDataMerger tile;
- public InventoryPlayer playerInv;
- public DataPacket settingsPacket;
- public GuiButtonIE buttonForward, buttonBackward;
-
- public GuiDataMerger(EntityPlayer player, TileEntityDataMerger tile)
- {
- super(new ContainerDataMerger(player, tile));
- this.ySize = 222;
- this.playerInv = player.inventory;
- this.tile = tile;
- this.settingsPacket = tile.settingsPacket;
- }
-
- @Override
- public void initGui()
- {
- super.initGui();
-
- this.buttonList.clear();
- addButton(buttonForward = new GuiButtonIE(0, guiLeft+4, guiTop+16, 8, 6, "", texture, 128, 222).setHoverOffset(8, 0));
- addButton(buttonBackward = new GuiButtonIE(1, guiLeft+4, guiTop+24, 8, 6, "", texture, 128, 228).setHoverOffset(8, 0));
-
- }
-
- @Override
- public void updateScreen()
- {
- super.updateScreen();
- }
-
- @Override
- protected void actionPerformed(GuiButton button)
- {
- if(button==buttonForward||button==buttonBackward)
- {
- //cycle the mode depending on button
- tile.mode = IIUtils.cycleEnum(button==buttonForward, DataMergerSendMode.class, tile.mode);
- //send update to server side
- IIPacketHandler.sendToServer(new MessageIITileSync(tile, EasyNBT.newNBT().withByte("mode", tile.mode.ordinal())));
- }
- }
-
- @Override
- public void drawScreen(int mx, int my, float partial)
- {
- super.drawScreen(mx, my, partial);
- this.fontRenderer.drawString(I18n.format(IIReference.DESCRIPTION_KEY+"data_merger."+tile.mode), guiLeft+14, guiTop+19, DecoColors.H1.getPackedRGB());
-
- ArrayList tooltip = new ArrayList<>();
-
- int i = 0;
- for(char c : DataPacket.VARIABLE_NAMES)
- {
- int xoff = (int)Math.floor(i/6f), yoff = i%6;
- int col = 0xefefef;
- if(settingsPacket.get(c) instanceof DataTypeInteger)
- {
- int o = ((DataTypeInteger)settingsPacket.get(c)).value;
- switch(o)
- {
- case -2:
- col = 0x26732e;
- break;
- case -1:
- col = 0x7c9d4b;
- break;
- case 1:
- col = 0xe5a64d;
- break;
- case 2:
- col = 0x922020;
- break;
- }
- }
- this.fontRenderer.drawString(String.valueOf(c), guiLeft+54+(xoff*20)+6-(int)(fontRenderer.getCharWidth(c)/2f), guiTop+16+(yoff*20)+2, col);
- i += 1;
- }
-
- }
-
- @Override
- public void onGuiClosed()
- {
- IIPacketHandler.sendToServer(new MessageIITileSync(tile, EasyNBT.newNBT().withTag("packet", settingsPacket.serializeNBT())));
- super.onGuiClosed();
- }
-
- @Override
- protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException
- {
- super.mouseClicked(mouseX, mouseY, mouseButton);
- if(mouseX >= guiLeft+54&&mouseX <= guiLeft+166&&mouseY >= guiTop+16&&mouseY <= guiTop+128)
- {
- boolean fw;
- if(mouseButton==0&&!Keyboard.isKeyDown(Keyboard.KEY_RSHIFT))
- fw = true;
- else if(mouseButton==1||Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
- fw = false;
- else
- return;
-
- int i_pos_x = (int)Math.floor((mouseX-guiLeft-54)/20f);
- int i_pos_y = (int)Math.floor((mouseY-guiTop-16)/20f);
-
- if(mouseX <= guiLeft+(i_pos_x*20)+12+54&&mouseY <= guiTop+(i_pos_y*20)+12+16)
- switchMode(DataPacket.VARIABLE_NAMES[i_pos_y+(i_pos_x*6)], fw);
- }
- }
-
- /**
- * Draws the background layer of this container (behind the items).
- */
- @Override
- protected void drawGuiContainerBackgroundLayer(float f, int mx, int my)
- {
- GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
- ClientUtils.bindTexture(texture);
- this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
- }
-
- void switchMode(char c, boolean forward)
- {
- DataType p = settingsPacket.get(c);
- //increment or decrement the number, clamp it between -2 and 2
- if(p instanceof DataTypeInteger)
- settingsPacket.set(c, new DataTypeInteger(
- MathHelper.clamp(((DataTypeInteger)p).value+(forward?1: -1), -2, 2)
- ));
- else
- //if there's no such variable, set it to -1 or 1, as 0 is the default state
- settingsPacket.set(c, new DataTypeInteger(forward?1: -1));
- }
-
-}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataRedstoneInterface.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataRedstoneInterface.java
index 65e73500d..f349c06eb 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataRedstoneInterface.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiDataRedstoneInterface.java
@@ -7,7 +7,7 @@
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent.MouseButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoArrows;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
@@ -38,7 +38,7 @@
* @since 09.02.2020
*/
@DecoTemplate(name = "data_redstone_interface", category = DecoGuiCategory.DATA_TILE)
-public class GuiDataRedstoneInterface extends DecoGui
+public class GuiDataRedstoneInterface extends DecoTileGui
{
@DecoResource
public static ResourceLocation PROGRESS_IMAGE = ResLoc.of(IIReference.RES_II, "gui/data_input_machine");
@@ -116,7 +116,7 @@ public void onInit()
new DecoList(32, 8)
.withSize(136+24+8+2, 120)
- .withEntries(redstoneToData ? dataSettings : redstoneSettings)
+ .withEntries(redstoneToData?dataSettings: redstoneSettings)
.withCreateAction(ConversionSetting::new)
.withScroll(scroll)
.withGuiSaveAction(gui -> this.scroll = gui.getScroll())
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiElectrolyzer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiElectrolyzer.java
index a413163f9..d591a1c1e 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiElectrolyzer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiElectrolyzer.java
@@ -3,7 +3,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Optional.Method;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
@@ -22,7 +22,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "electrolyzer", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiElectrolyzer extends DecoGui
+public class GuiElectrolyzer extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE = ResLoc.of(IIReference.RES_II, "gui/electrolyzer");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFiller.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFiller.java
index 8d8c70ce5..f31821d98 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFiller.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFiller.java
@@ -3,7 +3,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Optional.Method;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoDustTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
@@ -23,7 +23,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "filler", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiFiller extends DecoGui
+public class GuiFiller extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE = IIReference.RES_II.with("gui/filler");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFuelStation.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFuelStation.java
index f286bc239..aaf86a32a 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFuelStation.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiFuelStation.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
@@ -18,7 +18,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "fuel_station", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiFuelStation extends DecoGui
+public class GuiFuelStation extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE = IIReference.RES_II.with("gui/fuel_station");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiGearbox.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiGearbox.java
index 5b6ce9416..77a952cb0 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiGearbox.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiGearbox.java
@@ -3,7 +3,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextFormatting;
import pl.pabilo8.immersiveintelligence.api.rotary.IIRotaryUtils;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBarGroup;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
@@ -17,7 +17,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "wooden_gearbox", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiGearbox extends DecoGui
+public class GuiGearbox extends DecoTileGui
{
public GuiGearbox(EntityPlayer player, TileEntityGearbox tile)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMedicalCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMedicalCrate.java
index d496cf09c..c553be1e3 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMedicalCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMedicalCrate.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
@@ -23,7 +23,7 @@
*/
@DecoTemplate(name = "medicalcrate", category = DecoGuiCategory.GENERIC_TILE)
-public class GuiMedicalCrate extends DecoGui
+public class GuiMedicalCrate extends DecoTileGui
{
@DecoResource
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMetalCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMetalCrate.java
index ab7c75331..906c2aaa0 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMetalCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiMetalCrate.java
@@ -1,7 +1,7 @@
package pl.pabilo8.immersiveintelligence.client.gui.block;
import net.minecraft.entity.player.EntityPlayer;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
@@ -15,7 +15,7 @@
* @since 17.05.2019
*/
@DecoTemplate(name = "metal_crate", category = DecoGuiCategory.GENERIC_TILE)
-public class GuiMetalCrate extends DecoGui>
+public class GuiMetalCrate extends DecoTileGui>
{
public GuiMetalCrate(EntityPlayer player, TileEntityMetalCrate tile)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrecisionAssembler.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrecisionAssembler.java
index 239d7bc06..c9a9a7f36 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrecisionAssembler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrecisionAssembler.java
@@ -3,7 +3,7 @@
import blusunrize.immersiveengineering.common.util.Utils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage.ImageAnimationDirection;
@@ -25,7 +25,7 @@
*/
@DecoTemplate(name = "precision_assembler", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiPrecisionAssembler extends DecoGui
+public class GuiPrecisionAssembler extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE_PRE = IIReference.RES_II.with("gui/precision_assembler");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrintingPress.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrintingPress.java
index d77478639..9495a41a8 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrintingPress.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiPrintingPress.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
@@ -23,7 +23,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "printing_press", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiPrintingPress extends DecoGui
+public class GuiPrintingPress extends DecoTileGui
{
@DecoResource
public static ResourceLocation TEXTURE = ResLoc.of(IIReference.RES_II, "gui/printing_press");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiProjectileWorkshop.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiProjectileWorkshop.java
index 01b54e7dc..b2df81d98 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiProjectileWorkshop.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiProjectileWorkshop.java
@@ -1,12 +1,14 @@
package pl.pabilo8.immersiveintelligence.client.gui.block;
import blusunrize.immersiveengineering.api.crafting.IngredientStack;
+import blusunrize.immersiveengineering.common.IEContent;
import blusunrize.immersiveengineering.common.util.Utils;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
+import net.minecraft.util.text.TextFormatting;
import pl.pabilo8.immersiveintelligence.api.ammo.AmmoRegistry;
import pl.pabilo8.immersiveintelligence.api.ammo.enums.CoreType;
import pl.pabilo8.immersiveintelligence.api.ammo.enums.FuseType;
@@ -18,7 +20,9 @@
import pl.pabilo8.immersiveintelligence.api.ammo.utils.AmmoBallisticsCache;
import pl.pabilo8.immersiveintelligence.api.ammo.utils.AmmoBallisticsCache.CachedBallisticStats;
import pl.pabilo8.immersiveintelligence.api.ammo.utils.IIAmmoUtils;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.api.crafting.BulletComponentStack;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoEntryPanelBuilder;
@@ -27,6 +31,7 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoScenarioDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage.ImageAnimationDirection;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTBullet;
@@ -37,11 +42,13 @@
import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.TileEntityProjectileWorkshop;
import pl.pabilo8.immersiveintelligence.common.gui.ContainerProjectileWorkshop;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
import pl.pabilo8.immersiveintelligence.common.util.multiblock.util.MultiblockInteractablePart;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -52,8 +59,10 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "projectile_workshop", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiProjectileWorkshop extends DecoGui
+public class GuiProjectileWorkshop extends DecoTileGui
{
+ private static final String GUI_KEY = IIReference.GUI_LABEL_KEY+"projectile_workshop.";
+
@DecoResource
public static ResourceLocation PROGRESS_BAR = IIReference.RES_II.with("gui/projectile_workshop");
@DecoResource
@@ -83,7 +92,7 @@ public class GuiProjectileWorkshop extends DecoGui coreTypeDropdown;
private IAmmoTypeItem, ?> ammoType;
private AmmoCore ammoCore;
@@ -93,8 +102,6 @@ public class GuiProjectileWorkshop extends DecoGui 0.5f?tile.lid1: tile.lid2), true);
+ syncAnimatedParts(openedPart = Utils.RAND.nextGaussian() > 0.5f?tile.lid1: tile.lid2, true);
//Add background
startBackground()
- .withBox(DecoTextures.BG_STEEL_ROUGH, DecoTextures.TEMPLATE_SQUARE, 0, 0, 256, 130)
+ .withBox(DecoTextures.BG_STEEL_ROUGH, DecoTextures.TEMPLATE_SQUARE, 0, 0, hasFillerUpgrade?176: 256, 130)
.withTitleBar(tile)
.withNextLayer()
- .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 44, 136, 176, 92)
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, hasFillerUpgrade?0: 44, 136, 176, 92)
.withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
.withInventoryTitleBar()
@@ -135,6 +142,13 @@ public void onInit()
.withNextLayer()
.withBox(DecoTextures.BG_PAPER, DecoTextures.TEMPLATE_TICKET, 44, 18, 96, 72)
)
+ .conditionally(hasFillerUpgrade, builder -> builder
+ .withInventorySlots(SlotStyle.IE_INPUT, container.inputSlot)
+ .withInventorySlots(SlotStyle.IE_INPUT, container.componentInputSlot)
+ .withNextLayer()
+ .withBox(DecoTextures.BG_PAPER, DecoTextures.TEMPLATE_PAPER, 4, 128+8-64-4, 176-4-8, 64)
+ .withTitleBar(GUI_KEY+"component_info", DecoAlignment.TOP_LEFT)
+ )
.build();
//Add foreground
@@ -150,7 +164,113 @@ public void onInit()
private void addCoreFillerComponents()
{
+ //Upgraded
+ addComponents(
+ //Energy bar
+ new DecoBar(176-8, 4)
+ .withSize(12, 64)
+ .withTemplate(DecoTemplates.BAR_ELECTRIC_ENERGY.apply(tile.energyStorage)),
+ //Right-side paper panel
+ this.fillerInfoPanel = new DecoPanel(4, 128+8-64+4)
+ .withSize(176, 64)
+ .withBackground(null),
+ //Stored component display
+ new DecoItemStackDisplay(176/2-9, 12)
+ .withSize(16, 16)
+ .withOnTooltip(gui -> {
+ AmmoComponent current = tile.componentInside.getComponent();
+ if(current==null||tile.componentInside.amount <= 0)
+ return Collections.singleton(I18n.format("gui.immersiveengineering.empty"));
+ return Arrays.asList(
+ tile.componentInside.getColor().getHexCol(tile.componentInside.getTranslatedName()),
+ tile.componentInside.amount+" mB"
+ );
+ })
+ .withBackgroundTexture(DecoSprite.atlasSprite(DecoTextures.SLOT_IE, 32, true))
+ .withProgressBar(partialTicks -> tile.componentInside.getAmountPercentage(),
+ () -> new IIColor[]{tile.componentInside.getColor()}
+ ),
+ new DecoItemStackDisplay(176-8-24+2, 45-8)
+ .withSize(16, 16)
+ .withBackgroundTexture(DecoSprite.atlasSprite(DecoTextures.SLOT_IE, 32, true)),
+
+ //Progress bar background
+ new DecoImage(8+64+8+2+1-48-2, 28+4+4+4+1)
+ .withSize(48, 8)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 16, 11, 16+48, 11+8),
+ new DecoImage(8+64+8+2+1, 28+4+4)
+ .withSize(8, 19)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 37, 19, 37+8, 19+19),
+ new DecoImage(8+64+8+2+1+2+8, 28+4+4+4)
+ .withSize(48, 10)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 16, 0, 16+48, 10),
+
+ //Progress bar
+ new DecoImage(8+64+8+2+1-48, 28+4+4+4+1+1)
+ .withSize(44, 6)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 0, 47, 44, 47+6)
+ .withAnimation(ImageAnimationDirection.LEFT_TO_RIGHT, DecoGuiUtils.getMultiblockProductionSingleProgress(tile, 0f, 0.45f)),
+ new DecoImage(8+64+8+2+1, 28+4+4)
+ .withSize(8, 19)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 45, 19, 45+8, 19+19)
+ .withAnimation(ImageAnimationDirection.LEFT_TO_RIGHT, DecoGuiUtils.getMultiblockProductionSingleProgress(tile, 0.45f, 0.55f)),
+ new DecoImage(8+64+8+2+1+2+8+2, 28+4+4+4+2)
+ .withSize(44, 6)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 0, 39, 44, 39+6)
+ .withAnimation(ImageAnimationDirection.LEFT_TO_RIGHT, DecoGuiUtils.getMultiblockProductionSingleProgress(tile, 0.55f, 1f))
+ );
+
+ addValueListener(() -> tile.componentInside.serializeNBT().toString()+"|"+tile.componentFillAmount)
+ .addObserver(hash -> updateFillerInfo());
+ updateFillerInfo();
+ }
+
+ private void updateFillerInfo()
+ {
+ BulletComponentStack stack = tile.componentInside;
+ this.fillerInfoPanel.cleanup();
+ if(stack==null||stack.isEmpty()||stack.component==null)
+ return;
+ fillerInfoPanel.addLabel(TextFormatting.ITALIC+stack.component.getTranslatedName(), 4, 0)
+ .withSize(76, 9)
+ .withAlign(DecoAlignment.LEFT);
+ fillerInfoPanel.addLabel(I18n.format(GUI_KEY+"component.role", stack.component.getRole().getLocalizedName()), 4, 12)
+ .withSize(100, 9)
+ .withAlign(DecoAlignment.LEFT);
+ fillerInfoPanel.addLabel(I18n.format(GUI_KEY+"component.density", stack.component.getDensity()), 4, 24)
+ .withSize(100, 9)
+ .withAlign(DecoAlignment.LEFT);
+ fillerInfoPanel.addLabel(I18n.format(GUI_KEY+"component.slots_taken", stack.component.getSlotsTaken()), 4, 36)
+ .withSize(100, 9)
+ .withAlign(DecoAlignment.LEFT);
+ if(stack.component.showInManual())
+ fillerInfoPanel.addComponent(new DecoButton(176-6-16-8-2, -4)
+ .withSize(20, 20)
+
+ .withBackground(DecoTextures.COMPONENT_BUTTON)
+ .withBackgroundColor(IIColor.fromPackedRGB(0x7A7ABC))
+ .withPadding(2, 2, 2, 2)
+ .withIconAlignment(DecoAlignment.CENTER)
+ //Engineer's Manual
+ .withIcon(new ItemStack(IEContent.itemTool, 1, 3))
+ .withTranslatedTooltip(IIReference.GUI_TOOLTIP_KEY+"widget.manual.page")
+
+ .withOnLMBPressed(() -> {
+ int index = AmmoRegistry.getAllComponents().stream()
+ .filter(AmmoPart::showInManual)
+ .filter(c -> !c.getMaterial().getExampleStack().isEmpty())
+ .collect(Collectors.toList())
+ .indexOf(stack.component);
+ openManualWidget("bullet_components", index);
+ })
+ );
}
private void addCoreWorkshopComponents()
@@ -176,12 +296,12 @@ private void addCoreWorkshopComponents()
new DecoLabel(fontRenderer, 20, 2)
.withSize(48, 18)
.withAlign(DecoAlignment.LEFT)
- .withText("Core")
+ .withText(GUI_KEY+"entry.core")
)
.withElementApplyMethod(this::drawCoreTypeEntry)
- .withElementTooltip(typeMeta -> "a")
+ .withElementTooltip(typeMeta -> GUI_KEY+"tooltip.core_type")
)
- .withTranslatedTooltip("Core Type"),
+ .withTranslatedTooltip(GUI_KEY+"tooltip.core_type"),
new DecoDropdown>(0, 93)
.withSize(144, 20)
@@ -203,13 +323,13 @@ private void addCoreWorkshopComponents()
new DecoLabel(fontRenderer, 20, 2)
.withSize(48, 18)
.withAlign(DecoAlignment.LEFT)
- .withText("Type")
+ .withText(GUI_KEY+"entry.type")
)
.withElementApplyMethod(this::drawAmmoTypeEntry)
- .withElementTooltip(typeMeta -> "a")
+ .withElementTooltip(typeMeta -> I18n.format(GUI_KEY+"tooltip.ammunition_type"))
)
- .withTranslatedTooltip("Ammunition Type"),
+ .withTranslatedTooltip(GUI_KEY+"tooltip.ammunition_type"),
//3D display and cost label item
scenario = new DecoScenarioDisplay(46, 20)
.withSize(80, 60)
@@ -229,14 +349,28 @@ private void addCoreWorkshopComponents()
.withSize(12, 69)
.withTemplate(DecoTemplates.BAR_ELECTRIC_ENERGY.apply(tile.energyStorage)),
- //Progress bar
+ //Progress bar background
new DecoImage(8, 28)
- .withSize(37, 39)
+ .withSize(16, 29)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 0, 0, 16, 29),
+ new DecoImage(8, 28+29)
+ .withSize(37, 10)
.withImageLocation(PROGRESS_BAR, true)
- .withUV(64, 0, 0, 37, 39)
+ .withUV(64, 0, 29, 37, 29+10),
+ //Progress bar
+ new DecoImage(8+2, 28+2)
+ .withSize(12, 27)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 52, 26, 52+12, 26+27)
+ .withAnimation(ImageAnimationDirection.TOP_TO_BOTTOM, DecoGuiUtils.getMultiblockProductionSingleProgress(tile, 0f, 0.6f)),
+ new DecoImage(8+2+4, 28+2+27+1)
+ .withSize(29, 7)
+ .withImageLocation(PROGRESS_BAR, true)
+ .withUV(64, 35, 57, 35+29, 57+7)
+ .withAnimation(ImageAnimationDirection.LEFT_TO_RIGHT, DecoGuiUtils.getMultiblockProductionSingleProgress(tile, 0.6f, 1f))
);
- addLabel("Cost:", 48, 79)
- .withSize(78, 9);
+ addLabel(GUI_KEY+"cost", 48, 79);
costLabel = addLabel("", 48, 79)
.withSize(62, 9)
.withAlign(DecoAlignment.RIGHT);
@@ -251,7 +385,7 @@ private void updateCoreInfo()
{
exampleStackDisplay.withStack(ItemStack.EMPTY);
scenario.withModel(false, new AMTLocator("missingno", Vec3d.ZERO));
- costLabel.withText("Cost: 250 Pabulions and one Yevreiski Cent");
+ costLabel.withText(GUI_KEY+"invalid_cost");
return;
}
@@ -264,7 +398,7 @@ private void updateCoreInfo()
.withSelectedEntry(coreType);
//List cost, available materials and update 3D model
- costLabel.withText(ammoType.getCoreMaterialNeeded()+"x");
+ costLabel.withRawText(I18n.format(GUI_KEY+"unit.multiplier", ammoType.getCoreMaterialNeeded()));
List stacks = AmmoRegistry.getAllCores().stream()
.map(AmmoCore::getMaterial)
.map(IngredientStack::getExampleStack)
@@ -280,7 +414,7 @@ private void updateCoreInfo()
ammoInfoPanel.cleanup();
//Core material dropdown
ammoInfoPanel.addLabel(new DecoLabel(fontRenderer, 0, 8)
- .addText("Material Preview")
+ .withText(GUI_KEY+"material_preview")
.withSize(ammoInfoPanel.width, 8)
.withAlign(DecoAlignment.CENTER)
);
@@ -304,7 +438,7 @@ private void updateCoreInfo()
new DecoLabel(fontRenderer, 20, 2)
.withSize(48, 16)
.withAlign(DecoAlignment.LEFT)
- .withText("Type")
+ .withText(GUI_KEY+"entry.type")
)
.withElementApplyMethod(this::drawAmmoCoreEntry)
@@ -317,19 +451,19 @@ private void updateCoreInfo()
//Core
ammoInfoPanel.addLabel(new DecoLabel(fontRenderer, 0, 37)
- .addText("Core")
+ .withText(GUI_KEY+"section.core")
.withSize(ammoInfoPanel.width, 8)
.withAlign(DecoAlignment.CENTER)
);
addImageWithLabel(1, 45, COMPONENT_SLOTS, coreType.getComponentSlots(),
- "Component Slots");
+ GUI_KEY+"tooltip.component_slots");
addImageWithLabel(ammoInfoPanel.width/2, 45, COMPONENT_SHAPE, "desc.immersiveintelligence.effect_shape."+coreType.getEffectShape().getName().toLowerCase(),
- "Component Effect Shape");
+ GUI_KEY+"tooltip.component_effect_shape");
- addImageWithLabel(1, 45+13, COMPONENT_EFFICIENCY, coreType.getComponentEffectivenessMod()*ammoCore.getExplosionModifier()+"x",
- "Component Efficiency Modifier", "Determines potency.", "Responsible for explosive power, chemical gas concentration.");
- addImageWithLabel(ammoInfoPanel.width/2, 45+13, COMPONENT_SIZE, Utils.formatDouble(ammoType.getComponentSize(), "0.##")+"x",
- "Component Size Multiplier", "Determines component volume, responsible for explosion radius, gas spread range multiplier.");
+ addImageWithLabel(1, 45+13, COMPONENT_EFFICIENCY, I18n.format(GUI_KEY+"unit.multiplier", coreType.getComponentEffectivenessMod()*ammoCore.getExplosionModifier()),
+ GUI_KEY+"tooltip.component_efficiency", GUI_KEY+"tooltip.component_efficiency.line1", GUI_KEY+"tooltip.component_efficiency.line2");
+ addImageWithLabel(ammoInfoPanel.width/2, 45+13, COMPONENT_SIZE, I18n.format(GUI_KEY+"unit.multiplier", Utils.formatDouble(ammoType.getComponentSize(), "0.##")),
+ GUI_KEY+"tooltip.component_size", GUI_KEY+"tooltip.component_size.line1");
//Ballistics
if(ammoType.getClass().isAnnotationPresent(IIAmmoProjectile.class))
@@ -338,30 +472,32 @@ private void updateCoreInfo()
assert projectileInfo!=null;
CachedBallisticStats stats = AmmoBallisticsCache.get(ammoType, ammoType.getAmmoStack(ammoCore, coreType, FuseType.CONTACT));
ammoInfoPanel.addLabel(new DecoLabel(fontRenderer, 0, 73)
- .addText("Ballistics")
+ .withText(GUI_KEY+"section.ballistics")
.withSize(ammoInfoPanel.width, 8)
.withAlign(DecoAlignment.CENTER)
);
addImageWithLabel(1, 81-2, MASS, Utils.formatDouble(ammoType.getCoreMass(ammoCore, new AmmoComponent[0]), "0.##"),
- "Core Mass");
+ GUI_KEY+"tooltip.core_mass");
addImageWithLabel(ammoInfoPanel.width/2, 81-2, DAMAGE, Utils.formatDouble(ammoType.getDamage()*ammoCore.getDamageModifier()*coreType.getDamageMod(), "0.##"),
- "Damage Dealt");
- addImageWithLabel(1, 81+13, VELOCITY, ammoType.getVelocity()+" b/t",
- "Velocity");
+ GUI_KEY+"tooltip.damage_dealt");
+ addImageWithLabel(1, 81+13, VELOCITY, I18n.format(GUI_KEY+"unit.blocks_per_tick", ammoType.getVelocity()),
+ GUI_KEY+"tooltip.velocity");
addImageWithLabel(ammoInfoPanel.width/2, 81+13, AVAILABLE_FUZES, ammoType.getAllowedFuseTypes().length+"/"+FuseType.values().length,
- "Available Fuzes");
+ GUI_KEY+"tooltip.available_fuzes");
addImageWithLabel(1, 81+13+13, PENETRATION_HARDNESS,
- Utils.formatDouble(IIAmmoUtils.getCombinedDepth(ammoType, coreType), "0.##")+"b "+
- I18n.format("desc.immersiveintelligence.penetration_hardness."+IIAmmoUtils.getCombinedHardness(ammoCore, coreType).getName().toLowerCase()),
- "Penetration Hardness");
+ I18n.format(GUI_KEY+"value.penetration_hardness",
+ Utils.formatDouble(IIAmmoUtils.getCombinedDepth(ammoType, coreType), "0.##"),
+ I18n.format("desc.immersiveintelligence.penetration_hardness."+IIAmmoUtils.getCombinedHardness(ammoCore, coreType).getName().toLowerCase())
+ ),
+ GUI_KEY+"tooltip.penetration_hardness");
/*addImageWithLabel(ammoInfoPanel.width/2, 81+13+13, MAX_PENETRATION_DEPTH, ,
"Max. Penetration Depth");*/
- addImageWithLabel(1, 81+13+13+13, FLAT_TRAJECTORY_RANGE, Utils.formatDouble(stats.getMaxDirectRange(), "0.##")+"b",
- "Flat-Trajectory Range");
+ addImageWithLabel(1, 81+13+13+13, FLAT_TRAJECTORY_RANGE, I18n.format(GUI_KEY+"unit.blocks", Utils.formatDouble(stats.getMaxDirectRange(), "0.##")),
+ GUI_KEY+"tooltip.flat_trajectory_range");
addImageWithLabel(ammoInfoPanel.width/2, 81+13+13+13, ARTILLERY_RANGE, projectileInfo.artillery()?
- Utils.formatDouble(stats.getGetMaxArtilleryRange(), "0.##")+"b": "-",
- "Max. Artillery Range");
+ I18n.format(GUI_KEY+"unit.blocks", Utils.formatDouble(stats.getGetMaxArtilleryRange(), "0.##")): "-",
+ GUI_KEY+"tooltip.max_artillery_range");
}
}
@@ -406,7 +542,11 @@ private void addImageWithLabel(int x, int y, ResourceLocation icon, Object value
@Override
protected EasyNBT onSaveTileData()
{
- return super.onSaveTileData()
+ EasyNBT nbt = super.onSaveTileData();
+ if(hasFillerUpgrade)
+ return nbt.withInt("component_fill_amount", tile.componentFillAmount);
+
+ return nbt
.withEnum("core_type", coreType)
.withString("produced_bullet", ammoType.getName());
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiRepairCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiRepairCrate.java
index 7b9c69847..980e6684a 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiRepairCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiRepairCrate.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
@@ -21,7 +21,7 @@
* @since 24.10.2025
*/
@DecoTemplate(name = "repaircrate", category = DecoGuiCategory.GENERIC_TILE)
-public class GuiRepairCrate extends DecoGui
+public class GuiRepairCrate extends DecoTileGui
{
@DecoResource
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSawmill.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSawmill.java
index 66bb2f178..73c4c6d49 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSawmill.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSawmill.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBarGroup;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage.ImageAnimationDirection;
@@ -21,7 +21,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "wooden_gearbox", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiSawmill extends DecoGui
+public class GuiSawmill extends DecoTileGui
{
@DecoResource
public static final ResourceLocation PROGRESS_ARROW = ResLoc.of(IIReference.RES_II, "gui/sawmill");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycartStation.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycartStation.java
index 35dba9928..f653afc51 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycartStation.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycartStation.java
@@ -3,7 +3,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextFormatting;
import pl.pabilo8.immersiveintelligence.api.rotary.IIRotaryUtils;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBarGroup;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
@@ -20,7 +20,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "skycart_station", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiSkycartStation extends DecoGui
+public class GuiSkycartStation extends DecoTileGui
{
public GuiSkycartStation(EntityPlayer player, TileEntitySkyCartStation tile)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycrateStation.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycrateStation.java
index 8ba8f7c2c..c95d84044 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycrateStation.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSkycrateStation.java
@@ -3,7 +3,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextFormatting;
import pl.pabilo8.immersiveintelligence.api.rotary.IIRotaryUtils;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBarGroup;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
@@ -20,7 +20,7 @@
* @since 10.07.2019
*/
@DecoTemplate(name = "skycrate_station", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiSkycrateStation extends DecoGui
+public class GuiSkycrateStation extends DecoTileGui
{
public GuiSkycrateStation(EntityPlayer player, TileEntitySkyCrateStation tile)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSmallCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSmallCrate.java
index 86f9277a5..ba27b1a29 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSmallCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiSmallCrate.java
@@ -1,7 +1,7 @@
package pl.pabilo8.immersiveintelligence.client.gui.block;
import net.minecraft.entity.player.EntityPlayer;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
@@ -15,7 +15,7 @@
* @since 17.05.2019
*/
@DecoTemplate(name = "small_crate", category = DecoGuiCategory.GENERIC_TILE)
-public class GuiSmallCrate extends DecoGui>
+public class GuiSmallCrate extends DecoTileGui>
{
public GuiSmallCrate(EntityPlayer player, TileEntitySmallCrate tile)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiUpgrade.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiTileUpgrade.java
similarity index 95%
rename from src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiUpgrade.java
rename to src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiTileUpgrade.java
index 6af64d921..3dba60d5e 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiUpgrade.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/GuiTileUpgrade.java
@@ -12,7 +12,7 @@
import pl.pabilo8.immersiveintelligence.api.upgrade.Upgrade;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradeOperation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoTreeDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
@@ -28,7 +28,7 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTModel;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
-import pl.pabilo8.immersiveintelligence.common.gui.ContainerUpgrade;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerTileUpgrade;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageBeginMachineUpgrade;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
@@ -45,8 +45,8 @@
* @author Pabilo8 (pabilo@iiteam.net)
* @since 10.07.2019
*/
-@DecoTemplate(name = "upgrade", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiUpgrade extends DecoGui>
+@DecoTemplate(name = "upgrade_tile", category = DecoGuiCategory.PRODUCTION_TILE)
+public class GuiTileUpgrade extends DecoTileGui>
{
private final UpgradeTechTree techTree;
private DecoTreeDisplay techTreeDisplay;
@@ -56,9 +56,9 @@ public class GuiUpgrade
+public class GuiVulcanizer extends DecoTileGui
{
@DecoResource
public static final ResourceLocation TEXTURE = IIReference.RES_II.with("gui/vulcanizer");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/ammunition_production/GuiAmmunitionAssembler.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/ammunition_production/GuiAmmunitionAssembler.java
index c4987e454..b9e5c88bc 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/ammunition_production/GuiAmmunitionAssembler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/ammunition_production/GuiAmmunitionAssembler.java
@@ -1,21 +1,30 @@
package pl.pabilo8.immersiveintelligence.client.gui.block.ammunition_production;
+import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
+import pl.pabilo8.immersiveintelligence.api.ammo.enums.FuseType;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoEntryPanelBuilder;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.DecoTextField;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.util.TextFilter;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage.ImageAnimationDirection;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.TileEntityAmmunitionAssembler;
import pl.pabilo8.immersiveintelligence.common.gui.ContainerAmmunitionAssembler;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
-
-import static pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures.*;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
/**
* @author Pabilo8 (pabilo@iiteam.net)
@@ -25,14 +34,14 @@
*/
@DecoTemplate(name = "ammunition_assembler", category = DecoGuiCategory.PRODUCTION_TILE)
-public class GuiAmmunitionAssembler extends DecoGui
+public class GuiAmmunitionAssembler extends DecoTileGui
{
-
@DecoResource
- public static ResourceLocation TEXTURE_AMMOAS = ResLoc.of(IIReference.RES_II.with("gui/ammunition_assembler"));
-
- private DecoButton btnProximity, btnContact, btnTime;
- private DecoTextField fuseTextField;
+ public static ResourceLocation TEXTURE = ResLoc.of(IIReference.RES_II.with("gui/ammunition_assembler"));
+ @SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
+ public FuseType fuseType;
+ @SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
+ public int fuseConfig;
public GuiAmmunitionAssembler(EntityPlayer player, TileEntityAmmunitionAssembler tile)
{
@@ -44,51 +53,98 @@ public GuiAmmunitionAssembler(EntityPlayer player, TileEntityAmmunitionAssembler
public void onInit()
{
startBackground()
- .withBox(DecoTextures.BG_STEEL_ROUGH, 0, 0, 176, 76)
+ .withBox(DecoTextures.BG_STEEL_ROUGH, 0, 0, 176, 76+24)
.withTitleBar(tile)
- .withInventorySlots(SlotStyle.IE_INPUT, container.inputSlot)
+ .withInventorySlots(SlotStyle.IE_INPUT, container.coreSlot, container.casingSlot)
.withInventorySlots(SlotStyle.IE_OUTPUT, container.outputSlot)
- .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 76, 176, 92)
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 76+24, 176, 92)
.withInventoryTitleBar()
- .withBox(DecoTextures.BG_BLUEPRINT, 100, 0, 76, 70)
.withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
.build();
+ //Set synced variables
+ this.fuseType = tile.fuseType;
+ this.fuseConfig = tile.fuseConfig;
+
+ DecoPanel configPanel;
addComponents(
+ //Energy bar
new DecoBar(150+11, 0)
.withTemplate(DecoTemplates.BAR_ELECTRIC_ENERGY.apply(tile.energyStorage)),
- new DecoButton(100, 10)
- .withIcon(ICON_PROXIMITY)
- .withTranslatedTooltip("PROXIMITY"),
-
- new DecoButton(120, 10)
- .withIcon(ICON_CONTACT)
- .withTranslatedTooltip("CONTACT"),
+ //Progress
+ new DecoImage(8+64+8+2+1-48-2-4+24-1, 28+4+4+4+1-16)
+ .withSize(64, 32)
+ .withImageLocation(TEXTURE, true)
+ .withUV(64, 0, 0, 64, 32),
+ new DecoImage(8+64+8+2+1-48-2-4+1+24-1, 28+4+4+4+1-16+1)
+ .withSize(64, 30)
+ .withImageLocation(TEXTURE, true)
+ .withUV(64, 0, 34, 64, 34+30)
+ .withAnimation(ImageAnimationDirection.LEFT_TO_RIGHT, DecoGuiUtils.getMultiblockProductionMultiProgress(tile)),
+
+ new DecoItemStackDisplay(8+64+8+2+1-48-2-4+64+2, 28+4+4+4+1-16+8),
+
+ //Config bar
+ configPanel = new DecoPanel(0, 76-2)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
+ .withSize(176, 24)
+ );
- new DecoButton(140, 10)
- .withIcon(ICON_TIME)
- .withTranslatedTooltip("TIMED"),
+ DecoLabel configLabel = configPanel.addLabel("pole wspaniale", 4+80+2, 2)
+ .withAlign(DecoAlignment.RIGHT)
+ .withSize(64-12, 18);
- new DecoTextField(96, 40)
- .withSize(65, 18)
+ DecoTextField textField;
+ configPanel.addComponents(
+ (textField = new DecoTextField(176-32-4, 2))
+ .withSize(32, 18)
.withTextColor(IIColor.WHITE)
- .withText("Fuze Time")
-
-/**
-
- new DecoImage(20, 20)
- .withSize(118, 33)
- .withImageLocation(TEXTURE_AMMOAS, false)
- .withUV(256, 127, 177, 122, 209),
-
- new DecoImage(20, 20)
- .withSize(118, 33)
- .withImageLocation(TEXTURE_AMMOAS, false)
- .withUV(256, 0, 177, 245, 209)
- .withAnimation(ImageAnimationDirection.LEFT_TO_RIGHT, DecoGuiUtils.getMultiblockProductionMultiProgress(tile))
- **/
+ .withFilter(TextFilter.DECIMAL)
+ .withText(this.fuseConfig)
+ .withOnTextChanged(newValue -> {
+ //Contact fuse has no config value
+ if(this.fuseType==FuseType.CONTACT)
+ textField.withText(newValue = "0");
+ this.fuseConfig = newValue.isEmpty()?0: Integer.parseInt(newValue);
+ }),
+ new DecoDropdown(4, 2)
+ .withEntries(FuseType.values())
+ .withDisplayFunction(new DecoEntryPanelBuilder()
+ //Type Icon, Label, and Letter
+ .withComponent("icon", new DecoImage(2, 2)
+ .withSize(16, 16)
+ )
+ .withLabel("label",
+ new DecoLabel(fontRenderer, 20, 2)
+ .withSize(48, 18)
+ .withAlign(DecoAlignment.LEFT)
+ .withText("Proximity")
+ )
+ .withElementApplyMethod(this::drawFuseEntry)
+ )
+ .withScrollBarBackground(DecoTextures.COMPONENT_SLIDER_PAPER)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
+ .withListBackground(DecoTextures.COMPONENT_TEXT_FIELD)
+ .withOnSelectedEntry((oldFuse, newFuse) -> {
+ textField.withDisabled(newFuse==FuseType.CONTACT);
+ textField.visible = newFuse!=FuseType.CONTACT;
+ configLabel.visible = newFuse!=FuseType.CONTACT;
+ this.fuseType = newFuse;
+ configLabel.withText(I18n.format(IIReference.GUI_LABEL_KEY+"ammunition_assembler.fuse_config."+newFuse.getName()))
+ .withTranslatedTooltip(IIReference.GUI_LABEL_KEY+"ammunition_assembler.fuse_config."+newFuse.getName()+".tooltip");
+ })
+ .withSelectedEntry(this.fuseType)
+ .withSize(80, 20)
);
}
+ private void drawFuseEntry(FuseType fuseType, DecoEntryPanelBuilder builder)
+ {
+ builder.label("label").withRawText(fuseType.getLocalizedName());
+ builder.component("icon", DecoImage.class)
+ .withImageLocation(ResLoc.of(IIReference.RES_II, "gui/deco/icons/icon_fuse_"+fuseType.getName()), true);
+ }
+
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachine.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachine.java
index a33fdf447..7e8fb5fd0 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachine.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachine.java
@@ -14,7 +14,7 @@
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeNull;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoTab;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoList;
@@ -45,7 +45,7 @@
* @since 30.06.2019
*/
@DecoTemplate(name = "arithmetic_logic_machine", category = DecoGuiCategory.DATA_TILE)
-public class GuiArithmeticLogicMachine extends DecoGui implements IDataMachineGui
+public class GuiArithmeticLogicMachine extends DecoTileGui implements IDataMachineGui
{
@SyncNBT
public int editedCircuit = 0;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachineEdit.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachineEdit.java
index 913f5abcb..28827904e 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachineEdit.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/arithmetic_logic_machine/GuiArithmeticLogicMachineEdit.java
@@ -2,6 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
import pl.pabilo8.immersiveintelligence.api.data.DataVariable;
import pl.pabilo8.immersiveintelligence.api.data.IIDataOperationUtils;
@@ -11,7 +12,7 @@
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeExpression;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoArrows;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoDropdownDataLetters;
@@ -28,13 +29,17 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.tileentity.TileEntityArithmeticLogicMachine;
import pl.pabilo8.immersiveintelligence.common.gui.ContainerArithmeticLogicMachine;
+import pl.pabilo8.immersiveintelligence.common.item.data.ItemIIFunctionalCircuit;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -44,7 +49,7 @@
* @since 30.06.2019
*/
@DecoTemplate(name = "arithmetic_logic_machine_edit", category = DecoGuiCategory.DATA_TILE)
-public class GuiArithmeticLogicMachineEdit extends DecoGui
+public class GuiArithmeticLogicMachineEdit extends DecoTileGui
{
@SyncNBT
public DataVariable variableToEdit;
@@ -52,6 +57,7 @@ public class GuiArithmeticLogicMachineEdit extends DecoGui circuitOperations;
+ private DataPacket packet;
private DataTypeExpression edited;
private ItemStack circuitStack;
private boolean cancel = false;
@@ -74,18 +80,27 @@ public void onInit()
syncAnimatedParts(tile.keyboard, true);
//Get circuit and list of all allowed operations
- this.circuitStack = tile.getInventory().get(editedCircuit);
+ this.circuitStack = editedCircuit >= 0&&editedCircuit < tile.getInventory().size()?tile.getInventory().get(editedCircuit): ItemStack.EMPTY;
+ this.packet = this.packet==null?getCircuitPacket().clone(): this.packet;
this.circuitOperations = IIContent.itemCircuit.getOperationsList(this.circuitStack).stream()
.map(IIDataOperationUtils::getOperationMeta)
+ .filter(Objects::nonNull)
.collect(Collectors.toList());
//Get currently edited operation
DataType value = variableToEdit.getValue();
- this.edited = value instanceof DataTypeExpression?(DataTypeExpression)value: new DataTypeExpression();
+ this.edited = value instanceof DataTypeExpression?(DataTypeExpression)value.clone(): new DataTypeExpression();
//If the current operation is not valid for this circuit, set it to the first valid one
- if(this.edited.getMeta()==DataOperationNull.INSTANCE_META)
- this.edited.setOperation(IIDataOperationUtils.getOperationInstance(circuitOperations.iterator().next().name()));
+ if(!isOperationAllowed(this.edited.getMeta()))
+ {
+ DataOperationMeta firstOperation = circuitOperations.isEmpty()?DataOperationNull.INSTANCE_META: circuitOperations.iterator().next();
+ this.edited.setOperation(IIDataOperationUtils.getOperationInstance(firstOperation.name()));
+ }
+
+ //A cloned packet without the currently edited variable is required, so the selector knows which variable names are unavailable
+ DataPacket constraints = packet.clone();
+ constraints.remove(variableToEdit.getName());
//Build background
startBackground()
@@ -108,11 +123,10 @@ public void onInit()
addComponents(
//Variable name selector
new DecoDropdownDataLetters(32+4+6+1-32, 4+8+2+1)
- .withConstraints(new DataPacket()) //TODO: 23.09.2025 replace with actual packet
+ .withConstraints(constraints)
.withSelectedEntry((Character)variableToEdit.getName())
.withTranslatedTooltip("desc.immersiveintelligence.variable_properties")
- .withOnSelectedEntry((oldChar, newChar) -> {
- })//changeVariableName(newChar))
+ .withOnSelectedEntry((oldChar, newChar) -> changeVariableName(newChar))
.withTextColor(DecoColors.H1, IIColor.fromPackedRGB(0x35322c))
.withBackground(DecoTextures.COMPONENT_DROPDOWN_DATA_LETTER_PAPER)
.withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER),
@@ -121,8 +135,8 @@ public void onInit()
.withSize(8, 14)
.withBackground(DecoTextures.COMPONENT_ARROWS_PAPER)
.withOnArrow(arrow -> {
- //char cycled = IIUtils.cycleDataPacketCharsAvoiding(variableToEdit.getName(), arrow, false, cloned);
- //changeVariableName(cycled);
+ char cycled = IIUtils.cycleDataPacketCharsAvoiding(variableToEdit.getName(), arrow, false, constraints);
+ changeVariableName(cycled);
}),
//Operation selector
@@ -139,6 +153,7 @@ public void onInit()
.withDisplayFunction(getOperationDropdownDisplayFunction())
.withOnSelectedEntry((oldMeta, newMeta) -> {
cancel = true;
+ storeEditorOutput();
edited.setOperation(IIDataOperationUtils.getOperationInstance(newMeta.name()));
variableToEdit = new DataVariable(variableToEdit.getName(), edited);
refreshGUI();
@@ -146,10 +161,28 @@ public void onInit()
new DecoButton(162+16-4, 2+8+4+1)
.withTemplate(DecoTemplates.ACTION_BUTTON_DUPLICATE)
- .withSize(18, 18),
+ .withSize(18, 18)
+ .withOnLMBPressed(() -> {
+ char name = findNextFreeVariableName();
+ if(name=='\0')
+ return;
+ cancel = true;
+ storeEditorOutput();
+ packet.with(variableToEdit);
+ variableToEdit = new DataVariable(name, edited.clone());
+ refreshGUI();
+ }),
new DecoButton(162+16-4+1+18, 2+8+4+1)
.withTemplate(DecoTemplates.ACTION_BUTTON_CLEAR)
.withSize(18, 18)
+ .withOnLMBPressed(() -> {
+ cancel = true;
+ edited = new DataTypeExpression();
+ if(!circuitOperations.isEmpty())
+ edited.setOperation(IIDataOperationUtils.getOperationInstance(circuitOperations.iterator().next().name()));
+ variableToEdit = new DataVariable(variableToEdit.getName(), edited);
+ refreshGUI();
+ })
);
//Add editor
@@ -160,6 +193,8 @@ public void onInit()
.withText("ii.gui.editor.editor_style")
.withCurrentState(this.codeEditMode)
.withOnToggle(result -> {
+ cancel = true;
+ storeEditorOutput();
this.codeEditMode = result;
refreshGUI();
})
@@ -168,20 +203,102 @@ public void onInit()
addComponents(
new DecoButton(xSize-48-4-4-4-2, 128+8-16+32-2+3+16+2+4)
.withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
- .withText("desc.immersiveintelligence.variable_apply")
+ .withText("ii.gui.button.apply")
.withSize(48, 12)
- .withOnPressed((gui, button, mouseX, mouseY) -> changeGUI(IIGUI.ARITHMETIC_LOGIC_MACHINE_VARIABLES)),
+ .withOnPressed((gui, button, mouseX, mouseY) -> {
+ cancel = false;
+ return changeGUI(IIGUI.ARITHMETIC_LOGIC_MACHINE_VARIABLES);
+ }),
new DecoButton(xSize-48*2-4-4-4-2, 128+8+32-16-2+3+16+2+4)
.withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
- .withText("Cancel")
+ .withText("ii.gui.button.cancel")
.withSize(48, 12)
.withOnPressed((gui, button, mouseX, mouseY) -> {
- //cancel = true;
+ cancel = true;
return changeGUI(IIGUI.ARITHMETIC_LOGIC_MACHINE_VARIABLES);
})
);
}
+ private void changeVariableName(Character newName)
+ {
+ //Do nothing if the name remains the same
+ if(newName==null||newName==variableToEdit.getName())
+ return;
+
+ cancel = true;
+ storeEditorOutput();
+
+ //Remove existing variable and place it in the packet with the new name
+ packet.remove(variableToEdit.getName());
+ variableToEdit = new DataVariable(newName, edited);
+ refreshGUI();
+ }
+
+ private char findNextFreeVariableName()
+ {
+ DataPacket currentPacket = packet.clone();
+ currentPacket.remove(variableToEdit.getName());
+ for(char c : DataPacket.VARIABLE_NAMES)
+ if(!currentPacket.has(c))
+ return c;
+ return '\0';
+ }
+
+ private boolean isOperationAllowed(DataOperationMeta meta)
+ {
+ return meta!=null&&circuitOperations.stream().anyMatch(m -> m.name().equals(meta.name()));
+ }
+
+ private DataPacket getCircuitPacket()
+ {
+ if(tile.getInventory().size() <= editedCircuit)
+ return new DataPacket();
+ ItemStack stack = tile.getInventory().get(editedCircuit);
+ if(stack.isEmpty()||!(stack.getItem() instanceof ItemIIFunctionalCircuit))
+ return new DataPacket();
+ return ((ItemIIFunctionalCircuit)stack.getItem()).getStoredData(stack);
+ }
+
+ private void storeEditorOutput()
+ {
+ if(editor==null)
+ return;
+ DataType output = editor.outputType();
+ if(output instanceof DataTypeExpression)
+ edited = (DataTypeExpression)output;
+ variableToEdit = new DataVariable(variableToEdit.getName(), edited);
+ }
+
+ private void updateLocalCircuitStack(DataPacket packet)
+ {
+ if(tile.getInventory().size() <= editedCircuit)
+ return;
+ ItemStack stack = tile.getInventory().get(editedCircuit);
+ if(stack.isEmpty()||!(stack.getItem() instanceof ItemIIFunctionalCircuit))
+ return;
+ ((ItemIIFunctionalCircuit)stack.getItem()).writeDataToItem(stack, packet);
+ tile.getInventory().set(editedCircuit, stack);
+ }
+
+ @Override
+ protected EasyNBT onSaveTileData()
+ {
+ EasyNBT nbt = super.onSaveTileData();
+ if(editor==null||cancel)
+ return nbt;
+
+ storeEditorOutput();
+ DataPacket updatedPacket = packet.with(variableToEdit);
+ updateLocalCircuitStack(updatedPacket);
+
+ NBTTagCompound expressions = EasyNBT.newNBT()
+ .withInt("page", editedCircuit)
+ .withSerializable("list", updatedPacket)
+ .unwrap();
+ return nbt.withTag("expressions", expressions);
+ }
+
private DecoElementDisplay getOperationDropdownDisplayFunction()
{
return new DecoEntryPanelBuilder()
@@ -208,6 +325,6 @@ private DecoElementDisplay getOperationDropdownDisplayFunctio
panel.component("image", DecoImage.class)
.withImageLocation(metaInfo.getTextureLocation(), true);
})
- .withElementTooltip(operation -> "datasystem.immersiveintelligence.function"+operation.name()+".desc");
+ .withElementTooltip(operation -> "datasystem.immersiveintelligence.function."+operation.name()+".desc");
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachine.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachine.java
index 358986636..189af4cc4 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachine.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachine.java
@@ -9,7 +9,7 @@
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeNull;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent.MouseButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
@@ -42,7 +42,7 @@
* @since 30.06.2019
*/
@DecoTemplate(name = "data_input_machine", category = DecoGuiCategory.DATA_TILE)
-public class GuiDataInputMachine extends DecoGui implements IDataMachineGui
+public class GuiDataInputMachine extends DecoTileGui implements IDataMachineGui
{
@DecoResource
public static ResourceLocation ICON_SEND_PACKET = ResLoc.of(IIReference.RES_II, "gui/tab_icons/send_packet");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachineEdit.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachineEdit.java
index ee719ec4f..13df45f3b 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachineEdit.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_input_machine/GuiDataInputMachineEdit.java
@@ -6,17 +6,15 @@
import pl.pabilo8.immersiveintelligence.api.data.IDataMachineGui;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoArrows;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoDropdownDataLetters;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.data_editor.DecoDataEditor;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoEntryPanelBuilder;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.tileentity.TileEntityDataInputMachine;
@@ -35,7 +33,7 @@
* @since 30.06.2019
*/
@DecoTemplate(name = "data_input_machine_edit", category = DecoGuiCategory.DATA_TILE)
-public class GuiDataInputMachineEdit extends DecoGui implements IDataMachineGui
+public class GuiDataInputMachineEdit extends DecoTileGui implements IDataMachineGui
{
@SyncNBT
public DataVariable variableToEdit;
@@ -120,32 +118,9 @@ public void onInit()
.withSize(116, 18)
.withDropdownWidth(116)
.withMaxDisplayedEntries(5)
- .withEntries(DecoDataEditor.getEditorTypes(false))
+ .withEntries(DecoDataEditor.getEditorTypes(tile.isUpgradeInstalled(IIContent.UPGRADE_ADVANCED_DATA)))
.withSelectedEntry(variableToEdit.getValue().getTypeMeta())
- .withDisplayFunction(new DecoEntryPanelBuilder>()
- .withHeight(18)
- .withBackground(DecoTextures.BG_PAPER)
- .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
- //Type Icon, Label, and Letter
- .withComponent("image", new DecoImage(3, 1)
- .withSize(16, 16))
- .withLabel("typeLabel",
- new DecoLabel(fontRenderer, 20, 1)
- .withSize(48, 18)
- .withAlign(DecoAlignment.LEFT)
- .withText("Integer")
- )
- .withElementApplyMethod((typeMeta, panel) -> {
- //type label (f.e. integer)
- panel.label("typeLabel")
- .withText(typeMeta.getTranslatedName())
- .withTextColor(typeMeta.color.withBrightness(0.4f));
- //type icon
- panel.component("image", DecoImage.class)
- .withImageLocation(typeMeta.getTextureLocation(), true);
- })
- .withElementTooltip(typeMeta -> "a")
- )
+ .withDisplayFunction(DecoTemplates.getDataTypeEntryDisplay())
.withOnSelectedEntry((typeMetaInfo, typeMetaInfo2) -> {
cancel = true;
variableToEdit = new DataVariable(variableToEdit.getName(), typeMetaInfo2.supplier.get());
@@ -154,7 +129,7 @@ public void onInit()
new DecoButton(xSize-48-4-4-4-2, 153)
.withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
- .withText("Apply")
+ .withText("ii.gui.button.apply")
.withSize(48, 12)
.withOnPressed((gui, button, mouseX, mouseY) -> {
cancel = false;
@@ -162,7 +137,7 @@ public void onInit()
}),
new DecoButton(xSize-96-4-4-4-2, 153)
.withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
- .withText("Cancel")
+ .withText("ii.gui.button.cancel")
.withSize(48, 12)
.withOnPressed((gui, button, mouseX, mouseY) -> {
cancel = true;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_merger/GuiDataMerger.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_merger/GuiDataMerger.java
new file mode 100644
index 000000000..bc16e0d9d
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_merger/GuiDataMerger.java
@@ -0,0 +1,144 @@
+package pl.pabilo8.immersiveintelligence.client.gui.block.data_merger;
+
+import net.minecraft.client.resources.I18n;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoEntryPanelBuilder;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger.DataMergeRule;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerDataMerger;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
+
+/**
+ * Main Data Merger GUI: list of request/job merge rules.
+ *
+ * @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 02.06.2026
+ */
+@DecoTemplate(name = "data_merger", category = DecoGuiCategory.DATA_TILE)
+public class GuiDataMerger extends DecoTileGui
+{
+ private static final String KEY = IIReference.GUI_LABEL_KEY+"data_merger.";
+
+ @SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
+ public EasyCollection rules;
+ @SyncNBT
+ public int editedRule = -1;
+ @SyncNBT
+ public ListMode mode = ListMode.JOBS;
+
+ public GuiDataMerger(EntityPlayer player, TileEntityDataMerger tile)
+ {
+ super(player, tile, IIGUI.DATA_MERGER);
+ if(tile!=null)
+ rules = tile.mergeRules.clone();
+ }
+
+ @Override
+ public void onInit()
+ {
+ if(rules==null)
+ rules = new EasyCollection<>(DataMergeRule::new);
+
+ startBackground()
+ .withBox(DecoTextures.BG_STEEL, 0, 0, 176, 168-8)
+ .withTitleBar(tile)
+ .withNextLayer()
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 168-8, 176, 92)
+ .withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
+ .withInventoryTitleBar()
+ .withFrame(DecoTextures.FRAME_WOODEN_THIN, 4, false, new boolean[]{true, false, false, false})
+ .withNextLayer()
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_SQUARE, 0, 168-8-20, 176, 20)
+ .build();
+
+ DecoTaskList ruleList;
+ addComponent((ruleList = new DecoTaskList<>(2, 4))
+ .withSize(176-4, 116)
+ .withEntries(rules)
+ .withIsJobPredicate(DataMergeRule::isJob)
+ .withModeHandling(mode, m -> mode = m)
+ .withBlankTaskSupplier(() -> {
+ DataMergeRule rule = new DataMergeRule();
+ rule.usageLimit = ruleList.getMode()==ListMode.REQUESTS?1: -1;
+ return rule;
+ })
+ .withDisplayFunction(new DecoEntryPanelBuilder()
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_TICKET)
+ .withComponent("variable", new DecoButton(3, 2)
+ .withSize(20, 16)
+ .withDisabled(true)
+ .withTextDisabledColor(IIColor.fromPackedRGB(0xafafaf))
+ )
+ .withLabel("route", new DecoLabel(fontRenderer, 26, 5)
+ .withSize(116, 12)
+ .withAlign(DecoAlignment.LEFT)
+ )
+ .withComponent(p -> new DecoButton(p.width-17+1-14, 3)
+ .withTemplate(DecoTemplates.ACTION_BUTTON_EDIT)
+ .withOnLMBPressed(() -> {
+ editedRule = rules.indexOf(p.getCurrentElement());
+ if(editedRule >= 0)
+ changeGUI(IIGUI.DATA_MERGER_EDIT);
+ })
+ )
+ .withComponent(p -> new DecoButton(p.width-17+1, 3)
+ .withTemplate(DecoTemplates.ACTION_BUTTON_REMOVE)
+ .withOnLMBPressed(() -> {
+ int index = rules.indexOf(p.getCurrentElement());
+ if(index >= 0)
+ {
+ rules.remove(index);
+ refreshGUI();
+ }
+ })
+ )
+ .withElementApplyMethod((rule, panel) -> {
+ panel.component("variable", DecoButton.class)
+ .withRawText(String.valueOf(rule.variable))
+ .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
+ .withBackgroundColor(rule.triggerForwarding?DecoColors.ACTION_ADD: DecoColors.ACTION_REMOVE);
+
+ StringBuilder sb = new StringBuilder();
+ if(rule.acceptLeft)
+ sb.append(I18n.format(KEY+"left"));
+ if(rule.acceptRight)
+ {
+ if(sb.length() > 0)
+ sb.append(", ");
+ sb.append(I18n.format(KEY+"right"));
+ }
+ if(rule.triggerForwarding)
+ {
+ if(sb.length() > 0)
+ sb.append(" -> ");
+ sb.append(I18n.format(KEY+"send"));
+ }
+
+ panel.label("route").withRawText(sb.toString());
+ })
+ )
+ );
+ }
+
+ @Override
+ protected EasyNBT onSaveTileData()
+ {
+ return super.onSaveTileData()
+ .withSerializable("rules", rules);
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_merger/GuiDataMergerEdit.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_merger/GuiDataMergerEdit.java
new file mode 100644
index 000000000..42180bb7d
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_merger/GuiDataMergerEdit.java
@@ -0,0 +1,196 @@
+package pl.pabilo8.immersiveintelligence.client.gui.block.data_merger;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoCheckbox;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoDropdownDataLetters;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.DecoTextField;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.util.TextFilter;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger.DataMergeRule;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerDataMerger;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.IIStringUtil;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
+
+/**
+ * Data Merger rule editor.
+ *
+ * @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 02.06.2026
+ */
+@DecoTemplate(name = "data_merger_edit", category = DecoGuiCategory.DATA_TILE)
+public class GuiDataMergerEdit extends DecoTileGui
+{
+ private static final String KEY = IIReference.GUI_LABEL_KEY+"data_merger.";
+
+ @SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
+ public EasyCollection rules;
+ @SyncNBT
+ public int editedRule = -1;
+ @SyncNBT
+ public ListMode mode = ListMode.JOBS;
+ @SyncNBT
+ public DataMergeRule edited = new DataMergeRule();
+
+ private boolean cancel = true, loaded = false;
+
+ public GuiDataMergerEdit(EntityPlayer player, TileEntityDataMerger tile)
+ {
+ super(player, tile, IIGUI.DATA_MERGER_EDIT);
+ if(tile!=null)
+ rules = tile.mergeRules.clone();
+ }
+
+ @Override
+ public void onInit()
+ {
+ if(rules==null)
+ rules = new EasyCollection<>(DataMergeRule::new);
+ if(editedRule < 0||editedRule >= rules.size())
+ {
+ cancel = true;
+ changeGUI(IIGUI.DATA_MERGER);
+ return;
+ }
+ if(!loaded)
+ {
+ edited = rules.get(editedRule).copy();
+ loaded = true;
+ }
+
+ startBackground()
+ .withBox(DecoTextures.BG_STEEL, 0, 0, 176, 168-8)
+ .withTitleBar(KEY+"rule_properties")
+ .withNextLayer()
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 168-8, 176, 92)
+ .withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
+ .withInventoryTitleBar()
+ .withFrame(DecoTextures.FRAME_WOODEN_THIN, 4, false, new boolean[]{true, false, false, false})
+ .withNextLayer()
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_ROUND, 4, 8+4, 168-4, 72+8)
+ .withTitleBar(KEY+"inputs", DecoAlignment.TOP_LEFT)
+ .withNextLayer()
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_ROUND, 4, 8+4+72-4+16, 168-4, 84-16-8-8)
+ .withTitleBar(KEY+"override_policy", DecoAlignment.TOP_LEFT)
+ .build();
+
+ DecoPanel panel = addComponent(new DecoPanel(12, 16))
+ .withSize(216, 128)
+ .withBackground(null);
+
+ addInputSection(panel, 0);
+ addPolicySection(panel, 96-4);
+
+ addComponents(
+ new DecoButton(xSize-48-4, 156+8-8-2)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
+ .withText("ii.gui.button.apply")
+ .withSize(48, 12)
+ .withOnPressed((gui, button, mouseX, mouseY) -> {
+ rules.set(editedRule, edited.copy());
+ cancel = false;
+ return changeGUI(IIGUI.DATA_MERGER);
+ }),
+ new DecoButton(xSize-48*2-4, 156+8-8-2)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
+ .withText("ii.gui.button.cancel")
+ .withSize(48, 12)
+ .withOnPressed((gui, button, mouseX, mouseY) -> {
+ cancel = true;
+ return changeGUI(IIGUI.DATA_MERGER);
+ })
+ );
+ }
+
+ private void addInputSection(DecoPanel panel, int yy)
+ {
+ DecoPanel panelPaper = panel.addComponent(new DecoPanel(-4, yy+4)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
+ .withSize(176-8-12+4, 18)
+ );
+ panelPaper.addLabel(KEY+"variable", 4, 6)
+ .withSize(48, 9)
+ .withAlign(DecoAlignment.LEFT);
+ panelPaper.addComponent(new DecoDropdownDataLetters(176-8-12+4-18, 0)
+ .withConstraints(new DataPacket())
+ .withSelectedEntry((Character)edited.variable)
+ .withTextColor(DecoColors.H1, IIColor.fromPackedRGB(0x35322c))
+ .withBackground(DecoTextures.COMPONENT_DROPDOWN_DATA_LETTER_PAPER)
+ .withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER)
+ .withOnSelectedEntry((oldChar, newChar) -> edited.variable = newChar)
+ );
+
+ panel.addComponent(new DecoCheckbox(0, yy+22)
+ .withSize(84, 12)
+ .withText(KEY+"accept_left")
+ .withChecked(edited.acceptLeft)
+ .withOnToggle(checked -> edited.acceptLeft = checked)
+ .withTranslatedTooltip(KEY+"accept_left.tooltip")
+ );
+ panel.addComponent(new DecoCheckbox(0, yy+22+12)
+ .withSize(84, 12)
+ .withText(KEY+"accept_right")
+ .withChecked(edited.acceptRight)
+ .withOnToggle(checked -> edited.acceptRight = checked)
+ .withTranslatedTooltip(KEY+"accept_right.tooltip")
+ );
+ panel.addComponent(new DecoCheckbox(0, yy+22+12+12)
+ .withSize(120, 12)
+ .withText(KEY+"trigger_forwarding")
+ .withChecked(edited.triggerForwarding)
+ .withOnToggle(checked -> edited.triggerForwarding = checked)
+ .withTranslatedTooltip(KEY+"trigger_forwarding.tooltip")
+ );
+
+ panel.addLabel(KEY+"usage_limit", 0, yy+22+12+12+8+4+3)
+ .withSize(74, 9)
+ .withAlign(DecoAlignment.LEFT)
+ .withTranslatedTooltip(KEY+"usage_limit.tooltip");
+ panel.addComponent(new DecoTextField(78, yy+22+12+12+8+4-1)
+ .withSize(42, 16)
+ .withFilter(TextFilter.DECIMAL)
+ .withText(edited.usageLimit < 0?"": String.valueOf(edited.usageLimit))
+ .withOnTextChanged(text -> edited.usageLimit = text==null||text.trim().isEmpty()?-1: IIStringUtil.parseInt(text.trim()))
+ .withTranslatedTooltip(KEY+"usage_limit.tooltip")
+ );
+ }
+
+ private void addPolicySection(DecoPanel panel, int yy)
+ {
+ panel.addComponent(new DecoCheckbox(0, yy)
+ .withSize(164, 12)
+ .withText(KEY+"right_overrides_cached")
+ .withTranslatedTooltip(KEY+"right_overrides_cached.tooltip")
+ .withChecked(edited.rightOverridesCachedValue)
+ .withOnToggle(checked -> edited.rightOverridesCachedValue = checked)
+ );
+ panel.addComponent(new DecoCheckbox(0, yy+16)
+ .withSize(164, 12)
+ .withText(KEY+"right_overrides_value")
+ .withTranslatedTooltip(KEY+"right_overrides_value.tooltip")
+ .withChecked(edited.rightOverridesValue)
+ .withOnToggle(checked -> edited.rightOverridesValue = checked)
+ );
+ }
+
+ @Override
+ protected EasyNBT onSaveTileData()
+ {
+ return super.onSaveTileData()
+ .conditionally(!cancel&&rules!=null, easyNBT -> easyNBT.withSerializable("rules", rules));
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_router/GuiDataRouter.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_router/GuiDataRouter.java
new file mode 100644
index 000000000..2395e7878
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_router/GuiDataRouter.java
@@ -0,0 +1,130 @@
+package pl.pabilo8.immersiveintelligence.client.gui.block.data_router;
+
+import net.minecraft.client.resources.I18n;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoEntryPanelBuilder;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter.DataRoutingRule;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter.RoutingAction;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerDataRouter;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
+
+/**
+ * Main Data Router GUI: list of request/job routing rules.
+ *
+ * @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 02.06.2026
+ */
+@DecoTemplate(name = "data_router", category = DecoGuiCategory.DATA_TILE)
+public class GuiDataRouter extends DecoTileGui
+{
+ private static final String KEY = IIReference.GUI_LABEL_KEY+"data_router.";
+
+ @SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
+ public EasyCollection rules;
+ @SyncNBT
+ public int editedRule = -1;
+ @SyncNBT
+ public ListMode mode = ListMode.JOBS;
+
+ public GuiDataRouter(EntityPlayer player, TileEntityDataRouter tile)
+ {
+ super(player, tile, IIGUI.DATA_ROUTER);
+ if(tile!=null)
+ rules = tile.routingRules.clone();
+ }
+
+ @Override
+ public void onInit()
+ {
+ if(rules==null)
+ rules = new EasyCollection<>(DataRoutingRule::new);
+
+ startBackground()
+ .withBox(DecoTextures.BG_STEEL, 0, 0, 176, 168-8)
+ .withTitleBar(tile)
+ .withNextLayer()
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 168-8, 176, 92)
+ .withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
+ .withInventoryTitleBar()
+ .withFrame(DecoTextures.FRAME_WOODEN_THIN, 4, false, new boolean[]{true, false, false, false})
+ .withNextLayer()
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_SQUARE, 0, 168-8-20, 176, 20)
+ .build();
+
+ DecoTaskList ruleList;
+ addComponent((ruleList = new DecoTaskList<>(2, 4))
+ .withSize(176-4, 116)
+ .withEntries(rules)
+ .withIsJobPredicate(DataRoutingRule::isJob)
+ .withModeHandling(mode, m -> mode = m)
+ .withBlankTaskSupplier(() -> {
+ DataRoutingRule rule = new DataRoutingRule();
+ rule.usageLimit = ruleList.getMode()==ListMode.REQUESTS?1: -1;
+ return rule;
+ })
+ .withDisplayFunction(new DecoEntryPanelBuilder()
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_TICKET)
+ .withComponent("action", new DecoButton(3, 2)
+ .withSize(36, 16)
+ .withDisabled(true)
+ .withTextDisabledColor(IIColor.fromPackedRGB(0xafafaf))
+ )
+ .withLabel("route", new DecoLabel(fontRenderer, 3+36+2, 5)
+ .withSize(58, 12)
+ .withAlign(DecoAlignment.LEFT)
+ )
+ .withComponent(p -> new DecoButton(p.width-17+1-14, 2)
+ .withTemplate(DecoTemplates.ACTION_BUTTON_EDIT)
+ .withOnLMBPressed(() -> {
+ editedRule = rules.indexOf(p.getCurrentElement());
+ if(editedRule >= 0)
+ changeGUI(IIGUI.DATA_ROUTER_EDIT);
+ })
+ )
+ .withComponent(p -> new DecoButton(p.width-17+1, 2)
+ .withTemplate(DecoTemplates.ACTION_BUTTON_REMOVE)
+ .withOnLMBPressed(() -> {
+ int index = rules.indexOf(p.getCurrentElement());
+ if(index >= 0)
+ {
+ rules.remove(index);
+ refreshGUI();
+ }
+ })
+ )
+ .withElementApplyMethod((rule, panel) -> {
+ panel.component("action", DecoButton.class)
+ .withRawText(rule.action.getLocalizedName())
+ .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
+ .withBackgroundColor(rule.action==RoutingAction.ALLOW?DecoColors.ACTION_ADD: DecoColors.ACTION_REMOVE);
+ panel.label("route").withRawText(I18n.format(KEY+"into",
+ I18n.format(IIReference.DESCRIPTION_KEY+"side."+rule.outgoingSide.getName())
+ ));
+ })
+ )
+ );
+ }
+
+ @Override
+ protected EasyNBT onSaveTileData()
+ {
+ return super.onSaveTileData()
+ .withSerializable("rules", rules);
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_router/GuiDataRouterEdit.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_router/GuiDataRouterEdit.java
new file mode 100644
index 000000000..70f3ed855
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/data_router/GuiDataRouterEdit.java
@@ -0,0 +1,276 @@
+package pl.pabilo8.immersiveintelligence.client.gui.block.data_router;
+
+import net.minecraft.client.resources.I18n;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.EnumDyeColor;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumFacing;
+import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
+import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeNull;
+import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
+import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoCheckbox;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoDropdownDataLetters;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoElementDisplays;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.data_editor.DecoDataEditor;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.DecoTextField;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.util.TextFilter;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter.DataRoutingRule;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter.RoutingAction;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerDataRouter;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.IIStringUtil;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
+
+import javax.annotation.Nullable;
+
+/**
+ * Data Router rule editor.
+ *
+ * @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 02.06.2026
+ */
+@DecoTemplate(name = "data_router_edit", category = DecoGuiCategory.DATA_TILE)
+public class GuiDataRouterEdit extends DecoTileGui
+{
+ private static final String KEY = IIReference.GUI_LABEL_KEY+"data_router.";
+
+ @SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
+ public EasyCollection rules;
+ @SyncNBT
+ public int editedRule = -1;
+ @SyncNBT
+ public ListMode mode = ListMode.JOBS;
+ @SyncNBT
+ public DataRoutingRule edited = new DataRoutingRule();
+ @Nullable
+ private DecoDataEditor extends DataType> valueEditor;
+ private boolean cancel = true, loaded = false;
+
+ public GuiDataRouterEdit(EntityPlayer player, TileEntityDataRouter tile)
+ {
+ super(player, tile, IIGUI.DATA_ROUTER_EDIT);
+ if(tile!=null)
+ rules = tile.routingRules.clone();
+ }
+
+ @Override
+ public void onInit()
+ {
+ if(rules==null)
+ rules = new EasyCollection<>(DataRoutingRule::new);
+ if(editedRule < 0||editedRule >= rules.size())
+ {
+ cancel = true;
+ changeGUI(IIGUI.DATA_ROUTER);
+ return;
+ }
+ if(!loaded)
+ {
+ edited = rules.get(editedRule).copy();
+ loaded = true;
+ }
+
+ startBackground()
+ .withBox(DecoTextures.BG_STEEL, 0, 0, 240, 184+12)
+ .withTitleBar(KEY+"rule_properties")
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 32, 184+12, 176, 92)
+ .withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
+ .withInventoryTitleBar()
+ .withNextLayer()
+
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_ROUND, 4, 8+4, 224+8, 48-8)
+ .withTitleBar(KEY+"routing", DecoAlignment.TOP_LEFT)
+ .withNextLayer()
+
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_ROUND, 4, 8+4+48-4, 224+8, 128+12)
+ .withTitleBar(KEY+"packet_filters", DecoAlignment.TOP_LEFT)
+ .withNextLayer()
+ .build();
+
+ DecoPanel panel = addComponent(new DecoPanel(12, 16))
+ .withSize(216, 8+4+48-4+128+4)
+ .withBackground(null);
+
+ int yy = 0;
+ addRoutingSection(panel, yy);
+ yy += 48;
+ addPacketFilterSection(panel, yy);
+ yy += 14;
+ addValueFilterSection(panel, yy);
+
+ addComponents(
+ new DecoButton(xSize-48-4-4-4-2+2, 180+8-8-4+16)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
+ .withText("ii.gui.button.apply")
+ .withSize(48, 12)
+ .withOnPressed((gui, button, mouseX, mouseY) -> {
+ storeEditorValue();
+ rules.set(editedRule, edited.copy());
+ cancel = false;
+ return changeGUI(IIGUI.DATA_ROUTER);
+ }),
+ new DecoButton(xSize-48*2-4-4-4-2+2, 180+8-8-4+16)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_ROUND)
+ .withText("ii.gui.button.cancel")
+ .withSize(48, 12)
+ .withOnPressed((gui, button, mouseX, mouseY) -> {
+ cancel = true;
+ return changeGUI(IIGUI.DATA_ROUTER);
+ })
+ );
+ }
+
+ private void addRoutingSection(DecoPanel panel, int yy)
+ {
+ panel.addLabel(KEY+"incoming", 0, yy+5)
+ .withSize(46, 9)
+ .withAlign(DecoAlignment.LEFT);
+ for(int i = 0; i < EnumFacing.VALUES.length; i++)
+ {
+ EnumFacing side = EnumFacing.VALUES[i];
+ int x = 48+(i%3)*24;
+ int y = yy+(i/3)*12+4;
+ panel.addComponent(new DecoCheckbox(x, y)
+ .withSize(24, 10)
+ .withRawText(String.valueOf(side.getName().toUpperCase().charAt(0)))
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"side."+side.getName())
+ .withChecked(edited.receivingSides[side.ordinal()])
+ .withOnToggle(checked -> edited.receivingSides[side.ordinal()] = checked)
+ );
+ }
+
+ panel.addLabel(KEY+"outgoing", 132, yy+3)
+ .withSize(40, 9)
+ .withAlign(DecoAlignment.LEFT);
+ panel.addComponent(new DecoDropdown(172, yy)
+ .withSize(42, 16)
+ .withDropdownWidth(70)
+ .withEntries(EnumFacing.VALUES)
+ .withSelectedEntry(edited.outgoingSide)
+ .withOnSelectedEntry((oldSide, newSide) -> edited.outgoingSide = newSide)
+ .withDisplayFunction(DecoElementDisplays.getSimpleTextDisplay(side ->
+ I18n.format(IIReference.DESCRIPTION_KEY+"side."+side.getName())
+ ))
+ );
+
+ panel.addLabel(KEY+"action", 132, yy+18)
+ .withSize(40, 9)
+ .withAlign(DecoAlignment.LEFT);
+ panel.addComponent(new DecoDropdown(172, yy+15)
+ .withSize(42, 16)
+ .withDropdownWidth(70)
+ .withEntries(RoutingAction.values())
+ .withSelectedEntry(edited.action)
+ .withOnSelectedEntry((oldAction, newAction) -> edited.action = newAction)
+ );
+ }
+
+ private void addPacketFilterSection(DecoPanel panel, int yy)
+ {
+ panel.addComponent(new DecoCheckbox(0, yy)
+ .withSize(56, 12)
+ .withText(KEY+"filter.color")
+ .withChecked(edited.useColorFilter)
+ .withOnToggle(checked -> edited.useColorFilter = checked)
+ );
+ panel.addComponent(new DecoDropdown(58-8, yy)
+ .withTemplate(DecoTemplates.DYE_COLOR_DROPDOWN)
+ .withSize(56+8, 12)
+ .withDropdownWidth(80)
+ .withSelectedEntry(edited.packetColor)
+ .withOnSelectedEntry((oldColor, newColor) -> edited.packetColor = newColor)
+ );
+
+ panel.addComponent(new DecoCheckbox(120, yy)
+ .withSize(56, 12)
+ .withText(KEY+"filter.address")
+ .withChecked(edited.useAddressFilter)
+ .withOnToggle(checked -> edited.useAddressFilter = checked)
+ );
+ panel.addComponent(new DecoTextField(178, yy-2)
+ .withSize(36, 16)
+ .withFilter(TextFilter.DECIMAL)
+ .withText(edited.packetAddress < 0?"": String.valueOf(edited.packetAddress))
+ .withOnTextChanged(text -> edited.packetAddress = text==null||text.trim().isEmpty()?-1: IIStringUtil.parseInt(text.trim()))
+ );
+ }
+
+ private void addValueFilterSection(DecoPanel panel, int yy)
+ {
+ valueEditor = null;
+ panel.addComponent(new DecoCheckbox(0, yy+2)
+ .withSize(92, 12)
+ .withText(KEY+"filter.value")
+ .withChecked(edited.useValueFilter)
+ .withOnToggle(checked -> {
+ storeEditorValue();
+ edited.useValueFilter = checked;
+ refreshGUI();
+ })
+ );
+
+ if(edited.useValueFilter)
+ {
+ panel.addComponent(new DecoDropdownDataLetters(96, yy)
+ .withConstraints(new DataPacket())
+ .withSelectedEntry((Character)edited.valueVariable)
+ .withTextColor(DecoColors.H1, IIColor.fromPackedRGB(0x35322c))
+ .withOnSelectedEntry((oldChar, newChar) -> edited.valueVariable = newChar)
+ );
+ panel.addComponent(new DecoDropdown>(96+18, yy)
+ .withSize(128-24, 18)
+ .withDropdownWidth(116)
+ .withMaxDisplayedEntries(5)
+ .withEntries(DecoDataEditor.getEditorTypes(false))
+ .withSelectedEntry(edited.expectedValue.getTypeMeta())
+ .withDisplayFunction(DecoTemplates.getDataTypeEntryDisplay())
+ .withOnSelectedEntry((oldType, newType) -> {
+ storeEditorValue();
+ edited.expectedValue = newType==null?new DataTypeNull(): newType.supplier.get();
+ refreshGUI();
+ })
+ );
+
+ yy += 32;
+ panel.addComponent(new DecoCheckbox(63, yy-16+1)
+ .withSize(102, 12)
+ .withText(KEY+"remove_control_variable")
+ .withChecked(edited.removeControlVariable)
+ .withOnToggle(checked -> edited.removeControlVariable = checked)
+ );
+
+ valueEditor = DecoDataEditor.getEditorFor(edited.expectedValue, 8, yy);
+ int editorHeight = panel.height-yy;
+ if(valueEditor!=null)
+ addComponent(valueEditor)
+ .withSize(214+12, editorHeight);
+ }
+ }
+
+ private void storeEditorValue()
+ {
+ if(valueEditor!=null&&edited!=null&&edited.useValueFilter)
+ edited.expectedValue = valueEditor.outputType();
+ }
+
+ @Override
+ protected EasyNBT onSaveTileData()
+ {
+ return super.onSaveTileData()
+ .conditionally(!cancel&&rules!=null, easyNBT -> easyNBT.withSerializable("rules", rules));
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacement.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacement.java
index 362240386..2ee33876b 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacement.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacement.java
@@ -1,18 +1,20 @@
package pl.pabilo8.immersiveintelligence.client.gui.block.emplacement;
import net.minecraft.entity.player.EntityPlayer;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoAlignment;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement;
import pl.pabilo8.immersiveintelligence.common.gui.ContainerEmplacement;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
/**
* @author Pabilo8 (pabilo@iiteam.net)
* @since 16.07.2021
*/
-public abstract class GuiEmplacement extends DecoGui
+public abstract class GuiEmplacement extends DecoTileGui
{
public GuiEmplacement(EntityPlayer player, TileEntityEmplacement tile, IIGUI gui)
{
@@ -26,9 +28,19 @@ public void onInit()
.withBox(DecoTextures.BG_STEEL_ROUGH, 0, 0, 152+96, 152+8)
.withTitleBar(tile)
.withNextLayer()
+ //Bad practicle, I know, but it was a must
+ .conditionally(this instanceof GuiEmplacementPageStorage, builder -> builder
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_SQUARE, 4, 8+8, 152+96-8, 76-8-8)
+ .withTitleBar(IIReference.GUI_LABEL_KEY+"emplacement.platform_inventory", DecoAlignment.TOP_LEFT)
+ .withInventorySlots(SlotStyle.VANILLA, container.slotsBaseInventory)
+ .withNextLayer()
+ .withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_SQUARE, 4, 76+4+8, 152+96-8, 76-8-8)
+ .withTitleBar(IIReference.GUI_LABEL_KEY+"emplacement.base_inventory", DecoAlignment.TOP_LEFT)
+ .withInventorySlots(SlotStyle.VANILLA, container.slotsPlatformInventory))
+ .withNextLayer()
.withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 32, 152+8, 176, 92)
.withFrame(DecoTextures.FRAME_WOODEN_THIN, 4, false, new boolean[]{true, false, false, false})
- .withInventorySlots(SlotStyle.VANILLA, container.inventorySlots)
+ .withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
.withInventoryTitleBar()
.build();
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageConfig.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageConfig.java
index 2ab5deb5e..da76683bc 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageConfig.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageConfig.java
@@ -1,20 +1,24 @@
package pl.pabilo8.immersiveintelligence.client.gui.block.emplacement;
+import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoSlider;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoSwitch;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoMapDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.map.DecoMapDefaultColorMapper;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.map.scanners.BlockTypeScanner;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.tileentity.TileEntityArtilleryHowitzer;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.TileEntityFlagpole;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
/**
* @author Pabilo8 (pabilo@iiteam.net)
@@ -23,6 +27,12 @@
@DecoTemplate(name = "emplacement_config", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
public class GuiEmplacementPageConfig extends GuiEmplacement
{
+ private static final String KEY = IIReference.GUI_LABEL_KEY+"emplacement.config.";
+ @SyncNBT(events = {SyncEvents.TILE_CLIENT_MESSAGE})
+ public boolean redstoneControlEnabled, dataControlEnabled;
+ @SyncNBT(events = {SyncEvents.TILE_CLIENT_MESSAGE})
+ public float weaponHideHealthThreshold, weaponRepairSatisfactoryThreshold;
+
public GuiEmplacementPageConfig(EntityPlayer player, TileEntityEmplacement tile)
{
super(player, tile, IIGUI.EMPLACEMENT_CONFIG);
@@ -86,5 +96,59 @@ public void onInit()
.withBackground(DecoTextures.BG_PAPER)
.withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
);
+
+ addLabel(I18n.format(KEY+"vision_range", calculateRange(sightRange, pos)), 4, 132+8-1)
+ .withSize(120, 10)
+ .withAlign(DecoAlignment.LEFT);
+ addLabel(I18n.format(KEY+"attack_range", calculateRange(fireRange, pos)), 4, 142+8-1)
+ .withSize(120, 10)
+ .withAlign(DecoAlignment.LEFT);
+
+ addComponent(new DecoSwitch(136-4-2, 16-2)
+ .withText(KEY+"reacts_redstone")
+ .withSize(22, 14)
+ .withCurrentState(this.redstoneControlEnabled = tile.redstoneControlEnabled)
+ .withOnToggle(value -> this.redstoneControlEnabled = value)
+ .withTranslatedTooltip(KEY+"reacts_redstone.tooltip"));
+ addComponent(new DecoSwitch(136-4-2, 34-2-8+2)
+ .withText(KEY+"reacts_data")
+ .withSize(22, 14)
+ .withCurrentState(this.dataControlEnabled = tile.dataControlEnabled)
+ .withOnToggle(value -> this.dataControlEnabled = value)
+ .withTranslatedTooltip(KEY+"reacts_data.tooltip"));
+
+ addLabel(KEY+"hide_health", 136-4-2, 60-20-2)
+ .withSize(110, 24)
+ .withWrapping(true)
+ .withAlign(DecoAlignment.LEFT);
+ addComponent(new DecoSlider(136-4-2+1, 72-20+8)
+ .withSize(110, 12)
+ .withRange(0f, 1f)
+ .withValue(this.weaponHideHealthThreshold = tile.weaponHideHealthThreshold)
+ .withOnValueChanged(value -> this.weaponHideHealthThreshold = value)
+ .withBarColors(DecoColors.ARMOR_INTEGRITY_1, DecoColors.ARMOR_INTEGRITY_2)
+ .withTranslatedTooltip(KEY+"hide_health.tooltip"));
+
+ addLabel(KEY+"resurface_health", 136-4-2, 60-20+32-2)
+ .withSize(110, 24)
+ .withWrapping(true)
+ .withAlign(DecoAlignment.LEFT);
+ addComponent(new DecoSlider(136-4-2+1, 72-20+8+32)
+ .withSize(110, 12)
+ .withRange(0f, 1f)
+ .withValue(this.weaponRepairSatisfactoryThreshold = tile.weaponRepairSatisfactoryThreshold)
+ .withOnValueChanged(value -> this.weaponRepairSatisfactoryThreshold = Math.max(tile.weaponHideHealthThreshold, value))
+ .withBarColors(DecoColors.ARMOR_INTEGRITY_1, DecoColors.ARMOR_INTEGRITY_2)
+ .withTranslatedTooltip(KEY+"resurface_health.tooltip"));
+
+ }
+
+ private String calculateRange(AxisAlignedBB range, BlockPos center)
+ {
+ double value = Math.max(
+ Math.max(Math.abs(range.minX-center.getX()), Math.abs(range.maxX-center.getX())),
+ Math.max(Math.abs(range.minZ-center.getZ()), Math.abs(range.maxZ-center.getZ()))
+ );
+ return String.valueOf((int)Math.ceil(value));
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageFireMissions.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageFireMissions.java
index 87edabd73..761d93538 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageFireMissions.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageFireMissions.java
@@ -1,7 +1,7 @@
package pl.pabilo8.immersiveintelligence.client.gui.block.emplacement;
import net.minecraft.entity.player.EntityPlayer;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskJobList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
@@ -24,7 +24,7 @@ public void onInit()
{
super.onInit();
addComponents(
- new DecoTaskJobList<>(0, 0)
+ new DecoTaskList<>(0, 0)
.withSize(96, 152-32)
.withShowJobsTab(false)
);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageStorage.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageStorage.java
index abb80079c..81f41b455 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageStorage.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/emplacement/GuiEmplacementPageStorage.java
@@ -12,11 +12,14 @@
/**
* @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 02.06.2026
* @since 16.07.2021
*/
@DecoTemplate(name = "emplacement_storage", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
public class GuiEmplacementPageStorage extends GuiEmplacement
{
+ private static final String KEY = IIReference.GUI_LABEL_KEY+"emplacement.";
+
public GuiEmplacementPageStorage(EntityPlayer player, TileEntityEmplacement tile)
{
super(player, tile, IIGUI.EMPLACEMENT_STORAGE);
@@ -28,17 +31,12 @@ public void onInit()
super.onInit();
DecoPanel panelPlatform, panelBase;
addComponents(
- panelPlatform = new DecoPanel(4, 8+8)
+ panelPlatform = new DecoPanel(4, 8+8-4)
.withSize(152+96-8, 76-8)
- .withBackground(DecoTextures.BG_STEEL)
- .withBackgroundMask(DecoTextures.TEMPLATE_SQUARE)
- .withTitleLabel(IIReference.GUI_LABEL_KEY+"emplacement.platform_inventory", DecoAlignment.TOP_LEFT),
-
- panelBase = new DecoPanel(4, 76+4+8)
+ .withBackground(null),
+ panelBase = new DecoPanel(4, 76+4+8-4)
.withSize(152+96-8, 76-8)
- .withBackground(DecoTextures.BG_STEEL)
- .withBackgroundMask(DecoTextures.TEMPLATE_SQUARE)
- .withTitleLabel(IIReference.GUI_LABEL_KEY+"emplacement.base_inventory", DecoAlignment.TOP_LEFT)
+ .withBackground(null)
);
panelBase.addComponents(
@@ -64,6 +62,17 @@ public void onInit()
);
tile.currentWeapon.initializeGUI(panelBase, panelPlatform);
}
+ else
+ {
+ panelPlatform.addLabel(KEY+"no_weapon", 8, 18)
+ .withSize(panelPlatform.width-16, 12)
+ .withAlign(DecoAlignment.CENTER)
+ .withTextColor(DecoColors.H2);
+ panelBase.addLabel(KEY+"no_weapon", 8, 18)
+ .withSize(panelBase.width-16, 12)
+ .withAlign(DecoAlignment.CENTER)
+ .withTextColor(DecoColors.H2);
+ }
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpole.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpole.java
index 8ad0bfec7..33ede1c38 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpole.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpole.java
@@ -2,7 +2,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoCheckbox;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoSwitch;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
@@ -32,7 +32,7 @@
* @since 27.12.2025
*/
@DecoTemplate(name = "flagpole", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
-public class GuiFlagpole extends DecoGui
+public class GuiFlagpole extends DecoTileGui
{
@SyncNBT
public boolean filterFlagpoles = true, filterWeapons = true, filterLogistics = true, filterIntelligence = true, filterWireNetworks = true;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpoleFaction.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpoleFaction.java
index 8a3526515..ed0d734d7 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpoleFaction.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/flagpole/GuiFlagpoleFaction.java
@@ -5,7 +5,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBanner;
import net.minecraft.item.ItemStack;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoSwitch;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
@@ -43,7 +43,7 @@
* @since 27.12.2025
*/
@DecoTemplate(name = "flagpole_faction", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
-public class GuiFlagpoleFaction extends DecoGui
+public class GuiFlagpoleFaction extends DecoTileGui
{
private String factionName = null;
private IIColor factionColor = null;
@@ -202,32 +202,36 @@ protected boolean initialize()
.withTitleLabel("Permissions", DecoAlignment.TOP)
);
- panelPerms.addLabel("Role:", 4, 8+2-1)
- .withSize(panelPerms.width-72-2, 14)
- .withAlign(DecoAlignment.LEFT);
- panelPerms.addComponents(
- new DecoDropdown(panelPerms.width-72, 8+2-2)
- .withSize(72-4, 14)
- .withEntries(identity.getAvailableRoles().values())
- .withDisplayFunction(DecoElementDisplays.getSimpleTextDisplay(PermissionRole::getDisplayName))
- .withSelectedEntry(selectedRole = identity.getRoleOf(playerContainer.player.getUniqueID()))
- .withOnSelectedEntry((oldRole, newRole) -> selectedRole = newRole),
- new DecoList(2, 12+8+2+1)
- .withSize(panelPerms.width-4-2, panelPerms.height-32+8-2)
- .withEntries(PermissionCategory.values())
- .withDisplayFunction(new DecoEntryPanelBuilder()
- .withHeight(18)
- .withComponent("toggle", p -> new DecoSwitch(2, 2)
- .withOnToggle(change -> IIPacketHandler.sendToServer(MessageDiplomacyAction.changePermission(selectedRole,
- p.getCurrentElement(), change)))
- )
- .withElementApplyMethod((permission, panel) -> {
- panel.component("toggle", DecoSwitch.class)
- .withCurrentState(selectedRole.isAllowed(permission))
- .withText(permission.getFullLocaleKey());
- })
- )
- );
+ selectedRole = identity.getRoleOf(playerContainer.player.getUniqueID());
+ if(selectedRole!=null)
+ {
+ panelPerms.addLabel("Role:", 4, 8+2-1)
+ .withSize(panelPerms.width-72-2, 14)
+ .withAlign(DecoAlignment.LEFT);
+ panelPerms.addComponents(
+ new DecoDropdown(panelPerms.width-72, 8+2-2)
+ .withSize(72-4, 14)
+ .withEntries(identity.getAvailableRoles().values())
+ .withDisplayFunction(DecoElementDisplays.getSimpleTextDisplay(PermissionRole::getDisplayName))
+ .withSelectedEntry(selectedRole)
+ .withOnSelectedEntry((oldRole, newRole) -> selectedRole = newRole),
+ new DecoList(2, 12+8+2+1)
+ .withSize(panelPerms.width-4-2, panelPerms.height-32+8-2)
+ .withEntries(PermissionCategory.values())
+ .withDisplayFunction(new DecoEntryPanelBuilder()
+ .withHeight(18)
+ .withComponent("toggle", p -> new DecoSwitch(2, 2)
+ .withOnToggle(change -> IIPacketHandler.sendToServer(MessageDiplomacyAction.changePermission(selectedRole,
+ p.getCurrentElement(), change)))
+ )
+ .withElementApplyMethod((permission, panel) -> {
+ panel.component("toggle", DecoSwitch.class)
+ .withCurrentState(selectedRole.isAllowed(permission))
+ .withText(permission.getFullLocaleKey());
+ })
+ )
+ );
+ }
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/inserter/GuiInserter.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/inserter/GuiInserter.java
index 0ac030ba7..3d68e4b61 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/inserter/GuiInserter.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/inserter/GuiInserter.java
@@ -5,15 +5,15 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoElementDisplays;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoEntryPanelBuilder;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoIngredientStackPickerPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskJobList;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskJobList.ListMode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.DecoTextField;
@@ -41,14 +41,14 @@
* @since 20.01.2026
*/
@DecoTemplate(name = "inserter", category = DecoGuiCategory.DATA_TILE)
-public class GuiInserter extends DecoGui
+public class GuiInserter extends DecoTileGui
{
private static final String INSERTER_KEY = IIReference.GUI_LABEL_KEY+"inserter.";
- private ListMode mode = ListMode.TASKS;
- private DecoTaskJobList taskJobList;
+ private ListMode mode = ListMode.JOBS;
+ private DecoTaskList taskList;
private DecoPanel panelDetails;
@SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
- private EasyMultiTypeCollection tasks;
+ public EasyMultiTypeCollection tasks;
@Nullable
private InserterTask selected;
@@ -74,7 +74,7 @@ public void onInit()
.withBox(DecoTextures.BG_STEEL, DecoTextures.TEMPLATE_SQUARE, 108, 8+3, 120+16, 130+16-2)
.build();
- addComponent((taskJobList = new DecoTaskJobList<>(0, 2))
+ addComponent((taskList = new DecoTaskList<>(0, 2))
.withSize(108, 116)
.withEntries(tasks)
.withIsJobPredicate(InserterTask::isJob)
@@ -84,7 +84,7 @@ public void onInit()
if(!taskSupplier.isPresent())
return null;
InserterTask created = taskSupplier.get().get();
- created.isJob = (taskJobList.getMode()==ListMode.JOBS);
+ created.isJob = (taskList.getMode()==ListMode.JOBS);
return created;
})
.withOnSelectedChanged(task -> {
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPacker.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPacker.java
index 442cae8ad..867eb7e6a 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPacker.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPacker.java
@@ -8,7 +8,7 @@
import pl.pabilo8.immersiveintelligence.api.PackerHandler;
import pl.pabilo8.immersiveintelligence.api.PackerHandler.PackerActionType;
import pl.pabilo8.immersiveintelligence.api.PackerHandler.PackerTask;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoCheckbox;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
@@ -17,8 +17,8 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoIngredientStackPickerPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoIngredientStackPickerPanel.PickerPanelMode;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskJobList;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskJobList.ListMode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoFluidTank;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
@@ -53,7 +53,7 @@
* @since 25.08.2022
*/
@DecoTemplate(name = "packer", category = DecoGuiCategory.DATA_TILE)
-public class GuiPacker extends DecoGui
+public class GuiPacker extends DecoTileGui
{
@DecoResource
public static ResourceLocation ICON_LABELER = ResLoc.of(RES_II, "gui/upgrade/packer_naming");
@@ -61,10 +61,10 @@ public class GuiPacker extends DecoGui
@SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
public EasyCollection tasks;
@SyncNBT
- public ListMode mode = ListMode.TASKS;
+ public ListMode mode = ListMode.JOBS;
private PackerActionType actionType;
- private DecoTaskJobList taskJobList;
+ private DecoTaskList taskList;
private DecoPanel panelDetails, panelResources;
private DecoCheckbox expiresCheckbox;
private DecoTextField expiresTextField;
@@ -117,14 +117,14 @@ public void onInit()
}
// Replace mode tabs + list + action buttons with a single component
- addComponent((taskJobList = new DecoTaskJobList<>(0, 0))
+ addComponent((taskList = new DecoTaskList<>(0, 0))
.withSize(108, 116+12-8)
.withEntries(tasks)
- .withIsJobPredicate(t -> t.expirationAmount!=-1)
+ .withIsJobPredicate(t -> t.expirationAmount==-1)
.withModeHandling(mode, m -> mode = m)
.withBlankTaskSupplier(() -> {
PackerTask created = new PackerTask(PackerHandler.PackerPutMode.ALL_POSSIBLE, actionType, new IngredientStack("*"));
- created.expirationAmount = (taskJobList.getMode()==ListMode.TASKS)?-1: 1;
+ created.expirationAmount = (taskList.getMode()==ListMode.JOBS)?-1: 1;
return created;
})
.withOnSelectedChanged(task -> {
@@ -390,6 +390,8 @@ private void updateExpiresFields()
expiresCheckbox.withChecked(selected.expirationAmount!=-1);
if(expiresTextField!=null)
expiresTextField.withText(selected.expirationAmount==-1?"": String.valueOf(selected.expirationAmount));
+ if(taskList!=null)
+ taskList.setMode(selected.expirationAmount==-1?ListMode.JOBS: ListMode.REQUESTS);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPackerLabeler.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPackerLabeler.java
index 1a308e572..2267857e8 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPackerLabeler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/packer/GuiPackerLabeler.java
@@ -6,7 +6,7 @@
import net.minecraft.nbt.NBTTagCompound;
import pl.pabilo8.immersiveintelligence.api.LogisticTag;
import pl.pabilo8.immersiveintelligence.api.PackerHandler.LabelingTask;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoCheckbox;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
@@ -14,7 +14,8 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoIngredientStackPickerPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoIngredientStackPickerPanel.PickerPanelMode;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskJobList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoTaskList.ListMode;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.DecoTextField;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.text.util.TextFilter;
@@ -45,12 +46,14 @@
* @since 25.08.2022
*/
@DecoTemplate(name = "packer_labeler", category = DecoGuiCategory.DATA_TILE)
-public class GuiPackerLabeler extends DecoGui
+public class GuiPackerLabeler extends DecoTileGui
{
@SyncNBT(events = SyncEvents.TILE_CLIENT_MESSAGE)
public EasyCollection labels;
+ @SyncNBT
+ public ListMode mode = ListMode.JOBS;
- private DecoTaskJobList taskList;
+ private DecoTaskList taskList;
private DecoPanel panelDetails;
private DecoCheckbox expiresCheckbox, serialStartCheckbox;
private DecoTextField expiresTextField, serialStartTextField;
@@ -96,15 +99,16 @@ public void onInit()
addLinkTab(IIGUI.PACKER, DecoTextures.ICON_TASKS, "tasks_module");
addLinkTab(IIGUI.PACKER_LABELER, GuiPacker.ICON_LABELER, "labeler_module");
- // Replace list + action buttons with a standardized component (no Jobs tab here)
- addComponent((taskList = new DecoTaskJobList<>(0, 0))
+ // Replace mode tabs + list + action buttons with a standardized component
+ addComponent((taskList = new DecoTaskList<>(0, 0))
.withSize(108, 116+12-8)
.withEntries(labels)
- .withIsJobPredicate(t -> false)
+ .withIsJobPredicate(t -> t.expirationAmount==-1)
+ .withModeHandling(mode, m -> mode = m)
.withBlankTaskSupplier(() -> {
LabelingTask created = new LabelingTask();
created.filter = new IngredientStack("*");
- created.expirationAmount = -1;
+ created.expirationAmount = (taskList.getMode()==ListMode.JOBS)?-1: 1;
created.serialBatch = 0;
return created;
})
@@ -298,6 +302,8 @@ private void updateExpiresFields()
expiresCheckbox.withChecked(selected.expirationAmount!=-1);
if(expiresTextField!=null)
expiresTextField.withText(selected.expirationAmount==-1?"": String.valueOf(selected.expirationAmount));
+ if(taskList!=null)
+ taskList.setMode(selected.expirationAmount==-1?ListMode.JOBS: ListMode.REQUESTS);
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadar.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadar.java
index e69893f19..0ef65986f 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadar.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadar.java
@@ -7,7 +7,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoCheckbox;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoMapDisplay;
@@ -34,7 +34,7 @@
* @since 28.04.2023
*/
@DecoTemplate(name = "radar", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
-public class GuiRadar extends DecoGui
+public class GuiRadar extends DecoTileGui
{
@DecoResource
public static ResourceLocation ICON_RADAR = ResLoc.of(IIReference.RES_II, "gui/tab_icons/radar");
@@ -64,7 +64,7 @@ public void onInit()
//Tabs
addLinkTab(IIGUI.RADAR, GuiRadar.ICON_RADAR, "radar_module");
- addLinkTab(IIGUI.RADAR_CONFIG, DecoTextures.ICON_CONFIG, "config_module");
+ addLinkTab(IIGUI.RADAR_CONFIG, DecoTextures.ICON_CONFIG, "configuration_module");
addLinkTab(IIGUI.RADAR_TARGETS, DecoTextures.ICON_TARGETS, "targets_module");
BlockPos pos = tile.getPos();
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarConfig.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarConfig.java
index 0e01b00b5..9e826f480 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarConfig.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarConfig.java
@@ -1,7 +1,7 @@
package pl.pabilo8.immersiveintelligence.client.gui.block.radar;
import net.minecraft.entity.player.EntityPlayer;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
@@ -15,7 +15,7 @@
* @since 28.04.2023
*/
@DecoTemplate(name = "radar_config", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
-public class GuiRadarConfig extends DecoGui
+public class GuiRadarConfig extends DecoTileGui
{
public GuiRadarConfig(EntityPlayer player, TileEntityRadar tile)
{
@@ -35,7 +35,7 @@ public void onInit()
//Tabs
addLinkTab(IIGUI.RADAR, GuiRadar.ICON_RADAR, "radar_module");
- addLinkTab(IIGUI.RADAR_CONFIG, DecoTextures.ICON_CONFIG, "config_module");
+ addLinkTab(IIGUI.RADAR_CONFIG, DecoTextures.ICON_CONFIG, "configuration_module");
addLinkTab(IIGUI.RADAR_TARGETS, DecoTextures.ICON_TARGETS, "targets_module");
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarTargets.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarTargets.java
index d33aa0f9c..0038be262 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarTargets.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/block/radar/GuiRadarTargets.java
@@ -1,7 +1,7 @@
package pl.pabilo8.immersiveintelligence.client.gui.block.radar;
import net.minecraft.entity.player.EntityPlayer;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoTileGui;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
@@ -15,7 +15,7 @@
* @since 28.04.2023
*/
@DecoTemplate(name = "radar_targets", category = DecoGuiCategory.TERRITORY_CONTROL_TILE)
-public class GuiRadarTargets extends DecoGui
+public class GuiRadarTargets extends DecoTileGui
{
public GuiRadarTargets(EntityPlayer player, TileEntityRadar tile)
{
@@ -37,7 +37,7 @@ public void onInit()
//Tabs
addLinkTab(IIGUI.RADAR, GuiRadar.ICON_RADAR, "radar_module");
- addLinkTab(IIGUI.RADAR_CONFIG, DecoTextures.ICON_CONFIG, "config_module");
+ addLinkTab(IIGUI.RADAR_CONFIG, DecoTextures.ICON_CONFIG, "configuration_module");
addLinkTab(IIGUI.RADAR_TARGETS, DecoTextures.ICON_TARGETS, "targets_module");
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoEntityGui.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoEntityGui.java
new file mode 100644
index 000000000..f1d6c69bb
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoEntityGui.java
@@ -0,0 +1,68 @@
+package pl.pabilo8.immersiveintelligence.client.gui.deco;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.Container;
+import pl.pabilo8.immersiveintelligence.api.style.IStyleCustomizable;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoManualWidget;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoStyleWidget;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+
+/**
+ * Deco GUI backed by an Entity.
+ *
+ * The concrete entity GUI supplies its container directly, because IIGUI currently has tile and item factories only.
+ * Entity sync is intentionally left to concrete subclasses until a project-wide entity GUI packet exists.
+ *
+ */
+public abstract class DecoEntityGui extends DecoGui
+{
+ protected final E entity;
+
+ public DecoEntityGui(EntityPlayer player, E entity, IIGUI iigui)
+ {
+ //noinspection unchecked
+ super(player, (C)iigui.containerFromEntity.apply(player, entity), entity, iigui);
+ this.entity = entity;
+ }
+
+ @Override
+ protected void onInitStandardAddons()
+ {
+ if(category==DecoGuiCategory.VEHICLE_ENTITY)
+ addWidget(new DecoManualWidget());
+ if(entity instanceof IStyleCustomizable)
+ addWidget(new DecoStyleWidget(((IStyleCustomizable)entity)));
+ }
+
+ @Override
+ protected boolean isStoredGuiDataValid(EasyNBT nbt)
+ {
+ if(!super.isStoredGuiDataValid(nbt)||entity==null)
+ return false;
+ final boolean[] valid = {false};
+ nbt.checkSetString("entity", s -> valid[0] = getEntityGuiKey().equals(s));
+ return valid[0];
+ }
+
+ @Override
+ protected EasyNBT createGuiDataTag()
+ {
+ EasyNBT nbt = super.createGuiDataTag();
+ if(entity!=null)
+ nbt.withString("entity", getEntityGuiKey());
+ return nbt;
+ }
+
+ protected String getEntityGuiKey()
+ {
+ return entity.dimension+":"+entity.getEntityId();
+ }
+
+ public E getEntity()
+ {
+ return entity;
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoGui.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoGui.java
index 8dd429838..93c64aae7 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoGui.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoGui.java
@@ -1,10 +1,7 @@
package pl.pabilo8.immersiveintelligence.client.gui.deco;
import blusunrize.immersiveengineering.api.ApiUtils;
-import blusunrize.immersiveengineering.api.DimensionBlockPos;
import blusunrize.immersiveengineering.client.ClientUtils;
-import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
-import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiLabel;
@@ -16,6 +13,7 @@
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
@@ -33,7 +31,6 @@
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
-import pl.pabilo8.immersiveintelligence.api.style.IStyleCustomizable;
import pl.pabilo8.immersiveintelligence.client.ClientProxy;
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent;
@@ -43,25 +40,17 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoComponentWidgetBase;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoManualWidget;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoOwnershipWidget;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoStyleWidget;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
import pl.pabilo8.immersiveintelligence.client.render.IReloadableModelContainer;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.IILogger;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
-import pl.pabilo8.immersiveintelligence.common.network.messages.MessageBooleanAnimatedPartsSync;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageGuiNBT;
-import pl.pabilo8.immersiveintelligence.common.network.messages.MessageIITileSync;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
-import pl.pabilo8.immersiveintelligence.common.util.diplomacy.property.IOwnableProperty;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.NBTSerialisation;
-import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
-import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIBase;
-import pl.pabilo8.immersiveintelligence.common.util.multiblock.util.MultiblockInteractablePart;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -78,47 +67,43 @@
import java.util.function.Supplier;
/**
+ * Common base for Deco GUIs.
*
- * Introducing Deco, Immersive Intelligence's new GUI framework designed to be
- *
- * - Dynamic
- * - Elegant
- * - Compact
- * - Optimized
- *
- * Offering a variety of {@link pl.pabilo8.immersiveintelligence.client.gui.deco.component components},
- * {@link pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget widgets} and a tile-based
- * {@link DecoBackgroundBuilder} to make GUI creation easier and more efficient
+ * This class owns the reusable GUI mechanics: component lifecycle, widgets, labels, tooltips,
+ * value listeners, background drawing, JEI taken-space data and GUI screenshot export.
+ * Context-specific behaviour is supplied by subclasses such as {@link DecoTileGui},
+ * {@link DecoEntityGui} and {@link DecoItemGui}.
*
- * Class for advanced GUIs that store data in the client proxy NBT and use components for their display
- * Use annotation {@link DecoTemplate} to specify traits
+ * Use annotation {@link DecoTemplate} to specify traits.
*
* @author Pabilo8 (pabilo@iiteam.net)
* @since 04.01.2025
*/
-public abstract class DecoGui> extends GuiContainer
+@SuppressWarnings({"rawtypes", "unchecked"})
+public abstract class DecoGui extends GuiContainer
{
private static final int MAX_WIDGET_TIME = 40;
+ private static final String NBT_GUI_NAME = "decoGui";
//Gui basics
protected final String name;
- protected final T tile;
+ protected final T context;
protected final C container;
protected final DecoGuiCategory category;
protected final InventoryPlayer playerContainer;
+ protected final IIGUI gui;
//Components
protected final List tabList = new ArrayList<>();
protected final List widgetTabList = new ArrayList<>();
private final List> widgetList = new ArrayList<>();
private final List> valueListeners = new ArrayList<>();
- private final IIGUI gui;
/**
- * if true, the GUI won't perform saving to NBT during {@link #onGuiClosed()}, used for transitions between GUIs
+ * if true, the GUI won't perform default closing cleanup during {@link #onGuiClosed()}, used for transitions between GUIs
*/
protected boolean changeGUIFlag = false, refreshGUIFlag = false;
//Background
- private DecoBackgroundBuilder backgroundBuilder;
+ private DecoBackgroundBuilder backgroundBuilder;
private List takenSpace;
private DecoComponent> focusedElement;
private DecoComponent> hoveredElement;
@@ -130,26 +115,15 @@ public abstract class DecoGui)button).setParentGUI(this);
for(DecoComponentWidgetBase> widget : widgetList)
widget.setParentGUI(this);
-
-
}
/**
@@ -246,12 +218,15 @@ public final void initGui()
*/
protected void onInitStandardAddons()
{
- if(category==DecoGuiCategory.DATA_TILE||category==DecoGuiCategory.PRODUCTION_TILE||category==DecoGuiCategory.TERRITORY_CONTROL_TILE)
- addWidget(new DecoManualWidget());
- if(tile instanceof IOwnableProperty)
- addWidget(new DecoOwnershipWidget(((IOwnableProperty)tile)));
- if(tile instanceof IStyleCustomizable)
- addWidget(new DecoStyleWidget(((IStyleCustomizable)tile)));
+
+ }
+
+ /**
+ * Called when no {@link DecoBackgroundBuilder} was supplied.
+ */
+ protected void onNoBackgroundBuilder()
+ {
+ xSize = ySize = 64;
}
/**
@@ -427,7 +402,7 @@ protected final DecoLabel addLabel(DecoLabel label)
*/
protected DecoBackgroundBuilder startBackground()
{
- return this.backgroundBuilder = new DecoBackgroundBuilder<>(this);
+ return this.backgroundBuilder = new DecoBackgroundBuilder(this);
}
//--- GUI Rendering Methods ---//
@@ -460,15 +435,7 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
if(refreshGUIFlag)
{
- if(backgroundBuilder!=null)
- backgroundBuilder.cleanup();
- //Cleanup components
- for(GuiButton b : buttonList)
- if(b instanceof DecoComponent)
- ((DecoComponent>)b).cleanup();
- //Cleanup widgets
- for(DecoComponentWidgetBase> widget : widgetList)
- widget.cleanup();
+ cleanupDecoGui();
initGui();
refreshGUIFlag = false;
}
@@ -547,6 +514,19 @@ private void drawWidgets(int mouseX, int mouseY, float partialTicks)
}
}
+ protected void openManualWidget(String pageName, int index)
+ {
+ widgetList.stream()
+ .filter(widget -> widget instanceof DecoManualWidget)
+ .map(widget -> (DecoManualWidget)widget)
+ .findFirst().ifPresent(widget -> {
+ if(currentWidget!=widget)
+ setCurrentWidget(widget);
+ widget.setCurrentPage(pageName, index);
+ requestFocus(widget);
+ });
+ }
+
/**
* Renders the tooltip for a hovered-over component or itemstack.
*
@@ -690,27 +670,26 @@ protected final void mouseClickMove(int mouseX, int mouseY, int clickedMouseButt
}
/**
- * Triggered upon closing the GUI. Saves the GUI data to {@link ClientProxy} and (optionally) sends a sync message to the tile entity.
+ * Triggered upon closing the GUI. Saves the GUI data to {@link ClientProxy} and delegates context-specific sync to subclasses.
*/
@Override
public void onGuiClosed()
{
super.onGuiClosed();
- //Save GUI data
if(!changeGUIFlag)
{
- //Send an NBT sync message to the tile entity
- EasyNBT nbt = onSaveTileData();
- if(!nbt.isEmpty())
- IIPacketHandler.sendToServer(new MessageIITileSync(tile, nbt));
- //Clean stored data
- ((ClientProxy)ImmersiveIntelligence.proxy).setStoredGuiData();
+ onGuiClosedWithoutTransition();
+ clearStoredGuiData();
}
else
saveGuiData();
- //Perform background and component cleanup
+ cleanupDecoGui();
+ }
+
+ protected void cleanupDecoGui()
+ {
if(backgroundBuilder!=null)
backgroundBuilder.cleanup();
for(GuiButton b : buttonList)
@@ -721,6 +700,14 @@ public void onGuiClosed()
widget.cleanup();
}
+ /**
+ * Called when the GUI is closed normally, not when it is changing to another GUI.
+ */
+ protected void onGuiClosedWithoutTransition()
+ {
+
+ }
+
//--- Component Events ---//
protected List getTooltip()
@@ -763,19 +750,16 @@ public void requestFocus(DecoComponent> component)
//--- NBT ---//
/**
- * Called upon start and synchronisation, loads the data from the client proxy
+ * Called upon start and synchronisation, loads the data from the client proxy.
*
* @return The NBT compound containing the data
*/
- private EasyNBT loadGuiData()
+ protected EasyNBT loadGuiData()
{
- //Load GUI data from the proxy
- assert ImmersiveIntelligence.proxy instanceof ClientProxy;
- ClientProxy proxy = (ClientProxy)ImmersiveIntelligence.proxy;
+ ClientProxy proxy = getClientProxy();
EasyNBT nbt = proxy.getStoredGuiData();
- //Return a valid compound or an empty one if location mismatch
- if(!nbt.hasKey("pos")||!new DimensionBlockPos(tile).equals(nbt.getDimPos("pos")))
+ if(!isStoredGuiDataValid(nbt))
return proxy.setStoredGuiData();
//Deserialize all SyncNBT fields
@@ -784,17 +768,24 @@ private EasyNBT loadGuiData()
return nbt;
}
+ /**
+ * Checks whether stored GUI NBT belongs to this GUI instance.
+ */
+ protected boolean isStoredGuiDataValid(EasyNBT nbt)
+ {
+ final boolean[] valid = {false};
+ nbt.checkSetString(NBT_GUI_NAME, s -> valid[0] = s.equals(name));
+ return valid[0];
+ }
+
/**
* Called upon closing the GUI, gathers and saves the data to the client proxy.
*
* @return The NBT compound containing the data
*/
- private EasyNBT saveGuiData()
+ protected EasyNBT saveGuiData()
{
- //Save basic identification
- assert ImmersiveIntelligence.proxy instanceof ClientProxy;
- EasyNBT nbt = ((ClientProxy)ImmersiveIntelligence.proxy).setStoredGuiData()
- .withDimPos("pos", new DimensionBlockPos(tile));
+ EasyNBT nbt = createGuiDataTag();
//Save component data
for(GuiButton button : buttonList)
@@ -812,15 +803,23 @@ private EasyNBT saveGuiData()
}
/**
- * Called upon closing the GUI, collects data to be passed in a {@link MessageIITileSync} to the tile entity.
- *
- * @return The NBT compound containing the data
+ * Creates the client-side GUI persistence tag. Subclasses add their own identity keys here.
*/
- protected EasyNBT onSaveTileData()
+ protected EasyNBT createGuiDataTag()
{
- EasyNBT nbt = EasyNBT.newNBT();
- NBTSerialisation.synchroniseFor(this, (tag, gui) -> tag.serializeForEvent(gui, nbt.unwrap(), SyncEvents.TILE_CLIENT_MESSAGE));
- return nbt;
+ return getClientProxy().setStoredGuiData()
+ .withString(NBT_GUI_NAME, name);
+ }
+
+ protected final void clearStoredGuiData()
+ {
+ getClientProxy().setStoredGuiData();
+ }
+
+ protected final ClientProxy getClientProxy()
+ {
+ assert ImmersiveIntelligence.proxy instanceof ClientProxy;
+ return (ClientProxy)ImmersiveIntelligence.proxy;
}
@Nullable
@@ -867,8 +866,11 @@ public final List getTakenSpace()
List takenSpace = new ArrayList<>();
//Add rectangles from the background builder
if(backgroundBuilder!=null)
- for(DecoBackgroundTile rect : backgroundBuilder.getTakenSpace())
+ for(Object object : backgroundBuilder.getTakenSpace())
+ {
+ DecoBackgroundTile rect = (DecoBackgroundTile)object;
takenSpace.add(new Rectangle(guiLeft+rect.x, guiTop+rect.y, rect.width, rect.height));
+ }
//Add rectangles for each tab
for(DecoTab tab : tabList)
@@ -880,27 +882,14 @@ public final List getTakenSpace()
//Previous widget
takenSpace.add(new Rectangle(0, 0, 0, 0));
- //Current wigdet
+ //Current widget
takenSpace.add(new Rectangle(0, 0, 0, 0));
return this.takenSpace = takenSpace;
}
- /**
- * @return the tile entity associated with this GUI
- */
- public T getTile()
- {
- return tile;
- }
-
//--- Utilities ---//
- public void syncAnimatedParts(MultiblockInteractablePart part, boolean state)
- {
- IIPacketHandler.sendToServer(new MessageBooleanAnimatedPartsSync(part.getID(), state, tile));
- }
-
public final boolean refreshGUI()
{
return changeGUI(this.gui);
@@ -925,32 +914,45 @@ public final boolean changeGUI(@Nullable IIGUI newGUI)
}
/**
- * Changes the GUI to the specified one, ensuring data is saved and sent to the server
+ * Changes the GUI to the specified one, ensuring data is saved and sent to the server.
*
- * @param newGUI the new GUI to change to, null will close the current GUI
- * @param guiData additional data to save for the GUI
- * @param tileData additional data to save for the tile entity
+ * @param newGUI the new GUI to change to, null will close the current GUI
+ * @param guiData additional data to save for the GUI
+ * @param contextData additional data to save for the backing object
*/
- public final boolean changeGUI(@Nullable IIGUI newGUI, @Nullable EasyNBT guiData, @Nullable EasyNBT tileData)
+ public final boolean changeGUI(@Nullable IIGUI newGUI, @Nullable EasyNBT guiData, @Nullable EasyNBT contextData)
{
//Switch the Change GUI flag to prevent double saving
this.changeGUIFlag = true;
- //Save Tile Entity data
- EasyNBT nbt = onSaveTileData().conditionally(tileData!=null, e -> e.mergeWith(tileData));
- if(!nbt.isEmpty())
- IIPacketHandler.sendToServer(new MessageIITileSync(tile, nbt));
+ //Save context-specific data first
+ onBeforeGuiChange(contextData);
//Save GUI data
saveGuiData().conditionally(guiData!=null, e -> e.mergeWith(guiData));
- //Send change GUI message
+ return sendGuiChangeMessage(newGUI);
+ }
+
+ /**
+ * Gives subclasses a chance to sync their backing object before a GUI transition.
+ */
+ protected void onBeforeGuiChange(@Nullable EasyNBT contextData)
+ {
+
+ }
+
+ /**
+ * Sends the actual GUI transition message.
+ */
+ protected boolean sendGuiChangeMessage(@Nullable IIGUI newGUI)
+ {
if(newGUI==null)
IIPacketHandler.sendToServer(MessageGuiNBT.closeGuiMessage());
- else if(newGUI!=gui)
- IIPacketHandler.sendToServer(new MessageGuiNBT(newGUI, tile));
- else
+ else if(newGUI==gui)
refreshGUIFlag = true;
+ else
+ return false;
return true;
}
@@ -1056,8 +1058,9 @@ private void exportCurrentGui()
//Draw widgets
drawWidgets(0, 0, 0);
- //Draw tiled background,
- backgroundBuilder.draw();
+ //Draw tiled background, if present
+ if(backgroundBuilder!=null)
+ backgroundBuilder.draw();
GlStateManager.color(1f, 1f, 1f, 1f);
GlStateManager.enableAlpha();
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoHelpBox.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoHelpBox.java
deleted file mode 100644
index be907af4d..000000000
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoHelpBox.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package pl.pabilo8.immersiveintelligence.client.gui.deco;
-
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.resources.I18n;
-
-/**
- * A class for displaying help information when hovering over a part of the gui
- *
- * @author Pabilo8 (pabilo@iiteam.net)
- * @since 19.01.2024
- */
-public class DecoHelpBox
-{
- /**
- * The x position of the box
- */
- public int x;
- /**
- * The y position of the box
- */
- public int y;
- /**
- * The width of the box
- */
- public int width;
- /**
- * The height of the box
- */
- public int height;
- /**
- * The translated text to display in the box
- */
- public String text;
-
- public DecoHelpBox(int x, int y, int width, int height, String helpText)
- {
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- this.text = I18n.format(helpText);
- }
-
- /**
- * @param gui component this box is attached to
- */
- public DecoHelpBox(GuiButton gui, String helpText)
- {
- this(gui.x, gui.y, gui.width, gui.height, helpText);
- }
-}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoItemGui.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoItemGui.java
new file mode 100644
index 000000000..3a67620ef
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoItemGui.java
@@ -0,0 +1,66 @@
+package pl.pabilo8.immersiveintelligence.client.gui.deco;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumHand;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIItemBase;
+
+/**
+ * Deco GUI backed by an ItemStack and a {@link ContainerIIItemBase}.
+ */
+public abstract class DecoItemGui extends DecoGui
+{
+ protected final ItemStack itemStack;
+ protected final EnumHand hand;
+
+ public DecoItemGui(EntityPlayer player, ItemStack heldStack, EnumHand hand, IIGUI iigui)
+ {
+ super(player, createContainer(player, heldStack, hand, iigui), heldStack==null?ItemStack.EMPTY: heldStack, iigui);
+ this.itemStack = heldStack==null?ItemStack.EMPTY: heldStack;
+ this.hand = hand;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static C createContainer(EntityPlayer player, ItemStack heldStack, EnumHand hand, IIGUI iigui)
+ {
+ return player==null||heldStack==null||hand==null||iigui.containerFromStack==null?null:
+ (C)iigui.containerFromStack.apply(player, heldStack, hand);
+ }
+
+ @Override
+ protected void onNoBackgroundBuilder()
+ {
+ // Item GUIs often use a hand-drawn texture and set xSize/ySize in onInit().
+ }
+
+ @Override
+ protected boolean isStoredGuiDataValid(EasyNBT nbt)
+ {
+ if(!super.isStoredGuiDataValid(nbt)||hand==null)
+ return false;
+ final boolean[] valid = {false};
+ nbt.checkSetString("hand", s -> valid[0] = hand.name().equals(s));
+ return valid[0];
+ }
+
+ @Override
+ protected EasyNBT createGuiDataTag()
+ {
+ EasyNBT nbt = super.createGuiDataTag();
+ if(hand!=null)
+ nbt.withString("hand", hand.name());
+ return nbt;
+ }
+
+ public ItemStack getItemStack()
+ {
+ return itemStack;
+ }
+
+ public EnumHand getHand()
+ {
+ return hand;
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoTileGui.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoTileGui.java
new file mode 100644
index 000000000..328010e25
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/DecoTileGui.java
@@ -0,0 +1,121 @@
+package pl.pabilo8.immersiveintelligence.client.gui.deco;
+
+import blusunrize.immersiveengineering.api.DimensionBlockPos;
+import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
+import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
+import net.minecraft.entity.player.EntityPlayer;
+import pl.pabilo8.immersiveintelligence.api.style.IStyleCustomizable;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoManualWidget;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoOwnershipWidget;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.widget.DecoStyleWidget;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
+import pl.pabilo8.immersiveintelligence.common.network.messages.MessageBooleanAnimatedPartsSync;
+import pl.pabilo8.immersiveintelligence.common.network.messages.MessageGuiNBT;
+import pl.pabilo8.immersiveintelligence.common.network.messages.MessageIITileSync;
+import pl.pabilo8.immersiveintelligence.common.util.diplomacy.property.IOwnableProperty;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.NBTSerialisation;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT.SyncEvents;
+import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIITileBase;
+import pl.pabilo8.immersiveintelligence.common.util.multiblock.util.MultiblockInteractablePart;
+
+import javax.annotation.Nullable;
+
+/**
+ * Deco GUI backed by a TileEntity.
+ */
+public abstract class DecoTileGui> extends DecoGui
+{
+ protected final T tile;
+
+ public DecoTileGui(EntityPlayer player, T tile, IIGUI iigui)
+ {
+ super(player, createContainer(player, tile, iigui), tile, iigui);
+ this.tile = tile;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static > C createContainer(EntityPlayer player, T tile, IIGUI iigui)
+ {
+ return player==null?null: (C)iigui.containerFromTile.apply(player, tile);
+ }
+
+ @Override
+ protected void onInitStandardAddons()
+ {
+ if(category==DecoGuiCategory.DATA_TILE||category==DecoGuiCategory.PRODUCTION_TILE||category==DecoGuiCategory.TERRITORY_CONTROL_TILE)
+ addWidget(new DecoManualWidget());
+ if(tile instanceof IOwnableProperty)
+ addWidget(new DecoOwnershipWidget(((IOwnableProperty)tile)));
+ if(tile instanceof IStyleCustomizable)
+ addWidget(new DecoStyleWidget(((IStyleCustomizable)tile)));
+ }
+
+ @Override
+ protected boolean isStoredGuiDataValid(EasyNBT nbt)
+ {
+ return tile!=null&&nbt.hasKey("pos")&&new DimensionBlockPos(tile).equals(nbt.getDimPos("pos"));
+ }
+
+ @Override
+ protected EasyNBT createGuiDataTag()
+ {
+ return super.createGuiDataTag()
+ .withDimPos("pos", new DimensionBlockPos(tile));
+ }
+
+ @Override
+ protected void onGuiClosedWithoutTransition()
+ {
+ EasyNBT nbt = onSaveTileData();
+ if(!nbt.isEmpty())
+ IIPacketHandler.sendToServer(new MessageIITileSync(tile, nbt));
+ }
+
+ @Override
+ protected void onBeforeGuiChange(@Nullable EasyNBT tileData)
+ {
+ EasyNBT nbt = onSaveTileData().conditionally(tileData!=null, e -> e.mergeWith(tileData));
+ if(!nbt.isEmpty())
+ IIPacketHandler.sendToServer(new MessageIITileSync(tile, nbt));
+ }
+
+ @Override
+ protected boolean sendGuiChangeMessage(@Nullable IIGUI newGUI)
+ {
+ if(newGUI==null)
+ IIPacketHandler.sendToServer(MessageGuiNBT.closeGuiMessage());
+ else if(newGUI!=gui)
+ IIPacketHandler.sendToServer(new MessageGuiNBT(newGUI, tile));
+ else
+ refreshGUIFlag = true;
+ return true;
+ }
+
+ /**
+ * Called upon closing or changing the GUI, collects data to be passed in a {@link MessageIITileSync} to the tile entity.
+ *
+ * @return The NBT compound containing the data
+ */
+ protected EasyNBT onSaveTileData()
+ {
+ EasyNBT nbt = EasyNBT.newNBT();
+ NBTSerialisation.synchroniseFor(this, (tag, gui) -> tag.serializeForEvent(gui, nbt.unwrap(), SyncEvents.TILE_CLIENT_MESSAGE));
+ return nbt;
+ }
+
+ /**
+ * @return the tile entity associated with this GUI
+ */
+ public T getTile()
+ {
+ return tile;
+ }
+
+ public void syncAnimatedParts(MultiblockInteractablePart part, boolean state)
+ {
+ IIPacketHandler.sendToServer(new MessageBooleanAnimatedPartsSync(part.getID(), state, tile));
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/DecoComponent.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/DecoComponent.java
index 80b383bbb..a1e19079d 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/DecoComponent.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/DecoComponent.java
@@ -1,14 +1,12 @@
package pl.pabilo8.immersiveintelligence.client.gui.deco.component;
import blusunrize.immersiveengineering.client.ClientUtils;
-import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
-import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.resources.I18n;
+import net.minecraft.inventory.Container;
import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
import pl.pabilo8.immersiveintelligence.common.util.IIMath;
-import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIBase;
import javax.annotation.Nullable;
import java.util.*;
@@ -80,7 +78,7 @@ public List getTooltip()
//--- Property Setters ---//
- public > void setParentGUI(DecoGui parent)
+ public void setParentGUI(DecoGui parent)
{
this.parentGui = parent;
this.x += parent.guiLeft;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoCodeEditor.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoCodeEditor.java
index 46c2def9b..784ed7f95 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoCodeEditor.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoCodeEditor.java
@@ -42,6 +42,7 @@ protected boolean initialize()
@Override
public DataType outputType()
{
- return null;
+ // The code view is currently a read-only preview; never return null, or applying the editor would erase the variable.
+ return dataType;
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditor.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditor.java
index 336e0d8ff..765f99994 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditor.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditor.java
@@ -75,7 +75,7 @@ public static List> getEditorTypes(boolean advanced)
{
return EDITORS.keySet().stream()
.map(IIDataTypeUtils.metaTypesByClass::get)
- //.filter(typeMetaInfo -> !advanced||typeMetaInfo.isAdvancedType())
+ .filter(typeMetaInfo -> advanced||!typeMetaInfo.isAdvancedType())
.collect(Collectors.toList());
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditorExpression.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditorExpression.java
index a0d907093..7a6a7536f 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditorExpression.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/data_editor/DecoDataEditorExpression.java
@@ -1,29 +1,42 @@
package pl.pabilo8.immersiveintelligence.client.gui.deco.component.data_editor;
-import net.minecraft.util.text.TextFormatting;
+import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
import pl.pabilo8.immersiveintelligence.api.data.IIDataTypeUtils;
import pl.pabilo8.immersiveintelligence.api.data.operations.DataOperation.DataOperationMeta;
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeAccessor;
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeExpression;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoTab;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoTabGroup;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.*;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoAlignment;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoColors;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplates;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
-import pl.pabilo8.immersiveintelligence.common.util.IIStringUtil;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+
+import javax.annotation.Nullable;
/**
+ * Visual editor for {@link DataTypeExpression} used by the Arithmetic-Logic Machine.
+ *
* @author Pabilo8 (pabilo@iiteam.net)
* @since 07.09.2021
*/
public class DecoDataEditorExpression extends DecoDataEditor
{
private int page = 0;
+ @Nullable
private DecoPanel editor;
+ @Nullable
+ private DecoDataEditor extends DataType> argumentEditor;
+ @Nullable
+ private DecoDropdownDataLetters argumentAccessorDropdown;
+ @Nullable
+ private DecoDropdownDataLetters conditionDropdown;
+ private boolean conditionEnabled;
public DecoDataEditorExpression(int x, int y, DataTypeExpression dataType)
{
@@ -36,90 +49,277 @@ protected boolean initialize()
cleanup();
if(!super.initialize())
return false;
+
DataOperationMeta meta = dataType.getMeta();
+ ensureArgumentArray(meta);
+ if(page < 0||page > meta.params().length)
+ page = 0;
+
+ addComponent(buildTabs(meta));
+
+ if(page==0)
+ initializePropertiesPage();
+ else
+ initializeArgumentPage(meta, page-1);
+
+ return true;
+ }
- //Initialize tabs
- DecoTabGroup groups = new DecoTabGroup(0, 4)
+ private DecoTabGroup buildTabs(DataOperationMeta meta)
+ {
+ DecoTabGroup group = new DecoTabGroup(0, 4)
.withSize(width, 12)
.withHorizontalAlignment(true)
.withTab((DecoTab)new DecoTab()
- .withText("Properties")
+ .withText(IIReference.DESCRIPTION_KEY+"variable_properties")
.withPadding(4, 2, 4, 2)
.withOnPressed((gui, button, mouseX, mouseY) -> setPage(0))
- .withTranslatedTooltip("Properties", IIStringUtil.getItalicString(TextFormatting.GRAY+"Edit expression properties, like conditional variables."))
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"variable_properties.tooltip")
);
+
String[] params = meta.params();
for(int paramID = 0; paramID < params.length; paramID++)
{
int finalParamID = paramID+1;
- groups.withTab((DecoTab)new DecoTab()
+ group.withTab((DecoTab)new DecoTab()
.withText("datasystem.immersiveintelligence.function."+meta.name()+".param."+params[paramID])
.withPadding(4, 2, 4, 2)
.withOnPressed((gui, button, mouseX, mouseY) -> setPage(finalParamID))
);
}
- addComponents(groups);
+ return group;
+ }
- //Initialize editor
- removeComponent(this.editor);
- if(page==0)
- {
- this.editor = addComponent(new DecoPanel(0, 16))
- .withSize(width, height-16)
- .withBackground(null);
- this.editor.addLabel("Here be parameters", 2, 2);
- }
- else
- {
- DataType argument = dataType.getArgument(page-1);
+ private void initializePropertiesPage()
+ {
+ this.editor = addComponent(new DecoPanel(0, 16))
+ .withSize(width, height-16)
+ .withBackground(null)
+ .withBackgroundMask(null);
- DecoPanel typePanel = addComponent(new DecoPanel(0, 16)
- .withSize(width, 20)
- .withBackground(DecoTextures.BG_PAPER)
- .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
- );
+ assert editor!=null;
- typePanel.addLabel("Type", 4, 2)
- .withSize(30, 16)
- .withAlign(DecoAlignment.LEFT);
- typePanel.addComponents(new DecoDropdown>(34, 2)
- .withSize(width-32-2-16-2-2, 16)
- .withDropdownWidth(width-16)
- .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
- .withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER)
- .withEntries(IIDataTypeUtils.metaTypesByClass.get(DataTypeAccessor.class),
- IIDataTypeUtils.metaTypesByClass.get(meta.allowedTypes()[page-1])
- ),
- new DecoButton(width-17-2, 2)
- .withText("@")
- .withSize(16, 16)
- .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
- );
+ conditionEnabled = dataType.getRequiredVariable()!=' ';
- //Get editor
- this.editor = DecoDataEditor.getEditorFor(argument, 0, 36);
- if(editor!=null)
- addComponent(editor.withSize(this.width, this.height-36)
- .withBackground(DecoTextures.BG_STEEL)
- .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
- );
- }
- return true;
+ DecoPanel basePanel = editor.addComponent(new DecoPanel(0, 0)
+ .withSize(width, 36)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
+ );
+
+ basePanel.addLabel(IIReference.DESCRIPTION_KEY+"conditional_variable", 4, 5)
+ .withSize(width-8, 10)
+ .withAlign(DecoAlignment.LEFT)
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"conditional_variable.enabled.tooltip");
+
+ editor.addComponent(new DecoSwitch(6, 18)
+ .withText(IIReference.DESCRIPTION_KEY+"conditional_variable.enabled")
+ .withCurrentState(conditionEnabled)
+ .withOnToggle(state -> {
+ conditionEnabled = state;
+ if(conditionDropdown!=null)
+ conditionDropdown.visible = conditionDropdown.enabled = state;
+ })
+ ).withSize(72, 12)
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"conditional_variable.enabled.tooltip");
+
+ editor.addComponent((conditionDropdown = new DecoDropdownDataLetters(width-26, 16-4))
+ .withConstraints(new DataPacket())
+ .withSelectedEntry((Character)(conditionEnabled?dataType.getRequiredVariable(): 'a'))
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"conditional_variable.tooltip")
+ .withTextColor(DecoColors.H1, IIColor.fromPackedRGB(0x35322c))
+ .withBackground(DecoTextures.COMPONENT_DROPDOWN_DATA_LETTER_PAPER)
+ .withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER)
+ );
+ conditionDropdown.withSize(18, 18);
+ conditionDropdown.visible = conditionDropdown.enabled = conditionEnabled;
+ }
+
+ private void initializeArgumentPage(DataOperationMeta meta, int argumentID)
+ {
+ Class extends DataType> expectedType = meta.allowedTypes()[argumentID];
+ DataType argument = getArgument(argumentID, expectedType);
+ boolean accessor = argument instanceof DataTypeAccessor;
+
+ this.editor = addComponent(new DecoPanel(0, 16))
+ .withSize(width, height-16)
+ .withBackground(null)
+ .withBackgroundMask(null);
+
+ TypeMetaInfo> accessorMeta = IIDataTypeUtils.metaTypesByClass.get(DataTypeAccessor.class);
+ TypeMetaInfo> expectedMeta = IIDataTypeUtils.metaTypesByClass.get(expectedType);
+
+ DecoPanel paperPanel;
+ editor.addComponents(
+ paperPanel = new DecoPanel(0, 0)
+ .withSize(width, 24)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_PAPER),
+ new DecoDropdown>(34, 3)
+ .withSize(width-34-22, 16)
+ .withDropdownWidth(width-16)
+ .withMaxDisplayedEntries(4)
+ .withScrollBarBackground(DecoTextures.COMPONENT_SLIDER_PAPER)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
+ .withListBackground(DecoTextures.COMPONENT_TEXT_FIELD)
+ .withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER)
+ .withEntries(accessorMeta, expectedMeta)
+ .withSelectedEntry(accessor?accessorMeta: expectedMeta)
+ .withDisplayFunction(DecoTemplates.getDataTypeEntryDisplay())
+ .withOnSelectedEntry((oldType, newType) -> {
+ storeCurrentPageOutput();
+ if(newType!=null&&newType.type==DataTypeAccessor.class)
+ setArgument(argumentID, new DataTypeAccessor(getCurrentAccessorVariable(argument)));
+ else
+ setArgument(argumentID, normalizeArgument(argument, expectedType));
+ refreshPage();
+ }),
+ new DecoButton(width-20, 3)
+ .withText("@")
+ .withSize(16, 16)
+ .withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"expression.accessor.tooltip")
+ .withOnLMBPressed(() -> {
+ storeCurrentPageOutput();
+ DataType current = getArgument(argumentID, expectedType);
+ if(current instanceof DataTypeAccessor)
+ setArgument(argumentID, normalizeArgument(current, expectedType));
+ else
+ setArgument(argumentID, new DataTypeAccessor('a'));
+ refreshPage();
+ })
+ );
+ paperPanel.addLabel(IIReference.DESCRIPTION_KEY+"variable_type", 4, 5)
+ .withSize(30, 16)
+ .withAlign(DecoAlignment.LEFT);
+
+ if(accessor)
+ initializeAccessorArgument(argument);
+ else
+ initializeLiteralArgument(argument, expectedType);
+ }
+
+ private void initializeAccessorArgument(DataType argument)
+ {
+ assert editor!=null;
+ editor.addLabel("datasystem.immersiveintelligence.datatype.accessor", 4, 30)
+ .withSize(60, 16)
+ .withAlign(DecoAlignment.LEFT);
+ editor.addComponent(
+ (argumentAccessorDropdown = new DecoDropdownDataLetters(64, 27))
+ .withConstraints(new DataPacket())
+ .withSelectedEntry((Character)getCurrentAccessorVariable(argument))
+ .withTranslatedTooltip(IIReference.DESCRIPTION_KEY+"expression.accessor.tooltip")
+ .withTextColor(IIColor.fromPackedRGB(0x161c26), IIColor.fromPackedRGB(0x35322c))
+ .withBackground(DecoTextures.COMPONENT_DROPDOWN_DATA_LETTER_PAPER)
+ .withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER)
+ );
+ argumentAccessorDropdown.withSize(18, 18);
+ }
+
+ private void initializeLiteralArgument(DataType argument, Class extends DataType> expectedType)
+ {
+ argumentEditor = DecoDataEditor.getEditorFor(argument, 4, 27);
+ assert editor!=null;
+ if(argumentEditor!=null)
+ editor.addComponent(argumentEditor)
+ .withSize(width-8, height-43);
+ else
+ editor.addLabel(IIReference.DESCRIPTION_KEY+"no_editor", 4, 30)
+ .withSize(width-8, 16)
+ .withAlign(DecoAlignment.LEFT)
+ .withTextColor(IIDataTypeUtils.metaTypesByClass.get(expectedType).color.withBrightness(0.4f));
}
+ //--- Utils ---//
+
private boolean setPage(int page)
{
if(page==this.page)
return false;
+ storeCurrentPageOutput();
this.page = page;
- this.initialized = false;
+ refreshPage();
return true;
}
+ private void refreshPage()
+ {
+ this.argumentEditor = null;
+ this.argumentAccessorDropdown = null;
+ this.conditionDropdown = null;
+ this.initialized = false;
+ }
+
+ private void storeCurrentPageOutput()
+ {
+ if(page==0)
+ {
+ if(conditionDropdown!=null)
+ {
+ Character selected = conditionDropdown.getSelectedEntry();
+ dataType.setRequiredVariable(conditionEnabled?(selected==null?'a': selected): ' ');
+ }
+ else if(!conditionEnabled)
+ dataType.setRequiredVariable(' ');
+ return;
+ }
+
+ int argumentID = page-1;
+ if(dataType.data==null||argumentID < 0||argumentID >= dataType.data.length)
+ return;
+
+ DataType current = dataType.data[argumentID];
+ if(current instanceof DataTypeAccessor)
+ {
+ Character selected = argumentAccessorDropdown==null?null: argumentAccessorDropdown.getSelectedEntry();
+ setArgument(argumentID, new DataTypeAccessor(selected==null?'a': selected));
+ }
+ else if(argumentEditor!=null)
+ setArgument(argumentID, argumentEditor.outputType());
+ }
+
+ private void ensureArgumentArray(DataOperationMeta meta)
+ {
+ if(dataType.data==null||dataType.data.length!=meta.allowedTypes().length)
+ dataType.setOperation(dataType.getOperation());
+ }
+
+ private DataType getArgument(int index, Class extends DataType> expectedType)
+ {
+ ensureArgumentArray(dataType.getMeta());
+ if(index < 0||index >= dataType.data.length)
+ return IIDataTypeUtils.getVarInstance(expectedType);
+ DataType argument = dataType.data[index];
+ if(argument instanceof DataTypeAccessor)
+ return argument;
+ return normalizeArgument(argument, expectedType);
+ }
+
+ private DataType normalizeArgument(@Nullable DataType argument, Class extends DataType> expectedType)
+ {
+ if(argument!=null&&expectedType.isAssignableFrom(argument.getClass()))
+ return argument.clone();
+ return IIDataTypeUtils.getVarInstance(expectedType);
+ }
+
+ private void setArgument(int index, DataType value)
+ {
+ if(dataType.data==null||index < 0||index >= dataType.data.length)
+ return;
+ dataType.data[index] = value;
+ }
+
+ private char getCurrentAccessorVariable(DataType argument)
+ {
+ return argument instanceof DataTypeAccessor?((DataTypeAccessor)argument).variable: 'a';
+ }
+
@Override
public DataTypeExpression outputType()
{
+ storeCurrentPageOutput();
return dataType;
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoPanel.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoPanel.java
index af53cd5a0..a4aa203df 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoPanel.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoPanel.java
@@ -1,13 +1,12 @@
package pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel;
import blusunrize.immersiveengineering.client.ClientUtils;
-import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
-import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.I18n;
+import net.minecraft.inventory.Container;
import org.lwjgl.opengl.GL11;
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui;
@@ -20,7 +19,6 @@
import pl.pabilo8.immersiveintelligence.client.util.IIDrawUtils;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
-import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIBase;
import javax.annotation.Nullable;
import java.util.ArrayList;
@@ -50,7 +48,7 @@ public DecoPanel(int x, int y)
}
@Override
- public > void setParentGUI(DecoGui parent)
+ public void setParentGUI(DecoGui parent)
{
super.setParentGUI(parent);
for(DecoLabel label : labels)
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoTaskJobList.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoTaskList.java
similarity index 77%
rename from src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoTaskJobList.java
rename to src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoTaskList.java
index db60e4e11..e1317ede1 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoTaskJobList.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/panel/DecoTaskList.java
@@ -22,9 +22,9 @@
import static pl.pabilo8.immersiveintelligence.common.util.IIReference.GUI_LABEL_KEY;
/**
- * Generic "task/job editor list" component:
+ * Generic "request/job editor list" component:
*
- * - mode tabs (Tasks/Jobs)
+ * - mode tabs (Requests/Jobs)
* - scrolled list
* - add/remove/duplicate/clear buttons
*
@@ -33,20 +33,20 @@
* @ii-approved 0.3.1
* @implSpec Callers must provide:
* - entries (full list)
- * - predicate telling whether entry is a "job"
+ * - predicate telling whether entry is a "job"; non-job entries are shown as requests
* - entry renderer + click callback
* - button actions (usually implemented by the GUI owning the data)
*
* @since 08.02.2026
*/
-public class DecoTaskJobList> extends DecoPanel
+public class DecoTaskList> extends DecoPanel
{
private static final int TAB_H = 18;
private static final int BTN_W = 25, BTN_H = 14, BTN_GAP = 1;
private static final int LIST_Y_OFF = 8+TAB_H-4;
private int listWidth, listHeight;
- private ListMode mode = ListMode.TASKS;
+ private ListMode mode = ListMode.JOBS;
private EasyCollection allEntries;
private Predicate isJobPredicate = t -> false;
private DecoList list;
@@ -66,7 +66,7 @@ public class DecoTaskJobList> extends
@Nullable
private Consumer onSelectedChanged;
- public DecoTaskJobList(int x, int y)
+ public DecoTaskList(int x, int y)
{
super(x, y);
withBackground(null);
@@ -76,29 +76,29 @@ public DecoTaskJobList(int x, int y)
//--- Setters ---//
@Override
- public DecoTaskJobList withSize(int width, int height)
+ public DecoTaskList withSize(int width, int height)
{
this.listWidth = width;
this.listHeight = height;
//noinspection unchecked
- return (DecoTaskJobList)super.withSize(listWidth, LIST_Y_OFF+listHeight+4+BTN_H+4);
+ return (DecoTaskList)super.withSize(listWidth, LIST_Y_OFF+listHeight+4+BTN_H+4);
}
- public DecoTaskJobList withEntries(EasyCollection entries)
+ public DecoTaskList withEntries(EasyCollection entries)
{
this.allEntries = entries;
refreshListEntries();
return this;
}
- public DecoTaskJobList withIsJobPredicate(Predicate predicate)
+ public DecoTaskList withIsJobPredicate(Predicate predicate)
{
this.isJobPredicate = predicate!=null?predicate: (t -> false);
refreshListEntries();
return this;
}
- public DecoTaskJobList withDisplayFunction(DecoEntryPanelBuilder builder)
+ public DecoTaskList withDisplayFunction(DecoEntryPanelBuilder builder)
{
this.displayFunction = builder;
if(list!=null)
@@ -106,9 +106,9 @@ public DecoTaskJobList withDisplayFunction(DecoEntryPanelBuilder builder)
return this;
}
- public DecoTaskJobList withModeHandling(@Nullable ListMode initialMode, Consumer onModeChanged)
+ public DecoTaskList withModeHandling(@Nullable ListMode initialMode, Consumer onModeChanged)
{
- this.mode = mode==null?ListMode.TASKS: mode;
+ this.mode = normalizeMode(initialMode);
this.onModeChanged = onModeChanged;
return this;
}
@@ -116,7 +116,7 @@ public DecoTaskJobList withModeHandling(@Nullable ListMode initialMode, Consu
/**
* Fired whenever selection changes (including becoming null due to filtering/mode change).
*/
- public DecoTaskJobList withOnSelectedChanged(@Nullable Consumer onSelectedChanged)
+ public DecoTaskList withOnSelectedChanged(@Nullable Consumer onSelectedChanged)
{
this.onSelectedChanged = onSelectedChanged;
return this;
@@ -125,7 +125,7 @@ public DecoTaskJobList withOnSelectedChanged(@Nullable Consumer onSelected
/**
* Supplies a new blank task for the Add button.
*/
- public DecoTaskJobList withBlankTaskSupplier(@Nullable Supplier blankTaskSupplier)
+ public DecoTaskList withBlankTaskSupplier(@Nullable Supplier blankTaskSupplier)
{
this.blankTaskSupplier = blankTaskSupplier;
return this;
@@ -134,7 +134,7 @@ public DecoTaskJobList withBlankTaskSupplier(@Nullable Supplier blankTaskS
/**
* For GUIs that only have a single list type but still want standardized list + buttons.
*/
- public DecoTaskJobList withShowJobsTab(boolean showJobsTab)
+ public DecoTaskList withShowJobsTab(boolean showJobsTab)
{
this.showJobsTab = showJobsTab;
return this;
@@ -147,12 +147,17 @@ public ListMode getMode()
public void setMode(ListMode mode)
{
- this.mode = mode==null?ListMode.TASKS: mode;
+ this.mode = normalizeMode(mode);
if(onModeChanged!=null)
onModeChanged.accept(this.mode);
refreshListEntries();
}
+ private static ListMode normalizeMode(@Nullable ListMode mode)
+ {
+ return mode==null||mode==ListMode.TASKS?ListMode.REQUESTS: mode;
+ }
+
@Nullable
public T getSelected()
{
@@ -160,7 +165,7 @@ public T getSelected()
}
/**
- * @return entries visible in the current tab (after applying TASKS/JOBS filter).
+ * @return entries visible in the current tab (after applying REQUESTS/JOBS filter).
*/
public List getFilteredEntries()
{
@@ -181,7 +186,7 @@ private void refreshListEntries()
//Drop selection if it moved out of current view
if(selected!=null&&((mode==ListMode.JOBS)!=isJobPredicate.test(selected)))
- setSelected(selected);
+ setSelected(null);
}
@Override
@@ -191,29 +196,30 @@ protected boolean initialize()
return false;
//Mode tabs
- DecoButton tabTasks = new DecoButton(0, 4)
- .withSize(listWidth/2, TAB_H)
- .withBackground(DecoTextures.COMPONENT_TAB_VERTICAL)
- .withText(GUI_LABEL_KEY+"task_editor.tasks")
- .withTranslatedTooltip(GUI_LABEL_KEY+"task_editor.tasks.tooltip")
- .withOnLMBPressed(() -> setMode(ListMode.TASKS));
-
- DecoButton tabJobs = new DecoButton(listWidth/2, 4)
+ DecoButton tabJobs = new DecoButton(0, 4)
.withSize(listWidth/2, TAB_H)
.withBackground(DecoTextures.COMPONENT_TAB_VERTICAL)
.withText(GUI_LABEL_KEY+"task_editor.jobs")
.withTranslatedTooltip(GUI_LABEL_KEY+"task_editor.jobs.tooltip")
.withOnLMBPressed(() -> setMode(ListMode.JOBS));
- addComponent(tabTasks);
+ DecoButton tabRequests = new DecoButton(listWidth/2, 4)
+ .withSize(listWidth/2, TAB_H)
+ .withBackground(DecoTextures.COMPONENT_TAB_VERTICAL)
+ .withText(GUI_LABEL_KEY+"task_editor.requests")
+ .withTranslatedTooltip(GUI_LABEL_KEY+"task_editor.requests.tooltip")
+ .withOnLMBPressed(() -> setMode(ListMode.REQUESTS));
+
addComponent(tabJobs);
+ addComponent(tabRequests);
if(!showJobsTab)
{
- //stretch tasks tab; hide jobs tab
- tabTasks.withSize(listWidth, TAB_H);
+ //stretch requests tab; hide jobs tab
+ tabRequests.withSize(listWidth, TAB_H);
+ tabRequests.x = tabJobs.x;
tabJobs.visible = tabJobs.enabled = false;
- this.mode = ListMode.TASKS;
+ this.mode = ListMode.REQUESTS;
}
//List
@@ -292,7 +298,7 @@ private void onDuplicatePressed()
//Create a new blank task and copy data from selected into it.
T created = allEntries.copyEntry(selected);
//Ensure duplicate is visible in current mode, otherwise switch mode to match it
- setMode(isJobPredicate.test(created)?ListMode.JOBS: ListMode.TASKS);
+ setMode(isJobPredicate.test(created)?ListMode.JOBS: ListMode.REQUESTS);
refreshListEntries();
}
@@ -302,7 +308,7 @@ private void onClearPressed()
if(allEntries==null)
return;
//Clear only current mode
- allEntries.removeIf(t -> isJobPredicate.test(t)^this.mode!=ListMode.JOBS);
+ allEntries.removeIf(t -> isJobPredicate.test(t)!=(this.mode==ListMode.JOBS));
selected = null;
refreshListEntries();
}
@@ -318,7 +324,12 @@ private void setSelected(@Nullable T selected)
public enum ListMode implements ISerializableEnum
{
- TASKS,
- JOBS
+ REQUESTS,
+ JOBS,
+ /**
+ * @deprecated Use REQUESTS. Kept only so older GUI-sync data and external references do not hard-fail.
+ */
+ @Deprecated
+ TASKS
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackDisplay.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackDisplay.java
index 6237e7f2b..907817ca5 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackDisplay.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackDisplay.java
@@ -11,6 +11,7 @@
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoAlignment;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoColors;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoSprite;
import pl.pabilo8.immersiveintelligence.client.util.IIDrawUtils;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
@@ -23,6 +24,7 @@
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
+import java.util.function.Supplier;
/**
* Displays an item stack inside a Deco GUI.
@@ -43,7 +45,8 @@ public class DecoItemStackDisplay extends DecoComponent
private DecoSprite backgroundSprite;
private Function progressBarValue;
- private IIColor barGradientColor1 = IIColor.fromPackedRGB(0xb51500), barGradientColor2 = IIColor.fromPackedRGB(0x600b00);
+ private Supplier barGradientColorSupplier =
+ () -> new IIColor[]{DecoColors.GRADIENT1, DecoColors.GRADIENT2};
private DecoAlignment iconAlignment = DecoAlignment.CENTER;
private int iconSize = 16;
private int cachedIconX, cachedIconY;
@@ -74,10 +77,15 @@ public DecoItemStackDisplay withStack(IngredientStack stack)
}
public DecoItemStackDisplay withProgressBar(Function progressBarValue, IIColor barGradientColor1, IIColor barGradientColor2)
+ {
+ final IIColor[] array = new IIColor[]{barGradientColor1, barGradientColor2};
+ return withProgressBar(progressBarValue, () -> array);
+ }
+
+ public DecoItemStackDisplay withProgressBar(Function progressBarValue, Supplier barGradientColorSupplier)
{
this.progressBarValue = progressBarValue;
- this.barGradientColor1 = barGradientColor1;
- this.barGradientColor2 = barGradientColor2;
+ this.barGradientColorSupplier = barGradientColorSupplier;
return this;
}
@@ -174,14 +182,17 @@ protected void draw(int mouseX, int mouseY, float partialTicks)
}
if(progressBarValue!=null)
{
+ GlStateManager.disableTexture2D();
float progress = MathHelper.clamp(progressBarValue.apply(partialTicks), 0, 1);
+ IIColor[] colors = barGradientColorSupplier.get();
IIDrawUtils.startColored()
.drawColorGradient(
x+width+padding[0]-padding[2]+2, y-padding[1]+padding[3]+height-((height+padding[1]+padding[3]-4)*progress),
2, ((height+padding[1]+padding[3]-4)*progress),
- barGradientColor1, barGradientColor2
+ colors[0], colors.length > 1?colors[1]: colors[0]
)
.finish();
+ GlStateManager.enableTexture2D();
}
GlStateManager.translate(cachedIconX, cachedIconY, 0);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackListDisplay.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackListDisplay.java
deleted file mode 100644
index d2690c9a6..000000000
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/storage/DecoItemStackListDisplay.java
+++ /dev/null
@@ -1,259 +0,0 @@
-package pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage;
-
-import blusunrize.immersiveengineering.client.ClientUtils;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.RenderHelper;
-import net.minecraft.client.util.ITooltipFlag.TooltipFlags;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.util.text.TextFormatting;
-import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent;
-import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoAlignment;
-import pl.pabilo8.immersiveintelligence.client.util.IIDrawUtils;
-import pl.pabilo8.immersiveintelligence.common.util.IIColor;
-
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Supplier;
-
-/**
- * Displays a whole list of item stacks inside a Deco GUI as a grid.
- *
- * @author Pabilo8 (pabilo@iiteam.net)
- * @ii-approved 0.3.1
- * @since 08.01.2026
- */
-@ParametersAreNonnullByDefault
-public class DecoItemStackListDisplay extends DecoComponent
-{
- private Supplier> stacksSupplier = Collections::emptyList;
-
- protected int[] padding = new int[]{2, 2, 2, 2};
- private ResourceLocation backgroundTexture;
-
- private DecoAlignment contentAlignment = DecoAlignment.CENTER;
-
- private int slotSize = 16;
- private int forcedSlotsPerRow = -1;
-
- private int cachedContentX, cachedContentY;
- private int cachedSlotsPerRow = 1;
- private int cachedRows = 1;
- private int cachedContentW = 0, cachedContentH = 0;
- private int lastMouseX, lastMouseY;
-
- private TooltipFlags tooltipFlag;
-
- public DecoItemStackListDisplay(int x, int y)
- {
- super(x, y);
- withForcedAdvancedTooltip(false);
- withOnTooltip(this::onDisplayTooltip);
- }
-
- public DecoItemStackListDisplay withStacks(List stacks)
- {
- this.stacksSupplier = () -> stacks;
- this.initialized = false;
- return this;
- }
-
- public DecoItemStackListDisplay withStacks(Supplier> stacksSupplier)
- {
- this.stacksSupplier = stacksSupplier;
- this.initialized = false;
- return this;
- }
-
- public DecoItemStackListDisplay withBackgroundTexture(@Nullable ResourceLocation backgroundTexture)
- {
- this.backgroundTexture = backgroundTexture;
- return this;
- }
-
- public DecoItemStackListDisplay withPadding(int[] padding)
- {
- this.padding = padding;
- this.initialized = false;
- return this;
- }
-
- public DecoItemStackListDisplay withContentAlignment(DecoAlignment alignment)
- {
- this.contentAlignment = alignment;
- this.initialized = false;
- return this;
- }
-
- public DecoItemStackListDisplay withSlotSize(int slotSize)
- {
- this.slotSize = MathHelper.clamp(slotSize, 8, 32);
- this.initialized = false;
- return this;
- }
-
- /**
- * Set to -1 to auto-compute.
- */
- public DecoItemStackListDisplay withForcedSlotsPerRow(int forcedSlotsPerRow)
- {
- this.forcedSlotsPerRow = forcedSlotsPerRow;
- this.initialized = false;
- return this;
- }
-
- public DecoItemStackListDisplay withForcedAdvancedTooltip(boolean forcedAdvancedTooltip)
- {
- this.tooltipFlag = forcedAdvancedTooltip||ClientUtils.mc().gameSettings.advancedItemTooltips?
- TooltipFlags.ADVANCED: TooltipFlags.NORMAL;
- this.initialized = false;
- return this;
- }
-
- @Override
- protected boolean initialize()
- {
- int xPad = padding[0]+padding[2];
- int yPad = padding[1]+padding[3];
-
- int contentBoxW = Math.max(0, width-xPad);
- int contentBoxH = Math.max(0, height-yPad);
-
- int computed = contentBoxW/slotSize;
- if(forcedSlotsPerRow > 0)
- cachedSlotsPerRow = forcedSlotsPerRow;
- else
- cachedSlotsPerRow = Math.max(1, computed);
-
- // Derive rows from current stack count (0 -> 1 row, renders nothing but alignment stays stable)
- int count = Math.max(0, getStacks().size());
- cachedRows = Math.max(1, (int)Math.ceil(count/(double)cachedSlotsPerRow));
-
- // Actual grid size (may exceed box vertically; caller can size component accordingly)
- cachedContentW = cachedSlotsPerRow*slotSize;
- cachedContentH = cachedRows*slotSize;
-
- cachedContentX = contentAlignment.getAlignX(x+padding[0], width, cachedContentW);
- cachedContentY = contentAlignment.getAlignY(y+padding[1], height, cachedContentH);
-
- return true;
- }
-
- private List getStacks()
- {
- List s = stacksSupplier.get();
- return s==null?Collections.emptyList(): s;
- }
-
- private int getHoveredIndex(int mouseX, int mouseY)
- {
- if(mouseX < cachedContentX||mouseY < cachedContentY)
- return -1;
-
- int localX = mouseX-cachedContentX;
- int localY = mouseY-cachedContentY;
-
- int col = localX/slotSize;
- int row = localY/slotSize;
-
- if(col < 0||row < 0||col >= cachedSlotsPerRow||row >= cachedRows)
- return -1;
-
- int idx = row*cachedSlotsPerRow+col;
- return idx;
- }
-
- private ItemStack getStackAt(int index)
- {
- List stacks = getStacks();
- if(index < 0||index >= stacks.size())
- return ItemStack.EMPTY;
- return stacks.get(index);
- }
-
- private List onDisplayTooltip(DecoItemStackListDisplay gui)
- {
- int hovered = getHoveredIndex(gui.lastMouseX, gui.lastMouseY);
- ItemStack stack = getStackAt(hovered);
- if(stack.isEmpty())
- return Collections.emptyList();
-
- List tooltip = stack.getTooltip(ClientUtils.mc().player, tooltipFlag);
- for(int i = 1; i < tooltip.size(); i++)
- tooltip.set(i, TextFormatting.GRAY+tooltip.get(i));
- return tooltip;
- }
-
- @Override
- protected void draw(int mouseX, int mouseY, float partialTicks)
- {
- GlStateManager.pushMatrix();
-
- this.lastMouseX = mouseX;
- this.lastMouseY = mouseY;
- if(backgroundTexture!=null)
- {
- bindAtlas();
- IIDrawUtils.startTexturedColored()
- .drawConnectedTexColorRect(x-padding[0], y-padding[1], width, height, IIColor.WHITE, backgroundTexture, 32, 32, 8, 8)
- .finish();
- }
-
- List stacks = getStacks();
- if(!stacks.isEmpty())
- {
- GlStateManager.enableDepth();
- GlStateManager.enableRescaleNormal();
- GlStateManager.color(1.0F, 1.0F, 1.0F);
- RenderHelper.enableGUIStandardItemLighting();
-
- for(int i = 0; i < stacks.size(); i++)
- {
- int col = i%cachedSlotsPerRow;
- int row = i/cachedSlotsPerRow;
-
- int px = cachedContentX+col*slotSize;
- int py = cachedContentY+row*slotSize;
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(px, py, 0);
-
- // Render in a "slotSize x slotSize" square by scaling vanilla 16x16 item render
- float scale = 16f/(float)slotSize;
- GlStateManager.scale(1f/scale, 1f/scale, 1f);
-
- ItemStack stack = stacks.get(i);
- ClientUtils.mc().getRenderItem().renderItemAndEffectIntoGUI(stack, 0, 0);
- ClientUtils.mc().getRenderItem().renderItemOverlayIntoGUI(IIClientUtils.fontRegular, stack, 0, 0, null);
-
- GlStateManager.popMatrix();
- }
-
- RenderHelper.disableStandardItemLighting();
- GlStateManager.disableRescaleNormal();
- GlStateManager.disableDepth();
- }
-
- GlStateManager.popMatrix();
- }
-
- @Override
- public void cleanup()
- {
-
- }
-
- @Nullable
- @Override
- public Object getProvidedIngredient()
- {
- int hovered = getHoveredIndex(this.lastMouseX, this.lastMouseY);
- ItemStack stack = getStackAt(hovered);
- return stack.isEmpty()?null: stack;
- }
-}
-
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoManualWidget.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoManualWidget.java
index 5201967a6..94fbcbab4 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoManualWidget.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoManualWidget.java
@@ -150,4 +150,15 @@ public DecoTab provideTab()
.withTranslatedTooltip(IIReference.GUI_TOOLTIP_KEY+"widget.manual.show");
}
+ public void setCurrentPage(String page)
+ {
+ setCurrentPage(page, 0);
+ }
+
+ public void setCurrentPage(String page, int index)
+ {
+ wrapper.setSelectedEntry(page);
+ wrapper.page = index;
+ }
+
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoStyleWidget.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoStyleWidget.java
index ba0592c0a..40c02db62 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoStyleWidget.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/component/widget/DecoStyleWidget.java
@@ -2,15 +2,19 @@
import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
import net.minecraft.client.resources.I18n;
+import net.minecraft.entity.Entity;
import net.minecraft.util.text.TextFormatting;
import pl.pabilo8.immersiveintelligence.api.style.IStyleCustomizable;
+import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints.PaintStyleConstraint;
import pl.pabilo8.immersiveintelligence.api.style.StyleCustomization;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoColorPicker;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoTab;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoDropdown;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoAlignment;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
+import pl.pabilo8.immersiveintelligence.common.network.messages.MessageEntityNBTSync;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageIITileSync;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
@@ -23,14 +27,14 @@
*/
public class DecoStyleWidget extends DecoComponentWidgetBase
{
- private final IStyleCustomizable tile;
+ private final IStyleCustomizable customizable;
private final StyleCustomization style;
- public DecoStyleWidget(IStyleCustomizable tile)
+ public DecoStyleWidget(IStyleCustomizable customizable)
{
super();
- this.tile = tile;
- this.style = tile.getStyle();
+ this.customizable = customizable;
+ this.style = customizable.getStyle();
withSize(128, 128+32);
withBackground(DecoTextures.BG_PAPER);
withBackgroundMask(DecoTextures.TEMPLATE_PAPER);
@@ -57,12 +61,35 @@ protected boolean initialize()
.withBackground(DecoTextures.COMPONENT_BUTTON_PAPER)
.withDropdownSymbol(DecoTextures.COMPONENT_DROPDOWN_SYMBOL_PAPER)
.withOnSelectedEntry((oldStyle, newStyle) -> {
- tile.getStyle().withStyle(newStyle);
- IIPacketHandler.sendToServer(new MessageIITileSync((TileEntityIEBase)tile, EasyNBT.newNBT()
- .withTag("style", tile.getStyle().serializeNBT()).unwrap()
- ));
+ customizable.getStyle().withStyle(newStyle);
+ //Notify the server side of the new style
+ if(customizable instanceof TileEntityIEBase)
+ IIPacketHandler.sendToServer(new MessageIITileSync((TileEntityIEBase)customizable, EasyNBT.newNBT()
+ .withTag("style", customizable.getStyle().serializeNBT()).unwrap()
+ ));
+ else if(customizable instanceof Entity)
+ IIPacketHandler.sendToServer(new MessageEntityNBTSync((Entity)customizable, EasyNBT.newNBT()
+ .withTag("style", customizable.getStyle().serializeNBT()).unwrap()
+ ));
})
);
+ if(style.getConstraints().getColorCustomization()!=PaintStyleConstraint.NOT_APPLICABLE)
+ addComponent(new DecoColorPicker(32, 10+16+headInfo.getTotalHeight())
+ .withWidth(width-32-4)
+ .withColor(style.getColor())
+ .withOnColorChanged(newColor -> {
+ customizable.getStyle().withColor(newColor);
+ //Notify the server side of the new color
+ if(customizable instanceof TileEntityIEBase)
+ IIPacketHandler.sendToServer(new MessageIITileSync((TileEntityIEBase)customizable, EasyNBT.newNBT()
+ .withTag("style", customizable.getStyle().serializeNBT()).unwrap()
+ ));
+ else if(customizable instanceof Entity)
+ IIPacketHandler.sendToServer(new MessageEntityNBTSync((Entity)customizable, EasyNBT.newNBT()
+ .withTag("style", customizable.getStyle().serializeNBT()).unwrap()
+ ));
+ })
+ );
return true;
}
return false;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/tree/upgrade/UpgradeTreeNodeRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/tree/upgrade/UpgradeTreeNodeRenderer.java
index 5bd67492a..57a2169c2 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/tree/upgrade/UpgradeTreeNodeRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/tree/upgrade/UpgradeTreeNodeRenderer.java
@@ -73,6 +73,12 @@ public Collection getTooltip(@Nonnull IDecoTreeNode node)
List tooltip = new ArrayList<>();
tooltip.add(upgrade.getLocalizedName());
+ if(upgrade.isWorkInProgress())
+ {
+ tooltip.add(IIColor.MC_YELLOW.getHexCol(I18n.format("ie.manual.entry.wip_warning0")));
+ tooltip.add(IIColor.MC_YELLOW.getHexCol(I18n.format("ie.manual.entry.wip_warning.upgrade")));
+ }
+
List description = IIClientUtils.fontRegular.listFormattedStringToWidth(
I18n.format(String.format("machineupgrade.%s.%s.desc",
upgrade.getId().getResourceDomain(),
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoBackgroundBuilder.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoBackgroundBuilder.java
index 5a094bdc1..cf3f54a13 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoBackgroundBuilder.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoBackgroundBuilder.java
@@ -2,13 +2,14 @@
import blusunrize.immersiveengineering.client.ClientUtils;
import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
-import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.I18n;
+import net.minecraft.entity.Entity;
+import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
@@ -23,7 +24,6 @@
import pl.pabilo8.immersiveintelligence.client.util.IIDrawUtils;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
-import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIBase;
import javax.annotation.Nonnull;
import java.util.ArrayList;
@@ -38,7 +38,7 @@
* @ii-approved 0.3.1
* @since 07.01.2025
**/
-public class DecoBackgroundBuilder>
+public class DecoBackgroundBuilder
{
private final List> backgroundTiles = new ArrayList<>();
private final List backgroundFrames = new ArrayList<>();
@@ -241,23 +241,34 @@ public DecoBackgroundBuilder withTitleBar(String title)
/**
* Adds a title bar component to the GUI
*
- * @param tile tile to get the title from
+ * @param type type to get the title from
*/
- public DecoBackgroundBuilder withTitleBar(T tile)
+ public DecoBackgroundBuilder withTitleBar(T type)
{
- ITextComponent displayName = tile.getDisplayName();
- if(displayName==null&&tile.hasWorld())
+ ITextComponent displayName = null;
+ if(type instanceof TileEntityIEBase)
{
- World world = tile.getWorld();
- BlockPos pos = tile.getPos();
- if(world.isBlockLoaded(pos))
+ TileEntityIEBase tile = (TileEntityIEBase)type;
+ displayName = tile.getDisplayName();
+ if(displayName==null&&tile.hasWorld())
{
- IBlockState state = world.getBlockState(tile.getPos());
- displayName = new TextComponentString(new ItemStack(state.getBlock(), 1, state.getBlock().getMetaFromState(state)).getDisplayName());
+ World world = tile.getWorld();
+ BlockPos pos = tile.getPos();
+ if(world.isBlockLoaded(pos))
+ {
+ IBlockState state = world.getBlockState(tile.getPos());
+ displayName = new TextComponentString(new ItemStack(state.getBlock(), 1, state.getBlock().getMetaFromState(state)).getDisplayName());
+ }
}
-
}
- return withTitleBar(displayName.getUnformattedText(), DecoAlignment.TOP);
+ else if(type instanceof ItemStack)
+ displayName = new TextComponentString(((ItemStack)type).getDisplayName());
+ else if(type instanceof Entity)
+ displayName = ((Entity)type).getDisplayName();
+
+ if(displayName!=null)
+ return withTitleBar(displayName.getUnformattedText(), DecoAlignment.TOP);
+ return this;
}
/**
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoColors.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoColors.java
index a1e5480b3..ba7541ebb 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoColors.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoColors.java
@@ -38,4 +38,7 @@ public class DecoColors
public static final IIColor REACTIVE_ARMOR_INTEGRITY_2 = IIColor.fromPackedRGB(0x30383b);
public static final IIColor STRUCTURAL_INTEGRITY_1 = IIColor.fromPackedRGB(0x79675a);
public static final IIColor STRUCTURAL_INTEGRITY_2 = IIColor.fromPackedRGB(0x4a3035);
+
+ public static final IIColor GRADIENT1 = IIColor.fromPackedRGB(0xb51500);
+ public static final IIColor GRADIENT2 = IIColor.fromPackedRGB(0x600b00);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoGuiCategory.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoGuiCategory.java
index 4ad7e46b0..210595821 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoGuiCategory.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoGuiCategory.java
@@ -12,7 +12,9 @@ public enum DecoGuiCategory
{
GENERIC_TILE,
GENERIC_ITEM,
+ GENERIC_ENTITY,
PRODUCTION_TILE,
TERRITORY_CONTROL_TILE,
- DATA_TILE
+ DATA_TILE,
+ VEHICLE_ENTITY
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTemplates.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTemplates.java
index 7afac319f..68fed6684 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTemplates.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTemplates.java
@@ -5,6 +5,7 @@
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
+import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType.TypeMetaInfo;
import pl.pabilo8.immersiveintelligence.api.rotary.IRotaryEnergy;
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.DecoComponent.DecoComponentTemplate;
@@ -165,4 +166,30 @@ public class DecoTemplates
})
);
+ public static DecoEntryPanelBuilder> getDataTypeEntryDisplay()
+ {
+ return new DecoEntryPanelBuilder>()
+ .withHeight(18)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
+ //Type Icon, Label, and Letter
+ .withComponent("image", new DecoImage(3, 1)
+ .withSize(16, 16))
+ .withLabel("typeLabel",
+ new DecoLabel(IIClientUtils.fontRegular, 20, 1)
+ .withSize(48, 18)
+ .withAlign(DecoAlignment.LEFT)
+ .withText("Integer")
+ )
+ .withElementApplyMethod((typeMeta, panel) -> {
+ //type label (f.e. integer)
+ panel.label("typeLabel")
+ .withText(typeMeta.getTranslatedName())
+ .withTextColor(typeMeta.color.withBrightness(0.4f));
+ //type icon
+ panel.component("image", DecoImage.class)
+ .withImageLocation(typeMeta.getTextureLocation(), true);
+ })
+ .withElementTooltip(typeMeta -> "a");
+ }
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTextures.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTextures.java
index ce1429394..b8bb74bff 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTextures.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/deco/util/DecoTextures.java
@@ -129,8 +129,11 @@ public class DecoTextures
public static final ResLoc ICON_ENERGY_OUTPUT = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_energy_output");
public static final ResLoc ICON_ENERGY_INPUT = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_energy_input");
public static final ResLoc ICON_ENERGY = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_energy");
- public static final ResLoc ICON_CONTACT = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_contact");
- public static final ResLoc ICON_PROXIMITY = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_proximity");
+
+ //--- Ammo Icons ---//
+ public static final ResLoc ICON_CONTACT = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_fuse_contact");
+ public static final ResLoc ICON_TIMED = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_fuse_timed");
+ public static final ResLoc ICON_PROXIMITY = ResLoc.of(RES_TEXTURES_DECO_ICON, "icon_fuse_proximity");
//--- Deco Bar Icons ---//
public static final ResLoc ICON_ACTION_DUPLICATE = ResLoc.of(RES_TEXTURES_DECO_ICON, "action_duplicate");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/entity/GuiEntityUpgrade.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/entity/GuiEntityUpgrade.java
new file mode 100644
index 000000000..2d67789e2
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/entity/GuiEntityUpgrade.java
@@ -0,0 +1,256 @@
+package pl.pabilo8.immersiveintelligence.client.gui.entity;
+
+import blusunrize.immersiveengineering.api.crafting.IngredientStack;
+import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.client.resources.I18n;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.util.text.TextFormatting;
+import pl.pabilo8.immersiveintelligence.api.upgrade.IUpgradableDevice;
+import pl.pabilo8.immersiveintelligence.api.upgrade.Upgrade;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradeOperation;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoEntityGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.button.DecoButton;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.collection.DecoTreeDisplay;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.label.DecoLabel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoBar;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoScenarioDisplay;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.visual.DecoImage;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.tree.IDecoTreeNode;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.tree.upgrade.UpgradeTechTreeWrapper;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.tree.upgrade.UpgradeTreeNodeRenderer;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.*;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTModel;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerEntityUpgrade;
+import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
+import pl.pabilo8.immersiveintelligence.common.network.messages.MessageBeginMachineUpgrade;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.SyncNBT;
+
+import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Pabilo8 (pabilo@iiteam.net)
+ * @since 10.07.2019
+ */
+@DecoTemplate(name = "upgrade_tile", category = DecoGuiCategory.GENERIC_ENTITY)
+public class GuiEntityUpgrade extends DecoEntityGui>
+{
+ private final UpgradeTechTree techTree;
+ private DecoTreeDisplay techTreeDisplay;
+ private DecoPanel panelInfo;
+
+ @SyncNBT(nullable = true)
+ public String lastUpgrade;
+ private DecoScenarioDisplay scenario;
+
+ public GuiEntityUpgrade(EntityPlayer player, T tile)
+ {
+ super(player, tile, IIGUI.UPGRADE_ENTITY);
+ this.techTree = tile!=null?UpgradeTechTree.getTreeFor(tile): null;
+ }
+
+ @Override
+ public void onInit()
+ {
+ ResLoc style = DecoTextures.BG_STEEL;
+ switch(entity.getUpgradableMachineStyle())
+ {
+ case WOODEN:
+ style = DecoTextures.BG_WOODEN;
+ break;
+ case BRICKS:
+ style = DecoTextures.BG_BRICKS;
+ break;
+ case CONCRETE:
+ style = DecoTextures.BG_CONCRETE;
+ break;
+ case SANDBAGS:
+ style = DecoTextures.BG_SANDBAGS;
+ break;
+ case STEEL:
+ default:
+ break;
+ }
+
+ startBackground()
+ .withBox(style, 0, 0, 256, 152+8+8)
+ .withTitleBar("desc.immersiveintelligence.upgrade_gui.title")
+ .withNextLayer()
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 40, 136+24+8, 176, 92)
+ .withFrame(DecoTextures.FRAME_WOODEN_THIN, 4, false, new boolean[]{true, false, false, false})
+ .withInventorySlots(SlotStyle.VANILLA, container.inventorySlots)
+ .withInventoryTitleBar()
+ .build();
+
+ //Upgrade
+ addComponents(
+ new DecoPanel(4, 4+8)
+ .withSize(108, 152)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_SQUARE),
+ scenario = new DecoScenarioDisplay(4+2, 4+2+8)
+ .withSize(108-4, 96)
+ .withBackgroundColor(IIColor.BLACK.withAlpha(32))
+ .withScale(0.125f)
+ .withRotation(-12.5f, 5)
+ .withRotationAnimation(240, 0)
+ .withInteractionAllowed(true),
+ new DecoButton(118-4, 16-8-4+14-14+8)
+ .withSize(69, 14)
+ .withBackground(DecoTextures.COMPONENT_TAB_VERTICAL)
+ .withText(IIReference.DESCRIPTION_KEY+"upgrade_gui.tech_tree")
+ .withOnLMBPressed(() -> {
+ panelInfo.visible = panelInfo.enabled = false;
+ techTreeDisplay.visible = techTreeDisplay.enabled = true;
+ refreshModelPreview(null);
+ }),
+ new DecoButton(118-4+69, 16-8-4+14-14+8)
+ .withSize(69, 14)
+ .withBackground(DecoTextures.COMPONENT_TAB_VERTICAL)
+ .withText(IIReference.DESCRIPTION_KEY+"upgrade_gui.info")
+ .withOnLMBPressed(() -> {
+ panelInfo.visible = panelInfo.enabled = true;
+ techTreeDisplay.visible = techTreeDisplay.enabled = false;
+ if(lastUpgrade!=null&&!lastUpgrade.isEmpty())
+ refreshModelPreview(Upgrade.getUpgradeByID(ResLoc.of(lastUpgrade)));
+ }),
+ panelInfo = new DecoPanel(118-4, 16-8-4+14+8)
+ .withSize(146-8, 146-8)
+ .withBackground(DecoTextures.BG_STEEL)
+ .withBackgroundMask(DecoTextures.TEMPLATE_SQUARE),
+ techTreeDisplay = new DecoTreeDisplay(118-4, 16-8-4+14+8)
+ .withTree(new UpgradeTechTreeWrapper(techTree, entity)
+ {
+ @Override
+ public void onNodeClicked(@Nonnull IDecoTreeNode node)
+ {
+ panelInfo.visible = panelInfo.enabled = true;
+ techTreeDisplay.visible = techTreeDisplay.enabled = false;
+ showUpgrade(node.getUserData());
+ refreshModelPreview(node.getUserData());
+ }
+ })
+ .withNodeRenderer(new UpgradeTreeNodeRenderer())
+ .withSize(146-8, 146-8)
+ .withBackground(DecoSprite.atlasSprite(DecoTextures.BG_DARK, 64))
+ );
+
+ if(lastUpgrade==null)
+ {
+ showUpgrade(null);
+ refreshModelPreview(null);
+ }
+ else
+ {
+ Upgrade current = Upgrade.getUpgradeByID(ResLoc.of(lastUpgrade));
+ showUpgrade(current);
+ refreshModelPreview(current);
+ }
+ }
+
+ private void showUpgrade(Upgrade upgrade)
+ {
+ panelInfo.cleanup();
+ if(upgrade!=null)
+ {
+ //Name and descriptionm
+ panelInfo.addLabel(upgrade.getLocalizedName(), 2+20, 2)
+ .withSize(panelInfo.width-4-20, 20)
+ .withWrapping(true)
+ .withAlign(DecoAlignment.CENTER);
+ DecoLabel descLabel = panelInfo.addLabel(TextFormatting.ITALIC+I18n.format(String.format("machineupgrade.%s.%s.desc",
+ upgrade.getId().getResourceDomain(),
+ upgrade.getId().getResourcePath().replace("/", "."))),
+ 4, 22)
+ .withSize(panelInfo.width-8, 20)
+ .withWrapping(true)
+ .withAlign(DecoAlignment.TOP_LEFT);
+
+ //Icon
+ panelInfo.addComponent(new DecoImage(4, 4))
+ .withSize(16, 16)
+ .withImageLocation(upgrade.getIcon(), true);
+ //Required stacks
+ List requiredStacks = upgrade.getRequiredStacks();
+ for(int i = 0; i < requiredStacks.size(); i++)
+ {
+ panelInfo.addComponent(new DecoItemStackDisplay(2+(i%7*20), 22+2+descLabel.getTotalHeight()+(i/7)))
+ .withSize(18, 18)
+ .withStack(requiredStacks.get(i));
+ }
+
+ //Required energy
+ int energyRequired = (int)(upgrade.getProgressRequired()*0.75f);
+ panelInfo.addComponent(new DecoBar(4, 22+64+28-16))
+ .withTemplate(DecoTemplates.BAR_ELECTRIC_ENERGY_INPUT)
+ .withLimits(0, energyRequired, upgrade::getProgressRequired)
+ .withSize(panelInfo.width-4-4, 12)
+ .withHorizontalMode(true);
+
+ //Install button
+ final boolean shouldInstall = !entity.isUpgradeInstalled(upgrade);
+ final boolean canInstall = entity.addUpgrade(upgrade, UpgradeOperation.PROBE);
+ DecoButton button = panelInfo.addComponent(new DecoButton(4, 22+64+28))
+ .withWidth(panelInfo.width-8)
+ .withText(IIReference.DESCRIPTION_KEY+(shouldInstall?"upgrade_gui.install": "upgrade_gui.remove"))
+ .withOnLMBPressed(() -> {
+ IIPacketHandler.sendToServer(new MessageBeginMachineUpgrade(entity, upgrade, this.mc.player, shouldInstall));
+ closeGUI();
+ });
+
+ if(shouldInstall&&!canInstall)
+ button.enabled = false;
+ }
+ }
+
+ private void refreshModelPreview(Upgrade upgrade)
+ {
+ ArrayList builder = new ArrayList<>();
+
+ //Add base model
+ ResLoc baseRes = techTree.getModelLocation();
+ if(baseRes!=null)
+ builder.add(new AMTModel(DefaultVertexFormats.ITEM, baseRes));
+
+ //Collect all installed upgrades
+ ArrayList upgrades = new ArrayList<>(entity.getAllInstalledUpgrades());
+ //Remove incompatible from preview and add requirements
+ if(upgrade!=null)
+ {
+ upgrades.removeAll(techTree.getAllIncompatibleUpgrades(upgrade));
+ upgrades.addAll(techTree.getAllRequiredUpgrades(upgrade.getPurpose()));
+ upgrades.add(upgrade);
+ }
+
+ //Add all installed upgrades
+ upgrades.stream().distinct()
+ .map(techTree::getUpgradeModelLocation)
+ .filter(Objects::nonNull)
+ .map(upgradeRes -> new AMTModel(DefaultVertexFormats.ITEM, upgradeRes))
+ .forEach(builder::add);
+
+ //Build
+ AMTModel built = new AMTModel(builder.toArray(new AMTModel[0]));
+ Vec3d center = built.findActualModelCenter();
+ Vec3d size = built.findModelSize();
+ float maxEdge = (float)Math.max(size.x, Math.max(size.y, size.z));
+
+ scenario.withModel(false, built);
+ scenario.withOrigin(center.x, center.y, center.z);
+ scenario.withTranslation(-center.x, -center.y, -center.z);
+ scenario.withScale(Math.min(maxEdge==0?0.125f: (0.125f/(maxEdge/6f)), 0.325f));
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/inworld_overlay/VehicleDebugOverlay.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/inworld_overlay/VehicleDebugOverlay.java
index e76e13825..f404778d5 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/inworld_overlay/VehicleDebugOverlay.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/inworld_overlay/VehicleDebugOverlay.java
@@ -15,12 +15,12 @@
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Graphics;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityVehicleBase;
-import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.VehicleDurability;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehiclePart;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleWheel;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.VerticalForces;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import pl.pabilo8.immersiveintelligence.common.util.entity.IIEntityUtils;
+import pl.pabilo8.immersiveintelligence.common.util.entity.SyncedDurability;
import javax.annotation.Nonnull;
import java.util.List;
@@ -42,7 +42,7 @@ public void draw(@Nonnull EntityPlayer player, @Nonnull World world, RayTraceRes
double posY = player.lastTickPosY+(player.posY-player.lastTickPosY)*(double)partialTicks;
double posZ = player.lastTickPosZ+(player.posZ-player.lastTickPosZ)*(double)partialTicks;
boolean displayWheelBoxes = true;
- boolean displayNames = true;
+ boolean displayNames = false;
if(!Graphics.vehicleDebugOverlay)
return;
@@ -115,7 +115,7 @@ else if(part.durability!=vehicle.durabilityMain)
GlStateManager.rotate(-player.rotationPitch, 1, 0, 0);
GlStateManager.scale(0.0625f/2, -0.0625f/2, 0.0625f/2);
- VehicleDurability durability = part.getDurability();
+ SyncedDurability durability = part.getDurability();
String[] lines;
if(durability!=null)
lines = new String[]{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/item/GuiCasingPouch.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/item/GuiCasingPouch.java
index a6672b99d..deceefd8d 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/item/GuiCasingPouch.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/item/GuiCasingPouch.java
@@ -1,46 +1,64 @@
package pl.pabilo8.immersiveintelligence.client.gui.item;
-import blusunrize.immersiveengineering.client.gui.GuiIEContainerBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
-import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoItemGui;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.component.storage.DecoItemStackDisplay;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoBackgroundBuilder.SlotStyle;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoGuiCategory;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
+import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTextures;
+import pl.pabilo8.immersiveintelligence.common.IIContent;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.gui.ContainerCasingPouch;
-import pl.pabilo8.immersiveintelligence.common.util.IIReference;
-import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
+import pl.pabilo8.immersiveintelligence.common.item.ammo.ItemIIAmmoCasing.Casing;
+import pl.pabilo8.immersiveintelligence.common.item.ammo.ItemIIBulletMagazine.Magazines;
+import pl.pabilo8.immersiveintelligence.common.util.IIColor;
/**
* @author Pabilo8 (pabilo@iiteam.net)
* @since 25.09.2023
*/
-public class GuiCasingPouch extends GuiIEContainerBase
+@DecoTemplate(name = "casing_pouch", category = DecoGuiCategory.GENERIC_TILE)
+public class GuiCasingPouch extends DecoItemGui
{
- private static final ResLoc texture = IIReference.RES_TEXTURES_GUI.with("casing_pouch").withExtension(ResLoc.EXT_PNG);
- private final ItemStack pouch;
-
public GuiCasingPouch(EntityPlayer player, ItemStack heldStack, EnumHand hand)
{
- super(new ContainerCasingPouch(player, heldStack, hand));
- this.pouch = heldStack;
- xSize = 176;
- ySize = 173;
- }
-
- /**
- * Draw the foreground layer for the GuiContainer (everything in front of the items)
- */
- @Override
- protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
- {
- IIClientUtils.drawStringCentered(this.fontRenderer, this.pouch.getDisplayName(), 0, 6, xSize, 0, 0xffc596);
-// this.fontRenderer.drawString(this.pouch.getDisplayName(), 8, 6, 0xffc596);
+ super(player, heldStack, hand, IIGUI.CASING_POUCH);
}
@Override
- protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
+ public void onInit()
{
- IIClientUtils.bindTexture(texture);
- this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
+ startBackground()
+ .withBox(DecoTextures.BG_STEEL_ROUGH, DecoTextures.TEMPLATE_ROUND, 0, 0, 176, 5*16, IIColor.fromPackedRGB(0x8dae77))
+ .withStandaloneFrame(6, 4, 176-12, 5*16-10, DecoTextures.FRAME_CORNERS_BRASS, 4, true)
+ .withTitleBar(itemStack)
+ .withInventorySlots(SlotStyle.VANILLA, container.slotsCasing)
+ .withInventorySlots(SlotStyle.VANILLA, container.slotsMagazine)
+ .withBox(DecoTextures.BG_WOODEN, DecoTextures.TEMPLATE_ROUND_WOODEN, 0, 5*16, 176, 92)
+ .withInventorySlots(SlotStyle.VANILLA, container.playerInventory)
+ .withInventoryTitleBar()
+ .build();
+ DecoPanel infoPanel = addComponent(new DecoPanel(64*2+8-2, 14)
+ .withSize(20, 16*4-6)
+ .withBackground(DecoTextures.BG_PAPER)
+ .withBackgroundMask(DecoTextures.TEMPLATE_PAPER)
+ );
+ infoPanel.addComponent(new DecoItemStackDisplay(2, 2)
+ .withStack(IIContent.itemAmmoCasing.getStack(Casing.MG_2BCAL))
+ .withOnTooltip(null)
+ );
+ infoPanel.addComponent(new DecoItemStackDisplay(2, 20)
+ .withStack(IIContent.itemAmmoCasing.getStack(Casing.MG_2BCAL))
+ .withOnTooltip(null)
+ );
+ infoPanel.addComponent(new DecoItemStackDisplay(2, 19+19+1)
+ .withStack(IIContent.itemBulletMagazine.getStack(Magazines.MACHINEGUN))
+ .withOnTooltip(null)
+ );
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/GuiOverlayTripodPeriscope.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/GuiOverlayTripodPeriscope.java
index fd7458de0..437b10e3c 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/GuiOverlayTripodPeriscope.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/GuiOverlayTripodPeriscope.java
@@ -8,7 +8,7 @@
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.RayTraceResult.Type;
import pl.pabilo8.immersiveintelligence.client.util.CameraHandler;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityTripodPeriscope;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityTripodPeriscope;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import javax.annotation.Nonnull;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayGunBase.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayGunBase.java
index c946cd3e2..8bf51f647 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayGunBase.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayGunBase.java
@@ -9,6 +9,7 @@
import pl.pabilo8.immersiveintelligence.client.util.IIDrawUtils;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
+import pl.pabilo8.immersiveintelligence.common.util.gun.GunAmmoProvider;
/**
* @author Pabilo8 (pabilo@iiteam.net)
@@ -16,14 +17,17 @@
*/
public abstract class GuiOverlayGunBase extends GuiOverlayBase
{
- void drawMagazine(ItemStack magazine, int width, int height)
+ protected void drawMagazine(GunAmmoProvider provider, int width, int height)
{
- drawMagazine(width, height,
- IIContent.itemBulletMagazine.readInventory(magazine)
- );
+ drawMagazine(provider.getAmmoList(), width, height);
+ }
+
+ protected void drawMagazine(ItemStack magazine, int width, int height)
+ {
+ drawMagazine(IIContent.itemBulletMagazine.readInventory(magazine), width, height);
}
- public void drawMagazine(int width, int height, NonNullList ammo)
+ protected void drawMagazine(NonNullList ammo, int width, int height)
{
IIDrawUtils draw = IIDrawUtils.startTexturedColored();
draw.drawTexColorRect(width-38, height-27, 36, 25, IIColor.WHITE, 15/256f, (15+36)/256f, 29/256f, (29+25)/256f);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayMachinegun.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayMachinegun.java
index 34df9f3b3..a46ced272 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayMachinegun.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayMachinegun.java
@@ -6,8 +6,8 @@
import net.minecraftforge.fluids.FluidStack;
import pl.pabilo8.immersiveintelligence.client.IIClientUtils;
import pl.pabilo8.immersiveintelligence.client.util.IIDrawUtils;
-import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.Machinegun;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityMachinegun;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMachinegun;
+import pl.pabilo8.immersiveintelligence.common.item.weapons.ItemIIWeaponUpgrade.WeaponUpgrade;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import javax.annotation.Nonnull;
@@ -19,7 +19,8 @@
*/
public class GuiOverlayMachinegun extends GuiOverlayGunBase
{
- private IIColor colorFrom = IIColor.fromPackedRGB(0xdf9916), colorTo = IIColor.fromPackedRGB(0xba0f0f);
+ private final IIColor colorFrom = IIColor.fromPackedRGB(0xdf9916);
+ private final IIColor colorTo = IIColor.fromPackedRGB(0xba0f0f);
@Override
public boolean shouldDraw(@Nonnull EntityPlayer player, @Nullable RayTraceResult mouseOver)
@@ -33,34 +34,37 @@ public void draw(@Nonnull EntityPlayer player, @Nullable RayTraceResult mouseOve
final EntityMachinegun mg = (EntityMachinegun)player.getRidingEntity();
assert mg!=null;
- IIDrawUtils draw;
-
- if(mg.hasSecondMag)
- drawMagazine(mg.magazine2, width, height);
-
- drawMagazine(mg.magazine1, width, height);
-
+ //Draw loaded ammo
+ if(mg.upgrades.contains(WeaponUpgrade.BELT_FED_LOADER))
+ drawMagazine(mg.loadingCrate, width, height);
+ else
+ {
+ if(mg.upgrades.contains(WeaponUpgrade.SECOND_MAGAZINE))
+ drawMagazine(mg.loadingMagazine2, width, height);
+ drawMagazine(mg.loadingMagazine1, width, height);
+ }
bindHUDTexture();
- draw = IIDrawUtils.startTexturedColored()
+
+ //Draw Overheat
+ IIDrawUtils draw = IIDrawUtils.startTexturedColored()
.setOffset(width-38-24, height)
.drawTexColorRect(0, -20, 22, 18, IIColor.WHITE, 0/256f, 22/256f, 62/256f, 80/256f)
.inBetween((x, y) -> {
- IIClientUtils.drawGradientBar(x+1, y-19, 3, 16, colorFrom, colorTo, mg.overheating/(float)Machinegun.maxOverheat);
+ IIClientUtils.drawGradientBar(x+1, y-19, 3, 16, colorFrom, colorTo, mg.recoil.getOverheat(0));
bindHUDTexture();
})
.drawTexColorRect(5, -19, 16, 16, IIColor.WHITE, 16/256f, 32/256f, 0, 16/256f);
draw.addOffset(0, -18);
//Draw Water
- if(mg.tankCapacity > 0)
+ if(mg.upgrades.contains(WeaponUpgrade.WATER_COOLING))
{
final FluidStack fluid = mg.tank.getFluid();
draw.drawTexColorRect(0, -20, 22, 18, IIColor.WHITE, 0/256f, 22/256f, 62/256f, 80/256f)
.inBetween((x, y) -> {
if(fluid==null)
return;
-
- float hh = 16*((float)mg.tank.getFluidAmount()/(float)mg.tankCapacity);
+ float hh = 16f*mg.tank.getFillPercentage();
ClientUtils.drawRepeatedFluidSprite(fluid, x+1, y-3-hh, 3, hh);
bindHUDTexture();
})
@@ -68,11 +72,11 @@ public void draw(@Nonnull EntityPlayer player, @Nullable RayTraceResult mouseOve
.addOffset(0, -18);
}
//Draw Shield
- if(mg.maxShieldStrength > 0)
+ if(mg.upgrades.contains(WeaponUpgrade.SHIELD))
{
draw
.drawTexColorRect(0, -20, 22, 18, IIColor.WHITE, 0/256f, 22/256f, 62/256f, 80/256f)
- .inBetween((x, y) -> IIClientUtils.drawArmorBar(x+1, y-19, 3, 16, mg.shieldStrength/mg.maxShieldStrength))
+ .inBetween((x, y) -> IIClientUtils.drawArmorBar(x+1, y-19, 3, 16, (float)mg.shield.getDamageFactor()))
.drawTexColorRect(5, -19, 16, 16, IIColor.WHITE, 32/256f, 48/256f, 0, 16/256f);
}
draw.finish();
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayRifle.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayRifle.java
index ebc88dd4d..31c5f0785 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayRifle.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/gui/overlay/gun/GuiOverlayRifle.java
@@ -40,7 +40,7 @@ public void draw(@Nonnull EntityPlayer player, @Nullable RayTraceResult mouseOve
NonNullList ammo = NonNullList.create();
for(NBTBase nbtBase : IIContent.itemRifle.getAmmoList(stack))
ammo.add(new ItemStack(((NBTTagCompound)nbtBase)));
- drawMagazine(width, height, ammo);
+ drawMagazine(ammo, width, height);
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/model/TextureRecoloringRegistry.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/model/TextureRecoloringRegistry.java
index f4acbcd5c..f29877e3a 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/model/TextureRecoloringRegistry.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/model/TextureRecoloringRegistry.java
@@ -66,7 +66,7 @@ public static SpriteRecolored getRecoloredTextureSprite(ResourceLocation base, I
RecolorableTexture texture = RECOLORABLE_TEXTURES.get(base);
if(texture==null)
return null;
- return texture.recoloredVariants.get(color);
+ return texture.recoloredVariants.get(color.constraintToPaintSystem());
}
private static class RecolorableTexture
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldFlakRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldFlakRenderer.java
new file mode 100644
index 000000000..9e803b45f
--- /dev/null
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldFlakRenderer.java
@@ -0,0 +1,133 @@
+package pl.pabilo8.immersiveintelligence.client.render.entity.vehicle;
+
+import net.minecraft.client.model.ModelBiped;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.util.math.MathHelper;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
+import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
+import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCachedMap;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCachedModelBuilder;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCrossVariantReference;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMT;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTBipedAdapter;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTLocator;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTParticle;
+import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IIEntityRenderer.RegisteredEntityRenderer;
+import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldFlak;
+import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
+
+@RegisteredEntityRenderer(clazz = EntityFieldFlak.class, name = "vehicle/field_flak")
+public class FieldFlakRenderer extends IIVehicleRenderer
+{
+ private IIAnimationCachedMap aimYaw, aimPitch, load1, load2, unload1, unload2, fire1, fire2;
+ private IIAnimationCachedMap forward, backward, left, right;
+ private AMTCrossVariantReference bipedGunner, bipedCommander;
+
+ public FieldFlakRenderer(RenderManager renderManager)
+ {
+ super(renderManager);
+ }
+
+ @Override
+ public void draw(EntityFieldFlak entity, BufferBuilder buf, float partialTicks, Tessellator tes)
+ {
+ //Apply vehicle transforms
+ double rotYaw = MathHelper.clampedLerp(entity.prevRotationYaw, entity.rotationYaw, partialTicks);
+ GlStateManager.rotate((float)(rotYaw-90), 0, 1, 0);
+ //TODO: 29.05.2026 proper rotations after Trej fixes the model
+
+ model.getVariant(entity, entity.getStyle());
+
+ //Animate wheels
+ applyWheelAnimations(entity, partialTicks);
+
+ //General animations
+ aimPitch.apply(1f-entity.aim.getPitchNormalized(partialTicks));
+ aimYaw.apply(1f-entity.aim.getYawNormalized(partialTicks));
+
+ if(entity.ammoProviderMagazine1.isReloading())
+ load1.apply(entity.ammoProviderMagazine1.getLoadingProgress(partialTicks));
+ if(entity.ammoProviderMagazine2.isReloading())
+ load2.apply(entity.ammoProviderMagazine2.getLoadingProgress(partialTicks));
+
+ //Finally, render
+ model.render(tes, buf);
+ }
+
+ @Override
+ public void compileModels()
+ {
+ //Assemble main model
+ model = AMTCachedModelBuilder.startEntityModel(EntityFieldFlak.class)
+ .withModel(modelFile)
+ .withHeader(headerFile)
+ .withTextureProvider(this::replaceVehicleTextures)
+ .withModelProvider((entity, header) -> new AMT[]{
+ new AMTBipedAdapter("hans_gunner", header),
+ new AMTBipedAdapter("hans_commander", header),
+ new AMTLocator("turret_base", header),
+ new AMTParticle("cannon1_fire", header),
+ new AMTParticle("cannon2_fire", header)
+ })
+ .build();
+
+ //Passenger display references
+ this.bipedGunner = new AMTCrossVariantReference<>("hans_gunner", model);
+ this.bipedCommander = new AMTCrossVariantReference<>("hans_commander", model);
+
+ //General animations
+ load1 = IIAnimationCachedMap.create(model, animationsDirectory.with("load1"));
+ load2 = IIAnimationCachedMap.create(model, animationsDirectory.with("load2"));
+ unload1 = IIAnimationCachedMap.create(model, animationsDirectory.with("unload1"));
+ unload2 = IIAnimationCachedMap.create(model, animationsDirectory.with("unload2"));
+ fire1 = IIAnimationCachedMap.create(model, animationsDirectory.with("fire1"));
+ fire2 = IIAnimationCachedMap.create(model, animationsDirectory.with("fire2"));
+
+ aimYaw = IIAnimationCachedMap.create(model, animationsDirectory.with("aim_yaw"));
+ aimPitch = IIAnimationCachedMap.create(model, animationsDirectory.with("aim_pitch"));
+
+ forward = IIAnimationCachedMap.create(model, animationsDirectory.with("forward"));
+ backward = IIAnimationCachedMap.create(model, animationsDirectory.with("backward"));
+ left = IIAnimationCachedMap.create(model, animationsDirectory.with("left"));
+ right = IIAnimationCachedMap.create(model, animationsDirectory.with("right"));
+
+ wheelAnimations = new WheelAnimationBuilder()
+ .withWheel(e -> e.partWheelRight, "wheel1")
+ .withWheel(e -> e.partWheelLeft, "wheel2")
+ .build();
+
+ //Upgrade system
+ UpgradeTechTree.getTreeFor(EntityFieldFlak.class)
+ .withBaseModelLocation(modelFile);
+ }
+
+ @Override
+ protected void nullifyModels()
+ {
+ AMTUtils.disposeOf(model);
+ }
+
+ @Override
+ public boolean handleBipedRotations(ModelBiped model, EntityFieldFlak entity, EntityLivingBase passenger, float partialTicks)
+ {
+ EntityVehicleSeat seat = (EntityVehicleSeat)passenger.getRidingEntity();
+ if(seat==null)
+ return false;
+ //Select animation adapter based on seat
+ switch(seat.info.getSeatID())
+ {
+ case "gunner":
+ //bipedGunner.get().applyAnimationStateTo(model);
+ return true;
+ case "commander":
+ //bipedCommander.get().applyAnimationStateTo(model);
+ return true;
+ default:
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldHowitzerRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldHowitzerRenderer.java
index c68a813f2..67110b54f 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldHowitzerRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/FieldHowitzerRenderer.java
@@ -4,20 +4,25 @@
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
-import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.EntityLivingBase;
-import pl.pabilo8.immersiveintelligence.client.util.amt.AMTLoader;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
-import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCachedModel;
+import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCachedMap;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCachedModelBuilder;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCrossVariantReference;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMT;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTBipedAdapter;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTParticle;
import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IIEntityRenderer.RegisteredEntityRenderer;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldHowitzer;
-import pl.pabilo8.immersiveintelligence.common.util.IIReference;
-import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
+import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
@RegisteredEntityRenderer(clazz = EntityFieldHowitzer.class, name = "vehicle/field_howitzer")
public class FieldHowitzerRenderer extends IIVehicleRenderer
{
- private static AMTCachedModel model;
+ private IIAnimationCachedMap load, fire, aimPitch;
+ private IIAnimationCachedMap forward, backward, left, right;
+ private AMTCrossVariantReference bipedGunner, bipedCommander;
public FieldHowitzerRenderer(RenderManager renderManager)
{
@@ -27,19 +32,67 @@ public FieldHowitzerRenderer(RenderManager renderManager)
@Override
public void draw(EntityFieldHowitzer entity, BufferBuilder buf, float partialTicks, Tessellator tes)
{
+ //Apply vehicle transforms
+ applyVehicleTransforms(entity, partialTicks);
+ model.getVariant(entity, entity.getStyle());
+ model.defaultize();
+ //Animate wheels
+ applyWheelAnimations(entity, partialTicks);
+
+ //General animations
+ aimPitch.apply(1f-entity.aim.getPitchNormalized(partialTicks));
+
+ if(entity.ammoProvider.isReloading())
+ load.apply(entity.ammoProvider.getLoadingProgress(partialTicks));
+ if(entity.commanderControls.getKey("forward"))
+ forward.apply(1f);
+ else if(entity.commanderControls.getKey("backwards"))
+ backward.apply(1f);
+ else if(entity.commanderControls.getKey("turnLeft"))
+ left.apply(1f);
+ else if(entity.commanderControls.getKey("turnRight"))
+ right.apply(1f);
+
+ //Finally, render
+ model.render(tes, buf);
}
@Override
public void compileModels()
{
+ //Assemble main model
+ model = AMTCachedModelBuilder.startEntityModel(EntityFieldHowitzer.class)
+ .withModel(modelFile)
+ .withHeader(headerFile)
+ .withTextureProvider(this::replaceVehicleTextures)
+ .withModelProvider((entity, header) -> new AMT[]{
+ new AMTBipedAdapter("hans_gunner", header),
+ new AMTBipedAdapter("hans_commander", header),
+ new AMTParticle("fire", header)
+ })
+ .build();
- }
+ //Passenger display references
+ this.bipedGunner = new AMTCrossVariantReference<>("hans_gunner", model);
+ this.bipedCommander = new AMTCrossVariantReference<>("hans_commander", model);
- @Override
- public void registerSprites(TextureMap map)
- {
- AMTLoader.preloadTexturesFromMTL(ResLoc.of(IIReference.RES_ENTITY_MODEL, "vehicle/field_howitzer/field_howitzer.obj").withExtension(ResLoc.EXT_MTL), map);
+ //General animations
+ load = IIAnimationCachedMap.create(model, animationsDirectory.with("load"));
+ fire = IIAnimationCachedMap.create(model, animationsDirectory.with("fire"));
+ aimPitch = IIAnimationCachedMap.create(model, animationsDirectory.with("aim_pitch"));
+ forward = IIAnimationCachedMap.create(model, animationsDirectory.with("forward"));
+ backward = IIAnimationCachedMap.create(model, animationsDirectory.with("backward"));
+ left = IIAnimationCachedMap.create(model, animationsDirectory.with("left"));
+ right = IIAnimationCachedMap.create(model, animationsDirectory.with("right"));
+ wheelAnimations = new WheelAnimationBuilder()
+ .withWheel(e -> e.partWheelRight, "wheel1")
+ .withWheel(e -> e.partWheelLeft, "wheel2")
+ .build();
+
+ //Upgrade system
+ UpgradeTechTree.getTreeFor(EntityFieldHowitzer.class)
+ .withBaseModelLocation(modelFile);
}
@Override
@@ -51,6 +104,20 @@ protected void nullifyModels()
@Override
public boolean handleBipedRotations(ModelBiped model, EntityFieldHowitzer entity, EntityLivingBase passenger, float partialTicks)
{
- return false;
+ EntityVehicleSeat seat = (EntityVehicleSeat)passenger.getRidingEntity();
+ if(seat==null)
+ return false;
+ //Select animation adapter based on seat
+ switch(seat.info.getSeatID())
+ {
+ case "gunner":
+ bipedGunner.get().applyAnimationStateTo(model);
+ return true;
+ case "commander":
+ bipedCommander.get().applyAnimationStateTo(model);
+ return true;
+ default:
+ return false;
+ }
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/IIVehicleRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/IIVehicleRenderer.java
index 7c4eba858..378512e5e 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/IIVehicleRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/IIVehicleRenderer.java
@@ -51,7 +51,7 @@ public abstract class IIVehicleRenderer> extends
protected ResLoc modelDirectory, animationsDirectory;
protected ResLoc modelFile, headerFile, mtlFile;
- protected IIVehicleRenderer(RenderManager render)
+ public IIVehicleRenderer(RenderManager render)
{
super(render);
@@ -153,9 +153,9 @@ protected void applyGearboxAnimation(VehicleTransmission transmission, IIAnim
}
- protected > void applyEngineAnimation(T engineBase,
- IIAnimationCachedMap startingAnimation, IIAnimationCachedMap runningAnimation,
- float partialTicks)
+ protected > void applyEngineAnimation(T engineBase,
+ IIAnimationCachedMap startingAnimation, IIAnimationCachedMap runningAnimation,
+ float partialTicks)
{
if(engineBase.isStarting())
startingAnimation.apply(engineBase.getStartingProgress(partialTicks));
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/TrackedMotorbikeRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/TrackedMotorbikeRenderer.java
index 5f2cf652a..85a427e37 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/TrackedMotorbikeRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/vehicle/TrackedMotorbikeRenderer.java
@@ -7,6 +7,7 @@
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.EntityLivingBase;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTLoader;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCachedMap;
@@ -23,7 +24,7 @@
@RegisteredEntityRenderer(clazz = EntityFieldHowitzer.class, name = "vehicle/tracked_motorbike")
public class TrackedMotorbikeRenderer extends IIVehicleRenderer
{
- private IIAnimationCachedMap engine, engineStarting, transmission, turn, passengerDefault;
+ private IIAnimationCachedMap engine, engineStarting, turn, passengerDefault;
private IIAnimationCachedMap gearPrimary, gearSecondary;
private IIAnimationCachedMap gearPrimaryReverse, gearPrimary1, gearPrimary2, gearSecondaryOverdrive, gearSecondaryReduction;
private AMTCrossVariantReference trackLeft, trackRight;
@@ -51,7 +52,6 @@ public void draw(EntityTrackedMotorbike entity, BufferBuilder buf, float partial
//General animations
passengerDefault.apply(0);
turn.apply((entity.partWheelFront.getSteeringAngle()/45f)*-0.5f+0.5f);
- transmission.apply(AMTUtils.getDebugProgress(8, partialTicks));
//Gearbox animations
applyGearboxAnimation(entity.transmission1, gearSecondary, partialTicks, gearSecondaryOverdrive);
@@ -105,7 +105,6 @@ public void compileModels()
//General animations
engine = IIAnimationCachedMap.create(model, animationsDirectory.with("engine"));
engineStarting = IIAnimationCachedMap.create(model, animationsDirectory.with("start_engine"));
- transmission = IIAnimationCachedMap.create(model, animationsDirectory.with("transmission"));
turn = IIAnimationCachedMap.create(model, animationsDirectory.with("turn"));
passengerDefault = IIAnimationCachedMap.create(model, animationsDirectory.with("hans_default"));
wheelAnimations = new WheelAnimationBuilder()
@@ -129,6 +128,10 @@ public void compileModels()
gearSecondary = IIAnimationCachedMap.create(model, animationsDirectory.with("gearbox_secondary"));
gearSecondaryOverdrive = IIAnimationCachedMap.create(model, animationsDirectory.with("gear_secondary_overdrive"));
gearSecondaryReduction = IIAnimationCachedMap.create(model, animationsDirectory.with("gear_secondary_reduction"));
+
+ //Upgrade system
+ UpgradeTechTree.getTreeFor(EntityTrackedMotorbike.class)
+ .withBaseModelLocation(modelFile);
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MachinegunRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MachinegunRenderer.java
index 8b57aea1e..d79591032 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MachinegunRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MachinegunRenderer.java
@@ -20,16 +20,17 @@
import pl.pabilo8.immersiveintelligence.client.model.weapon.ModelMachinegun;
import pl.pabilo8.immersiveintelligence.client.render.IPassengerAnimationsRenderer;
import pl.pabilo8.immersiveintelligence.client.render.IReloadableModelContainer;
+import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
import pl.pabilo8.immersiveintelligence.client.util.tmt.ModelRendererTurbo;
import pl.pabilo8.immersiveintelligence.client.util.tmt.TmtNamedBoxGroup;
-import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.Machinegun;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.BlockIIMetalDevice.IIBlockTypes_MetalDevice;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.effect_crate.TileEntityAmmunitionCrate;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityMachinegun;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMachinegun;
import pl.pabilo8.immersiveintelligence.common.item.ammo.ItemIIAmmoBase;
import pl.pabilo8.immersiveintelligence.common.item.weapons.ItemIIMachinegun;
+import pl.pabilo8.immersiveintelligence.common.item.weapons.ItemIIWeaponUpgrade.WeaponUpgrade;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import pl.pabilo8.immersiveintelligence.common.util.IISkinHandler;
import pl.pabilo8.immersiveintelligence.common.util.IISkinHandler.IISpecialSkin;
@@ -57,7 +58,7 @@ public MachinegunRenderer(RenderManager renderManager)
reloadModels();
}
- public static void renderMachinegun(ItemStack stack, @Nullable EntityMachinegun entity)
+ public static void renderMachinegun(ItemStack stack, @Nullable EntityMachinegun entity, float partialTicks)
{
GlStateManager.pushMatrix();
List renderParts = new ArrayList<>(defaultGunParts);
@@ -84,12 +85,9 @@ public static void renderMachinegun(ItemStack stack, @Nullable EntityMachinegun
}
specialText = I18n.format("skin.immersiveintelligence."+skin+".name");
- skin = ((skin.isEmpty()&&!canApply)?IIContent.itemMachinegun.getSkinnableDefaultTextureLocation(): IIReference.SKIN_LOCATION+skin+"/");
-
-
+ skin = skin.isEmpty()?IIContent.itemMachinegun.getSkinnableDefaultTextureLocation(): IIReference.SKIN_LOCATION+skin+"/";
ClientUtils.bindTexture(skin+texture);
-
for(Entry, BiConsumer>> s : upgrades.entrySet())
{
if(s.getKey()!=null&&s.getValue()!=null&&s.getKey().test(stack))
@@ -98,49 +96,24 @@ public static void renderMachinegun(ItemStack stack, @Nullable EntityMachinegun
if(entity!=null)
{
- float yaw = entity.gunYaw, pitch = entity.gunPitch;
- if(entity.setupTime < 1&&entity.getPassengers().size() > 0&&entity.getPassengers().get(0) instanceof EntityLivingBase)
- {
- EntityLivingBase psg = (EntityLivingBase)entity.getPassengers().get(0);
-
- float true_head_angle = MathHelper.wrapDegrees(psg.prevRotationYawHead-entity.setYaw);
- float true_head_angle2 = MathHelper.wrapDegrees(psg.rotationPitch);
-
- if(entity.gunYaw < true_head_angle)
- yaw += ClientUtils.mc().getRenderPartialTicks()*2f;
- else if(entity.gunYaw > true_head_angle)
- yaw -= ClientUtils.mc().getRenderPartialTicks()*2f;
-
- if(Math.ceil(entity.gunYaw) <= Math.ceil(true_head_angle)+1f&&Math.ceil(entity.gunYaw) >= Math.ceil(true_head_angle)-1f)
- yaw = true_head_angle;
-
- if(entity.gunPitch < true_head_angle2)
- pitch += ClientUtils.mc().getRenderPartialTicks();
- else if(entity.gunPitch > true_head_angle2)
- pitch -= ClientUtils.mc().getRenderPartialTicks();
-
- yaw = entity.tripod?MathHelper.clamp(yaw, -82.5F, 82.5F): MathHelper.clamp(yaw, -45.0F, 45.0F);
- pitch = MathHelper.clamp(pitch, -20, 20);
-
- yaw += entity.recoilYaw;
- pitch += entity.recoilPitch;
-
- pitch = MathHelper.clamp(pitch, -20, 20);
- }
+ float yaw = entity.aim.getYaw(partialTicks)-entity.aim.getCenterYaw(), pitch = entity.aim.getPitch(partialTicks);
+ boolean tripod = entity.upgrades.contains(WeaponUpgrade.TRIPOD);
+ if(tripod)
+ GlStateManager.translate(0f, 0.5, 0f);
GlStateManager.translate(0f, -0.34375, 0f);
- float setup = Math.max(entity.setupTime-ClientUtils.mc().getRenderPartialTicks(), 0);
- GlStateManager.rotate(-25f*(setup/(float)entity.maxSetupTime), 1, 0, 0);
- GlStateManager.translate(0, 0.25*(setup/(float)entity.maxSetupTime), 0);
+ float setup = AMTUtils.getAnimationProgress(entity.setupTime, entity.maxSetupTime, true, partialTicks);
+ GlStateManager.rotate(-25f*setup, 1, 0, 0);
+ GlStateManager.translate(0, 0.25*setup, 0);
if(drawText)
{
GlStateManager.pushMatrix();
GlStateManager.scale(0.85, 0.85, 0.85);
- GlStateManager.rotate(180-entity.setYaw, 0f, 1f, 0f);
+ GlStateManager.rotate(180-entity.aim.getCenterYaw(), 0f, 1f, 0f);
GlStateManager.rotate(-yaw, 0f, 1f, 0f);
GlStateManager.rotate(-pitch, 1, 0, 0);
- GlStateManager.translate(-0.5f, 0.34375, 1.65625+(pitch/20*0.25));
+ GlStateManager.translate(-0.5f, 0.34375, 1.65625+pitch/20*0.25);
GlStateManager.rotate(90, 0, 1, 0);
GlStateManager.scale(-1, -1, 1);
@@ -162,35 +135,26 @@ else if(entity.gunPitch > true_head_angle2)
{
GlStateManager.pushMatrix();
GlStateManager.scale(0.85, 0.85, 0.85);
- GlStateManager.rotate(180-entity.setYaw, 0f, 1f, 0f);
+ GlStateManager.rotate(180-entity.aim.getCenterYaw(), 0f, 1f, 0f);
GlStateManager.translate(-0.5f, 0.34375+0.0625, 1.65625);
- nmod.render(0.0625f, setup/(float)entity.maxSetupTime);
+ nmod.render(0.0625f, setup);
GlStateManager.popMatrix();
}
else
{
GlStateManager.pushMatrix();
GlStateManager.scale(0.85, 0.85, 0.85);
- GlStateManager.rotate(180-entity.setYaw, 0f, 1f, 0f);
+ GlStateManager.rotate(180-entity.aim.getCenterYaw(), 0f, 1f, 0f);
GlStateManager.rotate(-yaw, 0f, 1f, 0f);
GlStateManager.rotate(-pitch, 1, 0, 0);
- GlStateManager.translate(-0.5f, 0.34375, 1.65625+(pitch/20*0.25));
+ GlStateManager.translate(-0.5f, 0.34375, 1.65625+pitch/20*0.25);
switch(nmod.getName())
{
case "ammo":
{
- boolean should_render = false;
- if(entity.currentlyLoaded==1)
- {
-
- float progress = entity.magazine1.isEmpty()?1f-Math.min(2*(float)entity.clipReload/(float)Machinegun.clipReloadTime, 1): (float)entity.clipReload/(float)Machinegun.clipReloadTime;
- GlStateManager.translate(0f, 0.375f*progress, 0f);
- should_render = true;
- }
- else if(!entity.magazine1.isEmpty())
- should_render = true;
-
+ boolean should_render = entity.loadingMagazine1.getLoadingProgress(partialTicks) > 0;
+ GlStateManager.translate(0f, 0.375f*(1f-entity.loadingMagazine1.getLoadingProgress(partialTicks)), 0f);
if(should_render)
nmod.render(0.0625f);
break;
@@ -199,18 +163,18 @@ else if(!entity.magazine1.isEmpty())
nmod.render(0.0625f);
IAmmoModel, EntityAmmoProjectile> mm = AmmoRegistry.getModel(IIContent.itemAmmoMachinegun);
GlStateManager.pushMatrix();
- GlStateManager.translate(0.69f, 0.65f, -0.0625f+(-0.0625f*1.5f));
+ GlStateManager.translate(0.69f, 0.65f, -0.0625f+-0.0625f*1.5f);
GlStateManager.rotate(180, 0, 1, 0);
GlStateManager.rotate(90, 1, 0, 0);
GlStateManager.scale(0.5f, 0.5f, 0.5f);
- BlockPos cratePos = entity.getPosition().offset(EnumFacing.fromAngle(entity.setYaw).getOpposite()).down();
+ BlockPos cratePos = entity.getPosition().offset(EnumFacing.fromAngle(entity.aim.getCenterYaw()).getOpposite()).down();
if(entity.getEntityWorld().getTileEntity(cratePos) instanceof TileEntityAmmunitionCrate)
{
- TileEntityAmmunitionCrate crate = ((TileEntityAmmunitionCrate)entity.getEntityWorld().getTileEntity(cratePos));
+ TileEntityAmmunitionCrate crate = (TileEntityAmmunitionCrate)entity.getEntityWorld().getTileEntity(cratePos);
assert crate!=null;
- int beltLength = (int)(24+(Math.max(Math.abs(entity.gunYaw)-55, 0)/2)-(Math.max(entity.gunPitch-20, 0)/2));
+ int beltLength = (int)(24+Math.max(Math.abs(entity.aim.getYaw(0f))-55, 0)/2-Math.max(entity.aim.getPitch(partialTicks)-20, 0)/2);
if(crate.open&&crate.isUpgradeInstalled(IIContent.UPGRADE_MG_LOADER))
{
@@ -226,11 +190,11 @@ else if(!entity.magazine1.isEmpty())
}
beltLength -= 4;
- float ammoDir = ((entity.gunYaw)/(entity.tripod?90f: 50f))*(1-((Math.abs(entity.gunPitch))/40f));
- float ammoTurn = entity.tripod?((Math.abs(entity.gunYaw)/90f)*(beltLength > 24?(beltLength-24)/24f: 1)): 0;
+ float ammoDir = entity.aim.getYaw(0f)/(tripod?90f: 50f)*(1-Math.abs(entity.aim.getPitch(partialTicks))/40f);
+ float ammoTurn = tripod?Math.abs(entity.aim.getYaw(0f))/90f*(beltLength > 24?(beltLength-24)/24f: 1): 0;
GlStateManager.pushMatrix();
- for(int i = 0; i < 4&&ammoStacks.size() > 0; i++)
+ for(int i = 0; i < 4&&!ammoStacks.isEmpty(); i++)
{
mm.renderAmmoComplete(false, ammoStacks.get(0));
GlStateManager.rotate(180f/4f, 0, 1, 0);
@@ -244,7 +208,7 @@ else if(!entity.magazine1.isEmpty())
GlStateManager.translate(-0.25f, 0, 0.25);
GlStateManager.pushMatrix();
- for(int i = 0; i < beltLength&&ammoStacks.size() > 0; i++)
+ for(int i = 0; i < beltLength&&!ammoStacks.isEmpty(); i++)
{
mm.renderAmmoComplete(false, ammoStacks.get(0));
GlStateManager.translate(0f, 0, 0.125f);
@@ -266,34 +230,25 @@ else if(!entity.magazine1.isEmpty())
break;
case "second_magazine_mag":
{
- boolean should_render = false;
- if(entity.currentlyLoaded==2)
- {
-
- float progress = entity.magazine2.isEmpty()?1f-Math.min(2*(float)entity.clipReload/(float)Machinegun.clipReloadTime, 1): (float)entity.clipReload/(float)Machinegun.clipReloadTime;
- GlStateManager.translate(0f, 0.375f*progress, 0f);
- should_render = true;
- }
- else if(!entity.magazine2.isEmpty())
- should_render = true;
-
+ boolean should_render = entity.loadingMagazine2.getLoadingProgress(partialTicks) > 0;
+ GlStateManager.translate(0f, 0.375f*(entity.loadingMagazine2.getLoadingProgress(partialTicks)), 0f);
if(should_render)
nmod.render(0.0625f);
break;
}
case "slide":
- if(((entity.currentlyLoaded==1&&entity.magazine1.isEmpty())||(entity.currentlyLoaded==2&&entity.magazine2.isEmpty()))&&((float)entity.clipReload/(float)Machinegun.clipReloadTime) > 0.5)
- {
- float curr = (((float)entity.clipReload/(float)Machinegun.clipReloadTime)-0.5f)/0.5f;
- float progress;
- if(curr > 0.65)
- progress = 1f-((curr-0.65f)/0.35f);
- else
- progress = (curr/0.65f);
- GlStateManager.translate(0f, 0f, progress*0.375);
- }
- nmod.render(0.0625f);
- break;
+ //if(entity.currentlyLoaded==1)
+ {
+ float curr = (entity.gunHandler.getLoadingProgress(partialTicks)-0.5f)/0.5f;
+ float progress;
+ if(curr > 0.65)
+ progress = 1f-(curr-0.65f)/0.35f;
+ else
+ progress = curr/0.65f;
+ GlStateManager.translate(0f, 0f, progress*0.375);
+ }
+ nmod.render(0.0625f);
+ break;
case "shield":
ClientUtils.bindTexture(skin+nmod.getTexturePath());
nmod.render(0.0625f);
@@ -318,9 +273,9 @@ else if(!entity.magazine2.isEmpty())
nmod.render(0.0625f, 1f);
continue;
}
- if(nmod.getName().equals("ammo")&&!(ItemNBTHelper.hasKey(stack, "magazine1")&&!(new ItemStack(ItemNBTHelper.getTagCompound(stack, "magazine1")).isEmpty())))
+ if(nmod.getName().equals("ammo")&&!(ItemNBTHelper.hasKey(stack, "magazine1")&&!new ItemStack(ItemNBTHelper.getTagCompound(stack, "magazine1")).isEmpty()))
continue;
- if(nmod.getName().equals("second_magazine_mag")&&!(ItemNBTHelper.hasKey(stack, "magazine2")&&!(new ItemStack(ItemNBTHelper.getTagCompound(stack, "magazine2")).isEmpty())))
+ if(nmod.getName().equals("second_magazine_mag")&&!(ItemNBTHelper.hasKey(stack, "magazine2")&&!new ItemStack(ItemNBTHelper.getTagCompound(stack, "magazine2")).isEmpty()))
continue;
for(ModelRendererTurbo m : nmod.getModel())
@@ -335,7 +290,7 @@ else if(!entity.magazine2.isEmpty())
* Renders the desired {@code T} type Entity.
*/
@Override
- public void doRender(EntityMachinegun entity, double x, double y, double z, float f0, float f1)
+ public void doRender(EntityMachinegun entity, double x, double y, double z, float entityYaw, float partialTicks)
{
GlStateManager.pushMatrix();
@@ -345,8 +300,9 @@ public void doRender(EntityMachinegun entity, double x, double y, double z, floa
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderHelper.enableStandardItemLighting();
- if(entity.gun!=null&&!entity.gun.isEmpty())
- renderMachinegun(entity.gun, entity);
+ ItemStack stack = entity.getOriginStack();
+ if(!stack.isEmpty())
+ renderMachinegun(stack, entity, partialTicks);
GlStateManager.disableBlend();
@@ -384,8 +340,9 @@ public void reloadModels()
@Override
public boolean handleBipedRotations(ModelBiped model, EntityMachinegun mg, EntityLivingBase passenger, float partialTicks)
{
- float ff = (float)(-1.35f-Math.toRadians(mg.gunPitch)*1.25);
- float true_head_angle = MathHelper.wrapDegrees(passenger.prevRotationYawHead-mg.setYaw);
+ float ff = (float)(-1.35f-Math.toRadians(mg.aim.getPitch(partialTicks))*1.25);
+ float setYaw = mg.aim.getCenterYaw();
+ float true_head_angle = MathHelper.wrapDegrees(passenger.prevRotationYawHead-setYaw);
float wtime;
mg.applyOrientationToEntity(passenger);
@@ -394,21 +351,23 @@ public boolean handleBipedRotations(ModelBiped model, EntityMachinegun mg, Entit
model.bipedLeftArm.rotateAngleY = .08726f+3.14f/6f;
IBlockState state = passenger.world.getBlockState(passenger.getPosition());
- if(!mg.tripod&&state.getMaterial().isSolid()&&!(state.getBlock()==IIContent.blockMetalDevice&&state.getValue(IIContent.blockMetalDevice.property)==IIBlockTypes_MetalDevice.AMMUNITION_CRATE))
+ boolean tripod = mg.upgrades.contains(WeaponUpgrade.TRIPOD);
+ float aimYaw = mg.aim.getYaw(0f)-setYaw;
+ if(!tripod&&state.getMaterial().isSolid()&&!(state.getBlock()==IIContent.blockMetalDevice&&state.getValue(IIContent.blockMetalDevice.property)==IIBlockTypes_MetalDevice.AMMUNITION_CRATE))
{
- if(Math.abs(mg.gunYaw-true_head_angle) > 5)
+ if(Math.abs(aimYaw-true_head_angle) > 5)
{
wtime = Math.abs((mg.getEntityWorld().getTotalWorldTime()+partialTicks)%20/20f-0.5f)/0.5f;
wtime *= 0.25f;
- if(mg.setupTime > 0)
+ if(!mg.isSetupComplete())
wtime = 0;
- if(mg.gunYaw < true_head_angle)
+ if(aimYaw < true_head_angle)
{
model.bipedRightLeg.rotateAngleY = -wtime*2f;
model.bipedLeftLeg.rotateAngleY = wtime*2f;
}
- else if(mg.gunYaw > true_head_angle)
+ else if(aimYaw > true_head_angle)
{
model.bipedRightLeg.rotateAngleY = -wtime*2f;
model.bipedLeftLeg.rotateAngleY = wtime*2f;
@@ -419,8 +378,8 @@ else if(mg.gunYaw > true_head_angle)
model.bipedRightLeg.rotateAngleX += 1.5f;
model.bipedLeftLeg.rotateAngleX += 1.5f;
- model.bipedRightArm.rotateAngleX += ff-0.5;
- model.bipedLeftArm.rotateAngleX += ff-0.5;
+ model.bipedRightArm.rotateAngleX += ff-0.5f;
+ model.bipedLeftArm.rotateAngleX += ff-0.5f;
model.bipedRightLeg.rotationPointY = 0f;
model.bipedLeftLeg.rotationPointY = 0f;
@@ -428,10 +387,10 @@ else if(mg.gunYaw > true_head_angle)
model.bipedRightLeg.rotationPointZ = 12f;
model.bipedLeftLeg.rotationPointZ = 12f;
- float maxRotation = mg.tripod?82.5F: 45.0F;
+ float maxRotation = 45.0F;
- model.bipedRightLeg.rotateAngleY += mg.gunYaw/maxRotation;
- model.bipedLeftLeg.rotateAngleY += mg.gunYaw/maxRotation;
+ model.bipedRightLeg.rotateAngleY += aimYaw/maxRotation;
+ model.bipedLeftLeg.rotateAngleY += aimYaw/maxRotation;
//model.bipedLeftLeg.rotateAngleY += ff+1f;
@@ -440,16 +399,16 @@ else if(mg.gunYaw > true_head_angle)
{
wtime = Math.abs((mg.getEntityWorld().getTotalWorldTime()+partialTicks)%40/40f-0.5f)/0.5f-0.5f;
wtime *= 0.65f;
- if(mg.setupTime > 0)
+ if(!mg.isSetupComplete())
wtime = 0;
model.bipedBody.rotateAngleX -= 0.0625f;
- if(Math.abs(mg.gunYaw-true_head_angle) > 5)
- if(mg.gunYaw < true_head_angle)
+ if(Math.abs(aimYaw-true_head_angle) > 5)
+ if(aimYaw < true_head_angle)
{
model.bipedRightLeg.rotateAngleX = wtime*2f;
model.bipedLeftLeg.rotateAngleX = -wtime*2f;
}
- else if(mg.gunYaw > true_head_angle)
+ else if(aimYaw > true_head_angle)
{
model.bipedRightLeg.rotateAngleX = -wtime*2f;
model.bipedLeftLeg.rotateAngleX = wtime*2f;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MortarRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MortarRenderer.java
index b79bd3737..489ca31c0 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MortarRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/MortarRenderer.java
@@ -21,7 +21,7 @@
import pl.pabilo8.immersiveintelligence.client.util.tmt.ModelRendererTurbo;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.Mortar;
import pl.pabilo8.immersiveintelligence.common.IIContent;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityMortar;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMortar;
/**
* @author Pabilo8 (pabilo@iiteam.net)
@@ -52,7 +52,7 @@ public void doRender(EntityMortar entity, double x, double y, double z, float en
float progress = MathHelper.clamp(((entity.setupTime+partialTicks)/Mortar.setupTime), 0, 1);
bindTexture(TEXTURE);
- GlStateManager.rotate(-entityYaw+90, 0, 1, 0);
+ GlStateManager.rotate(-entity.aim.getYaw(partialTicks)+90, 0, 1, 0);
if(progress==1)
renderNormal(entity, entityYaw, partialTicks, (entity.shootingProgress+partialTicks)/Mortar.shootTime);
@@ -68,7 +68,7 @@ private void renderNormal(EntityMortar entity, float entityYaw, float partialTic
{
GlStateManager.pushMatrix();
- float pitch = MathHelper.clamp((((entity.rotationPitch)+80)/25f), 0, 1);
+ float pitch = entity.aim.getPitchNormalized(partialTicks);
//0.0625f, 35f, 0.60625f, 0.25f
//-0.25f, 10f, 0f, 0.125f
@@ -102,7 +102,7 @@ private void renderNormal(EntityMortar entity, float entityYaw, float partialTic
{
float f = (progress-0.2f)/0.3f;
- if(entity.getPassengers().size() > 0)
+ if(!entity.getPassengers().isEmpty())
{
Entity psg = entity.getPassengers().get(0);
if(psg instanceof EntityLivingBase)
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/TripodPeriscopeRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/TripodPeriscopeRenderer.java
index ba787bdb7..618471a4a 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/TripodPeriscopeRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/entity/weapon/TripodPeriscopeRenderer.java
@@ -17,7 +17,7 @@
import pl.pabilo8.immersiveintelligence.client.render.IReloadableModelContainer;
import pl.pabilo8.immersiveintelligence.client.util.tmt.ModelRendererTurbo;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Tools.TripodPeriscope;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityTripodPeriscope;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityTripodPeriscope;
/**
* @author Pabilo8 (pabilo@iiteam.net)
@@ -49,9 +49,9 @@ public void doRender(EntityTripodPeriscope entity, double x, double y, double z,
ClientUtils.bindTexture(texture);
if(progress==1)
- renderNormal(entity, entityYaw, partialTicks, progress);
+ renderNormal(entity, 0, partialTicks, progress);
else
- renderProgress(entity, entityYaw, partialTicks, progress);
+ renderProgress(entity, 0, partialTicks, progress);
GlStateManager.disableBlend();
GlStateManager.disableRescaleNormal();
@@ -61,7 +61,6 @@ public void doRender(EntityTripodPeriscope entity, double x, double y, double z,
private void renderNormal(EntityTripodPeriscope entity, float entityYaw, float partialTicks, float progress)
{
GlStateManager.pushMatrix();
- GlStateManager.rotate(entityYaw, 0, 1, 0);
for(ModelRendererTurbo mod : model.baseModel)
mod.render();
@@ -72,11 +71,11 @@ private void renderNormal(EntityTripodPeriscope entity, float entityYaw, float p
for(ModelRendererTurbo mod : model.leg3Model)
mod.render();
- float yy = MathHelper.wrapDegrees(360+entity.periscopeNextYaw-entity.periscopeYaw);
- float yaw = MathHelper.wrapDegrees(entity.periscopeYaw+(Math.signum(yy)*MathHelper.clamp(Math.abs(yy), 0, TripodPeriscope.turnSpeed*partialTicks)));
+ float yy = MathHelper.wrapDegrees(360+entity.aim.getTargetYaw()-entity.aim.getYaw(partialTicks));
+ float yaw = MathHelper.wrapDegrees(entity.aim.getYaw(partialTicks)+(Math.signum(yy)*MathHelper.clamp(Math.abs(yy), 0, TripodPeriscope.turnSpeed*partialTicks)));
GlStateManager.popMatrix();
- GlStateManager.rotate(-yaw+90, 0, 1, 0);
+ GlStateManager.rotate(-entity.aim.getYaw(partialTicks)+90, 0, 1, 0);
for(ModelRendererTurbo mod : model.periscopeModel)
mod.render();
@@ -120,7 +119,7 @@ private void renderProgress(EntityTripodPeriscope entity, float entityYaw, float
GlStateManager.color(1f, 1f, 1f, Math.min(periscopePlacementProgress, 1));
GlStateManager.translate(0.0625f/2f, (1f-periscopePlacementProgress)*1.5f, -0.0625f/2f);
GlStateManager.rotate(periscopeRotationProgress*720, 0, 1, 0);
- GlStateManager.rotate(-entity.periscopeYaw+90, 0, 1, 0);
+ GlStateManager.rotate(-entity.aim.getYaw(partialTicks)+90, 0, 1, 0);
if(tripodProgress > 0)
{
for(ModelRendererTurbo mod : model.periscopeModel)
@@ -164,13 +163,13 @@ public boolean handleBipedRotations(ModelBiped model, EntityTripodPeriscope mg,
model.bipedHeadwear.rotateAngleY = 0;
- if(Math.abs(mg.periscopeYaw-true_head_angle) > 5)
- if(mg.periscopeYaw < true_head_angle)
+ if(Math.abs(mg.aim.getYaw(partialTicks)-true_head_angle) > 5)
+ if(mg.aim.getYaw(partialTicks) < true_head_angle)
{
model.bipedRightLeg.rotateAngleZ = -(1f-wtime)*0.25f;
model.bipedLeftLeg.rotateAngleZ = -wtime*0.25f-0.25f;
}
- else if(mg.periscopeYaw > true_head_angle)
+ else if(mg.aim.getYaw(partialTicks) > true_head_angle)
{
model.bipedRightLeg.rotateAngleZ = (1f-wtime)*0.25f+0.25f;
model.bipedLeftLeg.rotateAngleZ = wtime*0.25f;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MachinegunItemStackRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MachinegunItemStackRenderer.java
index a31d19026..fea22a0d0 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MachinegunItemStackRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MachinegunItemStackRenderer.java
@@ -20,7 +20,7 @@ public void renderByItem(ItemStack itemStackIn, float partialTicks)
GlStateManager.pushMatrix();
RenderHelper.enableStandardItemLighting();
- MachinegunRenderer.renderMachinegun(itemStackIn, null);
+ MachinegunRenderer.renderMachinegun(itemStackIn, null, 0);
GlStateManager.popMatrix();
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MineDetectorRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MineDetectorRenderer.java
index a7fef8c4a..0531c037f 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MineDetectorRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/item/MineDetectorRenderer.java
@@ -75,15 +75,15 @@ public float renderBase(EntityLivingBase player, float distance, boolean flipY)
v *= 1.125f;
}
- //v=distance;
- //v=distance-(((player.world.getTotalWorldTime()%100)/100f)*distance);
+ v = distance;
+ v = distance-(((player.world.getTotalWorldTime()%100)/100f)*distance);
- //GlStateManager.rotate(player.cameraPitch,1,0,0);
+ GlStateManager.rotate(player.cameraPitch, 1, 0, 0);
GlStateManager.translate(0, 1, -v);
GlStateManager.rotate(90, 0, 1, 0);
GlStateManager.scale(-1, -1, 1);
- //GlStateManager.rotate(player.rotationYawHead,0,1,0);
- //GlStateManager.rotate(180,0,1,0);
+ GlStateManager.rotate(player.rotationYawHead, 0, 1, 0);
+ GlStateManager.rotate(180, 0, 1, 0);
for(ModelRendererTurbo mod : model.baseModel)
mod.render();
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/metal_device/LatexCollectorRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/metal_device/LatexCollectorRenderer.java
index 96b0b15db..798335ce5 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/metal_device/LatexCollectorRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/metal_device/LatexCollectorRenderer.java
@@ -1,106 +1,71 @@
package pl.pabilo8.immersiveintelligence.client.render.metal_device;
-import blusunrize.immersiveengineering.api.IEProperties;
-import blusunrize.immersiveengineering.client.ClientUtils;
import net.minecraft.block.state.IBlockState;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.*;
-import net.minecraft.client.renderer.block.model.IBakedModel;
-import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.util.math.Vec3d;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraftforge.client.model.obj.OBJModel;
import net.minecraftforge.fluids.FluidStack;
-import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
-import net.minecraftforge.fluids.capability.IFluidHandlerItem;
-import org.lwjgl.opengl.GL11;
+import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
+import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCompiledMap;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTModel;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMT;
+import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTFluid;
+import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IITileRenderer;
+import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IITileRenderer.RegisteredTileRenderer;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.LatexCollector;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.TileEntityLatexCollector;
-
-import static blusunrize.immersiveengineering.api.IEProperties.FACING_HORIZONTAL;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
/**
* @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 13.05.2026
+ * @ii-approved 0.3.1
* @since 30.08.2020
*/
-public class LatexCollectorRenderer extends TileEntitySpecialRenderer
+@RegisteredTileRenderer(name = "latex_collector", clazz = TileEntityLatexCollector.class)
+public class LatexCollectorRenderer extends IITileRenderer
{
- // TODO: 11.07.2022 adapt to AMT
+ private IIAnimationCompiledMap placeBucket, extractorVisibility;
+ private AMTModel model;
+ private AMTFluid latex;
@Override
- public void render(TileEntityLatexCollector te, double x, double y, double z, float partialTicks, int destroyStage, float alpha)
+ public void draw(TileEntityLatexCollector te, BufferBuilder buf, float partialTicks, Tessellator tes)
{
- if(te!=null)
- {
- GlStateManager.pushMatrix();
- GlStateManager.translate(x, y, z);
- GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
-
- if(!te.bucket.isEmpty())
- {
-
- float progress = MathHelper.clamp(1f-((te.bucketTime-partialTicks)/10f), 0, 1);
-
- GlStateManager.enableBlend();
- GlStateManager.pushMatrix();
- GlStateManager.enableAlpha();
- GlStateManager.color(1f, 1f, 1f, 0.25f);
- GlStateManager.translate(0, 0, 0);
-
- final BlockRendererDispatcher blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
- BlockPos blockPos = te.getPos();
- IBlockState state = getWorld().getBlockState(te.getPos()).withProperty(IEProperties.BOOLEANS[0], true).withProperty(FACING_HORIZONTAL, te.facing);
- IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState(state);
-
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- RenderHelper.disableStandardItemLighting();
- GlStateManager.blendFunc(770, 771);
- GlStateManager.enableBlend();
- GlStateManager.disableCull();
-
- ClientUtils.bindAtlas();
-
- worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
- Vec3d vv = new Vec3d(blockPos).scale(-1).add(new Vec3d(0, 0.5, 0).add(new Vec3d(te.facing.getOpposite().getDirectionVec())).scale(0.5).scale((1-Math.min(progress, 1))));
- worldRenderer.setTranslation(vv.x, vv.y, vv.z);
-
- blockRenderer.getBlockModelRenderer().renderModel(te.getWorld(), model, state, blockPos, worldRenderer, true);
- worldRenderer.setTranslation(0.0D, 0.0D, 0.0D);
- tessellator.draw();
-
- float atime = te.timer;
- if(!te.bucket.isEmpty()&&te.timer==0&&te.bucket.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null))
- {
- IFluidHandlerItem cap = te.bucket.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null);
- if(cap!=null)
- {
- FluidStack drain = cap.drain(1000, false);
- atime += drain!=null&&drain.amount==1000?LatexCollector.collectTime: 0;
- }
- }
- float amount = Math.min((atime+(!te.bucket.isEmpty()&&te.isNextToTree()?(partialTicks*te.getIncomeModifier()): 0))/(float)LatexCollector.collectTime, 1f);
- if(progress >= 1&&amount > 0)
- {
- GlStateManager.translate(0.5, 0, 0.5);
- GlStateManager.rotate(-te.facing.getHorizontalAngle(), 0, 1, 0);
- GlStateManager.translate(-0.25, 0.3125+(0.655*amount), -0.125);
- GlStateManager.rotate(90, 1, 0, 0);
- GlStateManager.scale(0.0625f, 0.0625f, 0.0625f);
- ClientUtils.drawRepeatedFluidSprite(new FluidStack(IIContent.fluidLatex, 1), 0f, 0f, 8, 8);
- }
-
- RenderHelper.enableStandardItemLighting();
-
- GlStateManager.popMatrix();
- GlStateManager.disableBlend();
- }
+ //Bucket place animation
+ float bucketProgress = 0f;
+ if(!te.bucket.isEmpty())
+ bucketProgress = AMTUtils.getAnimationProgress(te.bucketTime, 10f, true, partialTicks);
+ placeBucket.apply(bucketProgress);
+ //Chain and extractor visibility
+ boolean nextToTree = te.isNextToTree();
+ extractorVisibility.apply(nextToTree?1f: 0f);
+
+ //Apply latex level
+ float atime = te.timer;
+ latex.withLevel(Math.min((atime+(!te.bucket.isEmpty()&&nextToTree?(partialTicks*te.getIncomeModifier()): 0))/(float)LatexCollector.collectTime, 1f));
+
+ //Render
+ applyStandardRotation(te.facing);
+ model.render(tes, buf);
+ }
- GlStateManager.popMatrix();
+ @Override
+ public void compileModels(IBlockState state, OBJModel model)
+ {
+ this.model = new AMTModel(state, model, header -> new AMT[]{
+ this.latex = new AMTFluid("latex", header)
+ .withFluid(new FluidStack(IIContent.fluidLatex, 1000))
+ });
+ this.placeBucket = IIAnimationCompiledMap.create(this.model, IIReference.RES_II.with("latex_collector/place_bucket"));
+ this.extractorVisibility = IIAnimationCompiledMap.create(this.model, IIReference.RES_II.with("latex_collector/extractor"));
+ }
- }
+ @Override
+ protected void nullifyModels()
+ {
+ this.model = AMTUtils.disposeOf(this.model);
+ this.latex = null;
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ArithmeticLogicMachineRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ArithmeticLogicMachineRenderer.java
index c67440a71..1ff8e1a48 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ArithmeticLogicMachineRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ArithmeticLogicMachineRenderer.java
@@ -7,6 +7,7 @@
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.client.model.obj.OBJModel;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCachedMap;
import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCachedModel;
@@ -125,6 +126,11 @@ public void compileModels(IBlockState state, OBJModel model)
this.animationDrawer = IIAnimationCachedMap.create(this.model, ResLoc.of(IIReference.RES_II, "arithmetic_logic_machine/open_drawer"));
this.animationDoor = IIAnimationCachedMap.create(this.model, ResLoc.of(IIReference.RES_II, "arithmetic_logic_machine/open_door"));
this.animationKeyboard = IIAnimationCachedMap.create(this.model, ResLoc.of(IIReference.RES_II, "arithmetic_logic_machine/open_keyboard"));
+
+ UpgradeTechTree.getTreeFor(TileEntityArithmeticLogicMachine.class)
+ .withBaseModelLocation(IIReference.RES_BLOCK_MODEL.with("multiblock/arithmetic_logic_machine/arithmetic_logic_machine_preview.obj"))
+ .withUpgradeModelLocation(IIContent.UPGRADE_MEMORY, resFolder.with("upgrades/circuit_racks.obj"))
+ .withUpgradeModelLocation(IIContent.UPGRADE_CIRCUIT_RACKS, resFolder.with("upgrades/memory.obj"));
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/DataInputMachineRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/DataInputMachineRenderer.java
index d7452f67f..532df4cf6 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/DataInputMachineRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/DataInputMachineRenderer.java
@@ -6,10 +6,14 @@
import net.minecraftforge.client.model.obj.OBJModel;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
-import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCompiledMap;
-import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTModel;
+import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCachedMap;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCachedModel;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTCachedModelBuilder;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTUpgradeCachedModel;
+import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTUpgradeCachedModel.MachineCachedUpgradeModelBuilder;
import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IIMultiblockRenderer;
import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IITileRenderer.RegisteredTileRenderer;
+import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.tileentity.TileEntityDataInputMachine;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
@@ -23,14 +27,16 @@
@RegisteredTileRenderer(name = "multiblock/data_input_machine", clazz = TileEntityDataInputMachine.class)
public class DataInputMachineRenderer extends IIMultiblockRenderer
{
- private AMTModel model;
- private IIAnimationCompiledMap animationDrawer, animationHatch, animationProgrammingStart;
+ private AMTCachedModel model;
+ private AMTUpgradeCachedModel upgradeAdvancedData;
+ private IIAnimationCachedMap animationDrawer, animationHatch, animationProgrammingStart;
@Override
public void drawAnimated(TileEntityDataInputMachine te, BufferBuilder buf, float partialTicks, Tessellator tes)
{
//Reset model to default state
- model.defaultize();
+ this.model.getVariant(te, te.upgradeManager);
+ this.model.defaultize();
animationDrawer.apply(te.drawer.getProgress(partialTicks));
animationHatch.apply(te.hatch.getProgress(partialTicks));
@@ -42,6 +48,10 @@ public void drawAnimated(TileEntityDataInputMachine te, BufferBuilder buf, float
//Draw
applyStandardMirroring(te, true);
+
+ //Display upgrade construction
+ upgradeAdvancedData.apply(te, tes, buf, partialTicks);
+
//Render
model.render(tes, buf);
applyStandardMirroring(te, false);
@@ -51,6 +61,7 @@ public void drawAnimated(TileEntityDataInputMachine te, BufferBuilder buf, float
public void drawSimple(BufferBuilder buf, float partialTicks, Tessellator tes)
{
//Reset model to default state
+ model.getBase();
model.defaultize();
//Render
model.render(tes, buf);
@@ -60,15 +71,31 @@ public void drawSimple(BufferBuilder buf, float partialTicks, Tessellator tes)
public void compileModels(IBlockState state, OBJModel model)
{
//model loading
- this.model = new AMTModel(state, model);
+ ResLoc resFolder = IIReference.RES_II.with("models/block/multiblock/data_input_machine/");
+ AMTCachedModelBuilder modelBuilder =
+ AMTCachedModelBuilder.startTileEntityModel(TileEntityDataInputMachine.class)
+ .withModel(model)
+ .withHeader(resFolder.with("data_input_machine.obj.amt"));
+
+ //upgrade models
+ this.upgradeAdvancedData = new MachineCachedUpgradeModelBuilder<>(modelBuilder)
+ .withUpgrade(IIContent.UPGRADE_ADVANCED_DATA)
+ .withConstructionModel(resFolder.with("upgrades/advanced_data.obj"))
+ .withAnimation(ResLoc.of(IIReference.RES_II, "data_input_machine/upgrade_advanced_data"))
+ .build();
+
+ //finish main model
+ this.model = modelBuilder.build();
//animations
- animationDrawer = IIAnimationCompiledMap.create(this.model, ResLoc.of(IIReference.RES_II, "data_input_machine/drawer"));
- animationHatch = IIAnimationCompiledMap.create(this.model, ResLoc.of(IIReference.RES_II, "data_input_machine/hatch"));
- animationProgrammingStart = IIAnimationCompiledMap.create(this.model, ResLoc.of(IIReference.RES_II, "data_input_machine/programming_start"));
+ animationDrawer = IIAnimationCachedMap.create(this.model, ResLoc.of(IIReference.RES_II, "data_input_machine/drawer"));
+ animationHatch = IIAnimationCachedMap.create(this.model, ResLoc.of(IIReference.RES_II, "data_input_machine/hatch"));
+ animationProgrammingStart = IIAnimationCachedMap.create(this.model, ResLoc.of(IIReference.RES_II, "data_input_machine/programming_start"));
UpgradeTechTree.getTreeFor(TileEntityDataInputMachine.class)
- .withBaseModelLocation(IIReference.RES_BLOCK_MODEL.with("multiblock/data_input_machine/data_input_machine.obj"));
+ .withBaseModelLocation(IIReference.RES_BLOCK_MODEL.with("multiblock/data_input_machine/data_input_machine_preview.obj"))
+ .withUpgradeModelLocation(IIContent.UPGRADE_ADVANCED_DATA, IIReference.RES_BLOCK_MODEL.with(
+ "multiblock/data_input_machine/upgrades/advanced_data.obj"));
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/PrintingPressRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/PrintingPressRenderer.java
index 7b19203ed..f508bb91d 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/PrintingPressRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/PrintingPressRenderer.java
@@ -5,6 +5,7 @@
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.item.ItemStack;
import net.minecraftforge.client.model.obj.OBJModel;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.client.util.amt.AMTUtils;
import pl.pabilo8.immersiveintelligence.client.util.amt.animation.IIAnimationCompiledMap;
import pl.pabilo8.immersiveintelligence.client.util.amt.models.AMTModel;
@@ -12,6 +13,7 @@
import pl.pabilo8.immersiveintelligence.client.util.amt.parts.AMTItem;
import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IIMultiblockRenderer;
import pl.pabilo8.immersiveintelligence.client.util.amt.renderer.IITileRenderer.RegisteredTileRenderer;
+import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.multiblock.MultiblockPrintingPress;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.tileentity.TileEntityPrintingPress;
import pl.pabilo8.immersiveintelligence.common.util.IIReference;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
@@ -36,8 +38,8 @@ public void drawAnimated(TileEntityPrintingPress te, BufferBuilder buf, float pa
model.defaultize();
animationDefault.apply(0);
- itemModel.setStack(te.inventory.get(TileEntityPrintingPress.SLOT_PAPER));
- stackModel.setStack(te.inventory.get(TileEntityPrintingPress.SLOT_OUTPUT));
+ itemModel.setStack(te.inventory.get(MultiblockPrintingPress.SLOT_PAPER));
+ stackModel.setStack(te.inventory.get(MultiblockPrintingPress.SLOT_OUTPUT));
if(!te.processQueue.isEmpty())
{
@@ -82,6 +84,9 @@ public void compileModels(IBlockState state, OBJModel model)
//animations
animationDefault = IIAnimationCompiledMap.create(this.model, ResLoc.of(IIReference.RES_II, "printing_press/default"));
animationWork = IIAnimationCompiledMap.create(this.model, ResLoc.of(IIReference.RES_II, "printing_press/work"));
+
+ UpgradeTechTree.getTreeFor(TileEntityPrintingPress.class)
+ .withBaseModelLocation(IIReference.RES_BLOCK_MODEL.with("multiblock/printing_press/printing_press_inv.obj"));
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ProjectileWorkshopRenderer.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ProjectileWorkshopRenderer.java
index d447a85b9..3d4e6b3eb 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ProjectileWorkshopRenderer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/render/multiblock/metal/ProjectileWorkshopRenderer.java
@@ -99,6 +99,6 @@ public void compileModels(IBlockState state, OBJModel model)
coreFiller = IIAnimationCompiledMap.create(this.model, ResLoc.of(IIReference.RES_II, "projectile_workshop/production_filling"));
UpgradeTechTree.getTreeFor(TileEntityProjectileWorkshop.class)
- .withBaseModelLocation(IIReference.RES_BLOCK_MODEL.with("multiblock/projectile_workshop/projectile_workshop.obj"));
+ .withBaseModelLocation(IIReference.RES_BLOCK_MODEL.with("multiblock/projectile_workshop/projectile_workshop_inv.obj"));
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/CameraHandler.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/CameraHandler.java
index 0c3685433..46c33c730 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/CameraHandler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/CameraHandler.java
@@ -7,11 +7,11 @@
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
-import pl.pabilo8.immersiveintelligence.api.utils.camera.IEntityZoomProvider;
-import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedZoomTool;
-import pl.pabilo8.immersiveintelligence.client.ClientEventHandler;
+import pl.pabilo8.immersiveintelligence.api.utils.camera.ICameraEntity;
+import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedZoom;
import pl.pabilo8.immersiveintelligence.common.entity.EntityCamera;
/**
@@ -25,12 +25,18 @@ public class CameraHandler
//--- ZoomHandler ---//
public static float fovZoom = 1;
public static ZoomType type = null;
- public static IAdvancedZoomTool zoom;
+ public static IAdvancedZoom zoom;
public static ItemStack stack;
+
//--- CameraHandler ---//
private static EntityCamera camera;
private static boolean enabled = false;
+ public static void setCameraPos(Vec3d pos)
+ {
+ setCameraPos(pos.x, pos.y, pos.z);
+ }
+
public static void setCameraPos(BlockPos pos)
{
setCameraPos(pos.getX()+0.5, pos.getY(), pos.getZ()+0.5);
@@ -101,21 +107,24 @@ private static boolean handleZoomLogic()
Entity lowestRidden;
//Zoom provider is an item in player's hand
- if((stack = player.getHeldItem(EnumHand.MAIN_HAND)).getItem() instanceof IAdvancedZoomTool)
+ if((stack = player.getHeldItem(EnumHand.MAIN_HAND)).getItem() instanceof IAdvancedZoom)
{
type = ZoomType.ITEM_MAINHAND;
- zoom = (IAdvancedZoomTool)(stack.getItem());
+ zoom = (IAdvancedZoom)(stack.getItem());
}
- else if((stack = player.getHeldItem(EnumHand.OFF_HAND)).getItem() instanceof IAdvancedZoomTool)
+ else if((stack = player.getHeldItem(EnumHand.OFF_HAND)).getItem() instanceof IAdvancedZoom)
{
type = ZoomType.ITEM_OFFHAND;
- zoom = (IAdvancedZoomTool)(stack.getItem());
+ zoom = (IAdvancedZoom)(stack.getItem());
}
//Zoom provider is an entity ridden by player
- else if(ClientEventHandler.mgAiming&&(lowestRidden = player.getLowestRidingEntity()) instanceof IEntityZoomProvider)
+ else if((lowestRidden = player.getLowestRidingEntity()) instanceof ICameraEntity)
{
+ ICameraEntity camera = (ICameraEntity)lowestRidden;
+ if(!camera.isCameraEnabled(player))
+ return false;
type = ZoomType.RIDING;
- zoom = ((IEntityZoomProvider)lowestRidden).getZoom();
+ zoom = camera.getZoom();
}
else
return false;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/IIKeybind.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/IIKeybind.java
index 911f2beff..6d8a9cfc4 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/IIKeybind.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/IIKeybind.java
@@ -2,9 +2,11 @@
import blusunrize.immersiveengineering.client.ClientUtils;
import net.minecraft.client.settings.KeyBinding;
+import net.minecraft.entity.Entity;
import net.minecraftforge.client.settings.IKeyConflictContext;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMountedWeapon;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
/**
@@ -21,7 +23,8 @@ public class IIKeybind extends KeyBinding
@Override
public boolean isActive()
{
- return ClientUtils.mc().player.getRidingEntity() instanceof EntityVehicleSeat;
+ Entity seat = ClientUtils.mc().player.getRidingEntity();
+ return seat instanceof EntityVehicleSeat||seat instanceof EntityMountedWeapon;
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/ShaderUtil.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/ShaderUtil.java
index 37b9b95ea..448c85866 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/ShaderUtil.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/ShaderUtil.java
@@ -61,6 +61,7 @@ public static boolean useShader(@Nullable Shaders shader, @Nonnull float... para
if(shader==null||!shader.use())
return false;
+ shader.setInt("lightmap", 1);
switch(shader)
{
case BLUEPRINT:
@@ -246,6 +247,11 @@ int getRef(String name)
return ARBShaderObjects.glGetUniformLocationARB(programID, name);
}
+ void setInt(String name, int value)
+ {
+ ARBShaderObjects.glUniform1iARB(getRef(name), value);
+ }
+
void setFloat(String name, float value)
{
ARBShaderObjects.glUniform1fARB(getRef(name), value);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/amt/AMTLoader.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/amt/AMTLoader.java
index 877157e13..a57889ba3 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/amt/AMTLoader.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/amt/AMTLoader.java
@@ -88,7 +88,7 @@ public static JsonObject readServerFileToJson(@Nonnull ResourceLocation res, Str
public static IIAnimation loadAnimation(@Nonnull ResourceLocation res)
{
ResourceLocation fullRes = new ResourceLocation(res.getResourceDomain(), "animations/"+res.getResourcePath()+".json");
- return new IIAnimation(res, readFileToJSON(fullRes, "model header"));
+ return new IIAnimation(res, readFileToJSON(fullRes, "animation"));
}
public static IIAnimation loadAnimationServer(@Nonnull ResourceLocation res)
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/carversound/CompoundSound.java b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/carversound/CompoundSound.java
index 7042c73cb..70ac3c630 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/client/util/carversound/CompoundSound.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/client/util/carversound/CompoundSound.java
@@ -64,8 +64,16 @@ public void setVolume(float volume)
this.volume = volume;
}
+ public void setPosition(Vec3d position)
+ {
+ this.xPosF = (float)position.x;
+ this.yPosF = (float)position.y;
+ this.zPosF = (float)position.z;
+ }
+
public void start()
{
Minecraft.getMinecraft().getSoundHandler().playSound(this);
}
+
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/CommonProxy.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/CommonProxy.java
index 4ed0f6e49..c95583910 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/CommonProxy.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/CommonProxy.java
@@ -22,6 +22,7 @@
import blusunrize.immersiveengineering.common.items.IEItemInterfaces.IGuiItem;
import blusunrize.immersiveengineering.common.util.ChatUtils;
import blusunrize.immersiveengineering.common.util.IEPotions;
+import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import net.minecraft.block.Block;
import net.minecraft.block.BlockTNT;
import net.minecraft.block.state.IBlockState;
@@ -84,7 +85,10 @@
import pl.pabilo8.immersiveintelligence.common.crafting.IIRecipes;
import pl.pabilo8.immersiveintelligence.common.crafting.RecipePowerpackAdvanced;
import pl.pabilo8.immersiveintelligence.common.crafting.RecipeSkinCraftingHandler;
-import pl.pabilo8.immersiveintelligence.common.entity.*;
+import pl.pabilo8.immersiveintelligence.common.entity.EntityHans;
+import pl.pabilo8.immersiveintelligence.common.entity.EntityParachute;
+import pl.pabilo8.immersiveintelligence.common.entity.EntitySkyCrate;
+import pl.pabilo8.immersiveintelligence.common.entity.EntitySkycrateInternal;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.component.*;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.*;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.naval_mine.EntityNavalMine;
@@ -99,14 +103,19 @@
import pl.pabilo8.immersiveintelligence.common.entity.minecart.crate.EntityMinecartCrateReinforced;
import pl.pabilo8.immersiveintelligence.common.entity.minecart.crate.EntityMinecartCrateSteel;
import pl.pabilo8.immersiveintelligence.common.entity.minecart.crate.EntityMinecartCrateWooden;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMachinegun;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMortar;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityTripodPeriscope;
import pl.pabilo8.immersiveintelligence.common.entity.tactile.EntityAMTTactile;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityDrone;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityMotorbike;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.EntityTrackedMotorbike;
+import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldFlak;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldGun;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.towable.gun.EntityFieldHowitzer;
import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
-import pl.pabilo8.immersiveintelligence.common.gui.ContainerUpgrade;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerEntityUpgrade;
+import pl.pabilo8.immersiveintelligence.common.gui.ContainerTileUpgrade;
import pl.pabilo8.immersiveintelligence.common.item.ItemIIMinecart.Minecarts;
import pl.pabilo8.immersiveintelligence.common.item.crafting.material.ItemIIMaterialDust.MaterialsDust;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
@@ -724,6 +733,7 @@ public void init(FMLInitializationEvent event)
registerEntity(i++, EntityMotorbike.class, "motorbike", 64, 1, false);
registerEntity(i++, EntityTrackedMotorbike.class, "tracked_motorbike", 64, 1, false);
registerEntity(i++, EntityFieldHowitzer.class, "field_howitzer", 64, 1, false);
+ registerEntity(i++, EntityFieldFlak.class, "field_flak", 64, 1, false);
registerEntity(i++, EntityFieldGun.class, "field_gun", 64, 1, false);
registerEntity(i++, EntityTripodPeriscope.class, "tripod_periscope", 64, 1, true);
@@ -790,12 +800,21 @@ public Object getServerGuiElement(int ID, EntityPlayer player, World world, int
EnumHand hand;
TileEntity te = world.getTileEntity(new BlockPos(x, y, z));
ItemStack stack = player.getHeldItem(hand = (player.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof IGuiItem?EnumHand.MAIN_HAND: EnumHand.OFF_HAND));
+ Entity entity = y==Integer.MIN_VALUE?world.getEntityByID(x): null;
- if(ID==IIGUI.UPGRADE.ordinal()&&te instanceof IUpgradableDevice)
+ if(ID==IIGUI.UPGRADE_TILE.ordinal()&&te instanceof IUpgradableDevice)
{
IUpgradableDevice upgradeMaster = ((IUpgradableDevice)te).master();
if(upgradeMaster!=null)
- return new ContainerUpgrade(player, (TileEntityIEBase & IUpgradableDevice)upgradeMaster);
+ //noinspection rawtypes,unchecked
+ return new ContainerTileUpgrade(player, (TileEntityIEBase & IUpgradableDevice)upgradeMaster);
+ }
+ if(ID==IIGUI.UPGRADE_ENTITY.ordinal()&&entity instanceof IUpgradableDevice)
+ {
+ IUpgradableDevice upgradeMaster = ((IUpgradableDevice)entity).master();
+ if(upgradeMaster!=null)
+ //noinspection rawtypes,unchecked
+ return new ContainerEntityUpgrade<>(player, (Entity & IUpgradableDevice & IIEInventory)upgradeMaster);
}
if(IIGUI.values().length > ID)
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/EventHandler.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/EventHandler.java
index 7473b81f6..77e506160 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/EventHandler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/EventHandler.java
@@ -2,7 +2,10 @@
import blusunrize.immersiveengineering.api.MultiblockHandler.MultiblockFormEvent.Post;
import blusunrize.immersiveengineering.common.util.ItemNBTHelper;
+import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
+import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.MultiPartEntityPart;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
@@ -13,6 +16,7 @@
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSourceIndirect;
+import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.world.GameRules;
import net.minecraft.world.GameRules.ValueType;
@@ -27,6 +31,7 @@
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent.EntityInteract;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickEmpty;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickItem;
@@ -42,9 +47,11 @@
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
+import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
import pl.pabilo8.immersiveintelligence.api.ammo.penetration.DamageBlockPos;
import pl.pabilo8.immersiveintelligence.api.ammo.utils.IIAmmoUtils;
import pl.pabilo8.immersiveintelligence.api.ammo.utils.PenetrationCache;
+import pl.pabilo8.immersiveintelligence.api.upgrade.IUpgradableDevice;
import pl.pabilo8.immersiveintelligence.api.utils.IAdvancedMultiblock;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Ammunition;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons;
@@ -52,8 +59,9 @@
import pl.pabilo8.immersiveintelligence.common.compat.IICompatModule;
import pl.pabilo8.immersiveintelligence.common.crafting.IIRecipes;
import pl.pabilo8.immersiveintelligence.common.entity.EntityHans;
-import pl.pabilo8.immersiveintelligence.common.entity.EntityMachinegun;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
+import pl.pabilo8.immersiveintelligence.common.entity.mounted_weapon.EntityMountedWeapon;
+import pl.pabilo8.immersiveintelligence.common.entity.vehicle.utils.part.EntityVehicleSeat;
import pl.pabilo8.immersiveintelligence.common.item.ammo.ItemIIBulletMagazine;
import pl.pabilo8.immersiveintelligence.common.item.armor.ItemIILightEngineerBoots;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
@@ -119,10 +127,8 @@ else if(event.getSource()==DamageSource.IN_FIRE||event.getSource()==DamageSource
}
//springs
else if(event.getSource()==DamageSource.FALL)
- {
if(ItemIIUpgradeableArmor.isArmorWithUpgrade(boots, "springs"))
event.setCanceled(true);
- }
}
//--- World Load Handling ---//
@@ -232,9 +238,8 @@ public void onWorldTick(WorldTickEvent event)
@SubscribeEvent
public void onMultiblockForm(Post event)
{
+ //Required by Advanced Structures!
if(event.isCancelable()&&!event.isCanceled()&&event.getMultiblock().getClass().isAnnotationPresent(IAdvancedMultiblock.class))
- {
- //Required by Advanced Structures!
if(!IIItemUtils.isAdvancedHammer(event.getHammer()))
{
if(!event.getEntityPlayer().getEntityWorld().isRemote)
@@ -242,15 +247,16 @@ public void onMultiblockForm(Post event)
IIStringUtil.getItemStackTextComponent(IIContent.itemHammer.getStack(1)));
event.setCanceled(true);
}
- }
}
- //Cancel when using a machinegun
@SubscribeEvent(priority = EventPriority.HIGH)
public void onItemUse(RightClickBlock event)
{
- EntityLivingBase living = event.getEntityLiving();
- if(living.isRiding()&&living.getRidingEntity() instanceof EntityMachinegun)
+ if(!event.getEntity().isRiding())
+ return;
+ Entity baseEntity = event.getEntity().getRidingEntity();
+ //Cancel when using a vehicle
+ if(baseEntity instanceof EntityMountedWeapon||baseEntity instanceof EntityVehicleSeat)
{
event.setResult(Result.DENY);
event.setCanceled(true);
@@ -261,8 +267,11 @@ public void onItemUse(RightClickBlock event)
@SubscribeEvent(priority = EventPriority.HIGH)
public void onBlockUse(RightClickItem event)
{
- //Machinegun
- if(event.getEntity().isRiding()&&event.getEntity().getRidingEntity() instanceof EntityMachinegun)
+ if(!event.getEntity().isRiding())
+ return;
+ Entity baseEntity = event.getEntity().getRidingEntity();
+ //Cancel when using a vehicle
+ if(baseEntity instanceof EntityMountedWeapon||baseEntity instanceof EntityVehicleSeat)
{
event.setResult(Result.DENY);
event.setCanceled(true);
@@ -273,10 +282,12 @@ public void onBlockUse(RightClickItem event)
@SubscribeEvent(priority = EventPriority.HIGH)
public void onEmptyRightclick(RightClickEmpty event)
{
- if(event.getEntity().isRiding()&&event.getEntity().getRidingEntity() instanceof EntityMachinegun)
- {
+ if(!event.getEntity().isRiding())
+ return;
+ Entity baseEntity = event.getEntity().getRidingEntity();
+ //Cancel when using a vehicle
+ if(baseEntity instanceof EntityMountedWeapon||baseEntity instanceof EntityVehicleSeat)
event.setResult(Result.DENY);
- }
}
@SubscribeEvent
@@ -299,6 +310,33 @@ public void onBreakBlock(BreakEvent event)
}
}
+ @SubscribeEvent
+ public void onPlayerInteractEntityInteract(EntityInteract event)
+ {
+ EntityPlayer player = event.getEntityPlayer();
+
+ //Display upgrade GUI for compatible entities when using a wrench
+ if(IIItemUtils.isWrench(player.getHeldItem(EnumHand.MAIN_HAND))||IIItemUtils.isWrench(player.getHeldItem(EnumHand.OFF_HAND)))
+ {
+ Entity interacted = event.getTarget();
+ if(interacted instanceof MultiPartEntityPart)
+ interacted = (Entity)((MultiPartEntityPart)interacted).parent;
+ if(interacted instanceof IUpgradableDevice)
+ {
+ if(!(interacted instanceof IIEInventory))
+ {
+ IILogger.error("Cannot open upgrade GUI for "+interacted+", it does not implement IIEInventory!");
+ return;
+ }
+ //Open entity GUI
+ player.openGui(ImmersiveIntelligence.INSTANCE, IIGUI.UPGRADE_ENTITY.ordinal(),
+ interacted.world, interacted.getEntityId(), Integer.MIN_VALUE, 0);
+ }
+ }
+
+ }
+
+
//--- Hanses ---//
@SubscribeEvent(priority = EventPriority.LOW)
@@ -316,12 +354,10 @@ public void onLivingUpdate(LivingUpdateEvent event)
EntityPlayer player = (EntityPlayer)living;
//Potion effects
+ //Apply radiation
if(world.getTotalWorldTime()%20==0)
- {
- //Apply radiation
if(!player.isCreative()&&biome==IIContent.biomeWasteland)
living.addPotionEffect(new PotionEffect(IIPotions.radiation, 2000, 0, false, false));
- }
//Handle powerpack crafted with armor
if(!living.getItemStackFromSlot(EntityEquipmentSlot.CHEST).isEmpty()
@@ -395,10 +431,8 @@ else if(event.getSource()==DamageSource.IN_FIRE||event.getSource()==DamageSource
}
//springs
else if(event.getSource()==DamageSource.FALL)
- {
if(ItemIIUpgradeableArmor.isArmorWithUpgrade(boots, "springs"))
event.setCanceled(true);
- }
}
/**
@@ -418,9 +452,7 @@ public void onLivingFallEvent(LivingFallEvent event)
if(!(piece.getItem() instanceof ItemIILightEngineerBoots)) continue;
ItemIILightEngineerBoots boots = (ItemIILightEngineerBoots)piece.getItem();
if(boots.hasUpgrade(piece, "internal_springs"))
- {
event.setDistance(0);
- }
}
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIConfigHandler.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIConfigHandler.java
index 9f9edd74d..087a133e1 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIConfigHandler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIConfigHandler.java
@@ -1822,7 +1822,7 @@ public static class Machinegun
public static int clipReloadTime = 35;
@Comment({"Time required to fire a single bullet in MG."})
- public static int bulletFireTime = 2;
+ public static int fireDelay = 2;
@Comment({"Time required to set up the MG (in ticks)."})
public static int setupTime = 50;
@@ -1836,8 +1836,10 @@ public static class Machinegun
@Comment({"Amount of vertical recoil after taking a shot."})
public static float recoilVertical = 2.5f;
+ //Upgrades
+
@Comment({"Fire rate multiplier when heavy barrel is mouted on mg."})
- public static float heavyBarrelFireRateMultiplier = 0.25f;
+ public static int heavyBarrelFireDelay = 1;
@Comment({"Horizontal recoil after taking a shot with heavy barrel mounted."})
public static float recoilHBHorizontal = 1.25f;
@@ -1881,10 +1883,10 @@ public static class Machinegun
@Comment({"Max zoom of a machinegun with a scope mounted (in Blu's Unit of Distance Measurementâ„¢)."})
@RequiresMcRestart
- public static float[] machinegunScopeMaxZoom = new float[]{0.55f, 0.35f, 0.15f};
+ public static float[] machinegunScopeZoom = new float[]{0.15f, 0.35f, 0.55f};
@Comment({"Shield's initial strength (resistance vs attacks)."})
- public static float shieldStrengthInitial = 45;
+ public static int shieldStrengthInitial = 45;
@Comment({"Setup time multiplier when a shield is mouted on mg."})
public static float shieldSetupTimeMultiplier = 0.5f;
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIContent.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIContent.java
index e18ccadbf..9193851a8 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIContent.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIContent.java
@@ -134,10 +134,12 @@ public class IIContent
.withType(UpgradePurpose.SPECIAL);
//allows printing bound pages, books and newspapers
public static final Upgrade UPGRADE_PRESS_BATCHING = new Upgrade("printing_press/batching")
- .withType(UpgradePurpose.SPECIAL);
+ .withType(UpgradePurpose.SPECIAL)
+ .withWIPStatus();
//allows printing envelopes
public static final Upgrade UPGRADE_PRESS_ENVELOPER = new Upgrade("printing_press/enveloper")
- .withType(UpgradePurpose.SPECIAL);
+ .withType(UpgradePurpose.SPECIAL)
+ .withWIPStatus();
//allows the radar to detect radio signal emitters and send their positions
public static final Upgrade UPGRADE_RADIO_LOCATORS = new Upgrade("radio_locators");
@@ -158,7 +160,8 @@ public class IIContent
.withType(UpgradePurpose.DATA);
//arithemtic logic machine upgrade
public static final Upgrade UPGRADE_MEMORY = new Upgrade("memory")
- .withType(UpgradePurpose.DATA);
+ .withType(UpgradePurpose.DATA)
+ .withWIPStatus();
public static final Upgrade UPGRADE_CIRCUIT_RACKS = new Upgrade("circuit_racks")
.withType(UpgradePurpose.CAPACITY);
@@ -190,7 +193,8 @@ public class IIContent
new UpgradeEmplacementWeapon<>("guided_missile_launcher", EmplacementWeaponGuidedMissileLauncher::new);
public static final Upgrade UPGRADE_SOVEREIGNTY = new Upgrade("sovereignty")
- .withType(UpgradePurpose.DEFENSE_SYSTEM);
+ .withType(UpgradePurpose.DEFENSE_SYSTEM)
+ .withWIPStatus();
public static final Upgrade UPGRADE_EMPLACEMENT_FALLBACK_GRENADES = new Upgrade("emplacement/emergency_smoke")
.withType(UpgradePurpose.DEFENSE_SYSTEM);
@@ -202,16 +206,20 @@ public class IIContent
public static final Upgrade UPGRADE_EMPLACEMENT_MACHINEGUN_WATERCOOLED = new Upgrade("emplacement/machinegun/watercooled")
.withType(UpgradePurpose.EFFICIENCY);
public static final Upgrade UPGRADE_EMPLACEMENT_MACHINEGUN_BUNKER = new Upgrade("emplacement/machinegun/additional_fortifications")
- .withType(UpgradePurpose.ARMOR);
+ .withType(UpgradePurpose.ARMOR)
+ .withWIPStatus();
public static final Upgrade UPGRADE_FLAGPOLE_CAPTURE_DEFIANCE = new Upgrade("flagpole/capture_defiance")
.withType(UpgradePurpose.DEFENSE_SYSTEM);
public static final Upgrade UPGRADE_FLAGPOLE_TASER_LOCKS = new Upgrade("flagpole/taser_locks")
- .withType(UpgradePurpose.DEFENSE_SYSTEM);
+ .withType(UpgradePurpose.DEFENSE_SYSTEM)
+ .withWIPStatus();
public static final Upgrade UPGRADE_FLAGPOLE_DISTRESS_SIGNAL = new Upgrade("flagpole/distress_signal")
- .withType(UpgradePurpose.DEFENSE_SYSTEM);
+ .withType(UpgradePurpose.DEFENSE_SYSTEM)
+ .withWIPStatus();
public static final Upgrade UPGRADE_FLAGPOLE_UNIT_POST = new Upgrade("flagpole/unit_post")
- .withType(UpgradePurpose.FULL_CONVERSION);
+ .withType(UpgradePurpose.FULL_CONVERSION)
+ .withWIPStatus();
public static final Upgrade UPGRADE_VEHICLE_SMALL_STORAGE = new Upgrade("vehicle/small/storage")
.withType(UpgradePurpose.CAPACITY);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/IICreativeTab.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/IICreativeTab.java
index 1b5051675..40cdfc284 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/IICreativeTab.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/IICreativeTab.java
@@ -623,7 +623,7 @@ public void addExampleAmmo(NonNullList list)
ItemStack stackP2 = addAmmo(list, item, name+"/P2 Spitzkopfgeschoss",
IIContent.ammoCoreSteel, CoreType.PIERCING, FuseType.CONTACT);
ItemStack stackP5 = addAmmo(list, item, name+"/P5 Phosphorpatrone",
- IIContent.ammoCoreBrass, CoreType.PIERCING, FuseType.CONTACT, IIContent.ammoComponentHMX);
+ IIContent.ammoCoreBrass, CoreType.PIERCING, FuseType.CONTACT, IIContent.ammoComponentWhitePhosphorus);
ItemStack stackW1 = addAmmo(list, item, name+"/W1 Flakpatrone",
IIContent.ammoCoreBrass, CoreType.CANISTER, FuseType.PROXIMITY,
IIContent.ammoComponentWhitePhosphorus, AmmoRegistry.getComponent("shrapnel_steel"), IIContent.ammoComponentTracerPowder);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIGUI.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIGUI.java
index dbb740523..bc097ed1c 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIGUI.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIGUI.java
@@ -4,6 +4,7 @@
import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import mezz.jei.api.IModRegistry;
import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
@@ -19,6 +20,10 @@
import pl.pabilo8.immersiveintelligence.client.gui.block.arithmetic_logic_machine.GuiArithmeticLogicMachineEdit;
import pl.pabilo8.immersiveintelligence.client.gui.block.data_input_machine.GuiDataInputMachine;
import pl.pabilo8.immersiveintelligence.client.gui.block.data_input_machine.GuiDataInputMachineEdit;
+import pl.pabilo8.immersiveintelligence.client.gui.block.data_merger.GuiDataMerger;
+import pl.pabilo8.immersiveintelligence.client.gui.block.data_merger.GuiDataMergerEdit;
+import pl.pabilo8.immersiveintelligence.client.gui.block.data_router.GuiDataRouter;
+import pl.pabilo8.immersiveintelligence.client.gui.block.data_router.GuiDataRouterEdit;
import pl.pabilo8.immersiveintelligence.client.gui.block.emplacement.GuiEmplacementPageConfig;
import pl.pabilo8.immersiveintelligence.client.gui.block.emplacement.GuiEmplacementPageFireMissions;
import pl.pabilo8.immersiveintelligence.client.gui.block.emplacement.GuiEmplacementPageStorage;
@@ -35,9 +40,11 @@
import pl.pabilo8.immersiveintelligence.client.gui.deco.DecoGui.DecoResourcesLoader;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoResource;
import pl.pabilo8.immersiveintelligence.client.gui.deco.util.DecoTemplate;
+import pl.pabilo8.immersiveintelligence.client.gui.entity.GuiEntityUpgrade;
import pl.pabilo8.immersiveintelligence.client.gui.item.GuiCasingPouch;
import pl.pabilo8.immersiveintelligence.client.gui.item.GuiPrintedPage;
import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataMerger;
+import pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity.TileEntityDataRouter;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.TileEntityMetalCrate;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.effect_crate.TileEntityAmmunitionCrate;
import pl.pabilo8.immersiveintelligence.common.block.metal_device.tileentity.effect_crate.TileEntityMedicalCrate;
@@ -55,7 +62,8 @@
import pl.pabilo8.immersiveintelligence.common.gui.*;
import pl.pabilo8.immersiveintelligence.common.util.ISerializableEnum;
import pl.pabilo8.immersiveintelligence.common.util.ResLoc;
-import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIBase;
+import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIIEntityBase;
+import pl.pabilo8.immersiveintelligence.common.util.gui.ContainerIITileBase;
import pl.pabilo8.immersiveintelligence.common.util.lambda.TriFunction;
import javax.annotation.Nonnull;
@@ -121,6 +129,9 @@ public enum IIGUI implements ISerializableEnum
FUEL_STATION(TileEntityFuelStation.class, ContainerFuelStation::new),
DATA_MERGER(TileEntityDataMerger.class, ContainerDataMerger::new),
+ DATA_MERGER_EDIT(TileEntityDataMerger.class, ContainerDataMerger::new),
+ DATA_ROUTER(TileEntityDataRouter.class, ContainerDataRouter::getMainGui),
+ DATA_ROUTER_EDIT(TileEntityDataRouter.class, ContainerDataRouter::getEditGui),
INSERTER(TileEntityInserterBase.class, ContainerInserter::new),
GEARBOX(TileEntityGearbox.class, ContainerGearbox::new),
@@ -129,8 +140,12 @@ public enum IIGUI implements ISerializableEnum
SAWMILL(TileEntitySawmill.class, ContainerSawmill::new),
@SuppressWarnings({"rawtypes", "unchecked"})
- UPGRADE(TileEntityIEBase.class,
- (player, te) -> new ContainerUpgrade(player, te)
+ UPGRADE_TILE(TileEntityIEBase.class,
+ (player, te) -> new ContainerTileUpgrade(player, te)
+ ),
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ UPGRADE_ENTITY(Entity.class,
+ (player, entity) -> new ContainerEntityUpgrade(player, entity)
),
VULCANIZER(TileEntityVulcanizer.class, ContainerVulcanizer::new),
@@ -153,13 +168,18 @@ public enum IIGUI implements ISerializableEnum
RADAR_TARGETS(TileEntityRadar.class, ContainerRadar::new);
public final Class extends TileEntity> teClass;
+ public final Class extends Entity> entityClass;
public final BiFunction containerFromTile;
+ public final BiFunction containerFromEntity;
public final TriFunction containerFromStack;
public boolean item;
+
@SideOnly(Side.CLIENT)
public BiFunction guiFromTile;
@SideOnly(Side.CLIENT)
public TriFunction guiFromStack;
+ @SideOnly(Side.CLIENT)
+ private BiFunction guiFromEntity;
//Required for JEI
@SideOnly(Side.CLIENT)
public Class extends DecoGui, ?>> guiClass;
@@ -167,11 +187,27 @@ public enum IIGUI implements ISerializableEnum
/**
* TileEntity GUI constructor
*/
- IIGUI(@Nonnull Class teClass, BiFunction containerFromTile)
+ IIGUI(@Nonnull Class teClass, @Nonnull BiFunction containerFunction)
{
- this.teClass = teClass;
- //noinspection unchecked
- this.containerFromTile = (player, tileEntity) -> containerFromTile.apply(player, (T)tileEntity);
+ if(TileEntity.class.isAssignableFrom(teClass))
+ {
+ //noinspection unchecked
+ this.teClass = (Class extends TileEntity>)teClass;
+ this.entityClass = null;
+ //noinspection unchecked
+ this.containerFromTile = (player, tileEntity) -> containerFunction.apply(player, (T)tileEntity);
+ this.containerFromEntity = null;
+ }
+ else if(Entity.class.isAssignableFrom(teClass))
+ {
+ this.teClass = null;
+ //noinspection unchecked
+ this.entityClass = (Class extends Entity>)teClass;
+ this.containerFromTile = null;
+ this.containerFromEntity = (player, entity) -> containerFunction.apply(player, (T)entity);
+ }
+ else
+ throw new IllegalArgumentException("Invalid GUI subject class: "+teClass);
this.containerFromStack = null;
this.item = false;
}
@@ -179,10 +215,12 @@ IIGUI(@Nonnull Class teClass, BiFunction containerFromStack)
+ IIGUI(@Nonnull TriFunction containerFromStack)
{
this.teClass = null;
+ this.entityClass = null;
this.containerFromTile = null;
+ this.containerFromEntity = null;
this.containerFromStack = containerFromStack;
this.item = true;
}
@@ -193,7 +231,9 @@ IIGUI(@Nonnull Class teClass, BiFunction IIGUI(@Nonnull Class teClass, BiFunction new GuiUpgrade(player, tile));
-
- IIGUI.FLAGPOLE.setClientDecoGui(GuiFlagpole::new);
- IIGUI.FLAGPOLE_FACTION.setClientDecoGui(GuiFlagpoleFaction::new);
- IIGUI.EMPLACEMENT_STORAGE.setClientDecoGui(GuiEmplacementPageStorage::new);
- IIGUI.EMPLACEMENT_CONFIG.setClientDecoGui(GuiEmplacementPageConfig::new);
- IIGUI.EMPLACEMENT_TARGET_FILTERS.setClientDecoGui(GuiEmplacementPageTargetFilters::new);
- IIGUI.EMPLACEMENT_FIRE_MISSIONS.setClientDecoGui(GuiEmplacementPageFireMissions::new);
-
- IIGUI.FILLER.setClientDecoGui(GuiFiller::new);
- IIGUI.CHEMICAL_PAINTER.setClientDecoGui(GuiChemicalPainter::new);
-
- IIGUI.AMMUNITION_ASSEMBLER.setClientDecoGui(GuiAmmunitionAssembler::new);
- IIGUI.PROJECTILE_WORKSHOP.setClientDecoGui(GuiProjectileWorkshop::new);
-
- IIGUI.RADAR.setClientDecoGui(GuiRadar::new);
- IIGUI.RADAR_CONFIG.setClientDecoGui(GuiRadarConfig::new);
- IIGUI.RADAR_TARGETS.setClientDecoGui(GuiRadarTargets::new);
- IIGUI.COAGULATOR.setClientDecoGui(GuiCoagulator::new);
- IIGUI.VULCANIZER.setClientDecoGui(GuiVulcanizer::new);
+ IIGUI.UPGRADE_TILE.setClientTileGui((player, tile) -> new GuiTileUpgrade(player, tile));
+ //noinspection rawtypes,unchecked
+ IIGUI.UPGRADE_ENTITY.setClientEntityGui((player, tile) -> new GuiEntityUpgrade(player, tile));
+
+ IIGUI.FLAGPOLE.setClientTileGui(GuiFlagpole::new);
+ IIGUI.FLAGPOLE_FACTION.setClientTileGui(GuiFlagpoleFaction::new);
+ IIGUI.EMPLACEMENT_STORAGE.setClientTileGui(GuiEmplacementPageStorage::new);
+ IIGUI.EMPLACEMENT_CONFIG.setClientTileGui(GuiEmplacementPageConfig::new);
+ IIGUI.EMPLACEMENT_TARGET_FILTERS.setClientTileGui(GuiEmplacementPageTargetFilters::new);
+ IIGUI.EMPLACEMENT_FIRE_MISSIONS.setClientTileGui(GuiEmplacementPageFireMissions::new);
+
+ IIGUI.FILLER.setClientTileGui(GuiFiller::new);
+ IIGUI.CHEMICAL_PAINTER.setClientTileGui(GuiChemicalPainter::new);
+
+ IIGUI.AMMUNITION_ASSEMBLER.setClientTileGui(GuiAmmunitionAssembler::new);
+ IIGUI.PROJECTILE_WORKSHOP.setClientTileGui(GuiProjectileWorkshop::new);
+
+ IIGUI.RADAR.setClientTileGui(GuiRadar::new);
+ IIGUI.RADAR_CONFIG.setClientTileGui(GuiRadarConfig::new);
+ IIGUI.RADAR_TARGETS.setClientTileGui(GuiRadarTargets::new);
+ IIGUI.COAGULATOR.setClientTileGui(GuiCoagulator::new);
+ IIGUI.VULCANIZER.setClientTileGui(GuiVulcanizer::new);
}
@SideOnly(Side.CLIENT)
@@ -280,16 +325,9 @@ public static void registerDecoJEICompat(IModRegistry registry)
registry.addAdvancedGuiHandlers(new DecoGuiJEIHandler<>(gui));
}
- @SideOnly(Side.CLIENT)
- @Deprecated
- public void setClientGui(BiFunction guiFromTile)
- {
- this.guiFromTile = (player, tileEntity) -> guiFromTile.apply(player, (T)tileEntity);
- }
-
@SideOnly(Side.CLIENT)
@SuppressWarnings("unchecked")
- public > void setClientDecoGui(BiFunction> guiFromTile)
+ public > void setClientTileGui(BiFunction> guiFromTile)
{
Class> klass = (Class>)guiFromTile.apply(null, null).getClass();
this.guiFromTile = (player, tileEntity) -> guiFromTile.apply(player, (T)tileEntity);
@@ -303,9 +341,7 @@ public >
List resources = new ArrayList<>();
for(Field field : klass.getFields())
- {
if(field.isAnnotationPresent(DecoResource.class)&&Modifier.isStatic(field.getModifiers()))
- {
try
{
Object value = field.get(null);
@@ -319,8 +355,6 @@ else if(value instanceof String)
{
IILogger.error("Failed to access field "+field.getName()+" in class "+klass.getName(), e);
}
- }
- }
if(!resources.isEmpty())
new DecoResourcesLoader(this.getName().replace("gui_", ""), resources);
@@ -330,6 +364,13 @@ else if(value instanceof String)
public void setClientStackGui(TriFunction guiFromStack)
{
this.guiFromStack = guiFromStack;
- item = true;
+ this.item = true;
+ }
+
+ @SideOnly(Side.CLIENT)
+ public > void setClientEntityGui(BiFunction> guiFromEntity)
+ {
+ this.guiFromEntity = (player, entity) -> guiFromEntity.apply(player, (T)entity);
+ this.item = false;
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/IISounds.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/IISounds.java
index c5b269ee0..2c0d33009 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/IISounds.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/IISounds.java
@@ -277,6 +277,8 @@ public class IISounds
public static SoundEvent constructionElectricWrench = registerSound("construction_electric_wrench");
@ModSound(sounds = {"construction/wrench/wrench{0..2}"}, subtitle = "construction")
public static SoundEvent constructionWrench = registerSound("construction_wrench");
+ @ModSound(sounds = {"weapons/weapon_placed/weapon_placed{0..1}"}, subtitle = "*")
+ public static SoundEvent weaponPlaced = registerSound("weapon_placed");
//--- Guns ---//
//Ammo Pickup
@@ -517,14 +519,20 @@ public class IISounds
public static SoundEvent impactFlesh = registerSound("impact_flesh");
//--- Vehicle ---//
- @ModSound(sounds = {"motorbike/start"}, subtitle = "*")
- public static SoundEvent motorbikeStart = registerSound("motorbike_start");
- @ModSound(sounds = {"motorbike/start_no_fuel"}, subtitle = "motorbike_start")
- public static SoundEvent motorbikeStartNoFuel = registerSound("motorbike_start_no_fuel");
- @ModSound(sounds = {"motorbike/engine"}, subtitle = "*")
- public static SoundEvent motorbikeEngine = registerSound("motorbike_engine");
- @ModSound(sounds = {"motorbike/horn"}, subtitle = "*")
- public static SoundEvent motorbikeHorn = registerSound("motorbike_horn");
+ @ModSound(sounds = {"vehicle/horn"}, subtitle = "*")
+ public static SoundEvent vehicleHorn = registerSound("vehicle_horn");
+ @ModSound(sounds = {"vehicle/engine_light/start"}, subtitle = "*")
+ public static SoundEvent engineLightStart = registerSound("engine_light_start");
+ @ModSound(sounds = {"vehicle/engine_light/start_no_fuel"}, subtitle = "light_engine_start")
+ public static SoundEvent engineLightStartNoFuel = registerSound("engine_light_start_no_fuel");
+ @ModSound(sounds = {"vehicle/engine_light/engine"}, subtitle = "*")
+ public static SoundEvent engineLight = registerSound("engine_light");
+ public static MultiSound engineLightLoop = new MultiSound(engineLight);
+
+ //--- Aircraft ---//
+ @ModSound(sounds = {"vehicle/drone/drone_propeller"}, subtitle = "*")
+ public static SoundEvent dronePropeller = registerSound("drone_propeller");
+ public static MultiSound dronePropellerLoop = new MultiSound(dronePropeller);
//--- Hans ---//
//public static SoundEvent hans_test_pl = registerSound("hans_test_pl");
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIUtils.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIUtils.java
index 4fc3cf628..e13861f59 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/IIUtils.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/IIUtils.java
@@ -16,9 +16,12 @@
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
import net.minecraft.item.ItemStack;
+import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
@@ -52,11 +55,7 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -400,6 +399,30 @@ public static void giveOrDropStack(@Nonnull Entity entity, ItemStack stack)
Utils.dropStackAtPos(entity.world, entity.getPosition(), stack);
}
+ /**
+ * Applies infrared vision to the entity if it's dark enough, otherwise blinds it.
+ *
+ * @return true if infrared vision was applied, false if the entity was blinded
+ */
+ public static boolean applyInfraredVision(Entity entity, int duration)
+ {
+ //Entity does not support potion effects
+ if(!(entity instanceof EntityLivingBase)||entity.world.isRemote)
+ return false;
+
+ //Apply infrared in darkness or blind the entity
+ if(entity.world.getLightBrightness(entity.getPosition()) <= 0.5f)
+ {
+ ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(IIPotions.infraredVision, duration, 1, true, false));
+ return true;
+ }
+ else
+ {
+ ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 240, 1, false, false));
+ return false;
+ }
+ }
+
@Nullable
public static T requireMaster(@Nullable T object, @Nonnull Function master)
{
@@ -447,7 +470,13 @@ public static T getAnnotation(Class annotationClass, O
@Nonnull
public static & ISerializableEnum> T enumValue(Class en, String name)
{
- return Enum.valueOf(en, name.toUpperCase());
+ try
+ {
+ return Enum.valueOf(en, name.toUpperCase());
+ } catch(IllegalArgumentException ignored)
+ {
+ return en.getEnumConstants()[0];
+ }
}
/**
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentHMX.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentHMX.java
index 0f3efcf67..dfa355456 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentHMX.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentHMX.java
@@ -34,7 +34,7 @@ public IngredientStack getMaterial()
public void onEffect(World world, Vec3d pos, Vec3d dir, ComponentEffectShape shape, NBTTagCompound tag, float componentSize, float multiplier, Entity owner)
{
new IIExplosion(world, owner, pos, dir,
- 12*componentSize, 18*multiplier, shape, false, componentSize > 0.125f, false)
+ 10*componentSize, 16*multiplier, shape, false, componentSize > 0.125f, false)
.doExplosion();
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentRDX.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentRDX.java
index 20d77a1ca..fa4783b12 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentRDX.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/explosives/AmmoComponentRDX.java
@@ -34,7 +34,7 @@ public IngredientStack getMaterial()
public void onEffect(World world, Vec3d pos, Vec3d dir, ComponentEffectShape shape, NBTTagCompound tag, float componentSize, float multiplier, Entity owner)
{
new IIExplosion(world, owner, pos, dir,
- 9*componentSize, 10*multiplier, shape, false, componentSize > 0.125f, false)
+ 8*componentSize, 8*multiplier, shape, false, componentSize > 0.125f, false)
.doExplosion();
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentFluid.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentFluid.java
index a2219e516..39e9fdc28 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentFluid.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentFluid.java
@@ -28,7 +28,8 @@
*/
public class AmmoComponentFluid extends AmmoComponent
{
- Fluid fluid;
+ private final Fluid fluid;
+ private IIColor overrideColor = null;
public AmmoComponentFluid(Fluid fluid)
{
@@ -59,6 +60,24 @@ public boolean showInManual()
return false;
}
+ @Override
+ public IIColor getColor()
+ {
+ if(this.overrideColor!=null)
+ return this.overrideColor;
+ return super.getColor();
+ }
+
+ public Fluid getFluid()
+ {
+ return fluid;
+ }
+
+ public void setOverrideColor(IIColor overrideColor)
+ {
+ this.overrideColor = overrideColor;
+ }
+
@Override
public void onEffect(World world, Vec3d pos, Vec3d dir, ComponentEffectShape shape, NBTTagCompound tag, float size, float multiplier, Entity owner)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentShrapnel.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentShrapnel.java
index 07f2514a5..8ea4e3b7f 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentShrapnel.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/factory/AmmoComponentShrapnel.java
@@ -50,7 +50,7 @@ public void onEffect(World world, Vec3d pos, Vec3d dir, ComponentEffectShape sha
{
Vec3d v = new Vec3d(0, -1, 0);
Vec3d throwerPos = pos.addVector(0, 3, 0);
- for(int i = 0; i < 50*multiplier; i++)
+ for(int i = 0; i < 20*size; i++)
{
Vec3d vecDir = v.addVector(Utils.RAND.nextGaussian()*.25f, Utils.RAND.nextGaussian()*.25f, Utils.RAND.nextGaussian()*.25f);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/incendiary/AmmoComponentWhitePhosphorus.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/incendiary/AmmoComponentWhitePhosphorus.java
index 841c14902..6ac826052 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/incendiary/AmmoComponentWhitePhosphorus.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/ammo/components/incendiary/AmmoComponentWhitePhosphorus.java
@@ -2,26 +2,31 @@
import blusunrize.immersiveengineering.api.crafting.IngredientStack;
import blusunrize.immersiveengineering.common.util.IEPotions;
-import blusunrize.immersiveengineering.common.util.Utils;
import net.minecraft.entity.Entity;
-import net.minecraft.entity.EntityAreaEffectCloud;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.init.Blocks;
+import net.minecraft.init.SoundEvents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
-import net.minecraft.util.EnumParticleTypes;
+import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundCategory;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import pl.pabilo8.immersiveintelligence.api.ammo.enums.ComponentEffectShape;
import pl.pabilo8.immersiveintelligence.api.ammo.enums.ComponentRole;
import pl.pabilo8.immersiveintelligence.api.ammo.parts.AmmoComponent;
-import pl.pabilo8.immersiveintelligence.common.IIPotions;
+import pl.pabilo8.immersiveintelligence.common.IILogger;
import pl.pabilo8.immersiveintelligence.common.IISounds;
+import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.component.EntityWhitePhosphorus;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageParticleEffect;
import pl.pabilo8.immersiveintelligence.common.util.IIColor;
import javax.annotation.Nullable;
+import java.util.Set;
/**
* @author Pabilo8 (pabilo@iiteam.net)
@@ -46,87 +51,68 @@ public IngredientStack getMaterial()
@Override
public void onEffect(World world, Vec3d pos, Vec3d dir, ComponentEffectShape shape, NBTTagCompound tag, float size, float multiplier, @Nullable Entity owner)
{
- // CLOUD shape: similar to what you implemented earlier
- if(shape==ComponentEffectShape.ORB)
- {
- // Effect logic for cloud shape (similar to your original implementation)
- if(world.isRemote)
- return;
-
- Vec3d v = dir.scale(-1); // Reverse direction for effect shaping
+ BlockPos blockPos = new BlockPos(pos);
+ if(size > 0.2)
IIPacketHandler.playRangedSound(world, pos, IISounds.explosionIncendiary, SoundCategory.NEUTRAL, (int)(40*multiplier), 1f, 1f);
+ else
+ world.playSound(null, blockPos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 1f, 1f);
- // Spawn phosphorus fragments
- for(int i = 0; i < 30*multiplier; i++)
- {
- Vec3d vecDir = new Vec3d(1, 0, 0).rotateYaw(i/(30f*multiplier)*360f).add(v);
- EntityWhitePhosphorus shrap = new EntityWhitePhosphorus(world, pos.x+vecDir.x, pos.y+v.y+1f, pos.z+vecDir.z, 0, 0, 0);
-
- shrap.motionX = vecDir.x*0.35f;
- shrap.motionY = 0.1f+(Utils.RAND.nextDouble()*0.2f);
- shrap.motionZ = vecDir.z*0.35f;
-
- world.spawnEntity(shrap);
- }
+ //Spawn main phosphorus entity, shared between all modes
+ EntityWhitePhosphorus main = new EntityWhitePhosphorus(world, pos.x-dir.x, pos.y-dir.y, pos.z-dir.z, 0, 0, 0);
+ main.motionX = -dir.x*0.75;
+ main.motionY = -dir.y*0.75;
+ main.motionZ = -dir.z*0.75;
- // Send particle effect message to nearby clients
- IIPacketHandler.sendToClient(new MessageParticleEffect("white_phosphorus", world,
- pos.addVector(0, 1, 0),
- Vec3d.ZERO, 0, 0, null
- ));
-
- // Area of effect cloud (applies potion effects)
- EntityAreaEffectCloud cloud = new EntityAreaEffectCloud(world, pos.x+v.x, pos.y+v.y+1f, pos.z+v.z);
- cloud.addEffect(new PotionEffect(IIPotions.brokenArmor, Math.round(240), 2));
- cloud.addEffect(new PotionEffect(IEPotions.flammable, Math.round(240), 4));
- cloud.addEffect(new PotionEffect(IEPotions.stunned, Math.round(160), 2));
- cloud.addEffect(new PotionEffect(IEPotions.flashed, Math.round(270), 1));
- cloud.setRadius(3f*multiplier);
- cloud.setDuration(Math.round(20f+(10f*Utils.RAND.nextFloat())));
- cloud.setParticle(EnumParticleTypes.CLOUD);
- world.spawnEntity(cloud);
- }
- // BURST shape: a more explosive spread of shrapnel and effects
- else if(shape==ComponentEffectShape.STAR)
+ if(size > 0.2f)
{
- if(world.isRemote)
- return;
-
- // Play a more intense sound for burst explosion
- IIPacketHandler.playRangedSound(world, pos, IISounds.explosionIncendiary, SoundCategory.NEUTRAL, (int)(60*multiplier), 1.2f, 1.2f);
-
- // Spawn shrapnel in a wider, explosive pattern
- for(int i = 0; i < 50*multiplier; i++)
- {
- // Adjust angles to spread more widely for burst effect
- Vec3d vecDir = new Vec3d(1, 0, 0).rotateYaw(i/(50f*multiplier)*360f).add(dir);
- EntityWhitePhosphorus shrap = new EntityWhitePhosphorus(world, pos.x+vecDir.x, pos.y+dir.y+1f, pos.z+vecDir.z, 0, 0, 0);
-
- // Burst fragments have higher speed and randomness
- shrap.motionX = vecDir.x*0.6f;
- shrap.motionY = 0.2f+(Utils.RAND.nextDouble()*0.3f);
- shrap.motionZ = vecDir.z*0.6f;
-
- world.spawnEntity(shrap);
- }
-
- // Send particle effect with burst ID
- IIPacketHandler.sendToClient(new MessageParticleEffect("white_phosphorus_burst", world,
- pos.addVector(0, 1, 0),
- Vec3d.ZERO, 0, 0, null
- ));
+ //Set fire to surrounding blocks in a radius
+ Set blocks = IIUtils.getBlocksInOrb(world, blockPos, size*4f);
+ for(BlockPos block : blocks)
+ if(world.isAirBlock(block))
+ world.setBlockState(block, Blocks.FIRE.getDefaultState());
+ }
+ //Deal fire damage to all entities around
+ for(Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(blockPos).grow(4f)))
+ {
+ if(entity instanceof EntityLivingBase)
+ ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(IEPotions.flammable, 80, 1));
+ entity.attackEntityFrom(DamageSource.IN_FIRE, 10f*multiplier);
+ entity.setFire(40);
+ }
- // A larger, faster dissipating cloud
- EntityAreaEffectCloud cloud = new EntityAreaEffectCloud(world, pos.x+dir.x, pos.y+dir.y+1f, pos.z+dir.z);
- cloud.addEffect(new PotionEffect(IIPotions.brokenArmor, Math.round(180), 3));
- cloud.addEffect(new PotionEffect(IEPotions.flammable, Math.round(180), 5));
- cloud.addEffect(new PotionEffect(IEPotions.stunned, Math.round(120), 3));
- cloud.addEffect(new PotionEffect(IEPotions.flashed, Math.round(220), 2));
- cloud.setRadius(4.5f*multiplier); // Burst shape has a larger radius
- cloud.setDuration(Math.round(15f+(8f*Utils.RAND.nextFloat()))); // Burst effect lasts a bit shorter
- cloud.setParticle(EnumParticleTypes.EXPLOSION_LARGE);
- world.spawnEntity(cloud);
+ switch(shape)
+ {
+ case ORB:
+ case STAR:
+ case CONE:
+ IIPacketHandler.sendToClient(new MessageParticleEffect("phosphorus/orb", world, pos, Vec3d.ZERO, 0, 0, null));
+ main.motionX = 0;
+ main.motionY = 0.4;
+ main.motionZ = 0;
+
+ float particlesInLayer = 10f*size;
+ // Spawn shrapnel in a wider, explosive pattern
+ for(int i = 0; i < 2*particlesInLayer; i++)
+ {
+ Vec3d vecDir = dir.scale(i < size*10?-1: -2).rotateYaw(i/(particlesInLayer)*360f);
+ EntityWhitePhosphorus shrap = new EntityWhitePhosphorus(world, pos.x+vecDir.x, pos.y-dir.y, pos.z+vecDir.z, 0, 0, 0);
+
+ vecDir = vecDir.scale(2);
+ shrap.motionX = vecDir.x*0.125f;
+ shrap.motionY = (vecDir.y+(i < size*10?2: 0.5))*0.125f*2;
+ shrap.motionZ = vecDir.z*0.125f;
+ world.spawnEntity(shrap);
+ }
+ break;
+ case LINE:
+ IILogger.info("Line!");
+ Set blocks = IIUtils.getBlocksInOrb(world, blockPos, 1f);
+ for(BlockPos block : blocks)
+ if(world.isAirBlock(block))
+ world.setBlockState(block, Blocks.FIRE.getDefaultState());
+ break;
}
+ world.spawnEntity(main);
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataMerger.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataMerger.java
index 3fe0746e5..052bc47f3 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataMerger.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataMerger.java
@@ -2,10 +2,8 @@
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IBlockBounds;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IDirectionalTile;
-import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IGuiTile;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IPlayerInteraction;
import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
-import blusunrize.immersiveengineering.common.util.inventory.IIEInventory;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -15,49 +13,107 @@
import net.minecraft.util.EnumHand;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
+import net.minecraftforge.common.util.Constants;
+import net.minecraftforge.common.util.INBTSerializable;
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
import pl.pabilo8.immersiveintelligence.api.data.IIDataHandlingUtils;
import pl.pabilo8.immersiveintelligence.api.data.device.IDataDevice;
+import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.multiblock.IIMultiblockInterfaces.IIIGuiMultiblockTile;
+import pl.pabilo8.immersiveintelligence.common.util.multiblock.IIMultiblockInterfaces.IIIInventory;
-import javax.annotation.Nullable;
+import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
/**
* @author Pabilo8 (pabilo@iiteam.net)
- * @updated 24.06.2025
+ * @updated 02.06.2026
* @since 17.05.2019
*/
-public class TileEntityDataMerger extends TileEntityIEBase implements IPlayerInteraction, ITickable, IBlockBounds, IDirectionalTile, IDataDevice, IGuiTile, IIEInventory
+public class TileEntityDataMerger extends TileEntityIEBase implements IPlayerInteraction, ITickable, IBlockBounds, IDirectionalTile, IDataDevice, IIIGuiMultiblockTile, IIIInventory
{
public EnumFacing facing = EnumFacing.NORTH;
- public DataPacket settingsPacket = new DataPacket();
- public DataMergerSendMode mode = DataMergerSendMode.SEND_ON_BOTH;
- DataPacket packetLeft = new DataPacket();
- DataPacket packetRight = new DataPacket();
+
+ public EasyCollection mergeRules = new EasyCollection<>(DataMergeRule::new);
+ public DataPacket packetLeft = new DataPacket();
+ public DataPacket packetRight = new DataPacket();
@Override
public void readCustomNBT(NBTTagCompound nbt, boolean descPacket)
{
- mode = DataMergerSendMode.values()[nbt.getByte("mode")];
facing = EnumFacing.getFront(nbt.getInteger("facing"));
- settingsPacket = new DataPacket(nbt.getCompoundTag("packet"));
+ if(nbt.hasKey("rules", Constants.NBT.TAG_LIST))
+ mergeRules.deserializeNBT(nbt.getTagList("rules", Constants.NBT.TAG_COMPOUND));
+ else if(nbt.hasKey("packet", Constants.NBT.TAG_COMPOUND))
+ migrateLegacySettings(new DataPacket(nbt.getCompoundTag("packet")));
+
packetLeft = new DataPacket(nbt.getCompoundTag("packetLeft"));
packetRight = new DataPacket(nbt.getCompoundTag("packetRight"));
-
}
@Override
public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket)
{
- nbt.setByte("mode", (byte)mode.ordinal());
nbt.setInteger("facing", facing.ordinal());
-
- nbt.setTag("packet", settingsPacket.serializeNBT());
+ nbt.setTag("rules", mergeRules.serializeNBT());
nbt.setTag("packetLeft", packetLeft.serializeNBT());
nbt.setTag("packetRight", packetRight.serializeNBT());
}
+ private void migrateLegacySettings(DataPacket settingsPacket)
+ {
+ mergeRules.clear();
+
+ for(char c : DataPacket.VARIABLE_NAMES)
+ IIDataHandlingUtils.optionalInt(c, settingsPacket).ifPresent(integer -> {
+ int mode = integer+2;
+ if(mode < 0||mode >= VariableMergeMode.values().length)
+ return;
+
+ VariableMergeMode legacy = VariableMergeMode.values()[mode];
+ if(legacy==VariableMergeMode.RETAIN_ORIGINAL)
+ return;
+
+ DataMergeRule rule = new DataMergeRule();
+ rule.variable = c;
+ rule.triggerForwarding = true;
+ rule.usageLimit = -1;
+
+ switch(legacy)
+ {
+ case PREFER_RIGHT:
+ rule.acceptLeft = true;
+ rule.acceptRight = true;
+ rule.rightOverridesCachedValue = true;
+ rule.rightOverridesValue = true;
+ break;
+ case FORCE_RIGHT:
+ rule.acceptLeft = false;
+ rule.acceptRight = true;
+ rule.rightOverridesCachedValue = true;
+ rule.rightOverridesValue = true;
+ break;
+ case PREFER_LEFT:
+ rule.acceptLeft = true;
+ rule.acceptRight = true;
+ rule.rightOverridesCachedValue = false;
+ rule.rightOverridesValue = true;
+ break;
+ case FORCE_LEFT:
+ rule.acceptLeft = true;
+ rule.acceptRight = false;
+ rule.rightOverridesCachedValue = false;
+ rule.rightOverridesValue = true;
+ break;
+ }
+ mergeRules.add(rule);
+ });
+ }
+
@Override
public boolean interact(EnumFacing side, EntityPlayer player, EnumHand hand, ItemStack heldItem, float hitX, float hitY, float hitZ)
{
@@ -74,10 +130,13 @@ public void receiveMessageFromServer(NBTTagCompound message)
public void receiveMessageFromClient(NBTTagCompound message)
{
super.receiveMessageFromClient(message);
- if(message.hasKey("mode"))
- mode = DataMergerSendMode.values()[message.getByte("mode")];
- if(message.hasKey("packet"))
- settingsPacket.deserializeNBT(message.getCompoundTag("packet"));
+ if(message.hasKey("rules", Constants.NBT.TAG_LIST))
+ {
+ mergeRules.deserializeNBT(message.getTagList("rules", Constants.NBT.TAG_COMPOUND));
+ markDirty();
+ if(world!=null)
+ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
+ }
}
@Override
@@ -131,53 +190,52 @@ public boolean canRotate(EnumFacing axis)
@Override
public void onReceive(DataPacket packet, EnumFacing side)
{
- boolean send = mode==DataMergerSendMode.SEND_ON_BOTH;
+ boolean fromLeft = side==facing.rotateYCCW();
+ boolean fromRight = side==facing.rotateY();
- //Incoming packet on the left
- if(side==facing.rotateYCCW())
- {
- packetLeft = packet.clone();
- send = send||mode==DataMergerSendMode.SEND_LEFT_ONLY;
- }
+ //The merger only listens to its two input sides.
+ if(!fromLeft&&!fromRight)
+ return;
- //Incoming packet on the right
- if(side==facing.rotateY())
+ DataPacket incoming = packet.clone();
+ DataPacket cache = fromLeft?packetLeft: packetRight;
+ boolean shouldForward = false;
+ List expiredRules = new ArrayList<>();
+
+ //Accept variables into the side cache and check if this packet should trigger output.
+ for(DataMergeRule rule : mergeRules)
+ if(rule.acceptsSide(fromLeft, fromRight)&&incoming.has(rule.variable))
+ {
+ cache.set(rule.variable, incoming.get(rule.variable).clone());
+ if(rule.triggerForwarding)
+ shouldForward = true;
+
+ rule.consumeUse();
+ if(rule.isExpired())
+ expiredRules.add(rule);
+ }
+
+ if(!shouldForward)
{
- packetRight = packet.clone();
- send = send||mode==DataMergerSendMode.SEND_RIGHT_ONLY;
+ if(!expiredRules.isEmpty())
+ {
+ mergeRules.removeAll(expiredRules);
+ markDirty();
+ }
+ return;
}
- if(!send)
- return;
+ DataPacket outgoing = incoming.clone();
+ for(DataMergeRule rule : mergeRules)
+ rule.applyTo(outgoing, incoming, packetLeft, packetRight);
- for(char c : DataPacket.VARIABLE_NAMES)
- IIDataHandlingUtils.optionalInt(c, packet).ifPresent(integer -> {
- switch(VariableMergeMode.values()[integer+2])
- {
- //Original
- case RETAIN_ORIGINAL:
- break;
- //Left
- case FORCE_LEFT:
- packet.set(c, packetLeft.get(c));
- break;
- case PREFER_LEFT:
- if(packetLeft.has(c))
- packet.set(c, packetLeft.get(c));
- break;
- //Right
- case FORCE_RIGHT:
- packet.set(c, packetRight.get(c));
- break;
- case PREFER_RIGHT:
- if(packetRight.has(c))
- packet.set(c, packetRight.get(c));
- break;
- }
- });
+ if(!expiredRules.isEmpty())
+ {
+ mergeRules.removeAll(expiredRules);
+ markDirty();
+ }
- //Send packet
- IIDataHandlingUtils.sendPacketAdjacently(packet, world, this.pos, facing);
+ IIDataHandlingUtils.sendPacketAdjacently(outgoing, world, this.pos, facing);
}
@Override
@@ -187,16 +245,15 @@ public boolean canOpenGui()
}
@Override
- public int getGuiID()
+ public TileEntity master()
{
- return IIGUI.DATA_MERGER.ordinal();
+ return this;
}
- @Nullable
@Override
- public TileEntity getGuiMaster()
+ public IIGUI getGUI()
{
- return this;
+ return IIGUI.DATA_MERGER;
}
@Override
@@ -223,14 +280,115 @@ public void doGraphicalUpdates(int slot)
}
- public enum DataMergerSendMode
+ public static class DataMergeRule implements INBTSerializable
{
- SEND_ON_BOTH,
- SEND_LEFT_ONLY,
- SEND_RIGHT_ONLY,
+ public char variable = 'a';
+ public boolean acceptLeft = true;
+ public boolean acceptRight = true;
+ public boolean triggerForwarding = true;
+
+ /**
+ * When both side caches hold the variable, true gives priority to right; false gives priority to left.
+ */
+ public boolean rightOverridesCachedValue = true;
+
+ /**
+ * When true, the selected cached value can replace the variable already present in the outgoing packet.
+ * When false, the incoming packet's value is preserved and the cache only fills missing variables.
+ */
+ public boolean rightOverridesValue = true;
+
+ /**
+ * -1 means infinite Job. Non-negative values are Requests and are decremented when the rule accepts a variable.
+ */
+ public int usageLimit = -1;
+
+ public boolean isJob()
+ {
+ return usageLimit < 0;
+ }
+
+ public boolean acceptsSide(boolean fromLeft, boolean fromRight)
+ {
+ return (fromLeft&&acceptLeft)||(fromRight&&acceptRight);
+ }
+
+ public void consumeUse()
+ {
+ if(usageLimit > 0)
+ usageLimit--;
+ }
+
+ public boolean isExpired()
+ {
+ return usageLimit==0;
+ }
+
+ public DataMergeRule copy()
+ {
+ DataMergeRule copy = new DataMergeRule();
+ copy.deserializeNBT(serializeNBT());
+ return copy;
+ }
+
+ public void applyTo(DataPacket outgoing, DataPacket incoming, DataPacket leftCache, DataPacket rightCache)
+ {
+ DataType cached = getSelectedCachedValue(leftCache, rightCache);
+ if(cached==null)
+ return;
+
+ //Preserve the incoming packet value unless this rule is allowed to override it.
+ if(incoming.has(variable)&&!rightOverridesValue)
+ return;
+
+ outgoing.set(variable, cached.clone());
+ }
+
+ private DataType getSelectedCachedValue(DataPacket leftCache, DataPacket rightCache)
+ {
+ boolean hasLeft = acceptLeft&&leftCache.has(variable);
+ boolean hasRight = acceptRight&&rightCache.has(variable);
+
+ if(hasLeft&&hasRight)
+ return rightOverridesCachedValue?rightCache.get(variable): leftCache.get(variable);
+ else if(hasRight)
+ return rightCache.get(variable);
+ else if(hasLeft)
+ return leftCache.get(variable);
+ return null;
+ }
+
+ @Nonnull
+ @Override
+ public NBTTagCompound serializeNBT()
+ {
+ NBTTagCompound nbt = new NBTTagCompound();
+ nbt.setString("variable", String.valueOf(variable));
+ nbt.setBoolean("accept_left", acceptLeft);
+ nbt.setBoolean("accept_right", acceptRight);
+ nbt.setBoolean("trigger_forwarding", triggerForwarding);
+ nbt.setBoolean("right_overrides_cached", rightOverridesCachedValue);
+ nbt.setBoolean("right_overrides_value", rightOverridesValue);
+ nbt.setInteger("usage_limit", usageLimit);
+ return nbt;
+ }
+
+ @Override
+ public void deserializeNBT(NBTTagCompound nbt)
+ {
+ String variableString = nbt.getString("variable");
+ variable = variableString.isEmpty()?'a': variableString.charAt(0);
+
+ acceptLeft = !nbt.hasKey("accept_left")||nbt.getBoolean("accept_left");
+ acceptRight = !nbt.hasKey("accept_right")||nbt.getBoolean("accept_right");
+ triggerForwarding = !nbt.hasKey("trigger_forwarding")||nbt.getBoolean("trigger_forwarding");
+ rightOverridesCachedValue = !nbt.hasKey("right_overrides_cached")||nbt.getBoolean("right_overrides_cached");
+ rightOverridesValue = !nbt.hasKey("right_overrides_value")||nbt.getBoolean("right_overrides_value");
+ usageLimit = nbt.hasKey("usage_limit")?nbt.getInteger("usage_limit"): -1;
+ }
}
- enum VariableMergeMode
+ private enum VariableMergeMode
{
PREFER_RIGHT,
FORCE_RIGHT,
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataRouter.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataRouter.java
index 4490df61f..4903ed519 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataRouter.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataRouter.java
@@ -1,128 +1,377 @@
package pl.pabilo8.immersiveintelligence.common.block.data_device.tileentity;
-import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IBlockBounds;
-import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IDirectionalTile;
-import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IHammerInteraction;
-import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IPlayerInteraction;
import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
-import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
-import net.minecraft.util.EnumHand;
-import net.minecraft.util.ITickable;
+import net.minecraft.util.NonNullList;
+import net.minecraftforge.common.util.INBTSerializable;
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
-import pl.pabilo8.immersiveintelligence.api.data.device.IDataConnector;
+import pl.pabilo8.immersiveintelligence.api.data.IIDataHandlingUtils;
+import pl.pabilo8.immersiveintelligence.api.data.IIDataTypeUtils;
import pl.pabilo8.immersiveintelligence.api.data.device.IDataDevice;
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeInteger;
-import pl.pabilo8.immersiveintelligence.common.IIUtils;
-import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
+import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeNull;
+import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
+import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.util.IIReference;
+import pl.pabilo8.immersiveintelligence.common.util.ILocalizedEnum;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.multiblock.IIMultiblockInterfaces.IIIGuiMultiblockTile;
+import pl.pabilo8.immersiveintelligence.common.util.multiblock.IIMultiblockInterfaces.IIIInventory;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Arrays;
/**
+ * A device that routes incoming {@link DataPacket DataPackets} according to an ordered rule list.
+ *
* @author Pabilo8 (pabilo@iiteam.net)
+ * @updated 02.06.2026
* @since 17.05.2019
*/
-public class TileEntityDataRouter extends TileEntityIEBase implements IPlayerInteraction, IHammerInteraction, ITickable, IBlockBounds, IDirectionalTile, IDataDevice
+public class TileEntityDataRouter extends TileEntityIEBase implements IDataDevice, IIIGuiMultiblockTile, IIIInventory
{
- public EnumFacing facing = EnumFacing.NORTH;
- char variable = '0';
+ public EasyCollection routingRules;
- @Override
- public void readCustomNBT(NBTTagCompound nbt, boolean descPacket)
+ public TileEntityDataRouter()
{
- variable = nbt.getString("variable").charAt(0);
-
+ super();
+ this.routingRules = new EasyCollection<>(DataRoutingRule::new);
+ migrateLegacyVariableRouter("0");
}
@Override
- public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket)
+ public void readCustomNBT(NBTTagCompound nbt, boolean descPacket)
{
- nbt.setString("variable", String.valueOf(variable));
+ if(nbt.hasKey("rules"))
+ routingRules.deserializeNBT(nbt.getTagList("rules", 10));
+ else if(nbt.hasKey("variable"))
+ migrateLegacyVariableRouter(nbt.getString("variable"));
}
@Override
- public boolean interact(EnumFacing side, EntityPlayer player, EnumHand hand, ItemStack heldItem, float hitX, float hitY, float hitZ)
+ public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket)
{
- return false;
+ nbt.setTag("rules", routingRules.serializeNBT());
}
@Override
- public void receiveMessageFromServer(NBTTagCompound message)
+ public void receiveMessageFromClient(@Nonnull NBTTagCompound message)
{
- super.receiveMessageFromServer(message);
+ super.receiveMessageFromClient(message);
+ if(message.hasKey("rules"))
+ {
+ routingRules.deserializeNBT(message.getTagList("rules", 10));
+ markDirty();
+ if(world!=null)
+ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
+ }
}
@Override
- public void update()
+ public void onReceive(DataPacket packet, EnumFacing side)
{
+ if(world==null||world.isRemote||packet==null||side==null)
+ return;
+
+ boolean changed = false;
+ for(DataRoutingRule rule : routingRules)
+ {
+ if(!rule.matches(packet, side))
+ continue;
+
+ rule.consumeUse();
+ changed = true;
+ if(rule.action==RoutingAction.DENY)
+ break;
+
+ DataPacket outgoingPacket = rule.getOutgoingPacket(packet);
+ IIDataHandlingUtils.sendPacketAdjacently(outgoingPacket, world, pos, rule.outgoingSide);
+ }
+
+ if(changed)
+ {
+ routingRules.removeIf(DataRoutingRule::isExpired);
+ markDirty();
+ if(world!=null)
+ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
+ }
}
+ //--- IIIGuiMultiblockTile ---//
+
@Override
- public float[] getBlockBounds()
+ public boolean canOpenGui()
{
- return new float[]{0f, 0f, 0f, 1f, 1f, 1f};
+ return true;
}
@Override
- public EnumFacing getFacing()
+ public TileEntity master()
{
- return facing;
+ return this;
}
@Override
- public void setFacing(EnumFacing facing)
+ public IIGUI getGUI()
{
- this.facing = facing;
+ return IIGUI.DATA_ROUTER;
}
+ //--- IIEInventory ---//
+
@Override
- public int getFacingLimitation()
+ public NonNullList getInventory()
{
- return 2;
+ return NonNullList.create();
}
@Override
- public boolean mirrorFacingOnPlacement(EntityLivingBase placer)
+ public boolean isStackValid(int slot, ItemStack stack)
{
return false;
}
- @Override
- public boolean canHammerRotate(EnumFacing side, float hitX, float hitY, float hitZ, EntityLivingBase entity)
+ public enum RoutingAction implements ILocalizedEnum
{
- return !entity.isSneaking();
- }
+ ALLOW,
+ DENY;
- @Override
- public boolean canRotate(EnumFacing axis)
- {
- return !axis.getAxis().isVertical();
+ @Override
+ public String geLocaleKey()
+ {
+ return IIReference.GUI_LABEL_KEY+"data_router.action.";
+ }
}
- @Override
- public void onReceive(DataPacket packet, EnumFacing side)
+ public static class DataRoutingRule implements INBTSerializable
{
- if(packet.get(variable) instanceof DataTypeInteger)
+ public final boolean[] receivingSides = new boolean[6];
+ public EnumFacing outgoingSide = EnumFacing.NORTH;
+
+ public boolean useColorFilter = false;
+ public EnumDyeColor packetColor = EnumDyeColor.WHITE;
+ public boolean useAddressFilter = false;
+ public int packetAddress = -1;
+
+ public String requiredVariables = "";
+ public boolean useValueFilter = false;
+ public char valueVariable = 'a';
+ public DataType expectedValue = new DataTypeNull();
+
+ /**
+ * -1 means infinite, any positive number means request-style finite use count.
+ */
+ public int usageLimit = -1;
+ public RoutingAction action = RoutingAction.ALLOW;
+ public boolean removeControlVariable = false;
+
+ public DataRoutingRule()
+ {
+ Arrays.fill(receivingSides, true);
+ }
+
+ public boolean isJob()
+ {
+ return usageLimit < 0;
+ }
+
+ public boolean isExpired()
{
- int c = ((DataTypeInteger)packet.get(variable)).value;
- if(world.isBlockLoaded(this.pos.offset(EnumFacing.getFront(c)))&&world.getTileEntity(this.pos.offset(EnumFacing.getFront(c))) instanceof IDataConnector)
+ return usageLimit==0;
+ }
+
+ public void consumeUse()
+ {
+ if(usageLimit > 0)
+ usageLimit--;
+ }
+
+ public boolean matches(@Nonnull DataPacket packet, @Nonnull EnumFacing receivedFrom)
+ {
+ if(isExpired()||!receivingSides[receivedFrom.ordinal()])
+ return false;
+
+ NBTTagCompound packetNBT = null;
+ if(useColorFilter||useAddressFilter)
+ packetNBT = packet.serializeNBT();
+
+ if(useColorFilter)
+ {
+ int color = packetNBT.hasKey("color")?packetNBT.getInteger("color"): EnumDyeColor.WHITE.getMetadata();
+ if(color!=packetColor.getMetadata())
+ return false;
+ }
+
+ if(useAddressFilter)
{
- IDataConnector d = (IDataConnector)world.getTileEntity(this.pos.offset(EnumFacing.getFront(c)));
- d.sendPacket(packet);
+ int address = packetNBT.hasKey("address")?packetNBT.getInteger("address"): -1;
+ if(address!=packetAddress)
+ return false;
}
+
+ for(char variable : requiredVariables.toCharArray())
+ if(DataPacket.isValidVariable(variable)&&!packet.has(variable))
+ return false;
+
+ if(useValueFilter)
+ {
+ if(!DataPacket.isValidVariable(valueVariable)||!packet.has(valueVariable))
+ return false;
+
+ DataType actual = packet.get(valueVariable);
+ if(actual==null||actual.getClass()!=expectedValue.getClass())
+ return false;
+
+ return actual.valueToNBT().equals(expectedValue.valueToNBT());
+ }
+
+ return true;
+ }
+
+ public DataPacket getOutgoingPacket(@Nonnull DataPacket source)
+ {
+ DataPacket outgoing = source.clone();
+ if(removeControlVariable)
+ {
+ if(useValueFilter&&DataPacket.isValidVariable(valueVariable))
+ outgoing.remove(valueVariable);
+ else
+ for(char variable : requiredVariables.toCharArray())
+ if(DataPacket.isValidVariable(variable))
+ outgoing.remove(variable);
+ }
+ return outgoing;
+ }
+
+ @Nonnull
+ public DataRoutingRule copy()
+ {
+ DataRoutingRule rule = new DataRoutingRule();
+ rule.deserializeNBT(this.serializeNBT());
+ return rule;
+ }
+
+ //--- NBT ---//
+
+ @Override
+ public NBTTagCompound serializeNBT()
+ {
+ NBTTagCompound nbt = new NBTTagCompound();
+ int[] receiving = new int[receivingSides.length];
+ for(int i = 0; i < receivingSides.length; i++)
+ receiving[i] = receivingSides[i]?1: 0;
+
+ nbt.setIntArray("receivingSides", receiving);
+ nbt.setInteger("outgoingSide", outgoingSide.ordinal());
+
+ nbt.setBoolean("useColorFilter", useColorFilter);
+ nbt.setInteger("packetColor", packetColor.getMetadata());
+ nbt.setBoolean("useAddressFilter", useAddressFilter);
+ nbt.setInteger("packetAddress", packetAddress);
+
+ nbt.setString("requiredVariables", sanitizeVariables(requiredVariables, true));
+ nbt.setBoolean("useValueFilter", useValueFilter);
+ nbt.setString("valueVariable", String.valueOf(valueVariable));
+ nbt.setTag("expectedValue", expectedValue.valueToNBT());
+
+ nbt.setInteger("usageLimit", usageLimit);
+ nbt.setString("action", action.name());
+ nbt.setBoolean("removeControlVariable", removeControlVariable);
+ return nbt;
+ }
+
+ @Override
+ public void deserializeNBT(NBTTagCompound nbt)
+ {
+ Arrays.fill(receivingSides, true);
+ int[] receiving = nbt.getIntArray("receivingSides");
+ for(int i = 0; i < Math.min(receiving.length, receivingSides.length); i++)
+ receivingSides[i] = receiving[i]!=0;
+
+ outgoingSide = getFacingSafe(nbt.getInteger("outgoingSide"));
+
+ useColorFilter = nbt.getBoolean("useColorFilter");
+ packetColor = EnumDyeColor.byMetadata(nbt.getInteger("packetColor"));
+ useAddressFilter = nbt.getBoolean("useAddressFilter");
+ packetAddress = nbt.hasKey("packetAddress")?nbt.getInteger("packetAddress"): -1;
+
+ requiredVariables = sanitizeVariables(nbt.getString("requiredVariables"), true);
+ useValueFilter = nbt.getBoolean("useValueFilter");
+ String valueVariableString = nbt.getString("valueVariable");
+ valueVariable = sanitizeVariable(valueVariableString.isEmpty()?'a': valueVariableString.charAt(0), 'a');
+ expectedValue = nbt.hasKey("expectedValue")?IIDataTypeUtils.getVarFromNBT(nbt.getCompoundTag("expectedValue")): new DataTypeNull();
+
+ usageLimit = nbt.hasKey("usageLimit")?nbt.getInteger("usageLimit"): -1;
+ try
+ {
+ action = RoutingAction.valueOf(nbt.getString("action"));
+ } catch(IllegalArgumentException exception)
+ {
+ action = RoutingAction.ALLOW;
+ }
+ removeControlVariable = nbt.getBoolean("removeControlVariable");
}
+ //--- Utilities ---//
+
+ public static String sanitizeVariables(@Nullable String variables, boolean keepUnique)
+ {
+ if(variables==null||variables.isEmpty())
+ return "";
+
+ StringBuilder builder = new StringBuilder();
+ for(char c : variables.toCharArray())
+ if(DataPacket.isValidVariable(c)&&(!keepUnique||builder.indexOf(String.valueOf(c)) < 0))
+ builder.append(c);
+ return builder.toString();
+ }
+
+ public static char sanitizeVariable(char variable, char fallback)
+ {
+ return DataPacket.isValidVariable(variable)?variable: fallback;
+ }
+
+ private static EnumFacing getFacingSafe(int ordinal)
+ {
+ return ordinal >= 0&&ordinal < EnumFacing.VALUES.length?EnumFacing.VALUES[ordinal]: EnumFacing.NORTH;
+ }
}
- @Override
- public boolean hammerUseSide(@Nonnull EnumFacing side, @Nonnull EntityPlayer player, float hitX, float hitY, float hitZ)
+ /**
+ * Migrates the old router rules based around a single control variable
+ *
+ * @param variableName old control variable
+ */
+ private void migrateLegacyVariableRouter(String variableName)
{
- variable = IIUtils.cycleDataPacketChars(variable, hitY >= 0.5f, false);
- IIPacketHandler.sendChatString(player, String.valueOf(variable));
- return true;
+ if(variableName==null||variableName.isEmpty())
+ return;
+ migrateLegacyVariableRouter(variableName.charAt(0));
+ }
+
+ private void migrateLegacyVariableRouter(char variable)
+ {
+ if(!DataPacket.isValidVariable(variable))
+ return;
+
+ routingRules.clear();
+ for(EnumFacing side : EnumFacing.VALUES)
+ {
+ DataRoutingRule rule = new DataRoutingRule();
+ rule.outgoingSide = side;
+ rule.useValueFilter = true;
+ rule.valueVariable = variable;
+ rule.expectedValue = new DataTypeInteger(side.ordinal());
+ rule.action = RoutingAction.ALLOW;
+ rule.removeControlVariable = false;
+ rule.usageLimit = -1;
+ routingRules.add(rule);
+ }
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/BlockIIMetalDevice.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/BlockIIMetalDevice.java
index c82d2d7a5..48f5a1b3e 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/BlockIIMetalDevice.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/BlockIIMetalDevice.java
@@ -54,21 +54,6 @@ public BlockIIMetalDevice()
IIBlockTypes_MetalDevice.SMALL_DATA_BUFFER, IIBlockTypes_MetalDevice.DATA_MERGER);
}
- @Override
- public String getMappingsExtension(int meta, boolean itemBlock)
- {
- switch(IIBlockTypes_MetalDevice.values()[meta])
- {
- default:
- return null;
-
- case AMMUNITION_CRATE:
- case MEDIC_CRATE:
- case REPAIR_CRATE:
- return IIBlockTypes_MetalDevice.values()[meta].getName();
- }
- }
-
@Nonnull
public EnumBlockRenderType getRenderType(IBlockState state)
{
@@ -109,7 +94,7 @@ public enum IIBlockTypes_MetalDevice implements IITileProviderEnum
@IIBlockProperties(category = IICategory.ELECTRONICS)
@EnumTileProvider(tile = TileEntityMetalCrate.class)
METAL_CRATE,
- @IIBlockProperties(category = IICategory.LOGISTICS)
+ @IIBlockProperties(category = IICategory.LOGISTICS, needsCustomState = true)
@EnumTileProvider(tile = TileEntityAmmunitionCrate.class)
AMMUNITION_CRATE,
@IIBlockProperties(category = IICategory.ELECTRONICS)
@@ -130,16 +115,16 @@ public enum IIBlockTypes_MetalDevice implements IITileProviderEnum
@IIBlockProperties(category = IICategory.ELECTRONICS)
@EnumTileProvider(tile = TileEntityDataMerger.class)
DATA_MERGER,
- @IIBlockProperties(category = IICategory.LOGISTICS)
+ @IIBlockProperties(category = IICategory.LOGISTICS, needsCustomState = true)
@EnumTileProvider(tile = TileEntityMedicalCrate.class)
MEDIC_CRATE,
- @IIBlockProperties(category = IICategory.LOGISTICS)
+ @IIBlockProperties(category = IICategory.LOGISTICS, needsCustomState = true)
@EnumTileProvider(tile = TileEntityRepairCrate.class)
REPAIR_CRATE,
- @IIBlockProperties(category = IICategory.TOOLS)
+ @IIBlockProperties(category = IICategory.TOOLS, needsCustomState = true)
@EnumTileProvider(tile = TileEntityLatexCollector.class)
LATEX_COLLECTOR
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/TileEntityLatexCollector.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/TileEntityLatexCollector.java
index 1358114bd..e722aa5d8 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/TileEntityLatexCollector.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/TileEntityLatexCollector.java
@@ -5,6 +5,7 @@
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IPlayerInteraction;
import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
import net.minecraft.block.state.IBlockState;
+import net.minecraft.client.resources.I18n;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
@@ -13,9 +14,15 @@
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ITickable;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedTextOverlay;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.LatexCollector;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.simple.BlockIIRubberLog;
@@ -28,7 +35,7 @@
* @author Pabilo8 (pabilo@iiteam.net)
* @since 19.05.2021
*/
-public class TileEntityLatexCollector extends TileEntityIEBase implements IPlayerInteraction, ITickable, IBlockBounds, IDirectionalTile
+public class TileEntityLatexCollector extends TileEntityIEBase implements IPlayerInteraction, ITickable, IBlockBounds, IDirectionalTile, IAdvancedTextOverlay
{
public EnumFacing facing = EnumFacing.NORTH;
public ItemStack bucket = ItemStack.EMPTY;
@@ -43,7 +50,7 @@ public void readCustomNBT(NBTTagCompound nbt, boolean descPacket)
bucket = new ItemStack(nbt.getCompoundTag("bucket"));
if(nbt.hasKey("noSetup"))
bucketTime = 0;
- this.timer = nbt.getFloat("timer"); // FIX: was writing into NBT, should read from it
+ this.timer = nbt.getFloat("timer");
}
@Override
@@ -53,7 +60,7 @@ public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket)
nbt.setTag("bucket", bucket.serializeNBT());
if(bucketTime < 10)
nbt.setBoolean("noSetup", true);
- nbt.setFloat("timer", timer); // FIX: was reading from NBT, should write into it
+ nbt.setFloat("timer", timer);
}
/**
@@ -226,4 +233,20 @@ public boolean canRotate(EnumFacing axis)
{
return false;
}
+
+ //--- IAdvancedTextOverlay ---//
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public String[] getOverlayText(EntityPlayer player, RayTraceResult mop)
+ {
+ int latex = (int)MathHelper.clamp(timer/LatexCollector.collectTime*1000, 0f, 1000f);
+ if(latex==0)
+ return new String[]{I18n.format("gui.immersiveengineering.empty")};
+
+ return new String[]{
+ IIContent.fluidLatex.getLocalizedName(new FluidStack(IIContent.fluidLatex, latex)),
+ TextFormatting.GRAY.toString()+latex+"/1000 mB"
+ };
+ }
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityAmmunitionCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityAmmunitionCrate.java
index 48d503f1d..3bc1238bd 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityAmmunitionCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityAmmunitionCrate.java
@@ -38,9 +38,7 @@ public class TileEntityAmmunitionCrate extends TileEntityEffectCrate
static
{
UpgradeTechTree.getTreeFor(TileEntityAmmunitionCrate.class)
- .withUpgrade(IIContent.UPGRADE_INSERTER, UpgradeTier.TIER_1)
- .withUpgrade(IIContent.UPGRADE_MG_LOADER, UpgradeTier.TIER_2)
- .withDependency(IIContent.UPGRADE_INSERTER, IIContent.UPGRADE_MG_LOADER);
+ .withUpgrade(IIContent.UPGRADE_MG_LOADER, UpgradeTier.TIER_1);
}
public TileEntityAmmunitionCrate()
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityEffectCrate.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityEffectCrate.java
index 6dc2a6c1b..a19922708 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityEffectCrate.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/effect_crate/TileEntityEffectCrate.java
@@ -19,7 +19,6 @@
import net.minecraft.util.math.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
-import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.storage.loot.ILootContainer;
@@ -28,7 +27,6 @@
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
-import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
import pl.pabilo8.immersiveintelligence.api.upgrade.IManagedUpgradableDevice;
import pl.pabilo8.immersiveintelligence.api.upgrade.IUpgradableDevice;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeManager;
@@ -117,7 +115,7 @@ public boolean canRotate(EnumFacing axis)
@Nullable
public ITextComponent getDisplayName()
{
- return name!=null?new TextComponentString(name): new TextComponentTranslation("tile."+ImmersiveIntelligence.MODID+".metal_device.metal_crate.name");
+ return name!=null?new TextComponentString(name): null;
}
@Override
@@ -177,6 +175,8 @@ public void readCustomNBT(NBTTagCompound nbt, boolean descPacket)
open = nbt.getBoolean("open");
if(nbt.hasKey("facing"))
setFacing(EnumFacing.getFront(nbt.getInteger("facing")));
+ if(nbt.hasKey("upgrades"))
+ upgradeManager.deserializeNBT(nbt.getCompoundTag("upgrades"));
energyStorage = nbt.getInteger("energyStorage");
if(!descPacket)
@@ -197,6 +197,7 @@ public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket)
nbt.setBoolean("open", open);
nbt.setInteger("facing", facing.getIndex());
nbt.setInteger("energyStorage", energyStorage);
+ nbt.setTag("upgrades", upgradeManager.serializeNBT());
if(!descPacket)
{
if(lootTable!=null)
@@ -221,6 +222,8 @@ public void onAnimationChangeServer(boolean state, int part)
@Override
public void receiveMessageFromServer(NBTTagCompound message)
{
+ if(message.hasKey("upgrades"))
+ upgradeManager.deserializeNBT(message.getCompoundTag("upgrades"));
if(message.hasKey("focused"))
focusedEntity = world.getEntityByID(message.getInteger("focused"));
else
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/inserter/TileEntityInserterBase.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/inserter/TileEntityInserterBase.java
index 7028fece9..1472bd1f7 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/inserter/TileEntityInserterBase.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/metal_device/tileentity/inserter/TileEntityInserterBase.java
@@ -25,6 +25,7 @@
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
@@ -706,17 +707,13 @@ public NBTTagCompound serializeNBT()
NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("name", getName());
if(facingIn!=null)
- {
nbt.setInteger("facingIn", facingIn.getIndex());
- if(distanceIn!=-1)
- nbt.setInteger("distanceIn", distanceIn);
- }
+ if(distanceIn!=-1)
+ nbt.setInteger("distanceIn", MathHelper.clamp(distanceIn, -1, 2));
if(facingOut!=null)
- {
nbt.setInteger("facingOut", facingOut.getIndex());
- if(distanceOut!=-1)
- nbt.setInteger("distanceOut", distanceOut);
- }
+ if(distanceOut!=-1)
+ nbt.setInteger("distanceOut", MathHelper.clamp(distanceOut, -1, 2));
nbt.setTag("stack", stack.writeToNBT(new NBTTagCompound()));
nbt.setBoolean("isJob", isJob);
@@ -731,17 +728,13 @@ public NBTTagCompound serializeNBT()
public void deserializeNBT(NBTTagCompound nbt)
{
if(nbt.hasKey("facingIn"))
- {
facingIn = EnumFacing.getFront(nbt.getInteger("facingIn"));
- if(nbt.hasKey("distanceIn"))
- distanceIn = nbt.getInteger("distanceIn");
- }
+ if(nbt.hasKey("distanceIn"))
+ distanceIn = MathHelper.clamp(nbt.getInteger("distanceIn"), -1, 2);
if(nbt.hasKey("facingOut"))
- {
facingOut = EnumFacing.getFront(nbt.getInteger("facingOut"));
- if(nbt.hasKey("distanceOut"))
- distanceOut = nbt.getInteger("distanceOut");
- }
+ if(nbt.hasKey("distanceOut"))
+ distanceOut = MathHelper.clamp(nbt.getInteger("distanceOut"), -1, 2);
if(nbt.hasKey("stack"))
{
stack = IngredientStack.readFromNBT(nbt.getCompoundTag("stack"));
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPacker.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPacker.java
index 3f23aece5..10b98823d 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPacker.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPacker.java
@@ -28,8 +28,9 @@ public MultiblockPacker()
.withUpgrade(IIContent.UPGRADE_PACKER_FLUID, UpgradeTier.TIER_1)
.withUpgrade(IIContent.UPGRADE_PACKER_ENERGY, UpgradeTier.TIER_1)
.withLockOut(IIContent.UPGRADE_PACKER_FLUID, IIContent.UPGRADE_PACKER_ENERGY)
- .withUpgrade(IIContent.UPGRADE_PACKER_NAMING, UpgradeTier.TIER_1)
- .withUpgrade(IIContent.UPGRADE_PACKER_RAILWAY, UpgradeTier.TIER_1);
+ .withUpgrade(IIContent.UPGRADE_PACKER_NAMING, UpgradeTier.TIER_1);
+ //TODO: 02.06.2026 actually implement
+ //.withUpgrade(IIContent.UPGRADE_PACKER_RAILWAY, UpgradeTier.TIER_1);
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPrintingPress.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPrintingPress.java
index f4ea15066..b78944754 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPrintingPress.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/multiblock/MultiblockPrintingPress.java
@@ -3,6 +3,8 @@
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3i;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradeTier;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.BlockIIMetalMultiblock0.MetalMultiblocks0;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock0.tileentity.TileEntityPrintingPress;
@@ -15,6 +17,10 @@
*/
public class MultiblockPrintingPress extends MultiblockStuctureBase
{
+ public static final int SLOT_PAPER = 0;
+ public static final int SLOT_OUTPUT = 1;
+ public static final int SLOT_BUCKET_IN = 2;
+ public static final int SLOT_BUCKET_OUT = 3;
public static MultiblockPrintingPress INSTANCE;
public MultiblockPrintingPress()
@@ -22,6 +28,11 @@ public MultiblockPrintingPress()
super(new ResourceLocation(ImmersiveIntelligence.MODID, "multiblocks/printing_press"));
offset = new Vec3i(1, 1, 0);
INSTANCE = this;
+
+ UpgradeTechTree.getTreeFor(TileEntityPrintingPress.class)
+ .withUpgrade(IIContent.UPGRADE_PRESS_PUNCHTAPES, UpgradeTier.TIER_1)
+ .withUpgrade(IIContent.UPGRADE_PRESS_BATCHING, UpgradeTier.TIER_1)
+ .withUpgrade(IIContent.UPGRADE_PRESS_ENVELOPER, UpgradeTier.TIER_1);
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArithmeticLogicMachine.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArithmeticLogicMachine.java
index 68d3c6dac..91e2098e7 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArithmeticLogicMachine.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArithmeticLogicMachine.java
@@ -2,15 +2,12 @@
import blusunrize.immersiveengineering.api.energy.immersiveflux.FluxStorageAdvanced;
import blusunrize.immersiveengineering.common.util.Utils;
+import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.util.SoundCategory;
-import org.apache.commons.lang3.ArrayUtils;
-import net.minecraft.entity.player.EntityPlayer;
-import javax.annotation.Nullable;
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
-import pl.pabilo8.immersiveintelligence.api.data.IIDataHandlingUtils;
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeExpression;
import pl.pabilo8.immersiveintelligence.api.data.types.generic.DataType;
import pl.pabilo8.immersiveintelligence.api.upgrade.IManagedUpgradableDevice;
@@ -34,14 +31,15 @@
import pl.pabilo8.immersiveintelligence.common.util.multiblock.util.MultiblockPOI;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
/**
* @author Pabilo8 (pabilo@iiteam.net)
* @author Avalon (avalon@iiteam.net)
* @updated 08.01.2024
* @ii-approved 0.3.1
- * @since 28.06.2019
* @updated 03.30.2026
+ * @since 28.06.2019
*/
public class TileEntityArithmeticLogicMachine extends TileEntityMultiblockIIGeneric
implements IIIGuiMultiblockTile, IBooleanAnimatedPartsBlock, IManagedUpgradableDevice
@@ -85,18 +83,25 @@ protected void dummyCleanup()
public void receiveMessageFromClient(@Nonnull NBTTagCompound message)
{
super.receiveMessageFromClient(message);
- //Receive edits from GUI
+ //Receive expression edits from the circuit editor GUI
if(message.hasKey("expressions"))
{
- //Get updated expressions
NBTTagCompound expressions = message.getCompoundTag("expressions");
int page = expressions.getInteger("page");
+ if(page < 0||page >= inventory.size())
+ return;
+
//Update circuit stack
ItemStack stack = inventory.get(page);
+ if(stack.isEmpty()||!(stack.getItem() instanceof ItemIIFunctionalCircuit))
+ return;
+
DataPacket packet = new DataPacket(expressions.getCompoundTag("list"));
((ItemIIFunctionalCircuit)stack.getItem()).writeDataToItem(stack, packet);
inventory.set(page, stack);
+ markDirty();
+ forceTileUpdate();
}
}
@@ -116,8 +121,10 @@ protected int[] listAllPOI(MultiblockPOI poi)
{
case ENERGY_INPUT:
return getPOI("energy");
- case DATA:
- return getPOI("data");
+ case DATA_INPUT:
+ return getPOI("data_in");
+ case DATA_OUTPUT:
+ return getPOI("data_out");
case MISC_CONTROL_PANEL:
return getPOI("front_panel");
case MISC_CRATE:
@@ -132,11 +139,11 @@ protected int[] listAllPOI(MultiblockPOI poi)
public void receiveData(DataPacket packet, int pos)
{
//Prepare reply packet
- boolean fromLeft = ArrayUtils.contains(getPOI("data_left"), pos);
DataPacket newPacket = packet.clone();
//Process received packet with circuits
- int circuitsAmount = isUpgradeInstalled(IIContent.UPGRADE_CIRCUIT_RACKS)?MultiblockArithmeticLogicMachine.CIRCUITS_UPGRADED: MultiblockArithmeticLogicMachine.CIRCUITS_BASE;
+ int circuitsAmount = isUpgradeInstalled(IIContent.UPGRADE_CIRCUIT_RACKS)?MultiblockArithmeticLogicMachine.CIRCUITS_UPGRADED:
+ MultiblockArithmeticLogicMachine.CIRCUITS_BASE;
boolean[] circuit = new boolean[circuitsAmount];
DataPacket[] cPacket = new DataPacket[circuitsAmount];
@@ -168,17 +175,14 @@ public void receiveData(DataPacket packet, int pos)
DataTypeExpression exp = ((DataTypeExpression)var);
char condition = exp.getRequiredVariable();
- //Respect condition, if set
- if(condition==' '||IIDataHandlingUtils.asBoolean(condition, packet))
+ //Respect condition, if set: expressions with a required variable only run when that variable is present in the input packet.
+ if(condition==' '||packet.has(condition))
newPacket.set(c, exp.getValue(newPacket));
}
}
//Send reply to opposite side
- sendData(newPacket,
- fromLeft?facing.rotateY(): facing.rotateYCCW(),
- (fromLeft?getPOI("data_right"): getPOI("data_left"))[0]
- );
+ sendData(newPacket, getDirection("data_out"), getPOI("data_out")[0]);
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArtilleryHowitzer.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArtilleryHowitzer.java
index 6210bc3ec..cbc8f51ff 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArtilleryHowitzer.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityArtilleryHowitzer.java
@@ -27,6 +27,8 @@
import pl.pabilo8.immersiveintelligence.api.data.IIDataHandlingUtils;
import pl.pabilo8.immersiveintelligence.api.data.types.*;
import pl.pabilo8.immersiveintelligence.api.utils.IBooleanAnimatedPartsBlock;
+import pl.pabilo8.immersiveintelligence.client.fx.utils.IIParticleUtils;
+import pl.pabilo8.immersiveintelligence.client.fx.utils.ParticleProperties;
import pl.pabilo8.immersiveintelligence.client.fx.utils.ParticleRegistry;
import pl.pabilo8.immersiveintelligence.client.util.carversound.ConditionCompoundSound;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.ArtilleryHowitzer;
@@ -350,7 +352,8 @@ private void fireGun(int i)
if(world.isRemote)
{
Vec3d gun_end_particle = gunVec.scale(4.5);
- ParticleRegistry.spawnGunfireFX(getGunPosition().add(gun_end_particle), gunVec, 8f);
+ ParticleRegistry.spawnParticle("ammo/gunfire", getGunPosition().add(gun_end_particle), Vec3d.ZERO, IIParticleUtils.toVector2f(gunVec))
+ .withProperty(ParticleProperties.SIZE, 4f);
}
IIPacketHandler.playRangedSound(world, gunEnd,
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityPrintingPress.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityPrintingPress.java
index 2ac9ce51a..9fa4e34ff 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityPrintingPress.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock0/tileentity/TileEntityPrintingPress.java
@@ -29,6 +29,9 @@
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
import pl.pabilo8.immersiveintelligence.api.data.IIDataHandlingUtils;
import pl.pabilo8.immersiveintelligence.api.data.types.DataTypeInteger;
+import pl.pabilo8.immersiveintelligence.api.upgrade.IManagedUpgradableDevice;
+import pl.pabilo8.immersiveintelligence.api.upgrade.Upgrade;
+import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeManager;
import pl.pabilo8.immersiveintelligence.api.utils.tools.IAdvancedTextOverlay;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.PrintingPress;
import pl.pabilo8.immersiveintelligence.common.IIContent;
@@ -46,6 +49,7 @@
import pl.pabilo8.immersiveintelligence.common.util.multiblock.production.TileEntityMultiblockProductionMulti;
import pl.pabilo8.immersiveintelligence.common.util.multiblock.util.MultiblockPOI;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
@@ -53,18 +57,16 @@
* @updated 13.12.2023
* @since 28.06.2019
*/
-public class TileEntityPrintingPress extends TileEntityMultiblockProductionMulti implements ITactileListener, IPlayerInteraction, IAdvancedTextOverlay
+public class TileEntityPrintingPress extends TileEntityMultiblockProductionMulti
+ implements ITactileListener, IPlayerInteraction, IAdvancedTextOverlay, IManagedUpgradableDevice
{
- /**
- * Inventory slots IDs
- */
- public static final int SLOT_PAPER = 0, SLOT_OUTPUT = 1, SLOT_BUCKET_IN = 2, SLOT_BUCKET_OUT = 3;
-
@SyncNBT(time = 40, events = {SyncEvents.TILE_GUI_OPENED, SyncEvents.TILE_RECIPE_CHANGED})
public MultiFluidTank tank;
+ @SyncNBT(name = "upgrades", events = SyncEvents.TILE_UPGRADES_MODIFIED)
+ public UpgradeManager upgradeManager;
- private IItemHandler inputHandler = getSingleInventoryHandler(SLOT_PAPER, true, true);
- private IItemHandler outputHandler = getSingleInventoryHandler(SLOT_OUTPUT, true, true);
+ private IItemHandler inputHandler = getSingleInventoryHandler(MultiblockPrintingPress.SLOT_PAPER, true, true);
+ private IItemHandler outputHandler = getSingleInventoryHandler(MultiblockPrintingPress.SLOT_OUTPUT, true, true);
private TactileManager tactileManager = null;
private EasyCollection printRequestsQueue;
@@ -76,6 +78,7 @@ public TileEntityPrintingPress()
this.energyStorage = new FluxStorageAdvanced(PrintingPress.energyCapacity);
this.inventory = NonNullList.withSize(4, ItemStack.EMPTY);
this.printRequestsQueue = new EasyCollection<>(PrintingRequest::new);
+ this.upgradeManager = new UpgradeManager<>(this);
}
@Override
@@ -94,6 +97,7 @@ protected void dummyCleanup()
this.inputHandler = null;
this.outputHandler = null;
this.tactileManager = null;
+ this.upgradeManager = null;
}
@Override
@@ -104,7 +108,7 @@ protected void onUpdate()
if(!world.isRemote)
tactileManager.defaultize();
- if(IIUtils.handleBucketTankInteraction(tank, inventory, SLOT_BUCKET_IN, SLOT_BUCKET_OUT, true,
+ if(IIUtils.handleBucketTankInteraction(tank, inventory, MultiblockPrintingPress.SLOT_BUCKET_IN, MultiblockPrintingPress.SLOT_BUCKET_OUT, true,
fs -> IIContent.fluidInkBlack.equals(fs.getFluid())||
IIContent.fluidInkCyan.equals(fs.getFluid())||
IIContent.fluidInkMagenta.equals(fs.getFluid())||
@@ -171,7 +175,7 @@ public void receiveData(DataPacket packet, int pos)
String printingMode = IIDataHandlingUtils.asString('m', packet);
PrintingRecipe.streamRecipes(PrintingRecipe.class)
- .filter(recipe -> recipe.getInput().matchesItemStack(inventory.get(SLOT_PAPER)))
+ .filter(recipe -> recipe.getInput().matchesItemStack(inventory.get(MultiblockPrintingPress.SLOT_PAPER)))
.filter(recipe -> recipe.getCategoryName().equals(printingMode))
.findFirst()
.ifPresent(printingRecipe -> {
@@ -193,12 +197,12 @@ public boolean isStackValid(int slot, ItemStack stack)
{
switch(slot)
{
- case SLOT_PAPER:
+ case MultiblockPrintingPress.SLOT_PAPER:
return Utils.compareToOreName(stack, "pageEmpty");
- case SLOT_OUTPUT:
+ case MultiblockPrintingPress.SLOT_OUTPUT:
return Utils.compareToOreName(stack, "pageWritten")||Utils.compareToOreName(stack, "pageEmpty");
- case SLOT_BUCKET_IN:
- case SLOT_BUCKET_OUT:
+ case MultiblockPrintingPress.SLOT_BUCKET_IN:
+ case MultiblockPrintingPress.SLOT_BUCKET_OUT:
return stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null);
default:
return false;
@@ -221,12 +225,12 @@ public int getMaxProductionQueue()
@Override
protected IIMultiblockProcess findNewProductionProcess()
{
- // Check for queued orders
+ //Check for queued orders
if(printRequestsQueue.isEmpty())
return null;
PrintingRequest found = printRequestsQueue.get(0);
- ItemStack input = inputHandler.extractItem(SLOT_PAPER, 1, true);
+ ItemStack input = inputHandler.extractItem(MultiblockPrintingPress.SLOT_PAPER, 1, true);
if(!found.recipe.getInput().matchesItemStack(input))
return null;
@@ -235,6 +239,11 @@ protected IIMultiblockProcess findNewProductionProcess()
ItemStack result = function.apply(input, found.data);
int[] inkCost = function.getInkTypesRequired(found.data);
+ //Check if the required upgrade is installed
+ Upgrade requiredUpgrade = function.getUpgradeRequired();
+ if(requiredUpgrade!=null&&!isUpgradeInstalled(requiredUpgrade))
+ return null;
+
//Check if there's enough ink
FluidStack[] fs = {
new FluidStack(IIContent.fluidInkCyan, inkCost[0]),
@@ -247,7 +256,7 @@ protected IIMultiblockProcess findNewProductionProcess()
return null;
//Use resources
- inputHandler.extractItem(SLOT_PAPER, 1, false);
+ inputHandler.extractItem(MultiblockPrintingPress.SLOT_PAPER, 1, false);
for(FluidStack f : fs)
tank.drain(f, true);
@@ -336,7 +345,7 @@ protected boolean isTankAvailable(int pos, int tank)
@Override
public int getSlotLimit(int slot)
{
- return slot==SLOT_OUTPUT?12: super.getSlotLimit(slot);
+ return slot==MultiblockPrintingPress.SLOT_OUTPUT?12: super.getSlotLimit(slot);
}
@Override
@@ -392,6 +401,15 @@ public String[] getOverlayText(EntityPlayer player, RayTraceResult mop)
return new String[0];
}
+ //--- IManagedUpgradableDevice ---//
+
+ @Nonnull
+ @Override
+ public UpgradeManager getUpgradeManager()
+ {
+ return upgradeManager;
+ }
+
//--- Utilities ---//
public static class PrintingRequest implements INBTSerializable
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockAmmunitionAssembler.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockAmmunitionAssembler.java
index 91f0204fd..25f82b324 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockAmmunitionAssembler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockAmmunitionAssembler.java
@@ -11,6 +11,10 @@
public class MultiblockAmmunitionAssembler extends MultiblockStuctureBase
{
+ public static final int SLOT_CORE = 0;
+ public static final int SLOT_CASING = 1;
+ public static final int SLOT_OUTPUT = 2;
+ public static final String NBT_KEY_EFFECT = "effect";
public static MultiblockAmmunitionAssembler INSTANCE;
public MultiblockAmmunitionAssembler()
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockEmplacement.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockEmplacement.java
index 2939ee1bc..dc7a2a214 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockEmplacement.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockEmplacement.java
@@ -5,6 +5,7 @@
import net.minecraft.util.math.Vec3i;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints;
+import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints.PaintStyleConstraint;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradePurpose;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradeTier;
@@ -29,7 +30,7 @@ public MultiblockEmplacement()
super(new ResourceLocation(ImmersiveIntelligence.MODID, "multiblocks/emplacement"));
offset = new Vec3i(1, 4, 0);
INSTANCE = this;
- STYLE_CONSTRAINTS = new StyleConstraints("sandbags", false,
+ STYLE_CONSTRAINTS = new StyleConstraints("sandbags", PaintStyleConstraint.NOT_APPLICABLE,
Sets.newHashSet("sandbags", "wooden", "steel", "bricks", "concrete"),
Collections.emptySet()
);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFlagpole.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFlagpole.java
index b7b4e34b2..bbcadaac1 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFlagpole.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFlagpole.java
@@ -5,6 +5,7 @@
import net.minecraft.util.math.Vec3i;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints;
+import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints.PaintStyleConstraint;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeTechTree;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.UpgradeTier;
import pl.pabilo8.immersiveintelligence.common.IIContent;
@@ -25,7 +26,7 @@ public MultiblockFlagpole()
super(new ResourceLocation(ImmersiveIntelligence.MODID, "multiblocks/flagpole"));
offset = new Vec3i(1, 3, 0);
INSTANCE = this;
- STYLE_CONSTRAINTS = new StyleConstraints("sandbags", false,
+ STYLE_CONSTRAINTS = new StyleConstraints("sandbags", PaintStyleConstraint.NOT_APPLICABLE,
Sets.newHashSet("sandbags", "wooden", "steel", "bricks", "concrete"),
Collections.emptySet()
);
@@ -33,9 +34,10 @@ public MultiblockFlagpole()
UpgradeTechTree.getTreeFor(TileEntityFlagpole.class)
.reset()
.withUpgrade(IIContent.UPGRADE_FLAGPOLE_CAPTURE_DEFIANCE, UpgradeTier.TIER_1)
- .withUpgrade(IIContent.UPGRADE_FLAGPOLE_TASER_LOCKS, UpgradeTier.TIER_1)
+ .withUpgrade(IIContent.UPGRADE_FLAGPOLE_TASER_LOCKS, UpgradeTier.TIER_2)
.withUpgrade(IIContent.UPGRADE_FLAGPOLE_UNIT_POST, UpgradeTier.TIER_1)
.withUpgrade(IIContent.UPGRADE_FLAGPOLE_DISTRESS_SIGNAL, UpgradeTier.TIER_1)
+ .withDependency(IIContent.UPGRADE_FLAGPOLE_CAPTURE_DEFIANCE, IIContent.UPGRADE_FLAGPOLE_TASER_LOCKS)
.withLockOut(IIContent.UPGRADE_FLAGPOLE_UNIT_POST, IIContent.UPGRADE_FLAGPOLE_TASER_LOCKS);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFuelStation.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFuelStation.java
index 7e0d7f5c8..925bea8d8 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFuelStation.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockFuelStation.java
@@ -5,6 +5,7 @@
import net.minecraft.util.math.Vec3i;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints;
+import pl.pabilo8.immersiveintelligence.api.style.StyleConstraints.PaintStyleConstraint;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.BlockIIMetalMultiblock1.MetalMultiblocks1;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.TileEntityFuelStation;
@@ -27,7 +28,7 @@ public MultiblockFuelStation()
super(new ResourceLocation(ImmersiveIntelligence.MODID, "multiblocks/fuel_station"));
offset = new Vec3i(0, 1, 0);
INSTANCE = this;
- STYLE_CONSTRAINTS = new StyleConstraints("wooden", false,
+ STYLE_CONSTRAINTS = new StyleConstraints("wooden", PaintStyleConstraint.NOT_APPLICABLE,
Sets.newHashSet("wooden", "naval", "steel"),
Collections.emptySet()
);
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockProjectileWorkshop.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockProjectileWorkshop.java
index c1f462a01..65755f5c1 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockProjectileWorkshop.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/multiblock/MultiblockProjectileWorkshop.java
@@ -13,6 +13,9 @@
public class MultiblockProjectileWorkshop extends MultiblockStuctureBase
{
+ public static final int SLOT_INPUT = 0;
+ public static final int SLOT_COMPONENT_INPUT = 1;
+ public static final int SLOT_OUTPUT = 2;
public static MultiblockProjectileWorkshop INSTANCE;
public MultiblockProjectileWorkshop()
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityAmmunitionAssembler.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityAmmunitionAssembler.java
index 7ec0db4cd..a512c59c6 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityAmmunitionAssembler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityAmmunitionAssembler.java
@@ -19,6 +19,7 @@
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.AmmunitionAssembler;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.IISounds;
+import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.multiblock.MultiblockAmmunitionAssembler;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageBooleanAnimatedPartsSync;
@@ -38,28 +39,34 @@
*/
public class TileEntityAmmunitionAssembler extends TileEntityMultiblockProductionMulti implements IBooleanAnimatedPartsBlock
{
- public static final int SLOT_CORE = 0, SLOT_CASING = 1, SLOT_OUTPUT = 2;
- public static final String NBT_KEY_EFFECT = "effect";
-
@SyncNBT(events = {SyncEvents.TILE_GUI_OPENED, SyncEvents.TILE_CLIENT_MESSAGE})
- public FuseType fuse = FuseType.CONTACT;
+ public FuseType fuseType = FuseType.CONTACT;
+ //depends on fuse type: time for timed fuse, distance for proximity fuse
@SyncNBT(events = {SyncEvents.TILE_GUI_OPENED, SyncEvents.TILE_CLIENT_MESSAGE})
- public int fuseConfig = 0; //depends on fuse type: time for timed fuse, distance for proximity fuse
+ public int fuseConfig = 0;
@SyncNBT
public MultiblockInteractablePart hatch;
//inventory: core, casing
- IItemHandler coreInputHandler = getSingleInventoryHandler(SLOT_CORE, true, false);
- IItemHandler casingInputHandler = getSingleInventoryHandler(SLOT_CASING, true, false);
+ private IItemHandler coreInputHandler = getSingleInventoryHandler(MultiblockAmmunitionAssembler.SLOT_CORE, true, false);
+ private IItemHandler casingInputHandler = getSingleInventoryHandler(MultiblockAmmunitionAssembler.SLOT_CASING, true, false);
public TileEntityAmmunitionAssembler()
{
super(MultiblockAmmunitionAssembler.INSTANCE);
energyStorage = new FluxStorageAdvanced(AmmunitionAssembler.energyCapacity);
- inventory = NonNullList.withSize(4, ItemStack.EMPTY);
+ inventory = NonNullList.withSize(3, ItemStack.EMPTY);
hatch = new MultiblockInteractablePart(10);
}
+ @Override
+ protected void dummyCleanup()
+ {
+ super.dummyCleanup();
+ this.coreInputHandler = this.casingInputHandler = null;
+ this.hatch = null;
+ }
+
@Override
protected void onUpdate()
{
@@ -99,9 +106,9 @@ public boolean isStackValid(int i, ItemStack stack)
{
switch(i)
{
- case SLOT_CORE:
+ case MultiblockAmmunitionAssembler.SLOT_CORE:
return stack.getItem() instanceof IAmmoTypeItem&&((IAmmoTypeItem, ?>)stack.getItem()).isBulletCore(stack);
- case SLOT_CASING:
+ case MultiblockAmmunitionAssembler.SLOT_CASING:
return AmmunitionAssemblerRecipe.streamRecipes(AmmunitionAssemblerRecipe.class)
.anyMatch(a -> a.casingInput.matchesItemStackIgnoringSize(stack));
default:
@@ -132,17 +139,17 @@ public int getMaxProductionQueue()
@Override
protected IIMultiblockProcess findNewProductionProcess()
{
- if(!inventory.get(SLOT_CORE).isEmpty()&&!inventory.get(SLOT_CASING).isEmpty())
+ if(!inventory.get(MultiblockAmmunitionAssembler.SLOT_CORE).isEmpty()&&!inventory.get(MultiblockAmmunitionAssembler.SLOT_CASING).isEmpty())
for(AmmunitionAssemblerRecipe recipe : AmmunitionAssemblerRecipe.getRecipes(AmmunitionAssemblerRecipe.class))
- if(!recipe.advanced&&recipe.casingInput.matchesItemStack(inventory.get(SLOT_CASING))&&recipe.coreInput.matches(inventory.get(SLOT_CORE)))
+ if(!recipe.advanced&&recipe.casingInput.matchesItemStack(inventory.get(MultiblockAmmunitionAssembler.SLOT_CASING))&&recipe.coreInput.matches(inventory.get(MultiblockAmmunitionAssembler.SLOT_CORE)))
{
IIMultiblockProcess process = new IIMultiblockProcess<>(recipe)
- .withNBT(nbt -> nbt.withItemStack(NBT_KEY_EFFECT, recipe.process.apply(inventory.get(SLOT_CORE), inventory.get(SLOT_CASING)))
- .withItemStack("core", inventory.get(SLOT_CORE))
+ .withNBT(nbt -> nbt.withItemStack(MultiblockAmmunitionAssembler.NBT_KEY_EFFECT, recipe.process.apply(inventory.get(MultiblockAmmunitionAssembler.SLOT_CORE), inventory.get(MultiblockAmmunitionAssembler.SLOT_CASING)))
+ .withItemStack("core", inventory.get(MultiblockAmmunitionAssembler.SLOT_CORE))
.withString("ammo", recipe.ammoItem.getName())
);
- inventory.get(SLOT_CORE).shrink(1);
- inventory.get(SLOT_CASING).shrink(1);
+ inventory.get(MultiblockAmmunitionAssembler.SLOT_CORE).shrink(1);
+ inventory.get(MultiblockAmmunitionAssembler.SLOT_CASING).shrink(1);
return process;
}
return null;
@@ -173,7 +180,7 @@ protected boolean attemptProductionOutput(IIMultiblockProcess process)
{
- outputOrDrop(process.processData.getItemStack(NBT_KEY_EFFECT), null, facing.getOpposite(), 34);
+ outputOrDrop(process.processData.getItemStack(MultiblockAmmunitionAssembler.NBT_KEY_EFFECT), null, facing.getOpposite(), 34);
}
//--- Data Handling ---//
@@ -182,14 +189,14 @@ protected void onProductionFinish(IIMultiblockProcess
public void receiveData(DataPacket packet, int pos)
{
if(packet.has('f'))
- fuse = FuseType.v(packet.get('f').toString());
+ fuseType = IIUtils.enumValue(FuseType.class, packet.get('f').toString());
}
public ItemStack getProductionResult(int processID)
{
if(processQueue.size() <= processID)
return ItemStack.EMPTY;
- return this.processQueue.get(processID).processData.getItemStack(NBT_KEY_EFFECT);
+ return this.processQueue.get(processID).processData.getItemStack(MultiblockAmmunitionAssembler.NBT_KEY_EFFECT);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityFlagpole.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityFlagpole.java
index c61367d4f..1c4a05dfe 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityFlagpole.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityFlagpole.java
@@ -13,6 +13,7 @@
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeManager;
import pl.pabilo8.immersiveintelligence.api.upgrade.UpgradeUtils.MachineStyle;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.Flagpole;
+import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
import pl.pabilo8.immersiveintelligence.common.IILogger;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.multiblock.MultiblockFlagpole;
@@ -223,10 +224,18 @@ public MultiblockHealth getHealthManager()
return health;
}
+ @Override
+ public boolean damageHealth(float damage)
+ {
+ if(isUpgradeInstalled(IIContent.UPGRADE_FLAGPOLE_CAPTURE_DEFIANCE))
+ damage /= 2;
+ return IManagedDamageResistantMultiblock.super.damageHealth(damage);
+ }
+
@Override
public float getExplosionResistance()
{
- return 3;
+ return isUpgradeInstalled(IIContent.UPGRADE_FLAGPOLE_CAPTURE_DEFIANCE)?6: 3;
}
//--- IIIGuiMultiblockTile ---//
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityHeavyAmmunitionAssembler.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityHeavyAmmunitionAssembler.java
index 30b45cbfa..bc4cde48b 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityHeavyAmmunitionAssembler.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityHeavyAmmunitionAssembler.java
@@ -16,6 +16,7 @@
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Machines.AmmunitionAssembler;
import pl.pabilo8.immersiveintelligence.common.IIGUI;
+import pl.pabilo8.immersiveintelligence.common.IIUtils;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.multiblock.MultiblockHeavyAmmunitionAssembler;
import pl.pabilo8.immersiveintelligence.common.entity.tactile.TactileManager;
import pl.pabilo8.immersiveintelligence.common.entity.tactile.TactileManager.ITactileListener;
@@ -189,7 +190,7 @@ protected void onProductionFinish(IIMultiblockProcess
public void receiveData(DataPacket packet, int pos)
{
if(packet.has('f'))
- fuse = FuseType.v(packet.get('f').toString());
+ fuse = IIUtils.enumValue(FuseType.class, packet.get('f').toString());
}
public ItemStack getProductionResult()
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityProjectileWorkshop.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityProjectileWorkshop.java
index 5e455a551..be4c132c2 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityProjectileWorkshop.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/TileEntityProjectileWorkshop.java
@@ -6,14 +6,20 @@
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.SoundCategory;
import net.minecraft.world.World;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.IFluidTank;
+import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import pl.pabilo8.immersiveintelligence.api.ammo.AmmoRegistry;
import pl.pabilo8.immersiveintelligence.api.ammo.enums.CoreType;
import pl.pabilo8.immersiveintelligence.api.ammo.parts.AmmoComponent;
+import pl.pabilo8.immersiveintelligence.api.ammo.parts.AmmoCore;
import pl.pabilo8.immersiveintelligence.api.ammo.parts.IAmmoTypeItem;
import pl.pabilo8.immersiveintelligence.api.crafting.BulletComponentStack;
import pl.pabilo8.immersiveintelligence.api.crafting.ProjectileWorkshopRecipe;
@@ -38,6 +44,7 @@
import pl.pabilo8.immersiveintelligence.common.util.multiblock.util.MultiblockPOI;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Optional;
@@ -50,34 +57,39 @@
public class TileEntityProjectileWorkshop extends TileEntityMultiblockProductionSingle
implements IManagedUpgradableDevice, IBooleanAnimatedPartsBlock
{
- public static final int SLOT_INPUT = 0, SLOT_COMPONENT_INPUT = 1, SLOT_OUTPUT = 2;
-
- //for core production
@Nonnull
public IAmmoTypeItem, ?> producedAmmo = IIContent.itemAmmoHeavyArtillery;
-
@Nonnull
@SyncNBT(events = {SyncEvents.TILE_GUI_OPENED, SyncEvents.TILE_CLIENT_MESSAGE})
public CoreType coreType = producedAmmo.getAllowedCoreTypes()[0];
-
- //how many slots to fill
@SyncNBT
- public int fillAmount = 1;
+ public int componentFillAmount = 1;
@SyncNBT
public BulletComponentStack componentInside = new BulletComponentStack();
+ private static final int COMPONENT_AMOUNT_PER_ITEM = 16;
+
/**
* Stores fluids to be converted to ammo components
*/
@SyncNBT
- public FluidTank tanksFiller = new FluidTank(ProjectileWorkshop.componentTankCapacity);
+ public FluidTank tanksFiller = new FluidTank(ProjectileWorkshop.componentTankCapacity)
+ {
+ @Override
+ public boolean canFillFluidType(FluidStack fluid)
+ {
+ return fluid!=null
+ &&getComponentForFluid(fluid).isPresent()
+ &&(componentInside.isEmpty()||componentInside.matches(fluid));
+ }
+ };
@SyncNBT
public MultiblockInteractablePart lid1, lid2;
@SyncNBT(name = "upgrades", events = SyncEvents.TILE_UPGRADES_MODIFIED)
public UpgradeManager upgrades;
- IItemHandler inputHandler = new IEInventoryHandler(1, this, 0, true, false);
- IItemHandler componentInputHandler = new IEInventoryHandler(1, this, 1, true, false);
+ private IItemHandler inputHandler = new IEInventoryHandler(1, this, 0, true, false);
+ private IItemHandler componentInputHandler = new IEInventoryHandler(1, this, 1, true, false);
public TileEntityProjectileWorkshop()
{
@@ -98,6 +110,7 @@ protected void dummyCleanup()
tanksFiller = null;
upgrades = null;
componentInside = null;
+ inputHandler = componentInputHandler = null;
}
@Override
@@ -108,26 +121,11 @@ protected void onUpdate()
lid2.update();
upgrades.update();
- //fill component tank
+ //Fill the internal ammunition component store from both item and fluid input.
if(isUpgradeInstalled(IIContent.UPGRADE_CORE_FILLER)&&!world.isRemote)
{
- if(!componentInputHandler.getStackInSlot(0).isEmpty())
- {
- ItemStack stack = componentInputHandler.getStackInSlot(0);
- if(componentInside.isEmpty())
- {
- Optional matching = AmmoRegistry.getAllComponents().stream().filter(comp -> comp.getMaterial().matchesItemStackIgnoringSize(stack)).findFirst();
- matching.ifPresent(component -> componentInside = new BulletComponentStack(component, componentInputHandler.extractItem(0, 1, false).getTagCompound()));
- }
- else
- {
- if(componentInside.matches(stack)&&componentInside.amount+16 <= ProjectileWorkshop.componentCapacity)
- {
- componentInside.amount += 16;
- componentInputHandler.extractItem(0, 1, false);
- }
- }
- }
+ pullComponentItem();
+ pullComponentFluid();
}
//Stop working when the machine is disabled
@@ -170,6 +168,10 @@ public void receiveMessageFromServer(@Nonnull NBTTagCompound message)
IAmmoTypeItem, ?> bb = AmmoRegistry.getAmmoItem(message.getString("produced_bullet"));
producedAmmo = bb==null?IIContent.itemAmmoHeavyArtillery: bb;
}
+ if(message.hasKey("core_type"))
+ coreType = CoreType.v(message.getString("core_type"));
+ if(message.hasKey("component_fill_amount"))
+ componentFillAmount = Math.max(1, message.getInteger("component_fill_amount"));
}
@Override
@@ -181,6 +183,10 @@ public void receiveMessageFromClient(NBTTagCompound message)
IAmmoTypeItem, ?> bb = AmmoRegistry.getAmmoItem(message.getString("produced_bullet"));
producedAmmo = bb==null?IIContent.itemAmmoHeavyArtillery: bb;
}
+ if(message.hasKey("core_type"))
+ coreType = CoreType.v(message.getString("core_type"));
+ if(message.hasKey("component_fill_amount"))
+ componentFillAmount = Math.max(1, message.getInteger("component_fill_amount"));
}
@Override
@@ -205,9 +211,9 @@ protected int[] listAllPOI(MultiblockPOI poi)
@Override
public boolean isStackValid(int slot, ItemStack stack)
{
- if(slot==SLOT_COMPONENT_INPUT&&isUpgradeInstalled(IIContent.UPGRADE_CORE_FILLER))
+ if(slot==MultiblockProjectileWorkshop.SLOT_COMPONENT_INPUT&&isUpgradeInstalled(IIContent.UPGRADE_CORE_FILLER))
return AmmoRegistry.getAllComponents().stream().anyMatch(comp -> comp.getMaterial().matchesItemStackIgnoringSize(stack));
- else if(slot==SLOT_INPUT)
+ else if(slot==MultiblockProjectileWorkshop.SLOT_INPUT)
{
if(isUpgradeInstalled(IIContent.UPGRADE_CORE_FILLER))
return stack.getItem() instanceof IAmmoTypeItem&&((IAmmoTypeItem, ?>)stack.getItem()).isBulletCore(stack);
@@ -220,61 +226,180 @@ else if(slot==SLOT_INPUT)
@Override
public int getSlotLimit(int i)
{
- return i==1?1: 64;
+ return i==MultiblockProjectileWorkshop.SLOT_COMPONENT_INPUT?1: 64;
}
- @Override
- protected IIMultiblockProcess findNewProductionProcess()
+
+ private int getFluidPerComponentAmount()
{
- //filling
- /*if(hasUpgrade(IIContent.UPGRADE_CORE_FILLER))
- {
- //check for valid component and ammo core
- if(componentInside.isEmpty()||inventory.get(SLOT_INPUT).isEmpty())
- return null;
-
- ItemStack stack = inventory.get(SLOT_INPUT);
- IAmmoTypeItem, ?> ammo = (IAmmoTypeItem, ?>)stack.getItem();
- int componentSlotsTaken = componentInside.component.getSlotsTaken()*fillAmount;
- int remainingSlots = ammo.getCoreType(stack).getComponentSlots()-
- Arrays.stream(ammo.getComponents(stack))
- .map(AmmoComponent::getSlotsTaken)
- .reduce(0, Integer::sum);
-
- //check if there is enough space in the ammo
- if(!componentInside.component.matchesBullet(ammo)||remainingSlots-componentSlotsTaken < 0)
- return null;
-
- IIMultiblockProcess out = new IIMultiblockProcess<>(new ProjectileWorkshopRecipe(stack, componentInside));
- stack.shrink(1);
- componentInside.subtract(ammo.getCoreMaterialNeeded());
- return out;
+ return Math.max(1, ProjectileWorkshop.componentTankCapacity/ProjectileWorkshop.componentCapacity);
+ }
+
+ private Optional getComponentForFluid(FluidStack fluid)
+ {
+ if(fluid==null)
+ return Optional.empty();
+
+ return AmmoRegistry.getAllComponents().stream()
+ .filter(component -> component.getMaterial().fluid!=null)
+ .filter(component -> fluid.isFluidEqual(component.getMaterial().fluid))
+ .findFirst();
+ }
+
+ private void pullComponentItem()
+ {
+ ItemStack stack = componentInputHandler.getStackInSlot(0);
+ if(stack.isEmpty())
+ return;
+
+ Optional matching = AmmoRegistry.getAllComponents().stream()
+ .filter(comp -> comp.getMaterial().matchesItemStackIgnoringSize(stack))
+ .findFirst();
+ if(!matching.isPresent())
+ return;
+
+ AmmoComponent component = matching.get();
+ if(componentInside.isEmpty())
+ {
+ if(COMPONENT_AMOUNT_PER_ITEM <= ProjectileWorkshop.componentCapacity)
+ {
+ ItemStack extracted = componentInputHandler.extractItem(0, 1, false);
+ componentInside = new BulletComponentStack(component, COMPONENT_AMOUNT_PER_ITEM, extracted.getTagCompound());
+ }
}
- else //production
+ else if(componentInside.matches(stack)
+ &&componentInside.amount+COMPONENT_AMOUNT_PER_ITEM <= ProjectileWorkshop.componentCapacity)
{
- ItemStack stack = inventory.get(SLOT_INPUT);
- if(stack.isEmpty())
- return null;
+ componentInside.amount += COMPONENT_AMOUNT_PER_ITEM;
+ componentInputHandler.extractItem(0, 1, false);
+ }
+ }
+
+ private void pullComponentFluid()
+ {
+ FluidStack fluid = tanksFiller.getFluid();
+ if(fluid==null)
+ return;
- Optional first = AmmoRegistry.getAllCores()
- .stream()
- .filter(core -> core.getMaterial().matchesItemStackIgnoringSize(inventory.get(0)))
- .findFirst();
+ Optional matching = getComponentForFluid(fluid);
+ if(!matching.isPresent())
+ return;
+
+ if(!componentInside.isEmpty()&&!componentInside.matches(fluid))
+ return;
- if(!first.isPresent()||stack.getCount() < producedAmmo.getCoreMaterialNeeded())
- return null;
+ int fluidPerAmount = getFluidPerComponentAmount();
+ int freeAmount = ProjectileWorkshop.componentCapacity-componentInside.amount;
+ int availableAmount = fluid.amount/fluidPerAmount;
+ int acceptedAmount = Math.min(freeAmount, availableAmount);
- IIMultiblockProcess out = new IIMultiblockProcess<>(new ProjectileWorkshopRecipe(producedAmmo, first.get(), coreType));
- stack.shrink(producedAmmo.getCoreMaterialNeeded());
- return out;
- }*/
- return null;
+ if(acceptedAmount <= 0)
+ return;
+
+ if(componentInside.isEmpty())
+ {
+ NBTTagCompound tag = fluid.tag==null?new NBTTagCompound(): fluid.tag.copy();
+ componentInside = new BulletComponentStack(matching.get(), 0, tag);
+ }
+
+ componentInside.amount += acceptedAmount;
+ tanksFiller.drain(acceptedAmount*fluidPerAmount, true);
+ }
+
+ private int getRemainingComponentSlots(IAmmoTypeItem, ?> ammo, ItemStack stack)
+ {
+ return ammo.getCoreType(stack).getComponentSlots()
+ -Arrays.stream(ammo.getComponents(stack))
+ .mapToInt(AmmoComponent::getSlotsTaken)
+ .sum();
+ }
+
+ private boolean canApplyComponent(ItemStack stack, IAmmoTypeItem, ?> ammo, AmmoComponent component, int fillAmount)
+ {
+ if(!component.matchesBullet(ammo))
+ return false;
+
+ int componentSlotsTaken = component.getSlotsTaken()*fillAmount;
+ return getRemainingComponentSlots(ammo, stack) >= componentSlotsTaken;
+ }
+
+ @Override
+ protected IIMultiblockProcess findNewProductionProcess()
+ {
+ if(isUpgradeInstalled(IIContent.UPGRADE_CORE_FILLER))
+ return findNewFillingProcess();
+ return findNewCoreProductionProcess();
+ }
+
+ private IIMultiblockProcess findNewCoreProductionProcess()
+ {
+ ItemStack stack = inventory.get(MultiblockProjectileWorkshop.SLOT_INPUT);
+ if(stack.isEmpty())
+ return null;
+
+ Optional first = AmmoRegistry.getAllCores()
+ .stream()
+ .filter(core -> core.getMaterial().matchesItemStackIgnoringSize(stack))
+ .findFirst();
+
+ if(!first.isPresent()||stack.getCount() < producedAmmo.getCoreMaterialNeeded())
+ return null;
+
+ ProjectileWorkshopRecipe recipe = new ProjectileWorkshopRecipe(producedAmmo, first.get(), coreType);
+ stack.shrink(producedAmmo.getCoreMaterialNeeded());
+ return new IIMultiblockProcess<>(recipe);
+ }
+
+ private IIMultiblockProcess findNewFillingProcess()
+ {
+ ItemStack stack = inventory.get(MultiblockProjectileWorkshop.SLOT_INPUT);
+ if(stack.isEmpty()||!(stack.getItem() instanceof IAmmoTypeItem))
+ return null;
+
+ IAmmoTypeItem, ?> ammo = (IAmmoTypeItem, ?>)stack.getItem();
+ if(!ammo.isBulletCore(stack))
+ return null;
+
+ if(componentInside.isEmpty()||componentInside.component==null)
+ return null;
+
+ int fillAmount = Math.max(1, componentFillAmount);
+ if(componentInside.amount < fillAmount)
+ return null;
+
+ ItemStack effect = stack.copy();
+ effect.setCount(1);
+
+ AmmoComponent component = componentInside.component;
+ BulletComponentStack usedComponent = new BulletComponentStack(component, fillAmount, componentInside.tagCompound.copy());
+ boolean canFill = canApplyComponent(effect, ammo, component, fillAmount);
+
+ if(canFill)
+ {
+ for(int i = 0; i < fillAmount; i++)
+ ammo.addComponents(effect, component, componentInside.tagCompound.copy());
+ componentInside.subtract(fillAmount);
+ }
+
+ stack.shrink(1);
+
+ IIMultiblockProcess process = new IIMultiblockProcess<>(ProjectileWorkshopRecipe.CORE_FILLING)
+ .withNBT(nbt -> nbt
+ .withItemStack("effect", effect)
+ .withBoolean("filled", canFill)
+ .withSerializable("component", usedComponent)
+ );
+ process.maxTicks *= ammo.getCaliber();
+ return process;
}
@Override
protected IIMultiblockProcess getProcessByName(String name)
{
+ if(ProjectileWorkshopRecipe.FILLING_RECIPE_NAME.equals(name))
+ return new IIMultiblockProcess<>(ProjectileWorkshopRecipe.CORE_FILLING);
+
ProjectileWorkshopRecipe recipe = IIMultiblockRecipe.getRecipe(ProjectileWorkshopRecipe.class, name);
return recipe==null?null: new IIMultiblockProcess<>(recipe);
}
@@ -288,7 +413,11 @@ public float getProductionStep(IIMultiblockProcess pro
@Override
protected boolean attemptProductionOutput(IIMultiblockProcess process)
{
- outputOrDrop(process.recipe.getEffect(), null, mirrored?facing.rotateYCCW(): facing.rotateY(),
+ ItemStack effect = process.recipe.isFilling?process.processData.getItemStack("effect"): process.recipe.getEffect();
+ if(effect.isEmpty())
+ return true;
+
+ outputOrDrop(effect, null, mirrored?facing.rotateYCCW(): facing.rotateY(),
getPOI(MultiblockPOI.ITEM_OUTPUT)
);
return true;
@@ -323,6 +452,35 @@ public void onAnimationChangeServer(boolean state, int part)
}
}
+ //--- Capabilities ---//
+ @Override
+ protected IFluidTank[] getFluidTanks(int pos, EnumFacing side)
+ {
+ if(isUpgradeInstalled(IIContent.UPGRADE_CORE_FILLER)
+ &&Arrays.stream(getPOI("component_fluid_in")).anyMatch(i -> i==pos))
+ return new FluidTank[]{tanksFiller};
+
+ return super.getFluidTanks(pos, side);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing facing)
+ {
+ if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
+ {
+ TileEntityProjectileWorkshop master = master();
+ assert master!=null;
+ if(isPOI("item_in"))
+ return (T)master.inputHandler;
+ else if(isPOI("component_in"))
+ return (T)master.componentInputHandler;
+ }
+ return super.getCapability(capability, facing);
+ }
+
+ //--- Data Handling ---//
+
@Override
public void receiveData(DataPacket packet, int pos)
{
@@ -338,10 +496,9 @@ public void receiveData(DataPacket packet, int pos)
this.coreType = this.producedAmmo.getAllowedCoreTypes()[0];
if(packet.has('a'))
- this.fillAmount = packet.getVarInType(DataTypeInteger.class, packet.get('a')).value;
+ this.componentFillAmount = packet.getVarInType(DataTypeInteger.class, packet.get('a')).value;
}
- //TODO: 09.07.2024 conveyor interaction
@Override
public void onEntityCollision(World world, Entity entity)
{
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/TileEntityEmplacement.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/TileEntityEmplacement.java
index e40c83e69..aac599871 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/TileEntityEmplacement.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/TileEntityEmplacement.java
@@ -8,12 +8,18 @@
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
+import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fml.common.Optional.Interface;
import net.minecraftforge.fml.common.Optional.Method;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
+import net.minecraftforge.items.CapabilityItemHandler;
import pl.pabilo8.immersiveintelligence.ImmersiveIntelligence;
import pl.pabilo8.immersiveintelligence.api.data.DataPacket;
import pl.pabilo8.immersiveintelligence.api.data.IIDataHandlingUtils;
@@ -39,6 +45,7 @@
import pl.pabilo8.immersiveintelligence.common.entity.tactile.TactileManager.ITactileListener;
import pl.pabilo8.immersiveintelligence.common.network.IIPacketHandler;
import pl.pabilo8.immersiveintelligence.common.network.messages.MessageBooleanAnimatedPartsSync;
+import pl.pabilo8.immersiveintelligence.common.util.IIMath;
import pl.pabilo8.immersiveintelligence.common.util.diplomacy.DiplomacyHandler;
import pl.pabilo8.immersiveintelligence.common.util.diplomacy.OwnerIdentity;
import pl.pabilo8.immersiveintelligence.common.util.diplomacy.property.IOwnableProperty;
@@ -67,6 +74,10 @@
public class TileEntityEmplacement extends TileEntityMultiblockIIGeneric implements IBooleanAnimatedPartsBlock,
IManagedUpgradableDevice, IOwnableProperty, IStyleCustomizable, IIIGuiMultiblockTile, IManagedDamageResistantMultiblock, ITactileListener, ILightEventConsumer
{
+ private static final int WEAPON_REPAIR_INTERVAL = 20;
+ private static final int WEAPON_REPAIR_ENERGY_COST = 80;
+ private static final float WEAPON_REPAIR_AMOUNT = 1.0f;
+
@SyncNBT(events = SyncEvents.TILE_OWNERSHIP_MODIFIED)
public OwnerIdentity ownerIdentity;
@SyncNBT(name = "upgrades", events = SyncEvents.TILE_UPGRADES_MODIFIED)
@@ -86,7 +97,10 @@ public class TileEntityEmplacement extends TileEntityMultiblockIIGeneric(this);
this.style = new StyleCustomization(MultiblockFlagpole.STYLE_CONSTRAINTS);
this.baseHealth = new MultiblockHealth(this, Emplacement.baseHealth);
this.ownerIdentity = DiplomacyHandler.NEUTRAL;
this.currentTarget = new TargetCoordinateReference(this::getWorld);
+ this.taskManager.setWorldSupplier(this::getWorld);
this.currentWeapon = null;
}
@@ -134,27 +150,41 @@ protected void onUpdate()
//Extract energy for merely existing
if(energyStorage.extractEnergy(Emplacement.baseEnergyUsage, false)==Emplacement.baseEnergyUsage)
{
+ //Finish previous task, if condition is met or the task is no longer valid.
+ if(currentTarget!=null&&!currentTarget.shouldBeExecuted(world))
+ {
+ currentTarget = null;
+ taskManager.pruneFinishedMissions();
+ updateTileForEvent(SyncEvents.TILE_CUSTOM1);
+ }
+
//Handle targeting
if(currentTarget==null)
currentTarget = taskManager.provideNextTask();
- //Handle the base behavior (without redstone control, it can be only changed through data)
- EmplacementStateNeeds baseNeeds = EmplacementStateNeeds.WANTS_HIDE;
- if(redstoneControlEnabled)
- baseNeeds = getRedstoneAtPos(0)?EmplacementStateNeeds.WANTS_SURFACE: EmplacementStateNeeds.MUST_HIDE;
+ //Base behaviour: redstone control either gates surfacing, or the platform wants to surface by default.
+ EmplacementStateNeeds baseNeeds = redstoneControlEnabled?
+ (getRedstoneAtPos(0)?EmplacementStateNeeds.WANTS_SURFACE: EmplacementStateNeeds.MUST_HIDE):
+ EmplacementStateNeeds.WANTS_SURFACE;
- //When no task at hand, emplacement could use the time to reload and repair
+ //When no task is waiting, use the downtime to reload and repair.
if(currentTarget==null&&baseNeeds==EmplacementStateNeeds.WANTS_SURFACE)
baseNeeds = EmplacementStateNeeds.WANTS_HIDE;
- //Handle the weapon, weapons need additional energy to operate
- EmplacementStateNeeds weaponNeeds = baseNeeds;
- if(currentWeapon!=null&&energyStorage.extractEnergy(currentWeapon.getEnergyUpkeepCost(), false)==currentWeapon.getEnergyUpkeepCost())
- weaponNeeds = this.currentWeapon.onUpdate(this, baseNeeds, currentTarget);
+ EmplacementStateNeeds serviceNeeds = getServiceNeeds();
+ EmplacementStateNeeds weaponNeeds = combineNeeds(baseNeeds, serviceNeeds);
+
+ //Handle the weapon only when it has enough upkeep power and is not forced into servicing.
+ if(currentWeapon!=null&&serviceNeeds!=EmplacementStateNeeds.MUST_HIDE
+ &&energyStorage.extractEnergy(currentWeapon.getEnergyUpkeepCost(), false)==currentWeapon.getEnergyUpkeepCost())
+ weaponNeeds = this.currentWeapon.onUpdate(this, weaponNeeds, currentTarget);
//Handle the door/platform
door.setState(combineNeeds(baseNeeds, weaponNeeds)==EmplacementStateNeeds.WANTS_SURFACE);
door.update();
+
+ if(!door.getState()&&door.isFullyClosed())
+ serviceWeaponInBase();
}
if(!this.world.isRemote)
this.tactileHandler.update(MultiblockEmplacement.animationPlatform, door.getProgress(0));
@@ -162,13 +192,64 @@ protected void onUpdate()
private EmplacementStateNeeds combineNeeds(EmplacementStateNeeds base, EmplacementStateNeeds weapon)
{
- if(base==EmplacementStateNeeds.WANTS_SURFACE||weapon==EmplacementStateNeeds.WANTS_SURFACE)
- return EmplacementStateNeeds.WANTS_SURFACE;
+ //Hard requirements win over soft wishes. Otherwise a redstone signal could keep a broken or empty weapon exposed.
if(base==EmplacementStateNeeds.MUST_HIDE||weapon==EmplacementStateNeeds.MUST_HIDE)
return EmplacementStateNeeds.MUST_HIDE;
+ if(base==EmplacementStateNeeds.WANTS_SURFACE||weapon==EmplacementStateNeeds.WANTS_SURFACE)
+ return EmplacementStateNeeds.WANTS_SURFACE;
return EmplacementStateNeeds.WANTS_HIDE;
}
+ private EmplacementStateNeeds getServiceNeeds()
+ {
+ if(currentWeapon==null)
+ return EmplacementStateNeeds.WANTS_HIDE;
+
+ float hideThreshold = MathHelper.clamp(weaponHideHealthThreshold, 0f, 1f);
+ float readyThreshold = MathHelper.clamp(Math.max(weaponRepairSatisfactoryThreshold, hideThreshold), 0f, 1f);
+
+ if(currentWeapon.isBelowHealthThreshold(hideThreshold))
+ weaponRepairing = true;
+ if(weaponRepairing)
+ {
+ if(currentWeapon.isRepairedTo(readyThreshold))
+ weaponRepairing = false;
+ else
+ return EmplacementStateNeeds.MUST_HIDE;
+ }
+
+ if(currentWeapon.needsSupply(this))
+ return EmplacementStateNeeds.MUST_HIDE;
+
+ return EmplacementStateNeeds.WANTS_SURFACE;
+ }
+
+ private void serviceWeaponInBase()
+ {
+ if(currentWeapon==null||world.isRemote)
+ return;
+
+ boolean changed = false;
+ if(currentWeapon.needsRestock(this))
+ changed |= currentWeapon.restockFromBase(this);
+
+ if(currentWeapon.getHealth() < currentWeapon.getMaxHealth())
+ {
+ weaponRepairTicker++;
+ if(weaponRepairTicker >= WEAPON_REPAIR_INTERVAL)
+ {
+ weaponRepairTicker = 0;
+ if(energyStorage.extractEnergy(WEAPON_REPAIR_ENERGY_COST, true)==WEAPON_REPAIR_ENERGY_COST)
+ changed |= currentWeapon.repair(WEAPON_REPAIR_AMOUNT);
+ }
+ }
+ else
+ weaponRepairTicker = 0;
+
+ if(changed)
+ updateTileForEvent(SyncEvents.TILE_CUSTOM2);
+ }
+
@Override
public void disassemble()
{
@@ -279,18 +360,14 @@ public void receiveData(DataPacket packet, int pos)
this.taskManager.resumeTask(true);
updateTileForEvent(SyncEvents.TILE_CUSTOM1);
break;
- case "targetshells":
-// this.taskManager.addTask(new EmplacementFireMissionShells());
- updateTileForEvent(SyncEvents.TILE_CUSTOM1);
- break;
case "fire":
Optional e = IIDataHandlingUtils.optionalEntity('e', packet);
- /*if(e.isPresent())
+ if(e.isPresent())
{
Entity entityByID = world.getEntityByID(e.get().entityID);
if(entityByID!=null)
- this.taskManager.addTask(new EmplacementFireMissionEntity(entityByID));
+ this.taskManager.addEntityMission(entityByID, IIDataHandlingUtils.optionalInt('a', packet).orElse(1));
updateTileForEvent(SyncEvents.TILE_CUSTOM1);
}
else
@@ -298,7 +375,7 @@ public void receiveData(DataPacket packet, int pos)
int amount = IIDataHandlingUtils.optionalInt('a', packet).orElse(1);
IIDataHandlingUtils.expectingVectorParam(packet, vec -> {
//Block/Vector based
- this.taskManager.addTask(new EmplacementFireMissionPosition(new BlockPos(vec).add(getPOIPos("weapon")), amount));
+ this.taskManager.addPositionMission(new BlockPos(vec).add(getPOIPos("weapon")), amount);
},
angle -> {
//Yaw+Pitch based
@@ -306,10 +383,10 @@ public void receiveData(DataPacket packet, int pos)
double true_angle2 = Math.toRadians(angle.y);
int distance = IIDataHandlingUtils.optionalInt('d', packet).orElse(40);
- this.taskManager.addTask(new EmplacementFireMissionPosition(new BlockPos(IIMath.offsetPosDirection(distance,
- true_angle, true_angle2)).add(getPOIPos("weapon")), amount));
+ this.taskManager.addPositionMission(new BlockPos(IIMath.offsetPosDirection(distance,
+ true_angle, true_angle2)).add(getPOIPos("weapon")), amount);
});
- }*/
+ }
//Synchronize the task
updateTileForEvent(SyncEvents.TILE_CUSTOM1);
break;
@@ -423,7 +500,43 @@ public Vec3d getWeaponCenter()
@Override
public boolean isStackValid(int slot, ItemStack stack)
{
- return false;
+ return currentWeapon!=null;
+ }
+
+ //--- Capabilities ---//
+
+ @Override
+ public boolean hasCapability(@Nonnull Capability> capability, @Nullable net.minecraft.util.EnumFacing facing)
+ {
+ TileEntityEmplacement master = master();
+ if(master!=null&&master.currentWeapon!=null)
+ {
+ if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY&&(isPOI("input")||isPOI("output")))
+ return master.currentWeapon.getBaseItemHandler()!=null;
+ if(capability==CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY&&(isPOI("input")||isPOI("output")))
+ return master.currentWeapon.getBaseFluidHandler()!=null;
+ }
+ return super.hasCapability(capability, facing);
+ }
+
+ @Nullable
+ @Override
+ @SuppressWarnings("unchecked")
+ public T getCapability(@Nonnull Capability capability, @Nullable net.minecraft.util.EnumFacing facing)
+ {
+ TileEntityEmplacement master = master();
+ if(master!=null&&master.currentWeapon!=null&&(isPOI("input")||isPOI("output")))
+ {
+ if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY&&master.currentWeapon.getBaseItemHandler()!=null)
+ return (T)master.currentWeapon.getBaseItemHandler();
+ if(capability==CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
+ {
+ IFluidHandler handler = master.currentWeapon.getBaseFluidHandler();
+ if(handler!=null)
+ return (T)handler;
+ }
+ }
+ return super.getCapability(capability, facing);
}
//--- IOwnableProperty ---//
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/task/EmplacementTargetManager.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/task/EmplacementTargetManager.java
index c733a9b0b..fc04af1c5 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/task/EmplacementTargetManager.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/task/EmplacementTargetManager.java
@@ -1,21 +1,83 @@
package pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.task;
+import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
import net.minecraftforge.common.util.INBTSerializable;
+import pl.pabilo8.immersiveintelligence.common.util.ISerializableEnum;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyCollection;
+import pl.pabilo8.immersiveintelligence.common.util.easynbt.EasyNBT;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.TargetCoordinateReference;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Iterator;
+import java.util.function.Supplier;
+
/**
+ * Stores emplacement requests. Fire Missions are requests, not jobs: they expire when the target is gone
+ * or when the finite shot counter reaches zero.
+ *
* @author Pabilo8 (pabilo@iiteam.net)
* @ii-approved 0.3.1
* @since 14.09.2025
*/
-public class EmplacementTargetManager implements INBTSerializable
+public class EmplacementTargetManager implements INBTSerializable, Cloneable
{
+ private Supplier worldSupplier = () -> null;
public boolean paused = false;
+ public EasyCollection fireMissions = new EasyCollection<>(() -> new EmplacementFireMission(worldSupplier));
+
+ public EmplacementTargetManager()
+ {
+
+ }
+
+ public EmplacementTargetManager(Supplier worldSupplier)
+ {
+ setWorldSupplier(worldSupplier);
+ }
+
+ public EmplacementTargetManager setWorldSupplier(Supplier worldSupplier)
+ {
+ this.worldSupplier = worldSupplier==null?() -> null: worldSupplier;
+ for(EmplacementFireMission mission : fireMissions)
+ mission.setWorldSupplier(this.worldSupplier);
+ return this;
+ }
+
+ public EasyCollection getFireMissions()
+ {
+ return fireMissions;
+ }
+
+ public void addEntityMission(Entity entity, int shots)
+ {
+ EmplacementFireMission mission = new EmplacementFireMission(worldSupplier)
+ .withEntity(entity);
+ if(shots > 0)
+ mission.withShotLimit(shots);
+ fireMissions.add(mission);
+ }
+
+ public void addPositionMission(BlockPos position, int shots)
+ {
+ EmplacementFireMission mission = new EmplacementFireMission(worldSupplier)
+ .withPosition(position);
+ if(shots > 0)
+ mission.withShotLimit(shots);
+ fireMissions.add(mission);
+ }
public void skipTask(int taskID)
{
paused = false;
+ if(taskID > 0&&taskID < fireMissions.size())
+ {
+ EmplacementFireMission mission = fireMissions.remove(taskID);
+ fireMissions.add(0, mission);
+ }
}
public void stopTask(boolean switchToDefault)
@@ -28,20 +90,170 @@ public void resumeTask(boolean switchToDefault)
paused = false;
}
+ @Nullable
public TargetCoordinateReference provideNextTask()
{
+ if(paused)
+ return null;
+
+ World world = worldSupplier.get();
+ for(Iterator iterator = fireMissions.iterator(); iterator.hasNext(); )
+ {
+ EmplacementFireMission mission = iterator.next();
+ mission.setWorldSupplier(worldSupplier);
+ if(!mission.shouldRemain(world))
+ {
+ iterator.remove();
+ continue;
+ }
+ return mission.target;
+ }
return null;
}
+ public void pruneFinishedMissions()
+ {
+ World world = worldSupplier.get();
+ fireMissions.removeIf(mission -> !mission.shouldRemain(world));
+ }
+
@Override
public NBTTagCompound serializeNBT()
{
- return new NBTTagCompound();
+ return EasyNBT.newNBT()
+ .withBoolean("paused", paused)
+ .withSerializable("fire_missions", fireMissions)
+ .unwrap();
}
@Override
public void deserializeNBT(NBTTagCompound nbt)
{
+ EasyNBT easyNBT = EasyNBT.wrapNBT(nbt);
+ this.paused = easyNBT.getBoolean("paused");
+ this.fireMissions.deserializeNBT(easyNBT.getList("fire_missions", EasyNBT.TAG_COMPOUND));
+ setWorldSupplier(worldSupplier);
+ }
+
+ @Override
+ public EmplacementTargetManager clone()
+ {
+ EmplacementTargetManager manager = new EmplacementTargetManager(worldSupplier);
+ manager.deserializeNBT(this.serializeNBT());
+ return manager;
+ }
+
+ public static class EmplacementFireMission implements INBTSerializable
+ {
+ public FireMissionTargetType type = FireMissionTargetType.POSITION;
+ public String name = "";
+ public TargetCoordinateReference target;
+ private Supplier worldSupplier;
+
+ public EmplacementFireMission()
+ {
+ this(() -> null);
+ }
+
+ public EmplacementFireMission(Supplier worldSupplier)
+ {
+ this.worldSupplier = worldSupplier==null?() -> null: worldSupplier;
+ this.target = new TargetCoordinateReference(this.worldSupplier)
+ .withPosition(BlockPos.ORIGIN)
+ .withShotLimit(1);
+ }
+
+ public EmplacementFireMission setWorldSupplier(Supplier worldSupplier)
+ {
+ this.worldSupplier = worldSupplier==null?() -> null: worldSupplier;
+ this.target.withWorldSupplier(this.worldSupplier);
+ return this;
+ }
+
+ public EmplacementFireMission withEntity(Entity entity)
+ {
+ this.type = FireMissionTargetType.ENTITY;
+ this.target.withEntity(entity);
+ return this;
+ }
+
+ public EmplacementFireMission withEntityID(int entityID)
+ {
+ this.type = FireMissionTargetType.ENTITY;
+ this.target.withEntityID(entityID);
+ return this;
+ }
+
+ public EmplacementFireMission withPosition(BlockPos position)
+ {
+ this.type = FireMissionTargetType.POSITION;
+ this.target.withPosition(position);
+ return this;
+ }
+
+ public EmplacementFireMission withShotLimit(int shots)
+ {
+ this.target.withShotLimit(shots);
+ return this;
+ }
+
+ public EmplacementFireMission withInfiniteShots()
+ {
+ this.target.withInfiniteShots();
+ return this;
+ }
+
+ public boolean isJob()
+ {
+ return false;
+ }
+
+ public boolean shouldRemain(@Nullable World world)
+ {
+ return target.shouldBeExecuted(world);
+ }
+
+ @Nonnull
+ public String getDisplayName()
+ {
+ if(name!=null&&!name.isEmpty())
+ return name;
+ if(type==FireMissionTargetType.ENTITY)
+ return "Entity #"+target.getEntityID();
+ BlockPos pos = target.getPosition();
+ return pos==null?"Position": pos.getX()+", "+pos.getY()+", "+pos.getZ();
+ }
+
+ @Override
+ public NBTTagCompound serializeNBT()
+ {
+ return EasyNBT.newNBT()
+ .withEnum("type", type)
+ .withString("name", name==null?"": name)
+ .withSerializable("target", target)
+ .unwrap();
+ }
+
+ @Override
+ public void deserializeNBT(NBTTagCompound nbt)
+ {
+ EasyNBT easyNBT = EasyNBT.wrapNBT(nbt);
+ this.type = easyNBT.hasKey("type")?easyNBT.getEnum("type", FireMissionTargetType.class): FireMissionTargetType.POSITION;
+ this.name = easyNBT.getString("name");
+ this.target = new TargetCoordinateReference(worldSupplier);
+ this.target.deserializeNBT(easyNBT.getCompound("target"));
+ }
+ }
+
+ public enum FireMissionTargetType implements ISerializableEnum
+ {
+ POSITION,
+ ENTITY;
+ @Override
+ public String getName()
+ {
+ return name().toLowerCase();
+ }
}
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeapon.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeapon.java
index ea7b10329..348299d61 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeapon.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeapon.java
@@ -122,12 +122,54 @@ public IItemHandler getBaseItemHandler()
return null;
}
+ @Nullable
+ public IItemHandler getPlatformItemHandler()
+ {
+ return null;
+ }
+
@Nullable
public IFluidHandler getBaseFluidHandler()
{
return null;
}
+ /**
+ * @return true when this weapon cannot operate until the platform is lowered and serviced.
+ */
+ public boolean needsSupply(TileEntityEmplacement te)
+ {
+ return false;
+ }
+
+ public boolean needsRestock(TileEntityEmplacement te)
+ {
+ return false;
+ }
+
+ public boolean restockFromBase(TileEntityEmplacement te)
+ {
+ return false;
+ }
+
+ public boolean isBelowHealthThreshold(float threshold)
+ {
+ return getMaxHealth() > 0&&getHealth()/getMaxHealth() < threshold;
+ }
+
+ public boolean isRepairedTo(float threshold)
+ {
+ return getMaxHealth() <= 0||getHealth()/getMaxHealth() >= threshold;
+ }
+
+ public boolean repair(float amount)
+ {
+ if(amount <= 0||health >= getMaxHealth())
+ return false;
+ health = Math.min(getMaxHealth(), health+amount);
+ return true;
+ }
+
public abstract int getEnergyUpkeepCost();
//--- GUI ---//
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponAutocannon.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponAutocannon.java
index cebb1b9fe..11f4bb8cb 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponAutocannon.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponAutocannon.java
@@ -1,35 +1,31 @@
package pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.weapon;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.NonNullList;
import net.minecraftforge.oredict.OreDictionary;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.EmplacementWeapons.Autocannon;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
import pl.pabilo8.immersiveintelligence.common.item.ammo.ItemIIBulletMagazine.Magazines;
-import pl.pabilo8.immersiveintelligence.common.util.multiblock.FilteredItemHandler;
public class EmplacementWeaponAutocannon extends EmplacementWeaponGunBase
{
public EmplacementWeaponAutocannon()
{
super();
- this.inventoryBase = NonNullList.withSize(18, ItemStack.EMPTY);
- this.inventoryPlatform = NonNullList.withSize(8, ItemStack.EMPTY);
}
@Override
protected void onInit(TileEntityEmplacement te)
{
super.onInit(te);
+ this.ammoFactory.setAmmo(IIContent.itemAmmoAutocannon);
this.visionAABB = this.visionAABB.grow(Autocannon.detectionRadius);
this.attackAABB = this.attackAABB.grow(Autocannon.attackRadius);
this.aim.withAimSpeed(Autocannon.yawRotateSpeed, Autocannon.pitchRotateSpeed);
- this.inventoryBaseHandler = new FilteredItemHandler(inventoryBase)
- .withFilter(stack -> OreDictionary.itemMatches(stack,
- IIContent.itemBulletMagazine.getMagazine(Magazines.AUTOCANNON), false));
+ setupItemHandlers(te, 18, 8, stack -> OreDictionary.itemMatches(stack,
+ IIContent.itemBulletMagazine.getMagazine(Magazines.AUTOCANNON), false), stack -> OreDictionary.itemMatches(stack,
+ IIContent.itemBulletMagazine.getMagazine(Magazines.AUTOCANNON), false));
}
@Override
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponCPDS.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponCPDS.java
index bb2797cce..23dfd6a1b 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponCPDS.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponCPDS.java
@@ -1,14 +1,11 @@
package pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.weapon;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.NonNullList;
import net.minecraftforge.oredict.OreDictionary;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.EmplacementWeapons.CPDS;
import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
import pl.pabilo8.immersiveintelligence.common.item.ammo.ItemIIBulletMagazine.Magazines;
-import pl.pabilo8.immersiveintelligence.common.util.multiblock.FilteredItemHandler;
/**
* CPDS Q&A
@@ -32,19 +29,18 @@ public class EmplacementWeaponCPDS extends EmplacementWeaponGunBase OreDictionary.itemMatches(stack,
- IIContent.itemBulletMagazine.getMagazine(Magazines.CPDS_DRUM), false));
+ setupItemHandlers(te, 8, 3, stack -> OreDictionary.itemMatches(stack,
+ IIContent.itemBulletMagazine.getMagazine(Magazines.CPDS_DRUM), false), stack -> OreDictionary.itemMatches(stack,
+ IIContent.itemBulletMagazine.getMagazine(Magazines.CPDS_DRUM), false));
this.aim.withAimSpeed(CPDS.yawRotateSpeed, CPDS.pitchRotateSpeed);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGuidedMissileLauncher.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGuidedMissileLauncher.java
index b9b4b07e4..8200847fc 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGuidedMissileLauncher.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGuidedMissileLauncher.java
@@ -1,30 +1,26 @@
package pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.weapon;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.NonNullList;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.EmplacementWeapons.Autocannon;
import pl.pabilo8.immersiveintelligence.common.IIConfigHandler.IIConfig.Weapons.EmplacementWeapons.CPDS;
+import pl.pabilo8.immersiveintelligence.common.IIContent;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
-import pl.pabilo8.immersiveintelligence.common.util.multiblock.FilteredItemHandler;
public class EmplacementWeaponGuidedMissileLauncher extends EmplacementWeaponGunBase
{
public EmplacementWeaponGuidedMissileLauncher()
{
- this.inventoryBase = NonNullList.withSize(12, ItemStack.EMPTY);
- this.inventoryPlatform = NonNullList.withSize(6, ItemStack.EMPTY);
}
@Override
protected void onInit(TileEntityEmplacement te)
{
super.onInit(te);
+ this.ammoFactory.setAmmo(IIContent.itemAmmoGuidedMissile);
this.visionAABB = this.visionAABB.grow(Autocannon.detectionRadius);
this.attackAABB = this.attackAABB.grow(Autocannon.attackRadius);
- this.inventoryBaseHandler = new FilteredItemHandler(inventoryBase)
- .withFilter(this.ammoFactory::isValidAmmo);
+ setupItemHandlers(te, 12, 6, this.ammoFactory::isValidAmmo, this.ammoFactory::isValidAmmo);
this.aim.withAimSpeed(CPDS.yawRotateSpeed, CPDS.pitchRotateSpeed);
}
diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGunBase.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGunBase.java
index ba8f19f7b..4c263fe54 100644
--- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGunBase.java
+++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/multiblock/metal_multiblock1/tileentity/emplacement/weapon/EmplacementWeaponGunBase.java
@@ -1,51 +1,51 @@
package pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.weapon;
-import blusunrize.immersiveengineering.common.util.Utils;
+import blusunrize.immersiveengineering.common.util.inventory.IEInventoryHandler;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.NonNullList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
-import net.minecraftforge.items.IItemHandler;
-import net.minecraftforge.items.ItemStackHandler;
import pl.pabilo8.immersiveintelligence.api.ammo.utils.AmmoFactory;
import pl.pabilo8.immersiveintelligence.client.gui.deco.component.panel.DecoPanel;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement;
import pl.pabilo8.immersiveintelligence.common.block.multiblock.metal_multiblock1.tileentity.emplacement.TileEntityEmplacement.EmplacementStateNeeds;
import pl.pabilo8.immersiveintelligence.common.entity.ammo.EntityAmmoBase;
+import pl.pabilo8.immersiveintelligence.common.entity.ammo.types.EntityAmmoProjectile;
import pl.pabilo8.immersiveintelligence.common.util.easynbt.TargetCoordinateReference;
+import pl.pabilo8.immersiveintelligence.common.util.gun.GunRecoil;
+import pl.pabilo8.immersiveintelligence.common.util.gun.GunShootingHandler;
+import pl.pabilo8.immersiveintelligence.common.util.gun.ammoprovider.GunAmmoProviderItemHandler;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
+import java.util.function.Predicate;
/**
* @author Pabilo8 (pabilo@iiteam.net)
* @ii-approved 0.3.1
- * @updated 30.12.2025
+ * @updated 03.06.2026
* @since 04.09.2025
*/
public abstract class EmplacementWeaponGunBase