mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-25 00:26:26 -04:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58cdf2e756 | ||
|
|
d4b6e36aab | ||
|
|
0fb721702d | ||
|
|
0e5053b787 | ||
|
|
f3867e0b1d |
@@ -396,6 +396,7 @@
|
||||
- Fixed `/giveallpokemon` not respecting the min and max parameters
|
||||
- Fixed the choose starter toast not disappearing when capturing a Pokémon instead of opening the starter selection screen
|
||||
- Fixed an issue where certain Sinister Tea seasonings were only applying as instant effects and would not apply over time
|
||||
- Long config option labels now scroll instead of overflowing
|
||||
|
||||
### Developer
|
||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
||||
|
||||
@@ -20,6 +20,8 @@ import net.minecraft.world.level.levelgen.structure.pools.alias.PoolAliasLookup;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -31,6 +33,9 @@ import java.util.Optional;
|
||||
@Mixin(JigsawPlacement.class)
|
||||
public class JigsawPlacementMixin {
|
||||
|
||||
@Unique
|
||||
private static final Logger cobblemon$LOGGER = LoggerFactory.getLogger("Cobblemon/HeightRangeVeto");
|
||||
|
||||
@Inject(
|
||||
method = "addPieces(Lnet/minecraft/world/level/levelgen/structure/Structure$GenerationContext;Lnet/minecraft/core/Holder;Ljava/util/Optional;ILnet/minecraft/core/BlockPos;ZLjava/util/Optional;ILnet/minecraft/world/level/levelgen/structure/pools/alias/PoolAliasLookup;Lnet/minecraft/world/level/levelgen/structure/pools/DimensionPadding;Lnet/minecraft/world/level/levelgen/structure/templatesystem/LiquidSettings;)Ljava/util/Optional;",
|
||||
at = @At("RETURN"),
|
||||
@@ -54,18 +59,30 @@ public class JigsawPlacementMixin {
|
||||
if (result.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos spawnPos = result.get().position();
|
||||
boolean canPlace = cobblemon$canAnyStartElementPlace(context, startPool, spawnPos);
|
||||
String poolId = startPool.unwrapKey().map(key -> key.location().toString()).orElse("unknown");
|
||||
boolean canPlace = cobblemon$canStructurePlace(context, startPool, spawnPos);
|
||||
|
||||
cobblemon$LOGGER.info(
|
||||
"[HeightRangeVeto] addPieces evaluated requestedPos={} spawnPos={} startPool={} -> canPlace={}",
|
||||
pos, spawnPos, poolId, canPlace
|
||||
);
|
||||
|
||||
if (canPlace) {
|
||||
return;
|
||||
}
|
||||
|
||||
cobblemon$LOGGER.info(
|
||||
"[HeightRangeVeto] Vetoing structure start at {} (startPool={})",
|
||||
spawnPos, poolId
|
||||
);
|
||||
|
||||
cir.setReturnValue(Optional.empty());
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static boolean cobblemon$canAnyStartElementPlace(
|
||||
private static boolean cobblemon$canStructurePlace(
|
||||
Structure.GenerationContext generationContext,
|
||||
Holder<StructureTemplatePool> startPool,
|
||||
BlockPos startPos
|
||||
@@ -74,7 +91,7 @@ public class JigsawPlacementMixin {
|
||||
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(element);
|
||||
|
||||
if (heightRangeProcessor.isEmpty()) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
HeightRangeStructureProcessor processor = heightRangeProcessor.get();
|
||||
@@ -85,12 +102,17 @@ public class JigsawPlacementMixin {
|
||||
startPos
|
||||
);
|
||||
|
||||
if (valid) {
|
||||
return true;
|
||||
cobblemon$LOGGER.info(
|
||||
"[HeightRangeVeto] template={} pos={} valid={}",
|
||||
element, startPos, valid
|
||||
);
|
||||
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Unique
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.minecraft.world.level.block.SoundType
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.entity.CommandBlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
@@ -80,11 +81,13 @@ class HabitatBlock(properties: Properties) : Block(properties), EntityBlock {
|
||||
}
|
||||
|
||||
override fun useWithoutItem(state: BlockState, level: Level, pos: BlockPos, player: Player, hitResult: BlockHitResult): InteractionResult {
|
||||
if (!level.isClientSide) {
|
||||
val be = level.getBlockEntity(pos) as? HabitatBlockEntity ?: return InteractionResult.PASS
|
||||
return be.onUse(player, hitResult)
|
||||
val blockEntity = level.getBlockEntity(pos)
|
||||
val be = level.getBlockEntity(pos) as? HabitatBlockEntity ?: return InteractionResult.PASS
|
||||
return if (blockEntity is HabitatBlockEntity && player.canUseGameMasterBlocks()) {
|
||||
be.onUse(player, hitResult)
|
||||
} else {
|
||||
InteractionResult.PASS
|
||||
}
|
||||
return InteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun getDrops(state: BlockState, params: LootParams.Builder): MutableList<ItemStack> {
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ class CobblemonConfigScreen(
|
||||
const val WIDGET_HEIGHT = SLOT_HEIGHT - PADDING
|
||||
const val LABEL_Y_OFFSET = 4
|
||||
const val WIDGET_Y_OFFSET = 0
|
||||
const val LABEL_MAX_WIDTH = SLOT_WIDTH - RESET_SLOT_WIDTH - WIDGET_WIDTH - PADDING * 2
|
||||
}
|
||||
|
||||
val clonedConfig = Cobblemon.config.clone()
|
||||
|
||||
+12
-8
@@ -8,17 +8,18 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.config.variable
|
||||
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.LABEL_Y_OFFSET
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.LABEL_MAX_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.RESET_SLOT_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.SLOT_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.WIDGET_HEIGHT
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.WIDGET_Y_OFFSET
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigVariableList
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigVariableList.CobblemonConfigVariableListEntry
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.drawScrollingText
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
import com.cobblemon.mod.common.config.CobblemonConfigField
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.gui.components.Tooltip
|
||||
@@ -91,12 +92,15 @@ abstract class CobblemonConfigVariable(
|
||||
val x = getX(left)
|
||||
val y = getY(top)
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = labelLang,
|
||||
x = getX(left),
|
||||
y = getY(top) + LABEL_Y_OFFSET,
|
||||
shadow = true
|
||||
drawScrollingText(
|
||||
context,
|
||||
Minecraft.getInstance().font,
|
||||
labelLang,
|
||||
x,
|
||||
y + WIDGET_Y_OFFSET,
|
||||
x + LABEL_MAX_WIDTH,
|
||||
y + WIDGET_Y_OFFSET + WIDGET_HEIGHT,
|
||||
-1
|
||||
)
|
||||
|
||||
resetButton.x = x + SLOT_WIDTH - RESET_SLOT_WIDTH
|
||||
|
||||
@@ -18,17 +18,23 @@ import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.Font
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun renderScaledGuiItemIcon(itemStack: ItemStack, x: Double, y: Double, scale: Double = 1.0, zTranslation: Float = 100.0F, matrixStack: PoseStack? = null) {
|
||||
val itemRenderer = Minecraft.getInstance().itemRenderer
|
||||
@@ -97,6 +103,55 @@ fun getDepletableRedGreen(
|
||||
return r.toFloat() to g.toFloat()
|
||||
}
|
||||
|
||||
fun drawScrollingText(
|
||||
context: GuiGraphics,
|
||||
font: Font,
|
||||
text: Component,
|
||||
minX: Int,
|
||||
minY: Int,
|
||||
maxX: Int,
|
||||
maxY: Int,
|
||||
colour: Int,
|
||||
minScrollVelocity: Double? = 10.0
|
||||
) {
|
||||
val textWidth = font.width(text)
|
||||
val fittedMaxX = if (textWidth <= maxX - minX) minX + textWidth else maxX
|
||||
renderScrollingString(context, font, text, minX, minY, fittedMaxX, maxY, colour, minScrollVelocity)
|
||||
}
|
||||
|
||||
/** Copied from [net.minecraft.client.gui.components.AbstractWidget.renderScrollingString] **/
|
||||
fun renderScrollingString(
|
||||
context: GuiGraphics,
|
||||
font: Font,
|
||||
text: Component,
|
||||
minX: Int,
|
||||
minY: Int,
|
||||
maxX: Int,
|
||||
maxY: Int,
|
||||
colour: Int,
|
||||
minScrollVelocity: Double? = 10.0
|
||||
) {
|
||||
val textWidth = font.width(text)
|
||||
val centerY = (minY + maxY - 9) / 2 + 1
|
||||
val boxWidth = maxX - minX
|
||||
if (textWidth <= boxWidth) {
|
||||
val centerX = Mth.clamp((minX + maxX) / 2, minX + textWidth / 2, maxX - textWidth / 2)
|
||||
context.drawCenteredString(font, text, centerX, centerY, colour)
|
||||
return
|
||||
}
|
||||
|
||||
val overflow = textWidth - boxWidth
|
||||
var period = (overflow * 0.5).coerceAtLeast(3.0)
|
||||
if (minScrollVelocity != null) {
|
||||
period = period.coerceAtMost(2 * overflow / minScrollVelocity)
|
||||
}
|
||||
val time = Util.getMillis() / 1000.0
|
||||
val easedProgress = sin((Math.PI / 2) * cos(2 * Math.PI * time / period)) / 2.0 + 0.5
|
||||
val offset = Mth.lerp(easedProgress, 0.0, overflow.toDouble())
|
||||
context.enableScissor(minX, minY, maxX, maxY)
|
||||
context.drawString(font, text, minX - offset.toInt(), centerY, colour)
|
||||
context.disableScissor()
|
||||
}
|
||||
|
||||
fun drawScaledText(
|
||||
context: GuiGraphics,
|
||||
|
||||
@@ -316,7 +316,6 @@ object CobblemonItemGroups {
|
||||
entries.accept(CobblemonItems.PASTURE)
|
||||
entries.accept(CobblemonItems.TM_MACHINE)
|
||||
entries.accept(CobblemonItems.DISC_SHELF)
|
||||
entries.accept(CobblemonItems.HABITAT_BLOCK)
|
||||
|
||||
entries.accept(CobblemonItems.GILDED_CHEST)
|
||||
entries.accept(CobblemonItems.YELLOW_GILDED_CHEST)
|
||||
|
||||
+11
-1
@@ -20,6 +20,7 @@ import net.minecraft.world.level.levelgen.RandomState
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class HeightRangeStructureProcessor(
|
||||
val minOffset: Int,
|
||||
@@ -43,7 +44,14 @@ class HeightRangeStructureProcessor(
|
||||
val referenceY = reference.getY(chunkGenerator, heightAccessor, randomState, pos)
|
||||
val minY = referenceY + minOffset
|
||||
val maxY = referenceY + maxOffset
|
||||
return pos.y in minY..maxY
|
||||
val valid = pos.y in minY..maxY
|
||||
|
||||
LOGGER.info(
|
||||
"[HeightRangeVeto] isValidPlacement pos={} reference={} referenceY={} minY={} maxY={} pos.y={} -> valid={}",
|
||||
pos, reference, referenceY, minY, maxY, pos.y, valid
|
||||
)
|
||||
|
||||
return valid
|
||||
}
|
||||
|
||||
override fun processBlock(
|
||||
@@ -105,6 +113,8 @@ class HeightRangeStructureProcessor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LoggerFactory.getLogger("Cobblemon/HeightRangeStructureProcessor")
|
||||
|
||||
val CODEC: MapCodec<HeightRangeStructureProcessor> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
Codec.INT.fieldOf("min_offset").forGetter { it.minOffset },
|
||||
|
||||
Reference in New Issue
Block a user