forked from mirrors/cobblemon
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fde1e4428 | ||
|
|
a2d574300c | ||
|
|
00eca1c019 | ||
|
|
babfb43750 | ||
|
|
3aa94fcd2a | ||
|
|
20a866a0e3 | ||
|
|
67f2146c3c | ||
|
|
ad49106132 | ||
|
|
064df9c26e | ||
|
|
ea2936f204 | ||
|
|
9d7eef9bcd |
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
-49
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -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)
|
||||
|
||||
}
|
||||
+44
-23
@@ -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 }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
+71
-24
@@ -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
|
||||
// }
|
||||
//}
|
||||
+34
-12
@@ -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")
|
||||
// }
|
||||
//}
|
||||
+57
-36
@@ -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)
|
||||
+65
@@ -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)
|
||||
-38
@@ -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)
|
||||
+35
-6
@@ -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)
|
||||
}*/
|
||||
+53
-5
@@ -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)*/
|
||||
+17
-16
@@ -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)
|
||||
}
|
||||
+50
-31
@@ -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)
|
||||
+20
-13
@@ -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")
|
||||
}
|
||||
}
|
||||
+13
-46
@@ -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
|
||||
}
|
||||
+51
-4
@@ -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
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
+3
-2
@@ -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) {
|
||||
|
||||
+5
-4
@@ -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")
|
||||
}
|
||||
+5
-6
@@ -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) }
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -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 {
|
||||
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+4
-4
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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()
|
||||
)
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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))
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+2
-3
@@ -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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
+4
-4
@@ -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
|
||||
}
|
||||
|
||||
+8
-8
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
+11
-23
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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)
|
||||
|
||||
+15
-20
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -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,
|
||||
|
||||
+3
-2
@@ -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(
|
||||
|
||||
+3
-3
@@ -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) {}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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) {}
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -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,
|
||||
|
||||
+16
-17
@@ -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))
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+1
-2
@@ -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
Reference in New Issue
Block a user