It's exactly Stressful!

- Added configurable levels of speed for requirements
- Added tooltip information to mechanical blocks with Stress Impact, Stress Capacity and Required speed level
- Fixed Belt connector not being a blockitem
- Made Stress capacity configuration more generic
This commit is contained in:
simibubi 2019-11-27 09:29:29 +01:00
parent 786789c312
commit 0bf30b2f93
14 changed files with 229 additions and 56 deletions

View File

@ -8,11 +8,13 @@ import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.TooltipHelper;
import com.simibubi.create.modules.contraptions.KineticDebugger;
import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.receivers.TurntableHandler;
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItemHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
@ -131,6 +133,7 @@ public class ClientEvents {
TooltipHelper.getTooltip(stack).addInformation(toolTip);
event.getToolTip().addAll(1, toolTip);
}
}
@SubscribeEvent

View File

@ -9,6 +9,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.modules.contraptions.base.KineticBlock;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
import net.minecraftforge.common.ForgeConfigSpec.Builder;
@ -60,11 +61,12 @@ public class CreateConfig {
inWorldProcessingTime;
public IntValue maxChassisForTranslation, maxChassisForRotation, maxChassisRange, maxPistonPoles;
public DoubleValue waterWheelCapacity;
public DoubleValue generatingFanCapacity;
public DoubleValue mechanicalBearingCapacity;
public DoubleValue motorCapacity;
public Map<String, DoubleValue> stressEntries = new HashMap<>();
public Map<ResourceLocation, DoubleValue> stressCapacityEntries = new HashMap<>();
public Map<ResourceLocation, DoubleValue> stressEntries = new HashMap<>();
public DoubleValue mediumSpeed, fastSpeed;
public DoubleValue mediumStressImpact, highStressImpact;
public DoubleValue mediumCapacity, highCapacity;
// Logistics
public IntValue extractorDelay, extractorAmount, linkRange;
@ -332,6 +334,36 @@ public class CreateConfig {
}
private void initStress(final ForgeConfigSpec.Builder builder) {
builder.comment("Configure speed/capacity levels for requirements and indicators.").push("rotationLevels");
String basePath = "create.config.rotationLevels.";
String name = "";
name = "mediumSpeed";
mediumSpeed = builder.comment("", "[in Degrees/Tick]", "Minimum speed of rotation to be considered 'medium'")
.translation(basePath + name).defineInRange(name, 32D, 0D, 4096D);
name = "fastSpeed";
mediumSpeed = builder.comment("", "[in Degrees/Tick]", "Minimum speed of rotation to be considered 'fast'")
.translation(basePath + name).defineInRange(name, 512D, 0D, 65535D);
name = "mediumStressImpact";
mediumStressImpact = builder.comment("", "Minimum stress impact to be considered 'medium'")
.translation(basePath + name).defineInRange(name, 8D, 0D, 4096D);
name = "highStressImpact";
highStressImpact = builder.comment("", "Minimum stress impact to be considered 'high'")
.translation(basePath + name).defineInRange(name, 32D, 0D, 65535D);
name = "mediumCapacity";
mediumCapacity = builder.comment("", "Minimum added Capacity by sources to be considered 'medium'")
.translation(basePath + name).defineInRange(name, 128D, 0D, 4096D);
name = "highCapacity";
highCapacity = builder.comment("", "Minimum added Capacity by sources to be considered 'high'")
.translation(basePath + name).defineInRange(name, 512D, 0D, 65535D);
builder.pop();
builder.comment(
"Configure the individual stress impact of mechanical blocks. Note that this cost is doubled for every speed increase it receives.")
.push("stress");
@ -345,18 +377,10 @@ public class CreateConfig {
builder.comment("Configure how much stress a source can accommodate.").push("capacity");
String basePath = "create.config.capacity.";
String name = "";
name = "waterWheelCapacity";
waterWheelCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 32D, 0D, 4096D);
name = "generatingFanCapacity";
generatingFanCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 64D, 0D, 4096D);
name = "mechanicalBearingCapacity";
mechanicalBearingCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 256D, 0D,
4096D);
name = "motorCapacity";
motorCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 1024D, 0D, 4096D);
for (AllBlocks block : AllBlocks.values()) {
if (block.get() instanceof KineticBlock)
initStressCapacityEntry(block, builder);
}
builder.pop();
@ -365,10 +389,36 @@ public class CreateConfig {
private void initStressEntry(AllBlocks block, final ForgeConfigSpec.Builder builder) {
String basePath = "create.config.stress.";
String name = block.name();
stressEntries.put(block.get().getRegistryName().getPath(), builder.comment("").translation(basePath + name)
stressEntries.put(block.get().getRegistryName(), builder.comment("").translation(basePath + name)
.defineInRange(name, getDefaultStressImpact(block), 0, 2048));
}
private void initStressCapacityEntry(AllBlocks block, final ForgeConfigSpec.Builder builder) {
double defaultStressCapacity = getDefaultStressCapacity(block);
if (defaultStressCapacity == -1)
return;
String basePath = "create.config.stressCapacity.";
String name = block.name();
stressCapacityEntries.put(block.get().getRegistryName(),
builder.comment("").translation(basePath + name).defineInRange(name, defaultStressCapacity, 0, 4096D));
}
public static double getDefaultStressCapacity(AllBlocks block) {
switch (block) {
case MOTOR:
return 1024;
case ENCASED_FAN:
return 64;
case WATER_WHEEL:
return 32;
case MECHANICAL_BEARING:
return 128;
default:
return -1;
}
}
public static double getDefaultStressImpact(AllBlocks block) {
switch (block) {

View File

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.utility;
import static com.simibubi.create.CreateConfig.parameters;
import static com.simibubi.create.foundation.utility.TooltipHelper.cutString;
import static net.minecraft.util.text.TextFormatting.AQUA;
import static net.minecraft.util.text.TextFormatting.BLUE;
@ -20,7 +21,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import com.simibubi.create.modules.contraptions.base.IRotate.StressImpact;
import net.minecraft.block.Block;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
@ -68,6 +75,58 @@ public class ItemDescription {
return this;
}
public ItemDescription withKineticStats(IRotate block) {
SpeedLevel minimumRequiredSpeedLevel = block.getMinimumRequiredSpeedLevel();
boolean hasSpeedRequirement = minimumRequiredSpeedLevel != SpeedLevel.NONE;
ResourceLocation id = ((Block) block).getRegistryName();
boolean hasStressImpact = parameters.stressEntries.containsKey(id);
boolean hasStressCapacity = parameters.stressCapacityEntries.containsKey(id);
if (hasSpeedRequirement) {
List<String> speedLevels = Lang.translatedOptions("tooltip.speedRequirement", "none", "medium", "high");
int index = minimumRequiredSpeedLevel.ordinal();
String level = minimumRequiredSpeedLevel.getColor() + makeProgressBar(3, index) + speedLevels.get(index);
add(linesOnShift, GRAY + Lang.translate("tooltip.speedRequirement"));
add(linesOnShift, level);
}
if (hasStressImpact) {
List<String> stressLevels = Lang.translatedOptions("tooltip.stressImpact", "low", "medium", "high");
double impact = parameters.stressEntries.get(id).get();
StressImpact impactId = impact >= parameters.highStressImpact.get() ? StressImpact.HIGH
: (impact >= parameters.mediumStressImpact.get() ? StressImpact.MEDIUM : StressImpact.LOW);
int index = impactId.ordinal();
String level = impactId.getColor() + makeProgressBar(3, index) + stressLevels.get(index);
add(linesOnShift, GRAY + Lang.translate("tooltip.stressImpact"));
add(linesOnShift, level);
}
if (hasStressCapacity) {
List<String> stressCapacityLevels = Lang.translatedOptions("tooltip.capacityProvided", "low", "medium",
"high");
double capacity = parameters.stressCapacityEntries.get(id).get();
StressImpact impactId = capacity >= parameters.highCapacity.get() ? StressImpact.LOW
: (capacity >= parameters.mediumCapacity.get() ? StressImpact.MEDIUM : StressImpact.HIGH);
int index = StressImpact.values().length - 1 - impactId.ordinal();
String level = impactId.getColor() + makeProgressBar(3, index) + stressCapacityLevels.get(index);
add(linesOnShift, GRAY + Lang.translate("tooltip.capacityProvided"));
add(linesOnShift, level);
}
if (hasSpeedRequirement || hasStressImpact || hasStressCapacity)
add(linesOnShift, "");
return this;
}
protected String makeProgressBar(int length, int filledLength) {
String bar = " ";
int emptySpaces = length - 1 - filledLength;
for (int i = 0; i <= filledLength; i++)
bar += "\u2588";
for (int i = 0; i < emptySpaces; i++)
bar += "\u2592";
return bar + " ";
}
public ItemDescription withBehaviour(String condition, String behaviour) {
add(linesOnShift, GRAY + condition);
add(linesOnShift, cutString(behaviour, palette.color, palette.hColor, 1));

View File

@ -10,8 +10,8 @@ import java.util.Map;
import com.mojang.bridge.game.Language;
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
import com.simibubi.create.modules.IModule;
import com.simibubi.create.modules.contraptions.base.IRotate;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.BlockItem;
@ -80,7 +80,7 @@ public class TooltipHelper {
public static boolean hasTooltip(ItemStack stack) {
checkLocale();
cachedTooltips.clear();
// cachedTooltips.clear();
String key = getTooltipTranslationKey(stack);
if (cachedTooltips.containsKey(key))
return cachedTooltips.get(key) != ItemDescription.MISSING;
@ -101,14 +101,15 @@ public class TooltipHelper {
private static boolean findTooltip(ItemStack stack) {
String key = getTooltipTranslationKey(stack);
if (I18n.hasKey(key)) {
cachedTooltips.put(key, buildToolTip(key, IModule.of(stack)));
cachedTooltips.put(key, buildToolTip(key, stack));
return true;
}
cachedTooltips.put(key, ItemDescription.MISSING);
return false;
}
private static ItemDescription buildToolTip(String translationKey, IModule module) {
private static ItemDescription buildToolTip(String translationKey, ItemStack stack) {
IModule module = IModule.of(stack);
ItemDescription tooltip = new ItemDescription(module.getToolTipColor());
String summaryKey = translationKey + ".summary";
@ -116,6 +117,14 @@ public class TooltipHelper {
if (I18n.hasKey(summaryKey))
tooltip = tooltip.withSummary(I18n.format(summaryKey));
// Requirements
if (stack.getItem() instanceof BlockItem) {
BlockItem item = (BlockItem) stack.getItem();
if (item.getBlock() instanceof IRotate) {
tooltip = tooltip.withKineticStats((IRotate) item.getBlock());
}
}
// Behaviours
for (int i = 1; i < 100; i++) {
String conditionKey = translationKey + ".condition" + i;
@ -138,14 +147,7 @@ public class TooltipHelper {
}
public static String getTooltipTranslationKey(ItemStack stack) {
if (stack.getItem() instanceof BlockItem) {
return getTooltipTranslationKey(((BlockItem) stack.getItem()).getBlock());
}
return stack.getItem().getTranslationKey() + ".tooltip";
}
public static String getTooltipTranslationKey(Block block) {
return block.getTranslationKey() + ".tooltip";
}
}

View File

@ -6,10 +6,29 @@ import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
public interface IRotate {
public enum SpeedLevel {
NONE, MEDIUM, FAST;
public TextFormatting getColor() {
return this == NONE ? TextFormatting.GREEN
: this == MEDIUM ? TextFormatting.AQUA : TextFormatting.LIGHT_PURPLE;
}
}
public enum StressImpact {
LOW, MEDIUM, HIGH;
public TextFormatting getColor() {
return this == LOW ? TextFormatting.YELLOW
: this == MEDIUM ? TextFormatting.GOLD : TextFormatting.RED;
}
}
public boolean hasShaftTowards(World world, BlockPos pos, BlockState state, Direction face);
public boolean hasCogsTowards(World world, BlockPos pos, BlockState state, Direction face);
@ -20,4 +39,8 @@ public interface IRotate {
return ActionResultType.PASS;
}
public default SpeedLevel getMinimumRequiredSpeedLevel() {
return SpeedLevel.NONE;
}
}

View File

@ -14,13 +14,16 @@ import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.SyncedTileEntity;
import com.simibubi.create.modules.contraptions.KineticNetwork;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.particles.RedstoneParticleData;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
@ -59,12 +62,16 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
}
public float getAddedStressCapacity() {
return 0;
Map<ResourceLocation, DoubleValue> capacityMap = CreateConfig.parameters.stressCapacityEntries;
ResourceLocation path = getBlockState().getBlock().getRegistryName();
if (!capacityMap.containsKey(path))
return 0;
return capacityMap.get(path).get().floatValue();
}
public float getStressApplied() {
Map<String, DoubleValue> stressEntries = CreateConfig.parameters.stressEntries;
String path = getBlockState().getBlock().getRegistryName().getPath();
Map<ResourceLocation, DoubleValue> stressEntries = CreateConfig.parameters.stressEntries;
ResourceLocation path = getBlockState().getBlock().getRegistryName();
if (!stressEntries.containsKey(path))
return 1;
return stressEntries.get(path).get().floatValue();
@ -282,11 +289,25 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
}
}
public boolean isSpeedRequirementFulfilled() {
BlockState state = getBlockState();
if (!(getBlockState().getBlock() instanceof IRotate))
return true;
IRotate def = (IRotate) state.getBlock();
SpeedLevel minimumRequiredSpeedLevel = def.getMinimumRequiredSpeedLevel();
if (minimumRequiredSpeedLevel == null)
return true;
if (minimumRequiredSpeedLevel == SpeedLevel.MEDIUM)
return Math.abs(getSpeed()) >= CreateConfig.parameters.mediumSpeed.get();
if (minimumRequiredSpeedLevel == SpeedLevel.FAST)
return Math.abs(getSpeed()) >= CreateConfig.parameters.fastSpeed.get();
return true;
}
public void addDebugInformation(List<String> lines) {
lines.add("Speed: " + GREEN + speed);
lines.add("Cost: " + GREEN + getStressApplied() + WHITE + "/" + GREEN + getAddedStressCapacity());
lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress);
// lines.add("Network: " + (hasNetwork() ? networkID.toString() : "Missing"));
}
}

View File

@ -30,11 +30,6 @@ public class MotorTileEntity extends GeneratingKineticTileEntity {
return generatedSpeed;
}
@Override
public float getAddedStressCapacity() {
return CreateConfig.parameters.motorCapacity.get().floatValue();
}
@Override
public boolean hasFastRenderer() {
return true;

View File

@ -4,7 +4,6 @@ import java.util.HashMap;
import java.util.Map;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.CreateConfig;
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
import net.minecraft.nbt.CompoundNBT;
@ -60,9 +59,4 @@ public class WaterWheelTileEntity extends GeneratingKineticTileEntity {
return speed;
}
@Override
public float getAddedStressCapacity() {
return CreateConfig.parameters.waterWheelCapacity.get().floatValue();
}
}

View File

@ -91,7 +91,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
@Override
public float getAddedStressCapacity() {
return isGenerator ? CreateConfig.parameters.generatingFanCapacity.get().floatValue() : 0;
return isGenerator ? super.getAddedStressCapacity() : 0;
}
@Override
@ -196,7 +196,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
return;
EncasedFanBeltHandler.tickBelts(this, affectedBelts);
List<Entity> frontEntities = world.getEntitiesWithinAABBExcludingEntity(null, frontBB);
for (Entity entity : frontEntities) {
moveEntity(entity, true);

View File

@ -132,5 +132,10 @@ public class MechanicalMixerBlock extends KineticBlock
return 0;
return tileEntity.currentValue;
}
@Override
public SpeedLevel getMinimumRequiredSpeedLevel() {
return SpeedLevel.MEDIUM;
}
}

View File

@ -179,7 +179,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity {
return;
}
if (speed < 32)
if (!isSpeedRequirementFulfilled())
return;
if (!checkBasin)
return;

View File

@ -1,7 +1,6 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.CreateConfig;
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
import net.minecraft.block.BlockState;
@ -43,7 +42,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
@Override
public float getAddedStressCapacity() {
return isWindmill ? CreateConfig.parameters.mechanicalBearingCapacity.get().floatValue() : 0;
return isWindmill ? super.getAddedStressCapacity() : 0;
}
public void neighbourChanged() {
@ -52,9 +51,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
return;
isWindmill = shouldWindmill;
if (isWindmill && !running)
if (isWindmill && !running)
assembleNextTick = true;
if (isWindmill && running)
if (isWindmill && running)
updateGeneratedRotation();
if (!isWindmill && running) {

View File

@ -11,7 +11,7 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import net.minecraft.block.BlockState;
import net.minecraft.item.Item;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
@ -23,12 +23,17 @@ import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BeltConnectorItem extends Item {
public class BeltConnectorItem extends BlockItem {
public BeltConnectorItem(Properties properties) {
super(properties);
super(AllBlocks.BELT.block, properties);
}
@Override
public String getTranslationKey() {
return getDefaultTranslationKey();
}
@Override
public ActionResultType onItemUse(ItemUseContext context) {
if (context.isPlacerSneaking()) {
@ -218,4 +223,5 @@ public class BeltConnectorItem extends Item {
return true;
}
}

View File

@ -380,7 +380,23 @@
"create.tooltip.holdKeyOrKey": "Hold [%1$s] or [%2$s]",
"create.tooltip.keyShift": "Shift",
"create.tooltip.keyCtrl": "Ctrl",
"create.tooltip.speedRequirement": "Speed Requirement: %1$s",
"create.tooltip.speedRequirement.none": "None",
"create.tooltip.speedRequirement.medium": "Moderate",
"create.tooltip.speedRequirement.high": "Fast",
"create.tooltip.stressImpact": "Stress Impact: %1$s",
"create.tooltip.stressImpact.low": "Low",
"create.tooltip.stressImpact.medium": "Moderate",
"create.tooltip.stressImpact.high": "High",
"create.tooltip.capacityProvided": "Stress Capacity: %1$s",
"create.tooltip.capacityProvided.low": "Small",
"create.tooltip.capacityProvided.medium": "Medium",
"create.tooltip.capacityProvided.high": "Large",
"create.mechanical_mixer.min_ingredients": "Min. Ingredients",
"_comment": "-------------------------] ITEM DESCRIPTIONS [------------------------------------------------",