Compare commits

...
Author SHA1 Message Date
apion 1fde1e4428 Merged main into 1.20.4 2024-04-25 10:18:17 -04:00
apion a2d574300c Merge branch 'main' into 1.20.4
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/block/TumblestoneBlock.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/block/chest/GildedChestBlock.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/block/entity/GildedChestBlockEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/summary/Summary.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Pokemon.kt
#	forge/src/main/java/com/cobblemon/mod/forge/mixin/LootManagerMixin.java
#	gradle/libs.versions.yml
2024-04-25 08:31:40 -04:00
Deltric 00eca1c019 fix: battle gui rendering bugs and removed old method 2024-03-17 01:02:43 -05:00
Deltric babfb43750 Merge remote-tracking branch 'origin/1.20.4' into 1.20.4
# Conflicts:
#	common/build.gradle.kts
#	common/src/main/kotlin/com/cobblemon/mod/common/block/chest/GildedChestBlock.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/startselection/StarterSelectionScreen.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Pokemon.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2024-03-17 00:25:21 -05:00
Deltric 3aa94fcd2a fixed two leftover errors from merging in main 2024-03-17 00:19:25 -05:00
Deltric 20a866a0e3 draft: rough port with some bugs to fix and code to clean up. 2024-03-16 23:39:29 -05:00
Deltric 67f2146c3c remove baked in adorn for compatibility mod 2024-03-16 23:27:16 -05:00
Deltric ad49106132 initial gradle changes 2024-03-16 23:27:09 -05:00
Deltric 064df9c26e draft: rough port with some bugs to fix and code to clean up. 2024-03-16 23:15:12 -05:00
Deltric ea2936f204 remove baked in adorn for compatibility mod 2024-03-02 17:44:25 -06:00
Deltric 9d7eef9bcd initial gradle changes 2024-03-02 17:18:50 -06:00
261 changed files with 1488 additions and 3656 deletions
+2 -4
View File
@@ -39,10 +39,8 @@ dependencies {
modImplementation(libs.fabricLoader)
//Flywheel has no common dep so just pick one and don't use any platform specific code in common
// modCompileOnly(libs.flywheelFabric)
//modCompileOnly(libs.flywheelFabric)
modApi(libs.molang)
compileOnlyApi(libs.jeiApi)
modCompileOnly(libs.adornFabric)
modCompileOnly(libs.lambDynamicLights) { isTransitive = false }
// For Showdown
@@ -98,4 +96,4 @@ sourceSets {
}
}
}
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.client.CobblemonClient;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.util.SkinTextures;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.resource.ResourceManager;
import org.spongepowered.asm.mixin.Mixin;
@@ -24,7 +25,7 @@ import java.util.Map;
@Mixin(EntityRenderDispatcher.class)
public class EntityRenderDispatcherMixin {
@Shadow private Map<String, EntityRenderer<? extends PlayerEntity>> modelRenderers;
@Shadow private Map<SkinTextures.Model, EntityRenderer<? extends PlayerEntity>> modelRenderers;
@Inject(
method = "reload",
@@ -33,4 +34,4 @@ public class EntityRenderDispatcherMixin {
public void resourceManagerReloadHook(ResourceManager resourceManager, CallbackInfo ci) {
CobblemonClient.INSTANCE.onAddLayer(this.modelRenderers);
}
}
}
@@ -21,13 +21,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Mouse.class)
public class PartyScrollMixin {
@Shadow
private double eventDeltaWheel;
private double eventDeltaVerticalWheel;
@Inject(
method = "onMouseScroll",
at = @At(
value = "FIELD",
target="Lnet/minecraft/client/Mouse;eventDeltaWheel:D",
target="Lnet/minecraft/client/Mouse;eventDeltaVerticalWheel:D",
opcode = Opcodes.PUTFIELD,
ordinal = 2,
shift = At.Shift.BEFORE
@@ -36,18 +36,18 @@ public class PartyScrollMixin {
)
public void onMouseScroll(long window, double horizontal, double vertical, CallbackInfo ci) {
if (PartySendBinding.INSTANCE.getWasDown()) {
int i = (int)eventDeltaWheel;
int i = (int)eventDeltaVerticalWheel;
if (i > 0) {
while (i-- > 0) CobblemonClient.INSTANCE.getStorage().shiftSelected(false);
ci.cancel();
eventDeltaWheel = 0;
eventDeltaVerticalWheel = 0;
PartySendBinding.INSTANCE.actioned();
} else if (i < 0) {
while (i++ < 0) CobblemonClient.INSTANCE.getStorage().shiftSelected(true);
ci.cancel();
eventDeltaWheel = 0;
eventDeltaVerticalWheel = 0;
PartySendBinding.INSTANCE.actioned();
}
}
}
}
}
@@ -15,15 +15,8 @@ import net.minecraft.structure.StructureTemplateManager;
import net.minecraft.structure.pool.*;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.HeightLimitView;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.noise.NoiseConfig;
import org.apache.commons.lang3.mutable.MutableObject;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@@ -33,9 +26,6 @@ import java.util.*;
@Mixin(StructurePoolBasedGenerator.StructurePoolGenerator.class)
public abstract class StructurePoolGeneratorMixin {
@Final
@Mutable
@Shadow Deque<StructurePoolBasedGenerator.ShapedPoolStructurePiece> structurePieces;
Map<String, Integer> generatedStructureGroupCounts;
@@ -103,7 +93,7 @@ public abstract class StructurePoolGeneratorMixin {
generatedStructureGroupCounts = new HashMap<>();
}
@ModifyVariable(method = "generatePiece", at = @At("STORE"), ordinal = 1)
@ModifyVariable(method = "generatePiece(Lnet/minecraft/structure/PoolStructurePiece;Lorg/apache/commons/lang3/mutable/MutableObject;IZLnet/minecraft/world/HeightLimitView;Lnet/minecraft/world/gen/noise/NoiseConfig;Lnet/minecraft/structure/pool/alias/StructurePoolAliasLookup;)V", at = @At("STORE"), ordinal = 1)
private Iterator<StructurePoolElement> reduceStructurePoolElementIterator(Iterator<StructurePoolElement> iterator) {
List<StructurePoolElement> reducedList = new ArrayList<>();
@@ -123,7 +113,7 @@ public abstract class StructurePoolGeneratorMixin {
return reducedList.iterator();
}
@ModifyVariable(method = "generatePiece", at = @At("STORE"), ordinal = 1)
@ModifyVariable(method = "generatePiece(Lnet/minecraft/structure/PoolStructurePiece;Lorg/apache/commons/lang3/mutable/MutableObject;IZLnet/minecraft/world/HeightLimitView;Lnet/minecraft/world/gen/noise/NoiseConfig;Lnet/minecraft/structure/pool/alias/StructurePoolAliasLookup;)V", at = @At("HEAD"), ordinal = 0, argsOnly = true)
private PoolStructurePiece injected(PoolStructurePiece poolStructurePiece) {
Identifier structureLocationKey = getCobblemonOnlyLocation(poolStructurePiece.getPoolElement());
if (structureLocationKey != null) {
@@ -133,42 +123,42 @@ public abstract class StructurePoolGeneratorMixin {
}
// This doesn't SEEM necessary? It appears to work without.
@Inject(method = "generatePiece", at = @At("HEAD"))
private void beforeGeneratePiece(PoolStructurePiece piece, MutableObject<VoxelShape> pieceShape, int minY, boolean modifyBoundingBox, HeightLimitView world, NoiseConfig noiseConfig, CallbackInfo ci) {
// Identifier structureLocationKey = getCobblemonOnlyLocation(piece.getPoolElement());
//
// if (structureLocationKey != null) {
// Integer currentlyGenerated = generatedStructureCounts.get(structureLocationKey);
// if (currentlyGenerated == null) currentlyGenerated = 0;
// generatedStructureCounts.put(structureLocationKey, currentlyGenerated + 1);
// }
//
// List<StructurePoolBasedGenerator.ShapedPoolStructurePiece> reducedStructurePiecesList = structurePieces.stream().toList();
//
// for (Identifier maxStructureLocationKey : structureMaxes.keySet()) {
// Integer maxAllowed = structureMaxes.get(maxStructureLocationKey);
//
// Integer currentlyGenerated = generatedStructureCounts.get(maxStructureLocationKey);
// if (currentlyGenerated == null) currentlyGenerated = 0;
// if (currentlyGenerated < maxAllowed) {
// continue;
// }
//
// //Already have max so need to remove
// reducedStructurePiecesList = reducedStructurePiecesList.stream()
// .filter(shapedStructurePiece -> {
// Identifier locationKey = getCobblemonOnlyLocation(shapedStructurePiece.piece.getPoolElement());
// if (locationKey == null) {
// return true;
// }
//
// return !locationKey.equals(maxStructureLocationKey);
// })
// .collect(Collectors.toList());
// }
//
// structurePieces = new ArrayDeque<>(reducedStructurePiecesList);
}
// @Inject(method = "generatePiece", at = @At("HEAD"))
// private void beforeGeneratePiece(PoolStructurePiece piece, MutableObject<VoxelShape> pieceShape, int minY, boolean modifyBoundingBox, HeightLimitView world, NoiseConfig noiseConfig, CallbackInfo ci) {
//// Identifier structureLocationKey = getCobblemonOnlyLocation(piece.getPoolElement());
////
//// if (structureLocationKey != null) {
//// Integer currentlyGenerated = generatedStructureCounts.get(structureLocationKey);
//// if (currentlyGenerated == null) currentlyGenerated = 0;
//// generatedStructureCounts.put(structureLocationKey, currentlyGenerated + 1);
//// }
////
//// List<StructurePoolBasedGenerator.ShapedPoolStructurePiece> reducedStructurePiecesList = structurePieces.stream().toList();
////
//// for (Identifier maxStructureLocationKey : structureMaxes.keySet()) {
//// Integer maxAllowed = structureMaxes.get(maxStructureLocationKey);
////
//// Integer currentlyGenerated = generatedStructureCounts.get(maxStructureLocationKey);
//// if (currentlyGenerated == null) currentlyGenerated = 0;
//// if (currentlyGenerated < maxAllowed) {
//// continue;
//// }
////
//// //Already have max so need to remove
//// reducedStructurePiecesList = reducedStructurePiecesList.stream()
//// .filter(shapedStructurePiece -> {
//// Identifier locationKey = getCobblemonOnlyLocation(shapedStructurePiece.piece.getPoolElement());
//// if (locationKey == null) {
//// return true;
//// }
////
//// return !locationKey.equals(maxStructureLocationKey);
//// })
//// .collect(Collectors.toList());
//// }
////
//// structurePieces = new ArrayDeque<>(reducedStructurePiecesList);
// }
private static Identifier getCobblemonOnlyLocation(StructurePoolElement structurePoolElement) {
Identifier location = getLocationIfAvailable(structurePoolElement);
@@ -214,4 +204,4 @@ public abstract class StructurePoolGeneratorMixin {
//
// return reducedList;
// }
}
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.mixin.invoker;
import net.minecraft.block.*;
import net.minecraft.resource.featuretoggle.FeatureFlag;
import net.minecraft.sound.BlockSoundGroup;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@@ -19,23 +18,23 @@ import org.spongepowered.asm.mixin.gen.Invoker;
public interface BlocksInvoker {
@Invoker("createLogBlock")
static PillarBlock createLogBlock(MapColor topMapColor, MapColor sideMapColor) {
static Block createLogBlock(MapColor topMapColor, MapColor sideMapColor) {
throw new UnsupportedOperationException();
}
@Invoker("createLeavesBlock")
static LeavesBlock createLeavesBlock(BlockSoundGroup soundGroup) {
static Block createLeavesBlock(BlockSoundGroup soundGroup) {
throw new UnsupportedOperationException();
}
@Invoker("createWoodenButtonBlock")
static ButtonBlock createWoodenButtonBlock(BlockSetType blockSetType, FeatureFlag... requiredFeatures) {
static Block createWoodenButtonBlock(BlockSetType blockSetType) {
throw new UnsupportedOperationException();
}
@Invoker("createFlowerPotBlock")
static FlowerPotBlock createFlowerPotBlock(Block flower, FeatureFlag... requiredFeatures) {
static Block createFlowerPotBlock(Block flower) {
throw new UnsupportedOperationException();
}
}
}
@@ -11,14 +11,13 @@ package com.cobblemon.mod.common.mixin.invoker;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockSetType;
import net.minecraft.block.DoorBlock;
import net.minecraft.sound.SoundEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(DoorBlock.class)
public interface DoorBlockInvoker {
@Invoker("<init>")
static DoorBlock cobblemon$create(AbstractBlock.Settings settings, BlockSetType blockSetType) {
static DoorBlock cobblemon$create(BlockSetType blockSetType, AbstractBlock.Settings settings) {
throw new UnsupportedOperationException();
}
}
}
@@ -11,14 +11,13 @@ package com.cobblemon.mod.common.mixin.invoker;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockSetType;
import net.minecraft.block.PressurePlateBlock;
import net.minecraft.sound.SoundEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(PressurePlateBlock.class)
public interface PressurePlateBlockInvoker {
@Invoker("<init>")
static PressurePlateBlock cobblemon$create(PressurePlateBlock.ActivationRule type, AbstractBlock.Settings settings, BlockSetType blockSetType) {
static PressurePlateBlock cobblemon$create(BlockSetType type, AbstractBlock.Settings settings) {
throw new UnsupportedOperationException();
}
}
}
@@ -11,14 +11,13 @@ package com.cobblemon.mod.common.mixin.invoker;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockSetType;
import net.minecraft.block.TrapdoorBlock;
import net.minecraft.sound.SoundEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(TrapdoorBlock.class)
public interface TrapdoorBlockInvoker {
@Invoker("<init>")
static TrapdoorBlock cobblemon$create(AbstractBlock.Settings settings, BlockSetType blockSetType) {
static TrapdoorBlock cobblemon$create(BlockSetType blockSetType, AbstractBlock.Settings settings) {
throw new UnsupportedOperationException();
}
}
}
@@ -115,11 +115,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE))
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(APRICORN_WOOD_TYPE, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField // Note At the time of 1.20.0 we don't need our own BlockSetType for Apricorn wood
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD), APRICORN_BLOCK_SET_TYPE))
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(APRICORN_BLOCK_SET_TYPE, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD)))
@JvmField
val APRICORN_SIGN = this.create("apricorn_sign", CobblemonSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_SIGN), APRICORN_WOOD_TYPE))
@JvmField
@@ -133,9 +133,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
@JvmField
val APRICORN_STAIRS = this.create("apricorn_stairs", StairsBlockInvoker.`cobblemon$create`(APRICORN_PLANKS.defaultState, AbstractBlock.Settings.copy(APRICORN_PLANKS)))
@JvmField
val APRICORN_DOOR = this.create("apricorn_door", DoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque(), APRICORN_BLOCK_SET_TYPE))
val APRICORN_DOOR = this.create("apricorn_door", DoorBlockInvoker.`cobblemon$create`(APRICORN_BLOCK_SET_TYPE, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque()))
@JvmField
val APRICORN_TRAPDOOR = this.create("apricorn_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning { _, _, _, _ -> false }, APRICORN_BLOCK_SET_TYPE))
val APRICORN_TRAPDOOR = this.create("apricorn_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(APRICORN_BLOCK_SET_TYPE, AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning { _, _, _, _ -> false }))
private val PLANT_PROPERTIES = AbstractBlock.Settings.create().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.GRASS).pistonBehavior(PistonBehavior.DESTROY)
@JvmField
@@ -560,7 +560,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
/**
* Calls helper method from Vanilla
*/
private fun log(name: String, arg: MapColor = MapColor.DIRT_BROWN, arg2: MapColor = MapColor.DIRT_BROWN): PillarBlock {
private fun log(name: String, arg: MapColor = MapColor.DIRT_BROWN, arg2: MapColor = MapColor.DIRT_BROWN): Block {
val block = BlocksInvoker.createLogBlock(arg, arg2)
return this.create(name, block)
}
@@ -580,16 +580,16 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
return block
}
private fun evolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(AbstractBlock.Settings.copy(Blocks.IRON_ORE), UniformIntProvider.create(1, 2)))
private fun evolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(UniformIntProvider.create(1, 2), AbstractBlock.Settings.copy(Blocks.IRON_ORE)))
private fun deepslateEvolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(AbstractBlock.Settings.copy(Blocks.DEEPSLATE_IRON_ORE), UniformIntProvider.create(1, 2)))
private fun deepslateEvolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(UniformIntProvider.create(1, 2), AbstractBlock.Settings.copy(Blocks.DEEPSLATE_IRON_ORE)))
/**
* Helper method for creating leaves
* copied over from Vanilla
*/
private fun leaves(name: String): LeavesBlock {
private fun leaves(name: String): Block {
val block = BlocksInvoker.createLeavesBlock(BlockSoundGroup.GRASS)
return this.create(name, block)
}
}
}
@@ -146,7 +146,7 @@ interface CobblemonImplementation {
* @param criteria
* @return
*/
fun <T : Criterion<*>> registerCriteria(criteria: T): T
fun <T : Criterion<*>> registerCriteria(id: String, criteria: T): T
/**
* TODO
@@ -240,4 +240,4 @@ enum class Environment {
CLIENT,
SERVER
}
}
@@ -9,8 +9,18 @@
package com.cobblemon.mod.common.advancement
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.advancement.criterion.*
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.advancement.criterion.AspectCriterion
import com.cobblemon.mod.common.advancement.criterion.BattleCountableCriterion
import com.cobblemon.mod.common.advancement.criterion.CaughtPokemonCriterion
import com.cobblemon.mod.common.advancement.criterion.CountableCriterion
import com.cobblemon.mod.common.advancement.criterion.EvolvePokemonCriterion
import com.cobblemon.mod.common.advancement.criterion.LevelUpCriterion
import com.cobblemon.mod.common.advancement.criterion.PartyCheckCriterion
import com.cobblemon.mod.common.advancement.criterion.PlantTumblestoneCriterion
import com.cobblemon.mod.common.advancement.criterion.PokemonCriterion
import com.cobblemon.mod.common.advancement.criterion.PokemonInteractCriterion
import com.cobblemon.mod.common.advancement.criterion.SimpleCriterionTrigger
import com.cobblemon.mod.common.advancement.criterion.TradePokemonCriterion
import net.minecraft.advancement.criterion.Criterion
/**
@@ -20,107 +30,37 @@ import net.minecraft.advancement.criterion.Criterion
* @since October 26th, 2022
*/
object CobblemonCriteria {
val PICK_STARTER = this.create(
SimpleCriterionTrigger(
cobblemonResource("pick_starter"),
PickStarterCriterionCondition::class.java
)
)
val CATCH_POKEMON = this.create(
SimpleCriterionTrigger(
cobblemonResource("catch_pokemon"),
CaughtPokemonCriterionCondition::class.java
)
)
val CATCH_SHINY_POKEMON = this.create(
SimpleCriterionTrigger(
cobblemonResource("catch_shiny_pokemon"),
SimpleCountableCriterionCondition::class.java
)
)
val EGG_HATCH = this.create(
SimpleCriterionTrigger(
cobblemonResource("eggs_hatched"),
SimpleCountableCriterionCondition::class.java
)
)
val EVOLVE_POKEMON = this.create(
SimpleCriterionTrigger(
cobblemonResource("pokemon_evolved"),
EvolvePokemonCriterionCondition::class.java
)
)
val WIN_BATTLE = this.create(
BattleCountableCriterionTrigger(
cobblemonResource("battles_won"),
BattleCountableCriterionCondition::class.java
)
)
val PICK_STARTER = this.create("pick_starter", SimpleCriterionTrigger(PokemonCriterion.CODEC))
val DEFEAT_POKEMON = this.create(
SimpleCriterionTrigger(
cobblemonResource("pokemon_defeated"),
SimpleCountableCriterionCondition::class.java
)
)
val CATCH_POKEMON = this.create("catch_pokemon", SimpleCriterionTrigger(CaughtPokemonCriterion.CODEC))
val COLLECT_ASPECT = this.create(
AspectCriterionTrigger(
cobblemonResource("aspects_collected"),
AspectCriterionCondition::class.java
)
)
val CATCH_SHINY_POKEMON = this.create("catch_shiny_pokemon", SimpleCriterionTrigger(CountableCriterion.CODEC))
val POKEMON_INTERACT = this.create(
SimpleCriterionTrigger(
cobblemonResource("pokemon_interact"),
PokemonInteractCriterion::class.java
)
)
val EGG_HATCH = this.create("eggs_hatched", SimpleCriterionTrigger(CountableCriterion.CODEC))
val PARTY_CHECK = this.create(
SimpleCriterionTrigger(
cobblemonResource("party"),
PartyCheckCriterion::class.java
)
)
val EVOLVE_POKEMON = this.create("pokemon_evolved", SimpleCriterionTrigger(EvolvePokemonCriterion.CODEC))
val LEVEL_UP = this.create(
SimpleCriterionTrigger(
cobblemonResource("level_up"),
LevelUpCriterionCondition::class.java
)
)
val WIN_BATTLE = this.create("battles_won", SimpleCriterionTrigger(BattleCountableCriterion.CODEC))
val PASTURE_USE = this.create(
SimpleCriterionTrigger(
cobblemonResource("pasture_use"),
PickStarterCriterionCondition::class.java
)
)
val DEFEAT_POKEMON = this.create("pokemon_defeated", SimpleCriterionTrigger(CountableCriterion.CODEC))
val RESURRECT_POKEMON = this.create(
SimpleCriterionTrigger(
cobblemonResource("resurrect_pokemon"),
PickStarterCriterionCondition::class.java
)
)
val COLLECT_ASPECT = this.create("aspects_collected", SimpleCriterionTrigger(AspectCriterion.CODEC))
val TRADE_POKEMON = this.create(
SimpleCriterionTrigger(
cobblemonResource("trade_pokemon"),
TradePokemonCriterionCondition::class.java
)
)
val POKEMON_INTERACT = this.create("pokemon_interact", SimpleCriterionTrigger(PokemonInteractCriterion.CODEC))
val PARTY_CHECK = this.create("party", SimpleCriterionTrigger(PartyCheckCriterion.CODEC))
val LEVEL_UP = this.create("level_up", SimpleCriterionTrigger(LevelUpCriterion.CODEC))
val PASTURE_USE = this.create("pasture_use", SimpleCriterionTrigger(PokemonCriterion.CODEC))
val RESURRECT_POKEMON = this.create("resurrect_pokemon", SimpleCriterionTrigger(PokemonCriterion.CODEC))
val TRADE_POKEMON = this.create("trade_pokemon", SimpleCriterionTrigger(TradePokemonCriterion.CODEC))
// Advancement criteria for [grow_tumblestone.json]
val PLANT_TUMBLESTONE = this.create(
SimpleCriterionTrigger(
cobblemonResource("plant_tumblestone"),
PlantTumblestoneCriterionCondition::class.java
)
)
val PLANT_TUMBLESTONE = this.create("plant_tumblestone", SimpleCriterionTrigger(PlantTumblestoneCriterion.CODEC))
private fun <T : Criterion<*>> create(criteria: T): T = Cobblemon.implementation.registerCriteria(criteria)
private fun <T : Criterion<*>> create(id: String, criteria: T): T = Cobblemon.implementation.registerCriteria(id, criteria)
}
@@ -8,38 +8,59 @@
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
open class AspectCriterionTrigger(identifier: Identifier, criterionClass: Class<AspectCriterionCondition>) : SimpleCriterionTrigger<MutableMap<Identifier, MutableSet<String>>, AspectCriterionCondition>(identifier, criterionClass) {
class AspectCriterion(
playerCtx: Optional<LootContextPredicate>,
val pokemon: Identifier,
val aspects: List<String>
): SimpleCriterionCondition<MutableMap<Identifier, MutableSet<String>>>(playerCtx) {
}
class AspectCriterionCondition(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<MutableMap<Identifier, MutableSet<String>>>(id, predicate) {
var pokemon = Identifier("cobblemon:pikachu")
var aspects = mutableListOf<String>()
override fun toJson(json: JsonObject) {
json.add("aspects", JsonArray(aspects.size).also {
aspects.forEach { aspect -> it.add(aspect) }
})
json.addProperty("pokemon", pokemon.toString())
}
override fun fromJson(json: JsonObject) {
aspects.clear()
json.getAsJsonArray("aspects").forEach { element ->
aspects.add(element.asString)
}
pokemon = json.get("pokemon").asString.asIdentifierDefaultingNamespace()
companion object {
val CODEC: Codec<AspectCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(LootContextPredicate.CODEC, "player").forGetter(AspectCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Identifier.CODEC, "pokemon", Identifier("cobblemon:pikachu")).forGetter(AspectCriterion::pokemon),
Codecs.createStrictOptionalFieldCodec(Codec.STRING.listOf(), "aspects", listOf()).forGetter(AspectCriterion::aspects)
) .apply(it, ::AspectCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: MutableMap<Identifier, MutableSet<String>>): Boolean {
val caughtAspects = context.getOrDefault(pokemon, mutableSetOf())
return this.aspects.all { it in caughtAspects }
}
}
}
//open class AspectCriterionTrigger(identifier: Identifier, criterionClass: Class<AspectCriterionCondition>) : SimpleCriterionTrigger<MutableMap<Identifier, MutableSet<String>>, AspectCriterionCondition>(identifier, criterionClass) {
//
//}
//
//class AspectCriterionCondition(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<MutableMap<Identifier, MutableSet<String>>>(id, predicate) {
// var pokemon = Identifier("cobblemon:pikachu")
// var aspects = mutableListOf<String>()
// override fun toJson(json: JsonObject) {
// json.add("aspects", JsonArray(aspects.size).also {
// aspects.forEach { aspect -> it.add(aspect) }
// })
// json.addProperty("pokemon", pokemon.toString())
// }
//
// override fun fromJson(json: JsonObject) {
// aspects.clear()
// json.getAsJsonArray("aspects").forEach { element ->
// aspects.add(element.asString)
// }
// pokemon = json.get("pokemon").asString.asIdentifierDefaultingNamespace()
// }
//
// override fun matches(player: ServerPlayerEntity, context: MutableMap<Identifier, MutableSet<String>>): Boolean {
// val caughtAspects = context.getOrDefault(pokemon, mutableSetOf())
// return this.aspects.all { it in caughtAspects }
// }
//
//}
@@ -10,58 +10,105 @@ package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.util.toJsonArray
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
open class BattleCountableCriterionTrigger(identifier: Identifier, criterionClass: Class<BattleCountableCriterionCondition>) : SimpleCriterionTrigger<BattleCountableContext, BattleCountableCriterionCondition>(identifier, criterionClass) {
open class BattleCountableContext(var battle : PokemonBattle, times : Int) : CountableContext(times)
}
class BattleCountableCriterion(
playerCtx: Optional<LootContextPredicate>,
val battleTypes: List<String>,
count: Int
): CountableCriterion<BattleCountableContext>(playerCtx, count) {
class BattleCountableCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<BattleCountableContext>(id, predicate) {
private var battleTypes = mutableListOf("any")
override fun fromJson(json: JsonObject) {
super.fromJson(json)
if(!json.get("battle_types").isJsonNull) {
battleTypes.clear()
json.get("battle_types").asJsonArray.asList().forEach() {
battleTypes.add(it.asString)
}
}
}
override fun toJson(json: JsonObject) {
super.toJson(json)
json.add("battle_types", battleTypes.toJsonArray())
companion object {
val CODEC: Codec<BattleCountableCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(LootContextPredicate.CODEC, "player").forGetter(BattleCountableCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.STRING.listOf(), "battle_types", listOf("any")).forGetter(BattleCountableCriterion::battleTypes),
Codecs.createStrictOptionalFieldCodec(Codec.INT, "count", 0).forGetter(BattleCountableCriterion::count)
).apply(it, ::BattleCountableCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: BattleCountableContext): Boolean {
var typeCheck = false
val advancementData = Cobblemon.playerData.get(player).advancementData
if (battleTypes.isEmpty() || battleTypes.contains("any")) {
typeCheck = true
}
if (battleTypes.contains("pvp")) {
typeCheck = context.battle.isPvP
context.times = advancementData.totalPvPBattleVictoryCount
}
if (battleTypes.contains("pvw")) {
typeCheck = context.battle.isPvW
context.times = advancementData.totalPvWBattleVictoryCount
}
if (battleTypes.contains("pvn")) {
typeCheck = context.battle.isPvN
context.times = advancementData.totalPvWBattleVictoryCount
}
if (battleTypes.size > 1) {
context.times = advancementData.totalBattleVictoryCount
}
return context.times >= count && typeCheck
return typeCheck && super.matches(player, context)
}
}
open class BattleCountableContext(times : Int, var battle : PokemonBattle) : CountableContext(times)
//open class BattleCountableCriterionTrigger(identifier: Identifier, criterionClass: Class<BattleCountableCriterion>) : SimpleCriterionTrigger<BattleCountableContext, BattleCountableCriterion>(identifier, criterionClass) {
//
//}
//
//class BattleCountableCriterion(id: Identifier, predicate: LootContextPredicate) : CountableCriterion<BattleCountableContext>(id, predicate) {
//
// private var battleTypes = mutableListOf("any")
//
// override fun fromJson(json: JsonObject) {
// super.fromJson(json)
// if(!json.get("battle_types").isJsonNull) {
// battleTypes.clear()
// json.get("battle_types").asJsonArray.asList().forEach() {
// battleTypes.add(it.asString)
// }
// }
// }
//
// override fun toJson(json: JsonObject) {
// super.toJson(json)
// json.add("battle_types", battleTypes.toJsonArray())
// }
//
// override fun matches(player: ServerPlayerEntity, context: BattleCountableContext): Boolean {
// var typeCheck = false
// val advancementData = Cobblemon.playerData.get(player).advancementData
// if (battleTypes.isEmpty() || battleTypes.contains("any")) {
// typeCheck = true
// }
// if (battleTypes.contains("pvp")) {
// typeCheck = context.battle.isPvP
// context.times = advancementData.totalPvPBattleVictoryCount
// }
// if (battleTypes.contains("pvw")) {
// typeCheck = context.battle.isPvW
// context.times = advancementData.totalPvWBattleVictoryCount
// }
// if (battleTypes.contains("pvn")) {
// typeCheck = context.battle.isPvN
// context.times = advancementData.totalPvWBattleVictoryCount
// }
// if (battleTypes.size > 1) {
// context.times = advancementData.totalBattleVictoryCount
// }
// return context.times >= count && typeCheck
// }
//}
@@ -8,10 +8,13 @@
package com.cobblemon.mod.common.advancement.criterion
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
/**
* A context that is used when you require a [CountableContext] along with some type string.
@@ -21,19 +24,38 @@ import net.minecraft.util.Identifier
*/
open class CountablePokemonTypeContext(times: Int, var type: String) : CountableContext(times)
class CaughtPokemonCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountablePokemonTypeContext>(id, predicate) {
var type = "any"
override fun toJson(json: JsonObject) {
super.toJson(json)
json.addProperty("type", type)
}
class CaughtPokemonCriterion(
playerCtx: Optional<LootContextPredicate>,
val type: String,
count: Int
): CountableCriterion<CountablePokemonTypeContext>(playerCtx, count) {
override fun fromJson(json: JsonObject) {
super.fromJson(json)
type = json.get("type")?.asString ?: "any"
companion object {
val CODEC: Codec<CaughtPokemonCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(CaughtPokemonCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "type", "any").forGetter(CaughtPokemonCriterion::type),
Codecs.createStrictOptionalFieldCodec(Codec.INT, "count", 0).forGetter(CaughtPokemonCriterion::count)
).apply(it, ::CaughtPokemonCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: CountablePokemonTypeContext): Boolean {
return super.matches(player, context) && (context.type == type || type == "any")
}
}
}
//class CaughtPokemonCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountablePokemonTypeContext>(id, predicate) {
// var type = "any"
// override fun toJson(json: JsonObject) {
// super.toJson(json)
// json.addProperty("type", type)
// }
//
// override fun fromJson(json: JsonObject) {
// super.fromJson(json)
// type = json.get("type")?.asString ?: "any"
// }
//
// override fun matches(player: ServerPlayerEntity, context: CountablePokemonTypeContext): Boolean {
// return super.matches(player, context) && (context.type == type || type == "any")
// }
//}
@@ -8,48 +8,69 @@
package com.cobblemon.mod.common.advancement.criterion
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
/**
* A type of advancement criterion condition that requires some number of completions. This can be extended to add
* more conditions than just the count.
*
* @author Hiroku
* @since November 4th, 2022
*/
abstract class CountableCriterionCondition<T : CountableContext>(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<T>(id, predicate) {
var count = 0
override fun fromJson(json: JsonObject) {
count = json.get("count")?.asInt ?: 0
}
open class CountableContext(var times: Int)
override fun toJson(json: JsonObject) {
json.addProperty("count", count)
open class CountableCriterion<T : CountableContext>(
playerCtx: Optional<LootContextPredicate>,
val count: Int
): SimpleCriterionCondition<T>(playerCtx) {
companion object {
val CODEC: Codec<CountableCriterion<CountableContext>> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(CountableCriterion<CountableContext>::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.INT, "count", 0).forGetter(CountableCriterion<CountableContext>::count)
).apply(it, ::CountableCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: T) = context.times >= count
}
/**
* A concrete subclass of [CountableCriterionCondition] so that you can have advancements that really just need the
* count and nothing else.
*
* This is just a quirk of using generics like this, don't worry about it. The criterion conditions that get used must
* not be generic typed.
*
* @author Hiroku
* @since November 4th, 2022
*/
class SimpleCountableCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountableContext>(id, predicate)
fun SimpleCriterionTrigger<CountableContext, SimpleCountableCriterionCondition>.trigger(player: ServerPlayerEntity, times: Int) = trigger(player, CountableContext(times))
/**
* Some type of context that has a count associated with it, representing how many times the trigger has occurred.
*
* @author Hiroku
* @since November 4th, 2022
*/
open class CountableContext(var times: Int)
///**
// * A type of advancement criterion condition that requires some number of completions. This can be extended to add
// * more conditions than just the count.
// *
// * @author Hiroku
// * @since November 4th, 2022
// */
//abstract class CountableCriterionCondition<T : CountableContext>(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<T>(id, predicate) {
// var count = 0
// override fun fromJson(json: JsonObject) {
// count = json.get("count")?.asInt ?: 0
// }
//
// override fun toJson(json: JsonObject) {
// json.addProperty("count", count)
// }
//
// override fun matches(player: ServerPlayerEntity, context: T) = context.times >= count
//}
//
///**
// * A concrete subclass of [CountableCriterionCondition] so that you can have advancements that really just need the
// * count and nothing else.
// *
// * This is just a quirk of using generics like this, don't worry about it. The criterion conditions that get used must
// * not be generic typed.
// *
// * @author Hiroku
// * @since November 4th, 2022
// */
//class SimpleCountableCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountableContext>(id, predicate)
//fun SimpleCriterionTrigger<CountableContext, SimpleCountableCriterionCondition>.trigger(player: ServerPlayerEntity, times: Int) = trigger(player, CountableContext(times))
//
///**
// * Some type of context that has a count associated with it, representing how many times the trigger has occurred.
// *
// * @author Hiroku
// * @since November 4th, 2022
// */
//open class CountableContext(var times: Int)
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
class EvolvePokemonContext(val species : Identifier, val evolution : Identifier, times: Int) : CountableContext(times)
class EvolvePokemonCriterion(
playerCtx: Optional<LootContextPredicate>,
val species: String,
val evolution: String,
count: Int
): CountableCriterion<EvolvePokemonContext>(playerCtx, count) {
companion object {
val CODEC: Codec<EvolvePokemonCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(LootContextPredicate.CODEC, "player").forGetter(EvolvePokemonCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "species", "any").forGetter(EvolvePokemonCriterion::species),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "evolution", "any").forGetter(EvolvePokemonCriterion::evolution),
Codecs.createStrictOptionalFieldCodec(Codec.INT, "count", 0).forGetter(EvolvePokemonCriterion::count)
).apply(it, ::EvolvePokemonCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: EvolvePokemonContext): Boolean {
return context.times >= count && (context.species == species.asIdentifierDefaultingNamespace() || species == "any") &&
(context.evolution == evolution.asIdentifierDefaultingNamespace() || evolution == "any")
}
}
//class EvolvePokemonCriterion(id: Identifier, entity: LootContextPredicate) : CountableCriterion<EvolvePokemonContext>(id, entity) {
// var species = "any"
// var evolution = "any"
// override fun toJson(json: JsonObject) {
// super.toJson(json)
// json.addProperty("species", species)
// json.addProperty("evolution", evolution)
// }
//
// override fun fromJson(json: JsonObject) {
// super.fromJson(json)
// species = json.get("species")?.asString ?: "any"
// evolution = json.get("evolution")?.asString ?: "any"
// }
//
// override fun matches(player: ServerPlayerEntity, context: EvolvePokemonContext): Boolean {
// return context.times >= count && (context.species == species.asIdentifierDefaultingNamespace() || species == "any") &&
// (context.evolution == evolution.asIdentifierDefaultingNamespace() || evolution == "any")
// }
//}
//
//open class EvolvePokemonContext(val species : Identifier, val evolution : Identifier, times: Int) : CountableContext(times)
@@ -1,38 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonObject
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
class EvolvePokemonCriterionCondition(id: Identifier, entity: LootContextPredicate) : CountableCriterionCondition<EvolvePokemonContext>(id, entity) {
var species = "any"
var evolution = "any"
override fun toJson(json: JsonObject) {
super.toJson(json)
json.addProperty("species", species)
json.addProperty("evolution", evolution)
}
override fun fromJson(json: JsonObject) {
super.fromJson(json)
species = json.get("species")?.asString ?: "any"
evolution = json.get("evolution")?.asString ?: "any"
}
override fun matches(player: ServerPlayerEntity, context: EvolvePokemonContext): Boolean {
return context.times >= count && (context.species == species.asIdentifierDefaultingNamespace() || species == "any") &&
(context.evolution == evolution.asIdentifierDefaultingNamespace() || evolution == "any")
}
}
open class EvolvePokemonContext(val species : Identifier, val evolution : Identifier, times: Int) : CountableContext(times)
@@ -9,12 +9,43 @@
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.pokemon.Pokemon
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
class LevelUpCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<LevelUpContext>(id, entity) {
class LevelUpContext(val level: Int, val pokemon: Pokemon)
class LevelUpCriterion(
playerCtx: Optional<LootContextPredicate>,
val level: Int,
val evolved: Boolean
): SimpleCriterionCondition<LevelUpContext>(playerCtx) {
companion object {
val CODEC: Codec<LevelUpCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(LevelUpCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.INT, "level", 0).forGetter(LevelUpCriterion::level),
Codecs.createStrictOptionalFieldCodec(Codec.BOOL, "evolved", true).forGetter(LevelUpCriterion::evolved)
).apply(it, ::LevelUpCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: LevelUpContext): Boolean {
val preEvo = context.pokemon.preEvolution == null
val hasEvolution = !context.pokemon.evolutions.none()
var evolutionCheck = true
if (preEvo || hasEvolution) {
evolutionCheck = preEvo != hasEvolution
}
return level == context.level && evolutionCheck == evolved
}
}
/*class LevelUpCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<LevelUpContext>(id, entity) {
var level = 0
var evolved = true
override fun toJson(json: JsonObject) {
@@ -36,6 +67,4 @@ class LevelUpCriterionCondition(id: Identifier, entity: LootContextPredicate) :
}
return level == context.level && evolutionCheck == evolved
}
}
open class LevelUpContext(var level : Int, var pokemon : Pokemon)
}*/
@@ -10,14 +10,62 @@ package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.party
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
class PartyCheckCriterion(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<PartyCheckContext>(id, entity){
class PartyCheckCriterion(
playerCtx: Optional<LootContextPredicate>,
val party: List<Identifier>,
): SimpleCriterionCondition<PlayerPartyStore>(playerCtx) {
companion object {
val CODEC: Codec<PartyCheckCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(PartyCheckCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Identifier.CODEC.listOf(), "id", listOf()).forGetter(PartyCheckCriterion::party)
).apply(it, ::PartyCheckCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: PlayerPartyStore): Boolean {
val matches = mutableListOf<Identifier>()
party.forEach {
if (it == "any".asIdentifierDefaultingNamespace()) {
matches.add(it)
}
}
val partyCount = context.count()
if (matches.containsAll(party) && party.size == partyCount && matches.size == partyCount) return true
context.iterator().forEach {
if (party.contains(it.species.resourceIdentifier)) {
matches.add(it.species.resourceIdentifier)
}
}
return matches.containsAll(party) && matches.size == partyCount
}
}
/*class PartyCheckCriterion(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<PartyCheckContext>(id, entity){
val party = mutableListOf<Identifier>()
override fun toJson(json: JsonObject) {
json.add("party", JsonArray(party.size).also {
@@ -51,4 +99,4 @@ class PartyCheckCriterion(id: Identifier, entity: LootContextPredicate) : Simple
}
}
open class PartyCheckContext(val party : PlayerPartyStore)
open class PartyCheckContext(val party : PlayerPartyStore)*/
@@ -10,26 +10,27 @@ package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.pokemon.Pokemon
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
/**
* A criteria that is triggered when a player picks a starter.
*
* @author Licious, Hiroku
* @since October 26th, 2022
*/
class PickStarterCriterionCondition(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<Pokemon>(id, predicate) {
var properties = PokemonProperties()
override fun toJson(json: JsonObject) {
json.addProperty("properties", properties.originalString)
class PokemonCriterion(
playerCtx: Optional<LootContextPredicate>,
val properties: PokemonProperties
): SimpleCriterionCondition<Pokemon>(playerCtx) {
companion object {
val CODEC: Codec<PokemonCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(PokemonCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(PokemonProperties.CODEC, "properties", PokemonProperties()).forGetter(PokemonCriterion::properties)
).apply(it, ::PokemonCriterion) }
}
override fun fromJson(json: JsonObject) {
properties = PokemonProperties.parse(json.get("properties")?.asString ?: "")
override fun matches(player: ServerPlayerEntity, context: Pokemon): Boolean {
return properties.matches(context)
}
override fun matches(player: ServerPlayerEntity, context: Pokemon) = properties.matches(context)
}
@@ -9,44 +9,63 @@
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.block.TumblestoneBlock
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import net.minecraft.util.math.BlockPos
import java.util.Optional
/**
* A criterion condition for when a tumblestone block is planted
* @param id The identifier of the criterion
* @param predicate The predicate for the criterion
*
* @author Aethen
* @since 02/28/2024
*/
class PlantTumblestoneCriterionCondition(id: Identifier, predicate: LootContextPredicate) :
SimpleCriterionCondition<PlantTumblestoneContext>(id, predicate) {
override fun toJson(json: JsonObject) {
// Add properties to json if needed. None needed for this criterion
class PlantTumblestoneContext(val pos: BlockPos, val block: TumblestoneBlock)
class PlantTumblestoneCriterion(
playerCtx: Optional<LootContextPredicate>
): SimpleCriterionCondition<PlantTumblestoneContext>(playerCtx) {
companion object {
val CODEC: Codec<PlantTumblestoneCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(LootContextPredicate.CODEC, "player").forGetter(PlantTumblestoneCriterion::playerCtx)
).apply(it, ::PlantTumblestoneCriterion) }
}
override fun fromJson(json: JsonObject) {
// Parse properties from json if needed. None needed for this criterion
}
/**
* Checks if the tumblestone block can grow at the given position
* @param player The player that planted the tumblestone block
* @param context The context of the criterion
* @return True if the tumblestone block can grow at the given position, false otherwise
*/
override fun matches(player: ServerPlayerEntity, context: PlantTumblestoneContext): Boolean {
return context.tumbleStoneBlock.canGrow(context.pos, player.world)
return context.block.canGrow(context.pos, player.world)
}
}
/**
* The context of the [PlantTumblestoneCriterionCondition]
* @param pos The position of the tumblestone block
* @param tumbleStoneBlock The tumblestone block
*/
open class PlantTumblestoneContext(var pos: BlockPos, var tumbleStoneBlock: TumblestoneBlock)
///**
// * A criterion condition for when a tumblestone block is planted
// * @param id The identifier of the criterion
// * @param predicate The predicate for the criterion
// *
// * @author Aethen
// * @since 02/28/2024
// */
//class PlantTumblestoneCriterionCondition(id: Identifier, predicate: LootContextPredicate) :
// SimpleCriterionCondition<PlantTumblestoneContext>(id, predicate) {
// override fun toJson(json: JsonObject) {
// // Add properties to json if needed. None needed for this criterion
// }
//
// override fun fromJson(json: JsonObject) {
// // Parse properties from json if needed. None needed for this criterion
// }
//
// /**
// * Checks if the tumblestone block can grow at the given position
// * @param player The player that planted the tumblestone block
// * @param context The context of the criterion
// * @return True if the tumblestone block can grow at the given position, false otherwise
// */
// override fun matches(player: ServerPlayerEntity, context: PlantTumblestoneContext): Boolean {
// return context.tumbleStoneBlock.canGrow(context.pos, player.world)
// }
//}
//
///**
// * The context of the [PlantTumblestoneCriterionCondition]
// * @param pos The position of the tumblestone block
// * @param tumbleStoneBlock The tumblestone block
// */
//open class PlantTumblestoneContext(var pos: BlockPos, var tumbleStoneBlock: TumblestoneBlock)
@@ -9,26 +9,33 @@
package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
open class PokemonInteractContext(var type: Identifier, var item : Identifier)
class PokemonInteractCriterion(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<PokemonInteractContext>(id, entity) {
var type = "any"
var item = "any"
override fun toJson(json: JsonObject) {
json.addProperty("type", type)
json.addProperty("item", item)
}
class PokemonInteractContext(val type: Identifier, val item: Identifier)
override fun fromJson(json: JsonObject) {
type = json.get("type")?.asString ?: "any"
item = json.get("item")?.asString ?: "any"
class PokemonInteractCriterion(
playerCtx: Optional<LootContextPredicate>,
val type: Optional<String>,
val item: Optional<String>
): SimpleCriterionCondition<PokemonInteractContext>(playerCtx) {
companion object {
val CODEC: Codec<PokemonInteractCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(PokemonInteractCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "type").forGetter(PokemonInteractCriterion::type),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "item").forGetter(PokemonInteractCriterion::item)
).apply(it, ::PokemonInteractCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: PokemonInteractContext): Boolean {
return (context.type == type.asIdentifierDefaultingNamespace() || type == "any") && (context.item == item.asIdentifierDefaultingNamespace() || item == "any")
val otherType = this.type.orElse("any")
val otherItem = this.item.orElse("any")
return (context.type == otherType.asIdentifierDefaultingNamespace() || otherType == "any") && (context.type == otherItem.asIdentifierDefaultingNamespace() || otherItem == "any")
}
}
@@ -8,61 +8,28 @@
package com.cobblemon.mod.common.advancement.criterion
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import net.minecraft.advancement.criterion.AbstractCriterion
import net.minecraft.advancement.criterion.AbstractCriterionConditions
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer
import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import java.util.Optional
/**
* A wrapping around the AbstractCriterion system of Minecraft. This allows the same base class to be used
* for all advancements by wrapping the advancement-specific contextual data in the generic T, the instance of
* the advancement conditions in the generic C, and allowing the condition to do all serialization, deserialization,
* and matching of context against conditions.
*
* @author Hiroku
* @since November 4th, 2022
*/
open class SimpleCriterionTrigger<T, C : SimpleCriterionCondition<T>>(
val _id: Identifier,
val criterionClass: Class<C>
class SimpleCriterionTrigger<T, C : SimpleCriterionCondition<T>>(
val codec: Codec<C>,
) : AbstractCriterion<C>() {
override fun getId() = _id
override fun conditionsFromJson(
obj: JsonObject,
playerPredicate: LootContextPredicate,
predicateDeserializer: AdvancementEntityPredicateDeserializer
): C {
val instance = criterionClass.getConstructor(Identifier::class.java, LootContextPredicate::class.java).newInstance(id, playerPredicate)
instance.fromJson(obj)
return instance
}
override fun getConditionsCodec() = codec
fun trigger(player: ServerPlayerEntity, context: T) = this.trigger(player) { it.matches(player, context) }
fun trigger(player: ServerPlayerEntity, context: T) {
return this.trigger(player) {
it.matches(player, context)
}
}
}
/**
* The base of the conditions for Cobblemon's wrapping around Minecraft advancements. This is parameterized by whatever
* contextual information this condition needs to be checked, and must handle serialization and deserialization from JSON.
*
* @author Hiroku
* @since November 4th, 2022
*/
abstract class SimpleCriterionCondition<T>(
id: Identifier,
playerPredicate: LootContextPredicate
): AbstractCriterionConditions(id, playerPredicate) {
override fun toJson(predicateSerializer: AdvancementEntityPredicateSerializer): JsonObject {
val json = super.toJson(predicateSerializer)
toJson(json)
return json
}
abstract fun toJson(json: JsonObject)
abstract fun fromJson(json: JsonObject)
val playerCtx: Optional<LootContextPredicate>
) : AbstractCriterion.Conditions {
override fun player() = playerCtx
abstract fun matches(player: ServerPlayerEntity, context: T): Boolean
}
@@ -10,12 +10,59 @@ package com.cobblemon.mod.common.advancement.criterion
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.predicate.entity.EntityPredicate
import net.minecraft.predicate.entity.LootContextPredicate
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.dynamic.Codecs
import java.util.Optional
class TradePokemonCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<TradePokemonContext>(id, entity) {
class TradePokemonContext(val traded: Pokemon, val received: Pokemon)
class TradePokemonCriterion(
playerCtx: Optional<LootContextPredicate>,
val traded: String,
val received: String,
val tradedHeldItem: String,
val receivedHeldItem: String
): SimpleCriterionCondition<TradePokemonContext>(playerCtx) {
companion object {
val CODEC: Codec<TradePokemonCriterion> = RecordCodecBuilder.create { it.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(TradePokemonCriterion::playerCtx),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "traded", "any").forGetter(TradePokemonCriterion::traded),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "received", "any").forGetter(TradePokemonCriterion::received),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "traded_held_item", "minecraft:air").forGetter(TradePokemonCriterion::tradedHeldItem),
Codecs.createStrictOptionalFieldCodec(Codec.STRING, "received_held_item", "minecraft:air").forGetter(TradePokemonCriterion::receivedHeldItem)
).apply(it, ::TradePokemonCriterion) }
}
override fun matches(player: ServerPlayerEntity, context: TradePokemonContext): Boolean {
val heldItem1 = context.traded.heldItem().item.registryEntry.registryKey().value
val heldItem2 = context.received.heldItem().item.registryEntry.registryKey().value
if (traded != "any" && context.traded.species.resourceIdentifier != traded.asIdentifierDefaultingNamespace()) {
return false
}
if (received != "any" && context.received.species.resourceIdentifier != received.asIdentifierDefaultingNamespace()) {
return false
}
if (heldItem1 != tradedHeldItem.asIdentifierDefaultingNamespace() && heldItem1 != "minecraft:air".asIdentifierDefaultingNamespace()) {
return false
}
if (heldItem2 != receivedHeldItem.asIdentifierDefaultingNamespace() && heldItem2 != "minecraft:air".asIdentifierDefaultingNamespace()) {
return false
}
return true
}
}
/*class TradePokemonCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<TradePokemonContext>(id, entity) {
var traded = "any"
var received = "any"
var tradedHeldItem = "any"
@@ -44,4 +91,4 @@ class TradePokemonCriterionCondition(id: Identifier, entity: LootContextPredicat
}
}
open class TradePokemonContext(val traded: Pokemon, val received: Pokemon)
open class TradePokemonContext(val traded: Pokemon, val received: Pokemon)*/
@@ -13,8 +13,13 @@ import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.block.ApricornBlock
import com.cobblemon.mod.common.block.ApricornSaplingBlock
import com.cobblemon.mod.common.item.ApricornItem
import com.cobblemon.mod.common.world.feature.CobblemonConfiguredFeatures
import com.mojang.serialization.Codec
import net.minecraft.block.MapColor
import net.minecraft.item.BlockItem
import net.minecraft.registry.RegistryKey
import net.minecraft.util.StringIdentifiable
import net.minecraft.world.gen.feature.ConfiguredFeature
/**
* Contains the different Apricorn variants and util methods to get their item, block, seedling and sapling form.
@@ -22,7 +27,7 @@ import net.minecraft.item.BlockItem
* @author Licious
* @since October 29th, 2022
*/
enum class Apricorn {
enum class Apricorn : StringIdentifiable {
BLACK,
BLUE,
@@ -82,4 +87,20 @@ enum class Apricorn {
YELLOW -> MapColor.YELLOW
}
fun configuredFeature(): RegistryKey<ConfiguredFeature<*, *>> = when(this) {
BLACK -> CobblemonConfiguredFeatures.BLACK_APRICORN_TREE_KEY
BLUE -> CobblemonConfiguredFeatures.BLUE_APRICORN_TREE_KEY
GREEN -> CobblemonConfiguredFeatures.GREEN_APRICORN_TREE_KEY
PINK -> CobblemonConfiguredFeatures.PINK_APRICORN_TREE_KEY
RED -> CobblemonConfiguredFeatures.RED_APRICORN_TREE_KEY
WHITE -> CobblemonConfiguredFeatures.WHITE_APRICORN_TREE_KEY
YELLOW -> CobblemonConfiguredFeatures.YELLOW_APRICORN_TREE_KEY
}
override fun asString() = this.name.lowercase()
companion object {
val CODEC: Codec<Apricorn> = StringIdentifiable.createBasicCodec(::values)
}
}
@@ -497,4 +497,4 @@ open class PokemonBattle(
return queryStruct
}
}
}
@@ -48,7 +48,7 @@ object Berries : JsonDataRegistry<Berry> {
.disableHtmlEscaping()
.setPrettyPrinting()
.registerTypeAdapter(MulchVariant::class.java, MulchVariantAdapter)
.registerTypeAdapter(NumberRange.FloatRange::class.java, FloatNumberRangeAdapter)
.registerTypeAdapter(NumberRange.DoubleRange::class.java, FloatNumberRangeAdapter)
.registerTypeAdapter(Status::class.java, StatusAdapter)
.registerTypeAdapter(TypeToken.getParameterized(Collection::class.java, Box::class.java).type, BoxCollectionAdapter)
.registerTypeAdapter(Box::class.java, BoxAdapter)
@@ -103,4 +103,4 @@ object Berries : JsonDataRegistry<Berry> {
*/
fun getByName(name: String): Berry? = this.getByIdentifier(cobblemonResource(name))
}
}
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.fossil
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.pokemon.evolution.predicate.NbtItemPredicate
import net.minecraft.item.ItemStack
import net.minecraft.registry.Registries
import net.minecraft.text.MutableText
import net.minecraft.text.Text
import net.minecraft.util.Identifier
@@ -48,7 +47,7 @@ class Fossil(
}
return this.fossils.all { fossil ->
ingredients.any { fossil.item.fits(it.item, Registries.ITEM) && fossil.nbt.test(it) }
ingredients.any { fossil.test(it) }
}
}
@@ -64,7 +63,7 @@ class Fossil(
return ingredients.all { ingredient ->
ingredients.count { item -> ingredient.itemMatches(item.registryEntry) } <=
this.fossils.count { fossil -> fossil.item.fits(ingredient.item, Registries.ITEM) && fossil.nbt.test(ingredient) }
this.fossils.count { fossil -> fossil.test(ingredient) }
}
}
@@ -74,7 +73,7 @@ class Fossil(
* @return True if the [ItemStack] is an ingredient, false otherwise.
*/
fun isIngredient(itemStack: ItemStack): Boolean {
return this.fossils.any { it.item.fits(itemStack.item, Registries.ITEM) && it.nbt.test(itemStack) }
return this.fossils.any { it.test(itemStack) }
}
}
@@ -47,10 +47,10 @@ abstract class ParentWidget(
super.mouseMoved(pMouseX, pMouseY)
}
override fun mouseScrolled(pMouseX: Double, pMouseY: Double, pDelta: Double): Boolean {
override fun mouseScrolled(mouseX: Double, mouseY: Double, horizontalAmount: Double, verticalAmount: Double): Boolean {
return children.any {
it.mouseScrolled(pMouseX, pMouseY, pDelta)
} || super.mouseScrolled(pMouseX, pMouseY, pDelta)
it.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)
} || super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)
}
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
@@ -19,8 +19,8 @@ import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunctions
import com.cobblemon.mod.common.util.effectiveName
import com.cobblemon.mod.common.util.isInt
import com.cobblemon.mod.common.util.itemRegistry
import net.minecraft.block.Block
@@ -102,7 +102,7 @@ object MoLangFunctions {
fun ServerPlayerEntity.asMoLangValue(): ObjectValue<ServerPlayerEntity> {
val value = ObjectValue(
obj = this,
stringify = { it.entityName }
stringify = { it.effectiveName().string }
)
value.addFunctions(playerFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
return value
@@ -62,7 +62,7 @@ object ActionEffects : JsonDataRegistry<ActionEffectTimeline> {
.disableHtmlEscaping()
.setPrettyPrinting()
.registerTypeAdapter(ActionEffectKeyframe::class.java, ActionEffectKeyframeAdapter)
.registerTypeAdapter(NumberRange.FloatRange::class.java, FloatNumberRangeAdapter)
.registerTypeAdapter(NumberRange.DoubleRange::class.java, FloatNumberRangeAdapter)
.registerTypeAdapter(TypeToken.getParameterized(Collection::class.java, Box::class.java).type, BoxCollectionAdapter)
.registerTypeAdapter(Box::class.java, BoxAdapter)
.registerTypeAdapter(Vec3d::class.java, VerboseVec3dAdapter)
@@ -36,7 +36,7 @@ class MoveToTargetActionEffectKeyframe : ActionEffectKeyframe {
var timedOut = false
val proximity = this.proximity.takeIf { it != -1F } ?: (sqrt(2 * user.boundingBox.xLength.pow(2)) + 1.5F + sqrt(2 * target.boundingBox.xLength.pow(2))).toFloat()
val proximity = this.proximity.takeIf { it != -1F } ?: (sqrt(2 * user.boundingBox.lengthX.pow(2)) + 1.5F + sqrt(2 * target.boundingBox.lengthX.pow(2))).toFloat()
if (target.distanceTo(user) !in proximity..20F) {
future.complete(Unit)
@@ -9,7 +9,9 @@
package com.cobblemon.mod.common.api.multiblock
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
import net.minecraft.block.*
import net.minecraft.block.BlockRenderType
import net.minecraft.block.BlockState
import net.minecraft.block.BlockWithEntity
import net.minecraft.block.entity.BlockEntity
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.player.PlayerEntity
@@ -19,8 +21,8 @@ import net.minecraft.util.ActionResult
import net.minecraft.util.Hand
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.minecraft.world.WorldView
/**
* A block that can be part of a [MultiblockStructure]
@@ -59,14 +61,15 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
return super.onUse(state, world, pos, player, hand, hit)
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
super.onBreak(world, pos, state, player)
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?): BlockState {
val result = super.onBreak(world, pos, state, player)
if (!world.isClient) {
val entity = world.getBlockEntity(pos)
if (entity is MultiblockEntity && entity.multiblockStructure != null) {
entity.multiblockStructure!!.onBreak(world, pos, state, player)
}
}
return result
}
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity? {
@@ -78,11 +81,11 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
return BlockRenderType.MODEL
}
override fun getPickStack(world: BlockView, pos: BlockPos, state: BlockState): ItemStack {
override fun getPickStack(world: WorldView, pos: BlockPos, state: BlockState): ItemStack {
val blockEntity = world.getBlockEntity(pos) as? MultiblockEntity ?: return ItemStack.EMPTY
return if (blockEntity.multiblockStructure == null) super.getPickStack(world, pos, state) else ItemStack.EMPTY
}
abstract fun createMultiBlockEntity(pos: BlockPos, state: BlockState): FossilMultiblockEntity
}
}
@@ -43,6 +43,6 @@ interface MultiblockStructure {
return 0
}
fun markRemoved(world: World):Unit
fun markRemoved(world: World)
fun onTriggerEvent(state: BlockState?, world: ServerWorld?, pos: BlockPos?, random: Random?)
}
@@ -27,6 +27,7 @@ import com.cobblemon.mod.common.pokemon.status.PersistentStatus
import com.cobblemon.mod.common.util.*
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import kotlin.random.Random
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement
@@ -54,6 +55,11 @@ import java.util.UUID
*/
open class PokemonProperties {
companion object {
val CODEC: Codec<PokemonProperties> = Codec.STRING.xmap(
{ parse(it) },
{ it.originalString }
)
@JvmOverloads
fun parse(string: String, delimiter: String = " ", assigner: String = "="): PokemonProperties {
val props = PokemonProperties()
@@ -496,7 +502,7 @@ open class PokemonProperties {
shiny?.let { nbt.putBoolean(DataKeys.POKEMON_SHINY, it) }
gender?.let { nbt.putString(DataKeys.POKEMON_GENDER, it.name) }
species?.let { nbt.putString(DataKeys.POKEMON_SPECIES_TEXT, it) }
nickname?.let { nbt.putString(DataKeys.POKEMON_NICKNAME, Text.Serializer.toJson(it)) }
nickname?.let { nbt.putString(DataKeys.POKEMON_NICKNAME, Text.Serialization.toJsonString(it)) }
form?.let { nbt.putString(DataKeys.POKEMON_FORM_ID, it) }
friendship?.let { nbt.putInt(DataKeys.POKEMON_FRIENDSHIP, it) }
pokeball?.let { nbt.putString(DataKeys.POKEMON_CAUGHT_BALL, it) }
@@ -524,7 +530,7 @@ open class PokemonProperties {
shiny = if (tag.contains(DataKeys.POKEMON_SHINY)) tag.getBoolean(DataKeys.POKEMON_SHINY) else null
gender = if (tag.contains(DataKeys.POKEMON_GENDER)) Gender.valueOf(tag.getString(DataKeys.POKEMON_GENDER)) else null
species = if (tag.contains(DataKeys.POKEMON_SPECIES_TEXT)) tag.getString(DataKeys.POKEMON_SPECIES_TEXT) else null
nickname = if (tag.contains(DataKeys.POKEMON_NICKNAME)) Text.Serializer.fromJson(tag.getString(DataKeys.POKEMON_NICKNAME)) else null
nickname = if (tag.contains(DataKeys.POKEMON_NICKNAME)) Text.Serialization.fromJson(tag.getString(DataKeys.POKEMON_NICKNAME)) else null
form = if (tag.contains(DataKeys.POKEMON_FORM_ID)) tag.getString(DataKeys.POKEMON_FORM_ID) else null
friendship = if (tag.contains(DataKeys.POKEMON_FRIENDSHIP)) tag.getInt(DataKeys.POKEMON_FRIENDSHIP) else null
pokeball = if (tag.contains(DataKeys.POKEMON_CAUGHT_BALL)) tag.getString(DataKeys.POKEMON_CAUGHT_BALL) else null
@@ -554,7 +560,7 @@ open class PokemonProperties {
shiny?.let { json.addProperty(DataKeys.POKEMON_SHINY, it) }
gender?.let { json.addProperty(DataKeys.POKEMON_GENDER, it.name) }
species?.let { json.addProperty(DataKeys.POKEMON_SPECIES_TEXT, it) }
nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, Text.Serializer.toJson(it)) }
nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, Text.Serialization.toJsonString(it)) }
form?.let { json.addProperty(DataKeys.POKEMON_FORM_ID, it) }
friendship?.let { json.addProperty(DataKeys.POKEMON_FRIENDSHIP, it) }
pokeball?.let { json.addProperty(DataKeys.POKEMON_CAUGHT_BALL, it) }
@@ -583,7 +589,7 @@ open class PokemonProperties {
shiny = json.get(DataKeys.POKEMON_SHINY)?.asBoolean
gender = json.get(DataKeys.POKEMON_GENDER)?.asString?.let { Gender.valueOf(it) }
species = json.get(DataKeys.POKEMON_SPECIES_TEXT)?.asString
nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let { Text.Serializer.fromJson(it) }
nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let { Text.Serialization.fromJson(it) }
form = json.get(DataKeys.POKEMON_FORM_ID)?.asString
friendship = json.get(DataKeys.POKEMON_FRIENDSHIP)?.asInt
pokeball = json.get(DataKeys.POKEMON_CAUGHT_BALL)?.asString
@@ -671,4 +677,4 @@ open class PokemonProperties {
return potentialAbility.template.create(false)
}
}
}
@@ -46,7 +46,7 @@ class ReforgedConversion(val base: Path) : CobblemonConverter<NbtCompound> {
return null
}
val nbt = NbtIo.read(target.toFile())
val nbt = NbtIo.read(target)
if(nbt != null) {
return (if (extension == "pk") party(uuid, nbt) else pc(uuid, nbt)) as T
}
@@ -14,6 +14,7 @@ import java.io.File
import java.util.UUID
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtIo
import net.minecraft.nbt.NbtSizeTracker
/**
* A [OneToOneFileStoreAdapter] that can arbitrarily save a single [PokemonStore] into an [NbtCompound] with the
@@ -29,7 +30,7 @@ open class NBTStoreAdapter(
folderPerClass: Boolean,
) : OneToOneFileStoreAdapter<NbtCompound>(rootFolder, useNestedFolders, folderPerClass, "dat") {
override fun <E : StorePosition, T : PokemonStore<E>> serialize(store: T) = store.saveToNBT(NbtCompound())
override fun save(file: File, serialized: NbtCompound) = NbtIo.writeCompressed(serialized, file)
override fun save(file: File, serialized: NbtCompound) = NbtIo.writeCompressed(serialized, file.toPath())
override fun <E, T : PokemonStore<E>> load(file: File, storeClass: Class<out T>, uuid: UUID): T? {
val store = try {
storeClass.getConstructor(UUID::class.java).newInstance(uuid)
@@ -37,7 +38,7 @@ open class NBTStoreAdapter(
storeClass.getConstructor(UUID::class.java).newInstance(uuid)
}
return try {
val nbt = NbtIo.readCompressed(file)
val nbt = NbtIo.readCompressed(file.toPath(), NbtSizeTracker.ofUnlimitedBytes())
store.loadFromNBT(nbt)
store
} catch (e: Exception) {
@@ -16,6 +16,7 @@ import java.nio.file.Path
import java.util.UUID
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtIo
import net.minecraft.nbt.NbtSizeTracker
import net.minecraft.util.WorldSavePath
object NbtMoLangDataStoreFactory : MoLangDataStoreFactory {
@@ -61,13 +62,13 @@ object NbtMoLangDataStoreFactory : MoLangDataStoreFactory {
cache[uuid]!!
else {
val file = this.file(uuid)
if (!file.exists()) {
if (!file.toFile().exists()) {
val data = VariableStruct()
cache[uuid] = data
return data
}
val nbt = NbtIo.readCompressed(file(uuid))
val nbt = NbtIo.readCompressed(file(uuid), NbtSizeTracker.ofUnlimitedBytes())
// If it's not a VariableStruct then someone's fucked around and will subsequently find out
val data = readMoValueFromNBT(nbt) as VariableStruct
@@ -80,10 +81,10 @@ object NbtMoLangDataStoreFactory : MoLangDataStoreFactory {
val file = file(uuid)
val data = cache[uuid] ?: return
val nbt = writeMoValueToNBT(data)!! as NbtCompound
file.parentFile.mkdirs()
file.toFile().parentFile.mkdirs()
NbtIo.writeCompressed(nbt, file)
dirty -= uuid
}
private fun file(uuid: UUID) = savePath.resolve("playermolangdata/${uuid.toString().substring(0, 2)}/$uuid.dat").toFile()
private fun file(uuid: UUID) = savePath.resolve("playermolangdata/${uuid.toString().substring(0, 2)}/$uuid.dat")
}
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.storage.party
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.advancement.CobblemonCriteria
import com.cobblemon.mod.common.advancement.criterion.PartyCheckContext
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.pokemon.evolution.PassiveEvolution
import com.cobblemon.mod.common.api.storage.pc.PCStore
@@ -63,7 +62,7 @@ open class PlayerPartyStore(
pokemon.refreshOriginalTrainer()
return if (super.add(pokemon)) {
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, PartyCheckContext(this)) }
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, this) }
true
} else {
val player = playerUUID.getPlayer()
@@ -179,21 +178,21 @@ open class PlayerPartyStore(
if (pokemon1 != null && pokemon2 != null) {
val player = pokemon1.getOwnerPlayer()
if (player != null) {
CobblemonCriteria.PARTY_CHECK.trigger(player, PartyCheckContext(this))
CobblemonCriteria.PARTY_CHECK.trigger(player, this)
}
} else if (pokemon1 != null || pokemon2 != null) {
var player = pokemon1?.getOwnerPlayer()
if (player != null) {
CobblemonCriteria.PARTY_CHECK.trigger(player, PartyCheckContext(this))
CobblemonCriteria.PARTY_CHECK.trigger(player, this)
} else {
player = pokemon2!!.getOwnerPlayer()
CobblemonCriteria.PARTY_CHECK.trigger(player!!, PartyCheckContext(this))
CobblemonCriteria.PARTY_CHECK.trigger(player!!, this)
}
}
}
override fun set(position: PartyPosition, pokemon: Pokemon) {
super.set(position, pokemon)
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, PartyCheckContext(this)) }
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, this) }
}
}
@@ -8,7 +8,7 @@
package com.cobblemon.mod.common.api.storage.player
import com.cobblemon.mod.common.advancement.criterion.AspectCriterionCondition
import com.cobblemon.mod.common.advancement.criterion.AspectCriterion
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.network.ServerPlayerEntity
@@ -103,9 +103,9 @@ class PlayerAdvancementData {
fun updateAspectsCollected(player: ServerPlayerEntity, pokemon: Pokemon) {
val aspectConditions = player.advancementTracker.progress.keys
.flatMap { it.criteria.values }
.flatMap { it.value.criteria.values }
.mapNotNull { it.conditions }
.filterIsInstance<AspectCriterionCondition>()
.filterIsInstance<AspectCriterion>()
val trackedAspects = aspectConditions
.filter { it.pokemon == pokemon.species.resourceIdentifier }
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.battles
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
import com.cobblemon.mod.common.api.storage.party.PartyStore
@@ -18,15 +17,15 @@ import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.effectiveName
import com.cobblemon.mod.common.util.getBattleTheme
import com.cobblemon.mod.common.util.getPlayer
import com.cobblemon.mod.common.util.party
import java.util.Optional
import java.util.UUID
import net.minecraft.entity.Entity
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.text.MutableText
import net.minecraft.text.Text
import java.util.UUID
object BattleBuilder {
@JvmOverloads
@@ -170,8 +169,8 @@ interface BattleStartError {
fun getMessageFor(entity: Entity): MutableText
companion object {
fun alreadyInBattle(player: ServerPlayerEntity) = AlreadyInBattleError(player.uuid, player.displayName)
fun alreadyInBattle(pokemonEntity: PokemonEntity) = AlreadyInBattleError(pokemonEntity.uuid, pokemonEntity.displayName)
fun alreadyInBattle(player: ServerPlayerEntity) = AlreadyInBattleError(player.uuid, player.effectiveName())
fun alreadyInBattle(pokemonEntity: PokemonEntity) = AlreadyInBattleError(pokemonEntity.uuid, pokemonEntity.effectiveName())
fun alreadyInBattle(actor: BattleActor) = AlreadyInBattleError(actor.uuid, actor.getName())
fun targetIsBusy(targetName: MutableText) = BusyError(targetName)
@@ -211,7 +210,7 @@ class InsufficientPokemonError(
} else {
battleLang(
"error.insufficient_pokemon",
player.displayName,
player.effectiveName(),
requiredCount,
hadCount
)
@@ -26,7 +26,7 @@ import net.minecraft.world.biome.Biome
* @since December 2nd, 2022
*/
class BiomeDownfallGrowthFactor(
val range: NumberRange.FloatRange,
val range: NumberRange.DoubleRange,
val bonusYield: IntRange
) : GrowthFactor {
@@ -26,7 +26,7 @@ import net.minecraft.world.biome.Biome
* @since December 2nd, 2022
*/
class BiomeTemperatureGrowthFactor(
val range: NumberRange.FloatRange,
val range: NumberRange.DoubleRange,
val bonusYield: IntRange
) : GrowthFactor {
@@ -15,6 +15,8 @@ import com.cobblemon.mod.common.api.tags.CobblemonBlockTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.util.playSoundServer
import com.cobblemon.mod.common.util.toVec3d
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.*
import net.minecraft.entity.ItemEntity
import net.minecraft.entity.ai.pathing.NavigationType
@@ -111,7 +113,7 @@ class ApricornBlock(settings: Settings, val apricorn: Apricorn) : HorizontalFaci
else super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos)
}
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState, isClient: Boolean) = state.get(AGE) < MAX_AGE
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState) = state.get(AGE) < MAX_AGE
override fun canGrow(world: World, random: Random, pos: BlockPos, state: BlockState) = true
@@ -143,7 +145,7 @@ class ApricornBlock(settings: Settings, val apricorn: Apricorn) : HorizontalFaci
}
// We need to point back to the actual apricorn item, see SweetBerryBushBlock for example
override fun getPickStack(world: BlockView, pos: BlockPos, state: BlockState) = ItemStack(this.apricorn.item())
override fun getPickStack(world: WorldView, pos: BlockPos, state: BlockState) = ItemStack(this.apricorn.item())
private fun doHarvest(world: World, state: BlockState, pos: BlockPos, player: PlayerEntity) {
val resetState = this.harvest(world, state, pos)
@@ -188,7 +190,15 @@ class ApricornBlock(settings: Settings, val apricorn: Apricorn) : HorizontalFaci
return true
}
override fun getCodec(): MapCodec<out HorizontalFacingBlock> {
return CODEC
}
companion object {
val CODEC: MapCodec<ApricornBlock> = RecordCodecBuilder.mapCodec { it.group(
createSettingsCodec(),
Apricorn.CODEC.fieldOf("apricorn").forGetter(ApricornBlock::apricorn)
).apply(it, ::ApricornBlock) }
val AGE: IntProperty = Properties.AGE_3
const val MAX_AGE = Properties.AGE_3_MAX
@@ -10,5 +10,20 @@ package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.block.grower.ApricornTreeGrower
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.SaplingBlock
class ApricornSaplingBlock(properties : Settings, apricorn: Apricorn) : SaplingBlock(ApricornTreeGrower(apricorn), properties)
class ApricornSaplingBlock(properties : Settings, val apricorn: Apricorn) : SaplingBlock(ApricornTreeGrower(apricorn), properties) {
override fun getCodec(): MapCodec<out SaplingBlock> {
return CODEC
}
companion object {
val CODEC: MapCodec<ApricornSaplingBlock> = RecordCodecBuilder.mapCodec { it.group(
createSettingsCodec(),
Apricorn.CODEC.fieldOf("apricorn").forGetter(ApricornSaplingBlock::apricorn)
).apply(it, ::ApricornSaplingBlock) }
}
}
@@ -19,6 +19,8 @@ import com.cobblemon.mod.common.api.mulch.MulchVariant
import com.cobblemon.mod.common.api.mulch.Mulchable
import com.cobblemon.mod.common.api.tags.CobblemonBlockTags
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.Block
import net.minecraft.block.BlockRenderType
import net.minecraft.block.BlockState
@@ -68,21 +70,21 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
*/
fun berry(): Berry? = Berries.getByIdentifier(this.berryIdentifier)
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity): BlockState {
if (!player.isCreative && state.get(AGE) == FRUIT_AGE) {
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
treeEntity.harvest(world, state, pos, player).forEach { drop -> Block.dropStack(world, pos, drop) }
}
super.onBreak(world, pos, state, player)
return super.onBreak(world, pos, state, player)
}
override fun createBlockEntity(pos: BlockPos, state: BlockState) = BerryBlockEntity(pos, state, berryIdentifier)
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState, isClient: Boolean) = !this.isMaxAge(state)
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState) = !this.isMaxAge(state)
override fun canGrow(world: World, random: Random, pos: BlockPos, state: BlockState) = !this.isMaxAge(state)
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, blockWithEntityType: BlockEntityType<T>): BlockEntityTicker<T>? = checkType(blockWithEntityType, CobblemonBlockEntities.BERRY, BerryBlockEntity.TICKER)
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, blockWithEntityType: BlockEntityType<T>): BlockEntityTicker<T>? = validateTicker(blockWithEntityType, CobblemonBlockEntities.BERRY, BerryBlockEntity.TICKER)
init {
defaultState = this.stateManager.defaultState
@@ -192,6 +194,10 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
|| below.block is FarmlandBlock
}
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
@Deprecated("Deprecated in Java")
override fun getStateForNeighborUpdate(state: BlockState, direction: Direction, neighborState: BlockState, world: WorldAccess, pos: BlockPos, neighborPos: BlockPos): BlockState {
return if (state.canPlaceAt(world, pos)) super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos) else Blocks.AIR.defaultState
@@ -210,7 +216,7 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
builder.add(MULCH)
}
override fun getPickStack(world: BlockView?, pos: BlockPos?, state: BlockState?): ItemStack {
override fun getPickStack(world: WorldView?, pos: BlockPos?, state: BlockState?): ItemStack {
val berryItem = this.berry()?.item() ?: return ItemStack.EMPTY
return ItemStack(berryItem)
}
@@ -232,6 +238,11 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
override fun getRenderType(blockState: BlockState) = BlockRenderType.MODEL
companion object {
val CODEC: MapCodec<BerryBlock> = RecordCodecBuilder.mapCodec { it.group(
Identifier.CODEC.fieldOf("berry").forGetter(BerryBlock::berryIdentifier),
createSettingsCodec()
).apply(it, ::BerryBlock) }
const val MATURE_AGE = 3
const val FLOWER_AGE = 4
const val FRUIT_AGE = 5
@@ -312,4 +323,4 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
world.setBlockState(pos, state.with(MULCH, mulch))
}
}
}
}
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.block
import com.mojang.serialization.MapCodec
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
import net.minecraft.block.ShapeContext
@@ -39,10 +41,14 @@ class BigRootBlock(settings: Settings) : RootBlock(settings) {
override fun shearedDrop(): ItemStack = Items.STRING.defaultStack
override fun getCodec(): MapCodec<out Block> {
return CODEC
}
companion object {
val CODEC = createCodec(::BigRootBlock)
private val AABB = VoxelShapes.cuboid(0.2, 0.3, 0.2, 0.8, 1.0, 0.8)
}
}
@@ -8,13 +8,19 @@
package com.cobblemon.mod.common.block
import net.minecraft.block.*
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
import net.minecraft.block.HorizontalFacingBlock
import net.minecraft.block.ShapeContext
import net.minecraft.item.ItemPlacementContext
import net.minecraft.state.StateManager
import net.minecraft.state.property.BooleanProperty
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.shape.VoxelShape
import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
import net.minecraft.world.WorldAccess
@@ -51,6 +57,10 @@ class CoinPouchBlock(settings: Settings, val small: Boolean) : HorizontalFacingB
return null
}
override fun getCodec(): MapCodec<out HorizontalFacingBlock> {
return CODEC
}
@Deprecated("Deprecated in Java")
override fun getStateForNeighborUpdate(
state: BlockState,
@@ -70,5 +80,10 @@ class CoinPouchBlock(settings: Settings, val small: Boolean) : HorizontalFacingB
companion object {
val NATURAL: BooleanProperty = BooleanProperty.of("natural")
val CODEC: MapCodec<CoinPouchBlock> = RecordCodecBuilder.mapCodec { it.group(
createSettingsCodec(),
PrimitiveCodec.BOOL.fieldOf("small").forGetter(CoinPouchBlock::small),
).apply(it, ::CoinPouchBlock) }
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.block.entity.DisplayCaseBlockEntity
import com.cobblemon.mod.common.item.PokeBallItem
import com.mojang.serialization.MapCodec
import net.minecraft.block.*
import net.minecraft.block.HorizontalFacingBlock.*
import net.minecraft.entity.ai.pathing.NavigationType
@@ -36,10 +37,6 @@ class DisplayCaseBlock(settings: Settings) : BlockWithEntity(settings) {
.with(ITEM_DIRECTION, Direction.NORTH)
}
companion object {
val ITEM_DIRECTION = DirectionProperty.of("item_facing")
}
override fun getPlacementState(ctx: ItemPlacementContext): BlockState? {
var blockState = defaultState
val worldView = ctx.world
@@ -95,12 +92,12 @@ class DisplayCaseBlock(settings: Settings) : BlockWithEntity(settings) {
return result
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity): BlockState {
val entity = world.getBlockEntity(pos) as DisplayCaseBlockEntity
if (!entity.getStack().isEmpty && !player.isCreative) {
ItemScatterer.spawn(world, pos, entity.inv)
}
super.onBreak(world, pos, state, player)
return super.onBreak(world, pos, state, player)
}
override fun getRenderType(state: BlockState?) = BlockRenderType.MODEL
@@ -115,7 +112,15 @@ class DisplayCaseBlock(settings: Settings) : BlockWithEntity(settings) {
}
override fun hasComparatorOutput(state: BlockState?) = true
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
override fun canPathfindThrough(state: BlockState, world: BlockView, pos: BlockPos, type: NavigationType) = false
companion object {
val CODEC = createCodec(::DisplayCaseBlock)
val ITEM_DIRECTION = DirectionProperty.of("item_facing")
}
}
@@ -10,6 +10,8 @@ package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import com.mojang.serialization.MapCodec
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.ShapeContext
import net.minecraft.item.ItemStack
@@ -27,10 +29,14 @@ class EnergyRootBlock(settings: Settings) : RootBlock(settings) {
override fun shearedDrop(): ItemStack = CobblemonItems.ENERGY_ROOT.defaultStack
override fun getCodec(): MapCodec<out Block> {
return CODEC
}
companion object {
private val CODEC = createCodec(::EnergyRootBlock)
private val AABB = VoxelShapes.cuboid(0.2, 0.1, 0.2, 0.8, 1.0, 0.8)
}
}
@@ -14,9 +14,11 @@ import com.cobblemon.mod.common.block.entity.FossilAnalyzerBlockEntity
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockStructure
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
import com.mojang.serialization.MapCodec
import net.minecraft.block.Block
import net.minecraft.inventory.SidedInventory
import net.minecraft.block.BlockState
import net.minecraft.block.BlockWithEntity
import net.minecraft.block.HorizontalFacingBlock
import net.minecraft.block.InventoryProvider
import net.minecraft.block.entity.BlockEntity
@@ -41,11 +43,15 @@ class FossilAnalyzerBlock(properties: Settings) : MultiblockBlock(properties), I
return FossilAnalyzerBlockEntity(pos, state, FossilMultiblockBuilder(pos))
}
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
override fun <T : BlockEntity?> getTicker(
world: World?,
state: BlockState?,
type: BlockEntityType<T>?
): BlockEntityTicker<T>? = checkType(type, CobblemonBlockEntities.FOSSIL_ANALYZER, FossilMultiblockStructure.TICKER::tick)
): BlockEntityTicker<T>? = validateTicker(type, CobblemonBlockEntities.FOSSIL_ANALYZER, FossilMultiblockStructure.TICKER::tick)
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
return defaultState.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing)
@@ -68,5 +74,7 @@ class FossilAnalyzerBlock(properties: Settings) : MultiblockBlock(properties), I
companion object {
val ON = BooleanProperty.of("on")
val CODEC = createCodec(::FossilAnalyzerBlock)
}
}
}
@@ -34,7 +34,7 @@ abstract class GrowableStoneBlock(
settings: Settings,
val stage: Int,
val height: Int,
xzOffset: Int,
val xzOffset: Int,
val nextStage: Block?
) : FacingBlock(settings) {
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.text.green
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
import com.cobblemon.mod.common.util.*
import com.mojang.serialization.MapCodec
import net.minecraft.block.*
import net.minecraft.block.entity.BlockEntity
import net.minecraft.block.entity.BlockEntityTicker
@@ -47,6 +48,8 @@ import net.minecraft.world.World
@Suppress("DEPRECATED", "OVERRIDE_DEPRECATION")
class HealingMachineBlock(properties: Settings) : BlockWithEntity(properties) {
companion object {
val CODEC: MapCodec<HealingMachineBlock> = createCodec(::HealingMachineBlock)
private val NORTH_SOUTH_AABB = VoxelShapes.union(
VoxelShapes.cuboid(0.0, 0.0, 0.0, 1.0, 0.625, 1.0),
VoxelShapes.cuboid(0.0625, 0.625, 0.0, 0.9375, 0.875, 0.125),
@@ -93,6 +96,10 @@ class HealingMachineBlock(properties: Settings) : BlockWithEntity(properties) {
return this.defaultState.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing)
}
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
override fun canPathfindThrough(blockState: BlockState, blockGetter: BlockView, blockPos: BlockPos, pathComputationType: NavigationType): Boolean {
return false
}
@@ -190,7 +197,7 @@ class HealingMachineBlock(properties: Settings) : BlockWithEntity(properties) {
override fun getComparatorOutput(state: BlockState, world: World, pos: BlockPos): Int = (world.getBlockEntity(pos) as? HealingMachineBlockEntity)?.currentSignal ?: 0
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, blockWithEntityType: BlockEntityType<T>): BlockEntityTicker<T>? = checkType(blockWithEntityType, CobblemonBlockEntities.HEALING_MACHINE, HealingMachineBlockEntity.TICKER::tick)
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, blockWithEntityType: BlockEntityType<T>): BlockEntityTicker<T>? = validateTicker(blockWithEntityType, CobblemonBlockEntities.HEALING_MACHINE, HealingMachineBlockEntity.TICKER::tick)
override fun getRenderType(blockState: BlockState): BlockRenderType {
return BlockRenderType.MODEL
@@ -201,4 +208,4 @@ class HealingMachineBlock(properties: Settings) : BlockWithEntity(properties) {
tooltip.add("block.${Cobblemon.MODID}.healing_machine.tooltip2".asTranslated().gray())
}
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.tags.CobblemonBlockTags
import com.mojang.serialization.MapCodec
import net.minecraft.block.*
import net.minecraft.item.ItemConvertible
import net.minecraft.registry.tag.FluidTags
@@ -50,7 +51,7 @@ class MedicinalLeekBlock(settings: Settings) : CropBlock(settings) {
// These 3 are still around for the sake of compatibility, vanilla won't trigger it but some mods might
// We implement applyGrowth & getGrowthAmount for them
override fun isFertilizable(world: WorldView?, pos: BlockPos?, state: BlockState?, isClient: Boolean): Boolean = !this.isMature(state)
override fun isFertilizable(world: WorldView?, pos: BlockPos?, state: BlockState?): Boolean = !this.isMature(state)
override fun applyGrowth(world: World, pos: BlockPos, state: BlockState) {
world.setBlockState(pos, state.with(this.ageProperty, (this.getAge(state) + 1).coerceAtMost(this.maxAge)), NOTIFY_LISTENERS)
@@ -70,7 +71,12 @@ class MedicinalLeekBlock(settings: Settings) : CropBlock(settings) {
return floor.isIn(CobblemonBlockTags.MEDICINAL_LEEK_PLANTABLE) && fluidState.level == 8 && fluidState.isIn(FluidTags.WATER)
}
override fun getCodec(): MapCodec<out CropBlock> {
return CODEC
}
companion object {
val CODEC = createCodec(::MedicinalLeekBlock)
const val MATURE_AGE = 3
val AGE: IntProperty = Properties.AGE_3
@@ -11,7 +11,13 @@ package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.item.MintLeafItem
import net.minecraft.block.*
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.CropBlock
import net.minecraft.block.Fertilizable
import net.minecraft.block.ShapeContext
import net.minecraft.item.Item
import net.minecraft.item.ItemConvertible
import net.minecraft.registry.tag.BlockTags
@@ -19,6 +25,7 @@ import net.minecraft.server.world.ServerWorld
import net.minecraft.state.StateManager
import net.minecraft.state.property.BooleanProperty
import net.minecraft.state.property.IntProperty
import net.minecraft.util.StringIdentifiable
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.random.Random
import net.minecraft.util.shape.VoxelShape
@@ -74,8 +81,12 @@ class MintBlock(private val mintType: MintType, settings: Settings) : CropBlock(
world.setBlockState(pos, state.with(AGE, newAge), NOTIFY_LISTENERS)
}
override fun getCodec(): MapCodec<out CropBlock> {
return CODEC
}
@Suppress("unused")
enum class MintType {
enum class MintType : StringIdentifiable {
RED,
BLUE,
@@ -111,9 +122,18 @@ class MintBlock(private val mintType: MintType, settings: Settings) : CropBlock(
WHITE -> CobblemonBlocks.WHITE_MINT
}
override fun asString(): String = this.name.lowercase()
companion object {
val CODEC = StringIdentifiable.createBasicCodec(::values)
}
}
companion object {
val CODEC: MapCodec<MintBlock> = RecordCodecBuilder.mapCodec { it.group(
MintType.CODEC.fieldOf("mintType").forGetter(MintBlock::mintType),
createSettingsCodec()
).apply(it, ::MintBlock) }
val AGE: IntProperty = CropBlock.AGE
const val MATURE_AGE = MAX_AGE
@@ -139,4 +159,4 @@ class MintBlock(private val mintType: MintType, settings: Settings) : CropBlock(
)
}
}
}
@@ -12,8 +12,10 @@ import com.cobblemon.mod.common.api.multiblock.MultiblockBlock
import com.cobblemon.mod.common.api.multiblock.MultiblockEntity
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
import com.mojang.serialization.MapCodec
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.BlockWithEntity
import net.minecraft.block.HorizontalFacingBlock
import net.minecraft.block.ShapeContext
import net.minecraft.entity.ai.pathing.NavigationType
@@ -42,6 +44,10 @@ class MonitorBlock(properties: Settings) : MultiblockBlock(properties) {
)
}
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
return defaultState.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing)
}
@@ -84,6 +90,8 @@ class MonitorBlock(properties: Settings) : MultiblockBlock(properties) {
}
companion object {
val CODEC = createCodec(::MonitorBlock)
//0 is off
val SCREEN = EnumProperty.of("screen", MonitorScreen::class.java)
val HITBOX = VoxelShapes.union(
@@ -59,6 +59,7 @@ import net.minecraft.world.WorldView
class PCBlock(properties: Settings): BlockWithEntity(properties), Waterloggable {
companion object {
val CODEC = createCodec(::PCBlock)
val PART = EnumProperty.of("part", PCPart::class.java)
val ON = BooleanProperty.of("on")
val WATERLOGGED = BooleanProperty.of("waterlogged")
@@ -208,7 +209,7 @@ class PCBlock(properties: Settings): BlockWithEntity(properties), Waterloggable
return if (state.get(PART) == PCPart.BOTTOM) blockState.isSideSolidFullSquare(world, blockPos, Direction.UP) else blockState.isOf(this)
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?): BlockState {
if (!world.isClient && player?.isCreative == true) {
var blockPos: BlockPos = BlockPos.ORIGIN
var blockState: BlockState = state
@@ -219,9 +220,11 @@ class PCBlock(properties: Settings): BlockWithEntity(properties), Waterloggable
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, blockPos, getRawIdFromState(blockState))
}
}
super.onBreak(world, pos, state, player)
return super.onBreak(world, pos, state, player)
}
override fun getCodec() = CODEC
@Deprecated("Deprecated in Java")
override fun canPathfindThrough(blockState: BlockState, blockGetter: BlockView, blockPos: BlockPos, pathComputationType: NavigationType) = false
@@ -283,7 +286,7 @@ class PCBlock(properties: Settings): BlockWithEntity(properties), Waterloggable
return ActionResult.SUCCESS
}
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, BlockWithEntityType: BlockEntityType<T>) = checkType(BlockWithEntityType, CobblemonBlockEntities.PC, PCBlockEntity.TICKER::tick)
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, BlockWithEntityType: BlockEntityType<T>) = validateTicker(BlockWithEntityType, CobblemonBlockEntities.PC, PCBlockEntity.TICKER::tick)
@Deprecated("Deprecated in Java")
override fun getRenderType(blockState: BlockState): BlockRenderType {
@@ -21,6 +21,7 @@ import com.cobblemon.mod.common.util.isInBattle
import com.cobblemon.mod.common.util.playSoundServer
import com.cobblemon.mod.common.util.toVec3d
import com.cobblemon.mod.common.util.voxelShape
import com.mojang.serialization.MapCodec
import java.util.UUID
import net.minecraft.block.Block
import net.minecraft.block.BlockRenderType
@@ -64,6 +65,8 @@ import net.minecraft.world.WorldView
@Suppress("OVERRIDE_DEPRECATION", "DEPRECATION")
class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterloggable, PreEmptsExplosion {
companion object {
val CODEC = createCodec(::PastureBlock)
val PART: EnumProperty<PasturePart> = EnumProperty.of("part", PasturePart::class.java)
val ON: BooleanProperty = BooleanProperty.of("on")
val WATERLOGGED: BooleanProperty = BooleanProperty.of("waterlogged")
@@ -174,6 +177,10 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
private fun isBase(state: BlockState): Boolean = state.contains(PART) && state.get(PART) == PasturePart.BOTTOM
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
override fun canPathfindThrough(blockState: BlockState, blockGetter: BlockView, blockPos: BlockPos, pathComputationType: NavigationType) = false
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
@@ -193,7 +200,7 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
}
}
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?): BlockState {
checkBreakEntity(world, state, pos)
if (!world.isClient && player?.isCreative == true) {
var blockPos: BlockPos = BlockPos.ORIGIN
@@ -206,7 +213,7 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, blockPos, getRawIdFromState(blockState))
}
}
super.onBreak(world, pos, state, player)
return super.onBreak(world, pos, state, player)
}
override fun whenExploded(world: World, state: BlockState, pos: BlockPos) {
@@ -215,7 +222,7 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
}
override fun <T : BlockEntity?> getTicker(world: World, state: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? {
return checkType(type, CobblemonBlockEntities.PASTURE, PokemonPastureBlockEntity.TICKER::tick)
return validateTicker(type, CobblemonBlockEntities.PASTURE, PokemonPastureBlockEntity.TICKER::tick)
}
override fun onPlaced(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity?, itemStack: ItemStack?) {
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.multiblock.MultiblockEntity
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
import com.cobblemon.mod.common.block.entity.RestorationTankBlockEntity
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
import com.mojang.serialization.MapCodec
import net.minecraft.block.*
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.ai.pathing.NavigationType
@@ -51,7 +52,6 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
.with(ON, false)
}
fun getPositionOfOtherPart(state: BlockState, pos: BlockPos): BlockPos {
return if (state.get(PART) == TankPart.BOTTOM) {
pos.up()
@@ -70,13 +70,16 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
private fun isBase(state: BlockState): Boolean = state.get(PART) == TankPart.BOTTOM
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
super.onBreak(world, pos, state, player)
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?): BlockState {
val result = super.onBreak(world, pos, state, player)
val otherPart = world.getBlockState(getPositionOfOtherPart(state, pos))
if (otherPart.block is RestorationTankBlock) {
world.setBlockState(getPositionOfOtherPart(state, pos), Blocks.AIR.defaultState, 35)
world.syncWorldEvent(player, 2001, getPositionOfOtherPart(state, pos), getRawIdFromState(otherPart))
}
return result
}
override fun onPlaced(
@@ -222,9 +225,15 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
return false
}
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
companion object {
val CODEC = createCodec(::RestorationTankBlock)
val PART = EnumProperty.of("part", TankPart::class.java)
val TRIGGERED = Properties.TRIGGERED
val ON = BooleanProperty.of("on")
}
}
}
@@ -124,6 +124,7 @@ class RevivalHerbBlock(settings: Settings) : CropBlock(settings), Mulchable {
}
companion object {
val CODEC = createCodec(::RevivalHerbBlock)
const val MIN_AGE = 0
const val MAX_AGE = 8
@@ -70,7 +70,7 @@ abstract class RootBlock(settings: Settings) : Block(settings), Fertilizable, Sh
return if (direction == Direction.UP && !this.canPlaceAt(state, world, pos)) Blocks.AIR.defaultState else super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos)
}
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState, isClient: Boolean) = this.canSpread(world, pos, state)
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState) = this.canSpread(world, pos, state)
override fun canGrow(world: World, random: Random, pos: BlockPos, state: BlockState) = this.canSpread(world, pos, state)
@@ -187,4 +187,4 @@ abstract class RootBlock(settings: Settings) : Block(settings), Fertilizable, Sh
companion object {
const val MAX_PROPAGATING_LIGHT_LEVEL = 11
}
}
}
@@ -9,6 +9,11 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.api.tags.CobblemonBlockTags
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.PrimitiveCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.Block
import net.minecraft.block.FacingBlock
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import net.minecraft.block.*
import net.minecraft.entity.player.PlayerEntity
@@ -20,10 +25,9 @@ import net.minecraft.server.world.ServerWorld
import net.minecraft.state.StateManager
import net.minecraft.state.property.BooleanProperty
import net.minecraft.state.property.Properties
import net.minecraft.state.property.Properties.WATERLOGGED
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.math.random.Random
import net.minecraft.util.shape.VoxelShape
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.minecraft.world.WorldAccess
@@ -38,16 +42,24 @@ class TumblestoneBlock(
nextStage: Block?
) : GrowableStoneBlock(settings, stage, height, xzOffset, nextStage), Waterloggable {
// TODO(Deltric): Look into Block.CODEC for being optional more
companion object {
val CODEC: MapCodec<TumblestoneBlock> = RecordCodecBuilder.mapCodec { it.group(
createSettingsCodec(),
PrimitiveCodec.INT.fieldOf("stage").forGetter { it.stage },
PrimitiveCodec.INT.fieldOf("height").forGetter { it.height },
PrimitiveCodec.INT.fieldOf("xzOffset").forGetter { it.xzOffset },
Block.CODEC.fieldOf("nextStage").forGetter { it.nextStage }
).apply(it, ::TumblestoneBlock) }
val WATERLOGGED = BooleanProperty.of("waterlogged")
}
init {
this.defaultState = this.stateManager.defaultState
.with(FACING, Direction.DOWN)
.with(WATERLOGGED, false)
}
companion object {
val WATERLOGGED = BooleanProperty.of("waterlogged")
}
override fun canGrow(pos: BlockPos, world: BlockView): Boolean {
if (stage == MAX_STAGE) return false
val iterator: Iterator<BlockPos> =
@@ -62,6 +74,10 @@ class TumblestoneBlock(
return true
}
override fun getCodec(): MapCodec<out FacingBlock> {
return CODEC
}
override fun getFluidState(state: BlockState): FluidState {
return if (state.get(GildedChestBlock.WATERLOGGED)) {
Fluids.WATER.getStill(false)
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.CobblemonItems
import com.mojang.serialization.MapCodec
import net.minecraft.block.BlockState
import net.minecraft.block.CropBlock
import net.minecraft.block.ShapeContext
@@ -29,7 +30,12 @@ class VivichokeBlock(settings: Settings) : CropBlock(settings) {
override fun getSeedsItem(): ItemConvertible = CobblemonItems.VIVICHOKE_SEEDS
override fun getCodec(): MapCodec<out CropBlock> {
return CODEC
}
companion object {
val CODEC = createCodec(::VivichokeBlock)
private val STAGE_0_SHAPE = createCuboidShape(6.0, -1.0, 6.0, 10.0, 2.0, 10.0)
private val STAGE_1_SHAPE = createCuboidShape(6.0, -1.0, 6.0, 10.0, 5.0, 10.0)
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.toVec3d
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.block.*
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.ai.pathing.NavigationType
@@ -33,7 +35,13 @@ import net.minecraft.state.property.BooleanProperty
import net.minecraft.state.property.Properties
import net.minecraft.text.MutableText
import net.minecraft.text.Text
import net.minecraft.util.*
import net.minecraft.util.ActionResult
import net.minecraft.util.BlockMirror
import net.minecraft.util.BlockRotation
import net.minecraft.util.Hand
import net.minecraft.util.Identifier
import net.minecraft.util.ItemScatterer
import net.minecraft.util.StringIdentifiable
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
@@ -53,6 +61,11 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
}
companion object {
val CODEC: MapCodec<GildedChestBlock> = RecordCodecBuilder.mapCodec { it.group(
createSettingsCodec(),
Type.CODEC.fieldOf("chestType").forGetter(GildedChestBlock::type)
).apply(it, ::GildedChestBlock) }
val POKEMON_ARGS = "gimmighoul"
val LEVEL_RANGE = 5..30
val WATERLOGGED = BooleanProperty.of("waterlogged")
@@ -124,13 +137,16 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
fun isFake() = (type == Type.FAKE)
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity): BlockState {
if (isFake()) {
if (player is ServerPlayerEntity) {
spawnPokemon(world, pos, state, player)
}
world.setBlockState(pos, if (state.fluidState.isOf(Fluids.WATER)) Blocks.WATER.defaultState else Blocks.AIR.defaultState)
} else super.onBreak(world, pos, state, player)
val resultState = if (state.fluidState.isOf(Fluids.WATER)) Blocks.WATER.defaultState else Blocks.AIR.defaultState
world.setBlockState(pos, resultState)
return resultState
}
return super.onBreak(world, pos, state, player)
}
private fun spawnPokemon(world: World, pos: BlockPos, state: BlockState, player: ServerPlayerEntity) : ActionResult {
@@ -232,7 +248,7 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
return state.rotate(mirror.getRotation(state.get(Properties.HORIZONTAL_FACING) as Direction))
}
enum class Type(val poserId: Identifier) {
enum class Type(val poserId: Identifier): StringIdentifiable {
RED(cobblemonResource("gilded_chest")),
BLUE(cobblemonResource("blue_gilded_chest")),
GREEN(cobblemonResource("green_gilded_chest")),
@@ -240,7 +256,15 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
WHITE(cobblemonResource("white_gilded_chest")),
BLACK(cobblemonResource("black_gilded_chest")),
YELLOW(cobblemonResource("yellow_gilded_chest")),
FAKE(cobblemonResource("gilded_chest"))
FAKE(cobblemonResource("gilded_chest"));
override fun asString(): String {
return name.lowercase()
}
companion object {
val CODEC = StringIdentifiable.createBasicCodec(::values)
}
}
@Deprecated("Deprecated in Java")
@@ -248,6 +272,10 @@ class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWit
return false
}
override fun getCodec(): MapCodec<out BlockWithEntity> {
return CODEC
}
override fun onPlaced(
world: World,
pos: BlockPos,
@@ -73,6 +73,8 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
override fun createScreenHandler(syncId: Int, playerInventory: PlayerInventory?) =
GenericContainerScreenHandler.createGeneric9x3(syncId, playerInventory, this)
override fun method_11282() = inventoryContents
override fun onOpen(player: PlayerEntity) {
if (!this.removed && !player.isSpectator && type != Type.FAKE) {
stateManager.openContainer(player, this.getWorld(), this.getPos(), this.cachedState)
@@ -101,8 +103,6 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
override fun canPlayerUse(player: PlayerEntity) = !player.isSpectator
override fun getInvStackList(): DefaultedList<ItemStack> = inventoryContents
override fun setInvStackList(list: DefaultedList<ItemStack>) {
inventoryContents = list
}
@@ -150,7 +150,7 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
}
override fun writeNbt(nbt: NbtCompound?) {
super.writeNbt(nbt)
if (!serializeLootTable(nbt)) {
if (!writeLootTable(nbt)) {
Inventories.writeNbt(nbt, inventoryContents)
}
}
@@ -160,7 +160,7 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
inventoryContents= DefaultedList.ofSize(
size(), ItemStack.EMPTY
)
if (!deserializeLootTable(nbt)) {
if (!readLootTable(nbt)) {
Inventories.readNbt(nbt, inventoryContents)
}
}
@@ -60,7 +60,7 @@ class PokemonPastureBlockEntity(pos: BlockPos, val state: BlockState) : BlockEnt
val entityId: Int
) {
fun getPokemon() = Cobblemon.storage.getPC(pcId)[pokemonId]
val box = Box(minRoamPos, maxRoamPos)
val box = Box(minRoamPos.toVec3d(), maxRoamPos.toVec3d())
open fun canRoamTo(pos: BlockPos) = box.contains(pos.toCenterPos())
fun toDTO(player: ServerPlayerEntity): OpenPasturePacket.PasturePokemonDataDTO? {
@@ -129,7 +129,7 @@ class PokemonPastureBlockEntity(pos: BlockPos, val state: BlockState) : BlockEnt
val world = world ?: return false
val entity = PokemonEntity(world, pokemon = pokemon)
entity.calculateDimensions()
val width = entity.boundingBox.xLength
val width = entity.boundingBox.lengthX
val idealPlace = pos.add(directionToBehind.vector.multiply(ceil(width).toInt() + 1))
var box = entity.getDimensions(EntityPose.STANDING).getBoxAt(idealPlace.toCenterPos().subtract(0.0, 0.5, 0.0))
@@ -9,18 +9,12 @@
package com.cobblemon.mod.common.block.grower
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.world.feature.CobblemonConfiguredFeatures
import net.minecraft.block.sapling.SaplingGenerator
import net.minecraft.util.math.random.Random
import net.minecraft.block.SaplingGenerator
import java.util.Optional
class ApricornTreeGrower(private val apricorn: Apricorn) : SaplingGenerator() {
override fun getTreeFeature(random: Random, bl: Boolean) = when (this.apricorn) {
Apricorn.BLACK -> CobblemonConfiguredFeatures.BLACK_APRICORN_TREE_KEY
Apricorn.BLUE -> CobblemonConfiguredFeatures.BLUE_APRICORN_TREE_KEY
Apricorn.GREEN -> CobblemonConfiguredFeatures.GREEN_APRICORN_TREE_KEY
Apricorn.PINK -> CobblemonConfiguredFeatures.PINK_APRICORN_TREE_KEY
Apricorn.RED -> CobblemonConfiguredFeatures.RED_APRICORN_TREE_KEY
Apricorn.WHITE -> CobblemonConfiguredFeatures.WHITE_APRICORN_TREE_KEY
Apricorn.YELLOW -> CobblemonConfiguredFeatures.YELLOW_APRICORN_TREE_KEY
}
}
class ApricornTreeGrower(apricorn: Apricorn) : SaplingGenerator(
apricorn.asString(),
Optional.empty(),
Optional.of(apricorn.configuredFeature()),
Optional.empty()
)
@@ -161,9 +161,9 @@ class FossilMultiblockBuilder(val centerPos: BlockPos) : MultiblockStructureBuil
val RESTORATION_TANK_PRED = BlockPredicate.Builder.create()
.nbt(NBT_TO_CHECK)
.blocks(CobblemonBlocks.RESTORATION_TANK)
.state(StatePredicate.Builder.create().exactMatch(RestorationTankBlock.PART, RestorationTankBlock.TankPart.BOTTOM).build())
.state(StatePredicate.Builder.create().exactMatch(RestorationTankBlock.PART, RestorationTankBlock.TankPart.BOTTOM))
.build()
//lol thanks mojang for not allowing nbt puts to be chained
}
}
}
@@ -205,10 +205,10 @@ class FossilMultiblockStructure (
return ActionResult.PASS
}
public fun spawn(world: World, pos: BlockPos, directionToBehind: Direction, pokemon: Pokemon) : Boolean {
fun spawn(world: World, pos: BlockPos, directionToBehind: Direction, pokemon: Pokemon) : Boolean {
val entity = PokemonEntity(world, pokemon = pokemon)
entity.calculateDimensions()
val width = entity.boundingBox.xLength
val width = entity.boundingBox.lengthX
val idealPlace = pos.add(directionToBehind.vector.multiply(ceil(width / 2.0).toInt() + 1))
var box = entity.getDimensions(EntityPose.STANDING).getBoxAt(idealPlace.toCenterPos().subtract(0.0, 0.5, 0.0))
@@ -15,7 +15,7 @@ import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonHangingSignBlock(settings: Settings, woodType: WoodType) : HangingSignBlock(settings, woodType) {
class CobblemonHangingSignBlock(settings: Settings, woodType: WoodType) : HangingSignBlock(woodType, settings) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonHangingSignBlockEntity(pos, state)
@@ -15,7 +15,7 @@ import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonSignBlock(settings: Settings, woodType: WoodType) : SignBlock(settings, woodType) {
class CobblemonSignBlock(settings: Settings, woodType: WoodType) : SignBlock(woodType, settings) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
@@ -15,7 +15,7 @@ import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonWallHangingSignBlock(settings: Settings, woodType: WoodType) : WallHangingSignBlock(settings, woodType) {
class CobblemonWallHangingSignBlock(settings: Settings, woodType: WoodType) : WallHangingSignBlock(woodType, settings) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonHangingSignBlockEntity(pos, state)
@@ -15,7 +15,7 @@ import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonWallSignBlock(settings: Settings, woodType: WoodType) : WallSignBlock(settings, woodType) {
class CobblemonWallSignBlock(settings: Settings, woodType: WoodType) : WallSignBlock(woodType, settings) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
@@ -62,6 +62,7 @@ import net.minecraft.client.render.entity.LivingEntityRenderer
import net.minecraft.client.render.entity.model.BoatEntityModel
import net.minecraft.client.render.entity.model.ChestBoatEntityModel
import net.minecraft.client.render.entity.model.PlayerEntityModel
import net.minecraft.client.util.SkinTextures
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.resource.ResourceManager
@@ -237,10 +238,10 @@ object CobblemonClient {
}
@Suppress("UNCHECKED_CAST")
fun onAddLayer(skinMap: Map<String, EntityRenderer<out PlayerEntity>>?) {
var renderer: LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>? = skinMap?.get("default") as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>
fun onAddLayer(skinMap: Map<SkinTextures.Model, EntityRenderer<out PlayerEntity>>?) {
var renderer: LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>? = skinMap?.get(SkinTextures.Model.WIDE) as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>
renderer?.addFeature(PokemonOnShoulderRenderer(renderer))
renderer = skinMap["slim"] as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>?
renderer = skinMap[SkinTextures.Model.SLIM] as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>?
renderer?.addFeature(PokemonOnShoulderRenderer(renderer))
}
@@ -306,4 +307,4 @@ object CobblemonClient {
}
}
}
}
@@ -265,10 +265,10 @@ class PokemonClientDelegate : PoseableEntityState<PokemonEntity>(), PokemonSideD
return@Function StringValue(currentEntity.pokemon.form.name)
},
"width" to java.util.function.Function {
return@Function DoubleValue(currentEntity.boundingBox.xLength)
return@Function DoubleValue(currentEntity.boundingBox.lengthX)
},
"height" to java.util.function.Function {
return@Function DoubleValue(currentEntity.boundingBox.yLength)
return@Function DoubleValue(currentEntity.boundingBox.lengthY)
},
"weight" to java.util.function.Function {
return@Function DoubleValue(currentEntity.pokemon.species.weight.toDouble())
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.Text
class ExitButton(
@@ -29,7 +28,7 @@ class ExitButton(
private val iconResource = cobblemonResource("textures/gui/common/back_button_icon.png")
}
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
override fun renderWidget(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
blitk(
matrixStack = context.matrices,
texture = buttonResource,
@@ -56,4 +55,4 @@ class ExitButton(
}
fun isHovered(mouseX: Double, mouseY: Double) = mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT))
}
}
@@ -32,6 +32,7 @@ import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.hud.InGameHud
import net.minecraft.client.gui.screen.ChatScreen
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.toast.AdvancementToast
import net.minecraft.client.toast.Toast
import net.minecraft.util.math.MathHelper
@@ -64,7 +65,7 @@ class PartyOverlay : InGameHud(MinecraftClient.getInstance(), MinecraftClient.ge
CobblemonItems.POKE_BALL.defaultStack,
lang("ui.starter.choose_starter_title", SummaryBinding.boundKey().localizedText).red(),
lang("ui.starter.choose_starter_description", SummaryBinding.boundKey().localizedText).darkGray(),
Toast.TEXTURE,
AdvancementToast.TEXTURE,
-1F,
0
)
@@ -86,7 +87,7 @@ class PartyOverlay : InGameHud(MinecraftClient.getInstance(), MinecraftClient.ge
if (!screenExemptions.contains(minecraft.currentScreen?.javaClass as Class<out Screen>))
return
}
if (minecraft.options.debugEnabled) {
if (minecraft.debugHud.shouldShowDebugHud()) {
return
}
// Hiding if toggled via Keybind
@@ -27,7 +27,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.util.math.MatrixStack
class BattleGUI : Screen(battleLang("gui.title")) {
companion object {
const val OPTION_VERTICAL_SPACING = 3
@@ -82,12 +82,14 @@ class BattleGUI : Screen(battleLang("gui.title")) {
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
super.render(context, mouseX, mouseY, delta)
opacity = CobblemonClient.battleOverlay.opacityRatio.toFloat()
children().filterIsInstance<BattleMessagePane>().forEach { it.opacity = opacity.coerceAtLeast(0.3F) }
queuedActions.forEach { it() }
queuedActions.clear()
super.render(context, mouseX, mouseY, delta)
val battle = CobblemonClient.battle
if (battle == null) {
close()
@@ -140,6 +142,10 @@ class BattleGUI : Screen(battleLang("gui.title")) {
queuedActions.clear()
}
override fun renderBackground(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
}
fun deriveRootActionSelection(actor: ClientBattleActor, request: SingleActionRequest): BattleActionSelection {
return if (request.forceSwitch) {
BattleSwitchPokemonSelection(this, request)
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.client.gui.battle.subscreen
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
import com.cobblemon.mod.common.api.text.yellow
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.battle.SingleActionRequest
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
@@ -25,6 +23,7 @@ import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.client.sound.SoundManager
import net.minecraft.text.MutableText
import net.minecraft.util.Identifier
class BattleGeneralActionSelection(
battleGUI: BattleGUI,
request: SingleActionRequest
@@ -91,7 +90,7 @@ class BattleGeneralActionSelection(
)
}
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
for (tile in tiles) {
tile.render(context, mouseX, mouseY, delta)
}
@@ -182,7 +182,7 @@ class BattleMoveSelection(
}
}
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
moveTiles.forEach {
it.render(context, mouseX, mouseY, delta)
}
@@ -9,7 +9,8 @@
package com.cobblemon.mod.common.client.gui.battle.subscreen
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.battles.*
import com.cobblemon.mod.common.battles.ShowdownPokemon
import com.cobblemon.mod.common.battles.SwitchActionResponse
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.battle.SingleActionRequest
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
@@ -22,9 +23,8 @@ import net.minecraft.client.gui.Selectable
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder
import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.math.MathHelper.ceil
class BattleSwitchPokemonSelection(
battleGUI: BattleGUI,
request: SingleActionRequest
@@ -118,7 +118,7 @@ class BattleSwitchPokemonSelection(
}
}
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (opacity <= 0.05F) {
return
}
@@ -44,14 +44,6 @@ class ForfeitConfirmationSelection(
}
}
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (opacity <= 0.05F) {
return
}
forfeitButton.render(context, mouseX, mouseY, delta)
backButton.render(context.matrices, mouseX, mouseY, delta)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
if (backButton.isHovered(mouseX, mouseY)) {
battleGUI.changeActionSelection(null)
@@ -62,4 +54,12 @@ class ForfeitConfirmationSelection(
return forfeitButton.mouseClicked(mouseX, mouseY, button)
}
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (opacity <= 0.05F) {
return
}
forfeitButton.render(context, mouseX, mouseY, delta)
backButton.render(context.matrices, mouseX, mouseY, delta)
}
}
@@ -16,7 +16,6 @@ import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.OrderedText
/**
@@ -32,7 +31,6 @@ class BattleMessagePane(
TEXT_BOX_WIDTH, // width
TEXT_BOX_HEIGHT, // height
1, // top
1 + TEXT_BOX_HEIGHT, // bottom
LINE_HEIGHT
) {
var opacity = 1F
@@ -45,9 +43,7 @@ class BattleMessagePane(
init {
correctSize()
setRenderHorizontalShadows(false)
setRenderBackground(false)
setRenderSelection(false)
messageQueue.subscribe {
val fullyScrolledDown = maxScroll - scrollAmount < 10
@@ -60,8 +56,8 @@ class BattleMessagePane(
private fun correctSize() {
val textBoxHeight = if (expanded) TEXT_BOX_HEIGHT * 2 else TEXT_BOX_HEIGHT
updateSize(TEXT_BOX_WIDTH, textBoxHeight, appropriateY + 6, appropriateY + 6 + textBoxHeight)
setLeftPos(appropriateX)
setDimensionsAndPosition(TEXT_BOX_WIDTH, textBoxHeight, appropriateY + 6, appropriateY + 6)
this.x = appropriateX
}
companion object {
@@ -88,23 +84,15 @@ class BattleMessagePane(
}
override fun getScrollbarPositionX(): Int {
return left + 154
return this.x + 154
}
override fun getScrollAmount(): Double {
return super.getScrollAmount()
}
private fun scaleIt(i: Number): Int {
return (client.window.scaleFactor * i.toFloat()).toInt()
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
correctSize()
blitk(
matrixStack = context.matrices,
texture = if (expanded) battleMessagePaneFrameExpandedResource else battleMessagePaneFrameResource,
x = left,
x = this.x,
y = appropriateY,
height = if (expanded) FRAME_EXPANDED_HEIGHT else FRAME_HEIGHT,
width = FRAME_WIDTH,
@@ -113,18 +101,18 @@ class BattleMessagePane(
val textBoxHeight = if (expanded) TEXT_BOX_HEIGHT * 2 else TEXT_BOX_HEIGHT
context.enableScissor(
left + 5,
this.x + 5,
appropriateY + 6,
left + 5 + width,
this.x + 5 + width,
appropriateY + 6 + textBoxHeight
)
super.render(context, mouseX, mouseY, partialTicks)
super.renderWidget(context, mouseX, mouseY, partialTicks)
context.disableScissor()
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
val toggleOffsetY = if (expanded) 92 else 46
if (mouseX > (left + 160) && mouseX < (left + 160 + EXPAND_TOGGLE_SIZE) && mouseY > (appropriateY + toggleOffsetY) && mouseY < (appropriateY + toggleOffsetY + EXPAND_TOGGLE_SIZE)) {
if (mouseX > (this.x + 160) && mouseX < (this.x + 160 + EXPAND_TOGGLE_SIZE) && mouseY > (appropriateY + toggleOffsetY) && mouseY < (appropriateY + toggleOffsetY + EXPAND_TOGGLE_SIZE)) {
expanded = !expanded
}
@@ -139,7 +127,7 @@ class BattleMessagePane(
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
if (scrolling) {
if (mouseY < top) {
if (mouseY < this.y) {
scrollAmount = 0.0
} else if (mouseY > bottom) {
scrollAmount = maxScroll.toDouble()
@@ -153,7 +141,7 @@ class BattleMessagePane(
private fun updateScrollingState(mouseX: Double, mouseY: Double) {
scrolling = mouseX >= this.scrollbarPositionX.toDouble()
&& mouseX < (this.scrollbarPositionX + 3).toDouble()
&& mouseY >= top
&& mouseY >= this.y
&& mouseY < bottom
}
@@ -22,6 +22,7 @@ import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.ingame.InventoryScreen
import net.minecraft.util.Identifier
import org.joml.Quaternionf
import org.joml.Vector3f
/**
* Some time of face that can be rendered in a dialogue.
@@ -58,7 +59,7 @@ class PlayerRenderableFace(val playerId: UUID) : RenderableFace {
val size = 37
val xOffset = 0
val yOffset = 75
InventoryScreen.drawEntity(drawContext, xOffset, yOffset, size, quaternionf, quaternionf2, entity)
InventoryScreen.drawEntity(drawContext, xOffset.toFloat(), yOffset.toFloat(), size, Vector3f(), quaternionf, quaternionf2, entity)
// Resets the entity
entity.bodyYaw = oldBodyYaw
entity.setYaw(oldEntityYaw)
@@ -30,8 +30,8 @@ import net.minecraft.util.Language
*/
class DialogueBox(
val dialogueScreen: DialogueScreen,
val x: Int = 0,
val y: Int = 0,
x: Int = 0,
y: Int = 0,
val frameWidth: Int,
height: Int,
messages: List<MutableText>
@@ -40,7 +40,6 @@ class DialogueBox(
frameWidth - 14,
height, // height
1, // top
1 + height, // bottom
LINE_HEIGHT
) {
val dialogue = dialogueScreen.dialogueDTO
@@ -53,10 +52,10 @@ class DialogueBox(
get() = y
init {
this.x = x
this.y = y
correctSize()
setRenderHorizontalShadows(false)
setRenderBackground(false)
setRenderSelection(false)
val textRenderer = MinecraftClient.getInstance().textRenderer
@@ -67,8 +66,8 @@ class DialogueBox(
private fun correctSize() {
val textBoxHeight = height
updateSize(width, textBoxHeight, appropriateY + 6, appropriateY + 6 + textBoxHeight)
setLeftPos(appropriateX + 8)
setDimensionsAndPosition(width, textBoxHeight, appropriateY + 6, appropriateY + 6 + textBoxHeight)
setX(appropriateX + 8)
}
companion object {
@@ -86,23 +85,19 @@ class DialogueBox(
}
override fun getScrollbarPositionX(): Int {
return left + 144
}
override fun getScrollAmount(): Double {
return super.getScrollAmount()
return this.x + 144
}
private fun scaleIt(i: Number): Int {
return (client.window.scaleFactor * i.toFloat()).toInt()
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
correctSize()
blitk(
matrixStack = context.matrices,
texture = boxResource,
x = left - 8,
x = this.x - 8,
y = appropriateY - 1,
height = height + 12, // used to be FRAME_HEIGHT as below
width = frameWidth,
@@ -117,9 +112,9 @@ class DialogueBox(
override fun enableScissor(context: DrawContext) {
val textBoxHeight = height
context.enableScissor(
left,
this.x,
appropriateY + 7,
left + width - 10,
this.x + width - 10,
appropriateY + 7 + textBoxHeight
)
}
@@ -129,8 +124,8 @@ class DialogueBox(
// TODO change this coordinate check to just be "anywhere the scroll bar isn't"
if (!dialogueScreen.waitingForServerUpdate &&
mouseX > (left) &&
mouseX < (left + 160) &&
mouseX > (this.x) &&
mouseX < (this.x + 160) &&
mouseY > (appropriateY) &&
mouseY < (appropriateY + height)
) {
@@ -151,7 +146,7 @@ class DialogueBox(
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
if (scrolling) {
if (mouseY < top) {
if (mouseY < this.y) {
scrollAmount = 0.0
} else if (mouseY > bottom) {
scrollAmount = maxScroll.toDouble()
@@ -165,7 +160,7 @@ class DialogueBox(
private fun updateScrollingState(mouseX: Double, mouseY: Double) {
scrolling = mouseX >= this.scrollbarPositionX.toDouble()
&& mouseX < (this.scrollbarPositionX + 3).toDouble()
&& mouseY >= top
&& mouseY >= this.y
&& mouseY < bottom
}
@@ -14,7 +14,6 @@ import com.cobblemon.mod.common.api.gui.drawCenteredText
import com.cobblemon.mod.common.client.gui.dialogue.DialogueScreen
import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePacket
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.OverlayTexture
import net.minecraft.text.MutableText
import net.minecraft.util.Identifier
@@ -30,8 +29,7 @@ class DialogueOptionWidget(
val texture: Identifier,
val overlayTexture: Identifier
) : ParentWidget(x, y, width, height, text) {
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
blitk(
texture = texture,
matrixStack = context.matrices,
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePack
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.widget.TextFieldWidget
import net.minecraft.client.util.InputUtil
import org.lwjgl.glfw.GLFW
@@ -54,12 +55,12 @@ class DialogueTextInputWidget(
}
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (dialogueScreen.dialogueDTO.dialogueInput.inputType != DialogueInputDTO.InputType.TEXT || dialogueScreen.waitingForServerUpdate) {
return
}
if (cursor != text.length) {
setCursorToEnd()
setCursorToEnd(Screen.hasShiftDown())
}
blitk(
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.client.gui.interact.moveselect
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.moves.Move
import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.text.bold
@@ -24,6 +23,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.toRGB
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.gui.widget.ButtonWidget.NarrationSupplier
import net.minecraft.client.sound.SoundManager
import net.minecraft.text.Text
import net.minecraft.util.math.MathHelper
@@ -45,7 +45,7 @@ class MoveSlotButton(
const val HEIGHT = 22
}
override fun render(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
override fun renderWidget(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
hovered = pMouseX >= x && pMouseY >= y && pMouseX < x + width && pMouseY < y + height && enabled
val moveTemplate = Moves.getByNameOrDummy(move.name)
@@ -122,4 +122,4 @@ class MoveSlotButton(
}
override fun playDownSound(soundManager: SoundManager) {}
}
}
@@ -57,7 +57,7 @@ class PartySlotButton(
private val renderablePokemon = pokemon.asRenderablePokemon().also { it.aspects = aspects }
override fun render(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
override fun renderWidget(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
hovered = pMouseX >= x && pMouseY >= y && pMouseX < x + width && pMouseY < y + height && enabled
val alpha = if (enabled) 1.0 else 0.5
val matrices = context.matrices
@@ -198,4 +198,4 @@ class PartySlotButton(
}
override fun playDownSound(soundManager: SoundManager) {}
}
}
@@ -14,11 +14,9 @@ import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.tooltip.Tooltip
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import org.joml.Vector3f
import org.joml.Vector4f
class InteractWheelButton(
private val iconResource: Identifier?,
@@ -39,7 +37,7 @@ class InteractWheelButton(
const val ICON_OFFSET = 26.5
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
val matrices = context.matrices
blitk(
matrixStack = matrices,
@@ -30,15 +30,14 @@ import org.joml.Quaternionf
import org.joml.Vector3f
class PasturePokemonScrollList(
val x: Int,
val y: Int,
x: Int,
y: Int,
val parent: PastureWidget
) : AlwaysSelectedEntryListWidget<PasturePokemonScrollList.PastureSlot>(
MinecraftClient.getInstance(),
WIDTH, // width
HEIGHT, // height
0, // top
HEIGHT, // bottom
SLOT_HEIGHT + SLOT_SPACING
) {
companion object {
@@ -58,10 +57,10 @@ class PasturePokemonScrollList(
override fun getRowWidth() = SLOT_WIDTH
init {
this.x = x
this.y = y
correctSize()
setRenderHorizontalShadows(false)
setRenderBackground(false)
setRenderSelection(false)
parent.pasturePCGUIConfiguration.pasturedPokemon.subscribeIncludingCurrent {
val children = children()
@@ -73,19 +72,19 @@ class PasturePokemonScrollList(
}
}
override fun getScrollbarPositionX() = left + width - 3
override fun getScrollbarPositionX() = x + width - 3
public override fun addEntry(entry: PastureSlot) = super.addEntry(entry)
public override fun removeEntry(entry: PastureSlot) = super.removeEntry(entry)
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
correctSize()
context.enableScissor(
left,
top + 1,
left + width,
top + 1 + height
x,
y + 1,
x + width,
y + 1 + height
)
super.render(context, mouseX, mouseY, partialTicks)
@@ -95,8 +94,8 @@ class PasturePokemonScrollList(
blitk(
matrixStack = context.matrices,
texture = scrollOverlayResource,
x = left,
y = top - 12,
x = x,
y = y - 12,
height = 131,
width = WIDTH
)
@@ -124,7 +123,7 @@ class PasturePokemonScrollList(
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
if (scrolling) {
if (mouseY < top) {
if (mouseY < this.y) {
scrollAmount = 0.0
} else if (mouseY > bottom) {
scrollAmount = maxScroll.toDouble()
@@ -138,13 +137,13 @@ class PasturePokemonScrollList(
private fun updateScrollingState(mouseX: Double, mouseY: Double) {
scrolling = mouseX >= this.scrollbarPositionX.toDouble()
&& mouseX < (this.scrollbarPositionX + 3).toDouble()
&& mouseY >= top
&& mouseY >= y
&& mouseY < bottom
}
private fun correctSize() {
updateSize(WIDTH, HEIGHT, y + 1, (y + 1) + (HEIGHT - 2))
setLeftPos(x)
setDimensionsAndPosition(WIDTH, HEIGHT, y + 1, (y + 1) + (HEIGHT - 2))
setX(x)
}
fun isHovered(mouseX: Double, mouseY: Double) = mouseX.toFloat() in (x.toFloat()..(x.toFloat() + WIDTH)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + HEIGHT))
@@ -27,7 +27,7 @@ class PastureSlotIconButton(
private val baseResource = cobblemonResource("textures/gui/pasture/pasture_slot_icon_move.png")
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
blitk(
matrixStack = context.matrices,
x = xPos / SCALE,
@@ -48,7 +48,7 @@ class PastureWidget(
parent = this
)
public override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
blitk(
matrixStack = context.matrices,
texture = baseResource,
@@ -31,7 +31,7 @@ class RecallButton(
private val buttonResource = cobblemonResource("textures/gui/pasture/pasture_button.png")
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
blitk(
matrixStack = context.matrices,
texture = buttonResource,
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.client.gui.pc
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.util.math.MatrixStack
class GrabbedStorageSlot(
x: Int, y: Int,
@@ -18,7 +17,7 @@ class GrabbedStorageSlot(
private val pokemon: Pokemon
) : StorageSlot(x, y, parent, {}) {
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
renderSlot(context = context, posX = mouseX - (width / 2), posY = mouseY - (height / 2), partialTicks = delta)
}
@@ -15,7 +15,6 @@ import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.Text
class NavigationButton(
@@ -32,7 +31,7 @@ class NavigationButton(
private val backwardsButtonResource = cobblemonResource("textures/gui/pc/pc_arrow_previous.png")
}
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
override fun renderWidget(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
val hovered = (isHovered(pMouseX.toDouble(), pMouseY.toDouble()))
blitk(
matrixStack = context.matrices,
@@ -112,7 +112,7 @@ class PCGUI(
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
val matrices = context.matrices
renderBackground(context)
renderBackground(context, mouseX, mouseY, delta)
val x = (width - BASE_WIDTH) / 2
val y = (height - BASE_HEIGHT) / 2
@@ -425,13 +425,14 @@ class PCGUI(
}
}
override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double): Boolean {
override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double, verticalAmount: Double): Boolean {
if (storageWidget.pastureWidget != null) storageWidget.pastureWidget!!.pastureScrollList.mouseScrolled(
mouseX,
mouseY,
amount
amount,
verticalAmount
)
return children().any { it.mouseScrolled(mouseX, mouseY, amount) }
return children().any { it.mouseScrolled(mouseX, mouseY, amount, verticalAmount) }
}
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
@@ -17,7 +17,6 @@ import com.cobblemon.mod.common.util.lang
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.Text
class ReleaseButton(
@@ -33,7 +32,7 @@ class ReleaseButton(
private val buttonResource = cobblemonResource("textures/gui/pc/pc_release_button.png")
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (parent.canDeleteSelected() && !parent.displayConfirmRelease) {
blitk(
matrixStack = context.matrices,
@@ -17,7 +17,6 @@ import com.cobblemon.mod.common.util.lang
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.Text
class ReleaseConfirmButton(
@@ -34,7 +33,7 @@ class ReleaseConfirmButton(
private val buttonResource = cobblemonResource("textures/gui/pc/pc_release_button_confirm.png")
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (parent.canDeleteSelected() && parent.displayConfirmRelease) {
blitk(
matrixStack = context.matrices,
@@ -46,7 +46,7 @@ open class StorageSlot(
override fun playDownSound(soundManager: SoundManager) {
}
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
if (shouldRender()) {
renderSlot(context, x, y, delta)
}

Some files were not shown because too many files have changed in this diff Show More