forked from mirrors/cobblemon
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c89d6f274 | ||
|
|
8801423ac1 | ||
|
|
c1452c52a7 | ||
|
|
1896cffa66 | ||
|
|
9e8d5c71da | ||
|
|
9e486b9287 |
+9
-80
@@ -2,8 +2,8 @@
|
||||
## [1.5.0](#1-5-0)
|
||||
|
||||
### Additions
|
||||
- Added 17 ruin structures, where you can find Pokémon-themed Armor Trims and Pottery Sherds, Tumblestones, and more.
|
||||
- Added 22 fossil structures, where you can brush Suspicious Sand/Gravel for Fossils.
|
||||
- Added over (number here) ruin structures, where you can find Pokémon-themed Armor Trims and Pottery Sherds, Tumblestones, and more.
|
||||
- Added (number here) fossil structures, where you can brush Suspicious Sand/Gravel for Fossils.
|
||||
- Added the Data Monitor, Fossil Compartment, and Restoration Tank. Placed in the correct formation, you can use these to create a Restoration Machine where you can bring fossils back to life.
|
||||
- Added 3 variants of Tumblestones, which can be planted near Lava or Magma to grow harvestable Tumblestone Clusters.
|
||||
- Added Tumblestone Blocks, a storage block crafted from 9 Tumblestones.
|
||||
@@ -24,19 +24,19 @@
|
||||
- Added a new send-out ball toss animation that showcases the ball used for the Pokémon.
|
||||
- Added simple move animations for Pokémon in battle with a proof of concept for more complicated animations.
|
||||
- Added the EV Boosting Feathers.
|
||||
- Added Type Gems.
|
||||
- Added various new tags for searchability and better compatibility.
|
||||
- Added the [Ability Capsule](https://bulbapedia.bulbagarden.net/wiki/Ability_Capsule) and [Patch](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch), these have no acquisition method for now and only work as intended with the traditional ability format of 1 to 2 common abilities and 1 hidden ability.
|
||||
- Added Gilded Chests, available in all Apricorn colors.
|
||||
- Added Relic Coins, Relic Coin Pouches, and Relic Coin Sacks.
|
||||
- Added various new tags for searchability and better compatibility.
|
||||
- Added Type Gems. These items hold no functionality for now. Start collecting though...
|
||||
- Added 6 custom Pottery Sherds, obtained from ruin structures.
|
||||
- Added cries to Meowth, Alolan Meowth, Galaraian Meowth,
|
||||
- Completed the advancement for placing a Tumblestone near Lava or Magma to make it grow.
|
||||
- Added new held items: Ability Shield, Absorb Bulb, Air Balloon, Binding Band, Blunder Policy, Cell Battery, Covert Cloak, Damp Rock, Eject Button, Eviolite, Expert Belt, Float Stone, Focus Sash, Heat Rock, Icy Rock, Iron Ball, Light Ball, Loaded Dice, Red Card, Shell Bell, Sticky Barb, Smooth Rock, Soothe Bell and Weakness Policy.
|
||||
- Added Hisui starters to the starter selection menu.
|
||||
- Added bubble quirk to Krabby that only play during clear sunset's.
|
||||
- Added forfeit option to PVP battles.
|
||||
- Added visual changes for entities affected by Illusion, Imposter, or Transform in battle.
|
||||
- Added shoulder mounting for Squirtle, Ralts, Roggenrola, Charcadet, Sizzlipede, Litwick, Cutiefly, Flabebe, Flittle, and Scatterbug
|
||||
|
||||
### Pokémon Added
|
||||
#### Gen 2
|
||||
@@ -160,6 +160,8 @@
|
||||
- Dreepy
|
||||
- Drakloak
|
||||
- Dragapult
|
||||
- Hisuian Sliggoo
|
||||
- Hisuian Goodra
|
||||
- Impidimp
|
||||
- Morgrem
|
||||
- Grimmsnarl
|
||||
@@ -170,7 +172,7 @@
|
||||
- Additionally, if you give Gimmighoul a Netherite Scrap, you can increase its Netherite Stash. Who knows what might happen if it fills up?
|
||||
- Gholdengo
|
||||
|
||||
#### Cobblemon Exclusives
|
||||
#### Cobblemon Exclusive's
|
||||
- Hisui Bias Rowlet
|
||||
- Hisui Bias Dartrix
|
||||
- Hisui Bias Cyndaquil
|
||||
@@ -180,69 +182,6 @@
|
||||
- Hisui Bias Goomy
|
||||
- Hisui Bias Petilil
|
||||
|
||||
### Added cries to the following Pokémon
|
||||
- Alolan Raticate
|
||||
- Vulpix, Ninetales
|
||||
- Zubat, Golbat, Crobat
|
||||
- Meowth, Persian
|
||||
- Psyduck, Golduck
|
||||
- Growlithe, Arcanine
|
||||
- Geodude, Graveler, Golem
|
||||
- Doduo, Dodrio
|
||||
- Seel, Dewgong
|
||||
- Muk, Grimer
|
||||
- Krabby, Kingler
|
||||
- Voltorb, Electrode, Hisuian Voltorb, Hisuian Electrode
|
||||
- Tangela, Tangrowth
|
||||
- Snorlax
|
||||
- Cubone, Marowak
|
||||
- Koffing, Weezing
|
||||
- Aerodactyl
|
||||
- Elekid, Electabuzz, Electivire
|
||||
- Omanyte, Omastar
|
||||
- Kabuto, Kabutops
|
||||
- Lapras
|
||||
- Scyther
|
||||
- Hisui Bias Cyndaquil, Hisui Bias Quilava
|
||||
- Igglybuff
|
||||
- Yanma, Yanmega
|
||||
- Gligar, Gliscor
|
||||
- Qwilfish, Hisuian Qwilfish, Overqwil
|
||||
- Sneasel, Hisuian Sneasel, Weavile, Sneasler
|
||||
- Larvitar, Pupitar, Tyranitar
|
||||
- Swinub, Piloswine, Mamoswine
|
||||
- Aron, Lairon, Aggron
|
||||
- Trapinch, Vibrava, Flygon
|
||||
- Cacnea, Cacturne
|
||||
- Barboach, Whiscash
|
||||
- Lileep, Cradily
|
||||
- Anorith, Armaldo
|
||||
- Tropius
|
||||
- Chimecho
|
||||
- Bidoof, Bibarel
|
||||
- Buizel, Floatzel
|
||||
- Gible, Gabite, Garchomp
|
||||
- Hisui Bias Oshawott, Hisui Bias Dewott
|
||||
- Petilil, Lilligant, Hisui Bias Petilil, Hisuian Lilligant
|
||||
- Basculin, Basculegion
|
||||
- Sandile, Krokolok, Krookodile
|
||||
- Darumaka, Darmanitan
|
||||
- Archen, Archeops
|
||||
- Zorua, Zoroark, Hisuian Zorua, Hisuian Zoroark
|
||||
- Tyrunt, Tyrantrum
|
||||
- Amaura Aurorus
|
||||
- Carbink
|
||||
- Goomy, Sliggoo, Goodra, Hisui Bias Goomy, Hisuian Sliggoo, Hisuian Goodra
|
||||
- Klefki
|
||||
- Hisui Bias Rowlet, Hisui Bias Dartrix
|
||||
- Komala
|
||||
- Impidimp, Morgrem, Grimmsnarl
|
||||
- Cufant, Copperajah
|
||||
- Dreepy, Drakloak, Dragapult
|
||||
- Dracozolt, Arctozolt, Dracovish, Arctovish
|
||||
- Lechonk, Oinkologne
|
||||
- Maushold family of three and four
|
||||
|
||||
|
||||
### Changes
|
||||
- Alolan Pikachu and Exeggcute changed to Alola bias.
|
||||
@@ -268,17 +207,12 @@
|
||||
- Reorganised a few advancements.
|
||||
- Pokémon entity shadows now scale when the Pokémon is being sent out or recalled.
|
||||
- Remade Torkoal particles, now they only appear when in battle.
|
||||
- Updated shiny icon within summary and PC interfaces.
|
||||
- Changed the Poison Barb sprite so that it doesn't look like a sword when held.
|
||||
- Moon Stone ore generates more frequently in Taigas and has been added to Magical and Spooky biomes.
|
||||
- Density, Season, and Nether biome tags have been moved and renamed within the biome tags directory.
|
||||
- Added particles to Lucario when in battle.
|
||||
|
||||
### Fixes
|
||||
- Resized Snorlax
|
||||
- Re-added the recipe for the Iron Vitamin.
|
||||
- Cleaned up empty evolutions declaration in species files (no, I'm not listing all 169 by name).
|
||||
- Fixed Exeggcute and Pikachu not being able to evolve.
|
||||
- Fixed Exeggcute not being able to evolve.
|
||||
- Fixed battle lang for Poison Touch Ability
|
||||
- Fixed Cubone not being able to evolve into Alolan Marowak.
|
||||
- Fixed Squawkabilly forms not being recognized.
|
||||
@@ -297,10 +231,6 @@
|
||||
- Fixed an issue that allowed Pokemon to spawn on rails.
|
||||
- Fixed the data set on Pokémon when abilities are given via properties such as in ``/spawnpokemon``.
|
||||
- Fixed sometimes Pokémon losing hidden abilities when evolving, this fix will only take effect to newly created Pokémon.
|
||||
- Fixed capture messages not displaying.
|
||||
- Fixed illusion ability causing the wrong Pokémon to be targeted in battle.
|
||||
- Battles starting with fainted party members no longer cause a softlock on defeat.
|
||||
- Fixed some issues with eyes in the faint animations for Hitmonlee and Phantump
|
||||
|
||||
### Developer
|
||||
- Significantly changed the way properties in PokemonEntity work. This could break some plugins (not in a big way, but changes will be needed).
|
||||
@@ -320,7 +250,6 @@
|
||||
- ``Pokemon#rollAbility`` has been added, this rerolls a legal ability for the Pokémon.
|
||||
- `docs/cobblemon-tags` tags and spawn-presets can now be auto-generated from the current tags in the cobblemon mod with the `generateSpawnPresetList.py` and `generateTagList.py` scripts.
|
||||
- `public_spawns_to_json.py` script has been added to give the powerful spawn.json generator a simplistic UI.
|
||||
- Updated Showdown with Gen 9 DLC.
|
||||
|
||||
### Datapack & Resourcepack Creators
|
||||
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
|
||||
|
||||
@@ -39,8 +39,10 @@ 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
|
||||
@@ -96,4 +98,4 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -11,7 +11,6 @@ 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;
|
||||
@@ -25,7 +24,7 @@ import java.util.Map;
|
||||
@Mixin(EntityRenderDispatcher.class)
|
||||
public class EntityRenderDispatcherMixin {
|
||||
|
||||
@Shadow private Map<SkinTextures.Model, EntityRenderer<? extends PlayerEntity>> modelRenderers;
|
||||
@Shadow private Map<String, EntityRenderer<? extends PlayerEntity>> modelRenderers;
|
||||
|
||||
@Inject(
|
||||
method = "reload",
|
||||
@@ -34,4 +33,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 eventDeltaVerticalWheel;
|
||||
private double eventDeltaWheel;
|
||||
|
||||
@Inject(
|
||||
method = "onMouseScroll",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
target="Lnet/minecraft/client/Mouse;eventDeltaVerticalWheel:D",
|
||||
target="Lnet/minecraft/client/Mouse;eventDeltaWheel: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)eventDeltaVerticalWheel;
|
||||
int i = (int)eventDeltaWheel;
|
||||
if (i > 0) {
|
||||
while (i-- > 0) CobblemonClient.INSTANCE.getStorage().shiftSelected(false);
|
||||
ci.cancel();
|
||||
eventDeltaVerticalWheel = 0;
|
||||
eventDeltaWheel = 0;
|
||||
PartySendBinding.INSTANCE.actioned();
|
||||
} else if (i < 0) {
|
||||
while (i++ < 0) CobblemonClient.INSTANCE.getStorage().shiftSelected(true);
|
||||
ci.cancel();
|
||||
eventDeltaVerticalWheel = 0;
|
||||
eventDeltaWheel = 0;
|
||||
PartySendBinding.INSTANCE.actioned();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
-39
@@ -15,8 +15,15 @@ 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;
|
||||
@@ -26,6 +33,9 @@ import java.util.*;
|
||||
|
||||
@Mixin(StructurePoolBasedGenerator.StructurePoolGenerator.class)
|
||||
public abstract class StructurePoolGeneratorMixin {
|
||||
@Final
|
||||
@Mutable
|
||||
@Shadow Deque<StructurePoolBasedGenerator.ShapedPoolStructurePiece> structurePieces;
|
||||
|
||||
Map<String, Integer> generatedStructureGroupCounts;
|
||||
|
||||
@@ -93,7 +103,7 @@ public abstract class StructurePoolGeneratorMixin {
|
||||
generatedStructureGroupCounts = new HashMap<>();
|
||||
}
|
||||
|
||||
@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)
|
||||
@ModifyVariable(method = "generatePiece", at = @At("STORE"), ordinal = 1)
|
||||
private Iterator<StructurePoolElement> reduceStructurePoolElementIterator(Iterator<StructurePoolElement> iterator) {
|
||||
List<StructurePoolElement> reducedList = new ArrayList<>();
|
||||
|
||||
@@ -113,7 +123,7 @@ public abstract class StructurePoolGeneratorMixin {
|
||||
return reducedList.iterator();
|
||||
}
|
||||
|
||||
@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)
|
||||
@ModifyVariable(method = "generatePiece", at = @At("STORE"), ordinal = 1)
|
||||
private PoolStructurePiece injected(PoolStructurePiece poolStructurePiece) {
|
||||
Identifier structureLocationKey = getCobblemonOnlyLocation(poolStructurePiece.getPoolElement());
|
||||
if (structureLocationKey != null) {
|
||||
@@ -123,42 +133,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);
|
||||
@@ -204,4 +214,4 @@ public abstract class StructurePoolGeneratorMixin {
|
||||
//
|
||||
// return reducedList;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
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;
|
||||
@@ -18,23 +19,23 @@ import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
public interface BlocksInvoker {
|
||||
|
||||
@Invoker("createLogBlock")
|
||||
static Block createLogBlock(MapColor topMapColor, MapColor sideMapColor) {
|
||||
static PillarBlock createLogBlock(MapColor topMapColor, MapColor sideMapColor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Invoker("createLeavesBlock")
|
||||
static Block createLeavesBlock(BlockSoundGroup soundGroup) {
|
||||
static LeavesBlock createLeavesBlock(BlockSoundGroup soundGroup) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Invoker("createWoodenButtonBlock")
|
||||
static Block createWoodenButtonBlock(BlockSetType blockSetType) {
|
||||
static ButtonBlock createWoodenButtonBlock(BlockSetType blockSetType, FeatureFlag... requiredFeatures) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Invoker("createFlowerPotBlock")
|
||||
static Block createFlowerPotBlock(Block flower) {
|
||||
static FlowerPotBlock createFlowerPotBlock(Block flower, FeatureFlag... requiredFeatures) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,14 @@ 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(BlockSetType blockSetType, AbstractBlock.Settings settings) {
|
||||
static DoorBlock cobblemon$create(AbstractBlock.Settings settings, BlockSetType blockSetType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -11,13 +11,14 @@ 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(BlockSetType type, AbstractBlock.Settings settings) {
|
||||
static PressurePlateBlock cobblemon$create(PressurePlateBlock.ActivationRule type, AbstractBlock.Settings settings, BlockSetType blockSetType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -11,13 +11,14 @@ 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(BlockSetType blockSetType, AbstractBlock.Settings settings) {
|
||||
static TrapdoorBlock cobblemon$create(AbstractBlock.Settings settings, BlockSetType blockSetType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ import kotlin.reflect.jvm.javaField
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object Cobblemon {
|
||||
const val MODID = CobblemonBuildDetails.MOD_ID
|
||||
const val VERSION = CobblemonBuildDetails.VERSION
|
||||
const val MODID = "cobblemon"
|
||||
const val VERSION = "1.4.0"
|
||||
const val CONFIG_PATH = "config/$MODID/main.json"
|
||||
val LOGGER: Logger = LogManager.getLogger()
|
||||
|
||||
|
||||
@@ -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(APRICORN_WOOD_TYPE, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
|
||||
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))
|
||||
@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`(APRICORN_BLOCK_SET_TYPE, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD)))
|
||||
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))
|
||||
@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`(APRICORN_BLOCK_SET_TYPE, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).instrument(Instrument.BASS).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque()))
|
||||
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))
|
||||
@JvmField
|
||||
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 }))
|
||||
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))
|
||||
|
||||
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): Block {
|
||||
private fun log(name: String, arg: MapColor = MapColor.DIRT_BROWN, arg2: MapColor = MapColor.DIRT_BROWN): PillarBlock {
|
||||
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(UniformIntProvider.create(1, 2), AbstractBlock.Settings.copy(Blocks.IRON_ORE)))
|
||||
private fun evolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(AbstractBlock.Settings.copy(Blocks.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)))
|
||||
private fun deepslateEvolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(AbstractBlock.Settings.copy(Blocks.DEEPSLATE_IRON_ORE), UniformIntProvider.create(1, 2)))
|
||||
|
||||
/**
|
||||
* Helper method for creating leaves
|
||||
* copied over from Vanilla
|
||||
*/
|
||||
private fun leaves(name: String): Block {
|
||||
private fun leaves(name: String): LeavesBlock {
|
||||
val block = BlocksInvoker.createLeavesBlock(BlockSoundGroup.GRASS)
|
||||
return this.create(name, block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ interface CobblemonImplementation {
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
fun <T : Criterion<*>> registerCriteria(id: String, criteria: T): T
|
||||
fun <T : Criterion<*>> registerCriteria(criteria: T): T
|
||||
|
||||
/**
|
||||
* TODO
|
||||
@@ -240,4 +240,4 @@ enum class Environment {
|
||||
CLIENT,
|
||||
SERVER
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,18 +9,8 @@
|
||||
package com.cobblemon.mod.common.advancement
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
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 com.cobblemon.mod.common.advancement.criterion.*
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.advancement.criterion.Criterion
|
||||
|
||||
/**
|
||||
@@ -30,37 +20,107 @@ import net.minecraft.advancement.criterion.Criterion
|
||||
* @since October 26th, 2022
|
||||
*/
|
||||
object CobblemonCriteria {
|
||||
val PICK_STARTER = this.create("pick_starter", SimpleCriterionTrigger(PokemonCriterion.CODEC))
|
||||
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 CATCH_POKEMON = this.create("catch_pokemon", SimpleCriterionTrigger(CaughtPokemonCriterion.CODEC))
|
||||
val DEFEAT_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pokemon_defeated"),
|
||||
SimpleCountableCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val CATCH_SHINY_POKEMON = this.create("catch_shiny_pokemon", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
val COLLECT_ASPECT = this.create(
|
||||
AspectCriterionTrigger(
|
||||
cobblemonResource("aspects_collected"),
|
||||
AspectCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val EGG_HATCH = this.create("eggs_hatched", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
val POKEMON_INTERACT = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pokemon_interact"),
|
||||
PokemonInteractCriterion::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val EVOLVE_POKEMON = this.create("pokemon_evolved", SimpleCriterionTrigger(EvolvePokemonCriterion.CODEC))
|
||||
val PARTY_CHECK = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("party"),
|
||||
PartyCheckCriterion::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val WIN_BATTLE = this.create("battles_won", SimpleCriterionTrigger(BattleCountableCriterion.CODEC))
|
||||
val LEVEL_UP = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("level_up"),
|
||||
LevelUpCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val DEFEAT_POKEMON = this.create("pokemon_defeated", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
val PASTURE_USE = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pasture_use"),
|
||||
PickStarterCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val COLLECT_ASPECT = this.create("aspects_collected", SimpleCriterionTrigger(AspectCriterion.CODEC))
|
||||
val RESURRECT_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("resurrect_pokemon"),
|
||||
PickStarterCriterionCondition::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))
|
||||
val TRADE_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("trade_pokemon"),
|
||||
TradePokemonCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
// Advancement criteria for [grow_tumblestone.json]
|
||||
val PLANT_TUMBLESTONE = this.create("plant_tumblestone", SimpleCriterionTrigger(PlantTumblestoneCriterion.CODEC))
|
||||
val PLANT_TUMBLESTONE = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("plant_tumblestone"),
|
||||
PlantTumblestoneCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
private fun <T : Criterion<*>> create(id: String, criteria: T): T = Cobblemon.implementation.registerCriteria(id, criteria)
|
||||
private fun <T : Criterion<*>> create(criteria: T): T = Cobblemon.implementation.registerCriteria(criteria)
|
||||
|
||||
}
|
||||
+23
-44
@@ -8,59 +8,38 @@
|
||||
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
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 AspectCriterion(
|
||||
playerCtx: Optional<LootContextPredicate>,
|
||||
val pokemon: Identifier,
|
||||
val aspects: List<String>
|
||||
): SimpleCriterionCondition<MutableMap<Identifier, MutableSet<String>>>(playerCtx) {
|
||||
open class AspectCriterionTrigger(identifier: Identifier, criterionClass: Class<AspectCriterionCondition>) : SimpleCriterionTrigger<MutableMap<Identifier, MutableSet<String>>, AspectCriterionCondition>(identifier, criterionClass) {
|
||||
|
||||
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) }
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
//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 }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
}
|
||||
+24
-71
@@ -10,105 +10,58 @@ package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import com.cobblemon.mod.common.util.toJsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
open class BattleCountableContext(var battle : PokemonBattle, times : Int) : CountableContext(times)
|
||||
open class BattleCountableCriterionTrigger(identifier: Identifier, criterionClass: Class<BattleCountableCriterionCondition>) : SimpleCriterionTrigger<BattleCountableContext, BattleCountableCriterionCondition>(identifier, criterionClass) {
|
||||
|
||||
class BattleCountableCriterion(
|
||||
playerCtx: Optional<LootContextPredicate>,
|
||||
val battleTypes: List<String>,
|
||||
count: Int
|
||||
): CountableCriterion<BattleCountableContext>(playerCtx, count) {
|
||||
}
|
||||
|
||||
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) }
|
||||
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())
|
||||
}
|
||||
|
||||
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 typeCheck && super.matches(player, context)
|
||||
return context.times >= count && typeCheck
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//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
|
||||
// }
|
||||
//}
|
||||
open class BattleCountableContext(times : Int, var battle : PokemonBattle) : CountableContext(times)
|
||||
+12
-34
@@ -8,13 +8,10 @@
|
||||
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.predicate.entity.EntityPredicate
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* A context that is used when you require a [CountableContext] along with some type string.
|
||||
@@ -24,38 +21,19 @@ import java.util.Optional
|
||||
*/
|
||||
open class CountablePokemonTypeContext(times: Int, var type: String) : CountableContext(times)
|
||||
|
||||
class CaughtPokemonCriterion(
|
||||
playerCtx: Optional<LootContextPredicate>,
|
||||
val type: String,
|
||||
count: Int
|
||||
): CountableCriterion<CountablePokemonTypeContext>(playerCtx, count) {
|
||||
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)
|
||||
}
|
||||
|
||||
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 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")
|
||||
}
|
||||
}
|
||||
|
||||
//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")
|
||||
// }
|
||||
//}
|
||||
}
|
||||
+36
-57
@@ -8,69 +8,48 @@
|
||||
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.predicate.entity.EntityPredicate
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 toJson(json: JsonObject) {
|
||||
json.addProperty("count", count)
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: T) = context.times >= count
|
||||
|
||||
}
|
||||
|
||||
///**
|
||||
// * 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)
|
||||
/**
|
||||
* 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
@@ -1,65 +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.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
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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)
|
||||
+6
-35
@@ -9,43 +9,12 @@
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.predicate.entity.EntityPredicate
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
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) {
|
||||
class LevelUpCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<LevelUpContext>(id, entity) {
|
||||
var level = 0
|
||||
var evolved = true
|
||||
override fun toJson(json: JsonObject) {
|
||||
@@ -67,4 +36,6 @@ class LevelUpCriterion(
|
||||
}
|
||||
return level == context.level && evolutionCheck == evolved
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
open class LevelUpContext(var level : Int, var pokemon : Pokemon)
|
||||
+5
-53
@@ -10,62 +10,14 @@ 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.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.predicate.entity.EntityPredicate
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
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(
|
||||
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){
|
||||
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 {
|
||||
@@ -99,4 +51,4 @@ class PartyCheckCriterion(
|
||||
}
|
||||
}
|
||||
|
||||
open class PartyCheckContext(val party : PlayerPartyStore)*/
|
||||
open class PartyCheckContext(val party : PlayerPartyStore)
|
||||
+16
-17
@@ -10,27 +10,26 @@ package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.predicate.entity.EntityPredicate
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
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) }
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: Pokemon): Boolean {
|
||||
return properties.matches(context)
|
||||
override fun fromJson(json: JsonObject) {
|
||||
properties = PokemonProperties.parse(json.get("properties")?.asString ?: "")
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: Pokemon) = properties.matches(context)
|
||||
}
|
||||
+31
-50
@@ -9,63 +9,44 @@
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.block.TumblestoneBlock
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import java.util.Optional
|
||||
|
||||
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) }
|
||||
/**
|
||||
* 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.block.canGrow(context.pos, player.world)
|
||||
return context.tumbleStoneBlock.canGrow(context.pos, player.world)
|
||||
}
|
||||
}
|
||||
|
||||
///**
|
||||
// * 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)
|
||||
/**
|
||||
* 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)
|
||||
|
||||
+13
-20
@@ -9,33 +9,26 @@
|
||||
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.EntityPredicate
|
||||
import com.google.gson.JsonObject
|
||||
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 PokemonInteractContext(val type: Identifier, val item: Identifier)
|
||||
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 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 fromJson(json: JsonObject) {
|
||||
type = json.get("type")?.asString ?: "any"
|
||||
item = json.get("item")?.asString ?: "any"
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: PokemonInteractContext): Boolean {
|
||||
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")
|
||||
return (context.type == type.asIdentifierDefaultingNamespace() || type == "any") && (context.item == item.asIdentifierDefaultingNamespace() || item == "any")
|
||||
}
|
||||
}
|
||||
+46
-13
@@ -8,28 +8,61 @@
|
||||
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.google.gson.JsonObject
|
||||
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 java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class SimpleCriterionTrigger<T, C : SimpleCriterionCondition<T>>(
|
||||
val codec: Codec<C>,
|
||||
/**
|
||||
* 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>
|
||||
) : AbstractCriterion<C>() {
|
||||
override fun getConditionsCodec() = codec
|
||||
|
||||
fun trigger(player: ServerPlayerEntity, context: T) {
|
||||
return this.trigger(player) {
|
||||
it.matches(player, context)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
fun trigger(player: ServerPlayerEntity, context: T) = 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>(
|
||||
val playerCtx: Optional<LootContextPredicate>
|
||||
) : AbstractCriterion.Conditions {
|
||||
override fun player() = playerCtx
|
||||
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)
|
||||
|
||||
abstract fun matches(player: ServerPlayerEntity, context: T): Boolean
|
||||
}
|
||||
+4
-51
@@ -10,59 +10,12 @@ package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.predicate.entity.EntityPredicate
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.dynamic.Codecs
|
||||
import java.util.Optional
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
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) {
|
||||
class TradePokemonCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<TradePokemonContext>(id, entity) {
|
||||
var traded = "any"
|
||||
var received = "any"
|
||||
var tradedHeldItem = "any"
|
||||
@@ -91,4 +44,4 @@ class TradePokemonCriterion(
|
||||
}
|
||||
}
|
||||
|
||||
open class TradePokemonContext(val traded: Pokemon, val received: Pokemon)*/
|
||||
open class TradePokemonContext(val traded: Pokemon, val received: Pokemon)
|
||||
@@ -13,13 +13,8 @@ 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.
|
||||
@@ -27,7 +22,7 @@ import net.minecraft.world.gen.feature.ConfiguredFeature
|
||||
* @author Licious
|
||||
* @since October 29th, 2022
|
||||
*/
|
||||
enum class Apricorn : StringIdentifiable {
|
||||
enum class Apricorn {
|
||||
|
||||
BLACK,
|
||||
BLUE,
|
||||
@@ -87,20 +82,4 @@ enum class Apricorn : StringIdentifiable {
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.cobblemon.mod.common.api.battles.effects
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.spawning.TimeRange
|
||||
import com.cobblemon.mod.common.util.math.orMax
|
||||
import com.cobblemon.mod.common.util.math.orMin
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
/**
|
||||
* Represents a field condition that can occur at battle start.
|
||||
*
|
||||
* @param identifier The [Identifier] of this condition.
|
||||
* @param biomes: A [MutableSet] of biomes that this condition will succeed in.
|
||||
* @param timeRange A [TimeRange] that this condition will succeed in.
|
||||
* @param isRaining Whether this condition requires rain to succeed. When null, will not perform any check.
|
||||
* @param isThundering Whether this condition requires thunder to succeed. When null, will not perform any check.
|
||||
* @param result The showdown ID of the field condition to apply.
|
||||
*
|
||||
* @author whatsy
|
||||
* @since April 9th, 2024
|
||||
*/
|
||||
data class BattleStartCondition(
|
||||
var identifier: Identifier,
|
||||
val biomes: MutableSet<RegistryLikeCondition<Biome>>,
|
||||
val timeRange: TimeRange? = null,
|
||||
val isRaining: Boolean?,
|
||||
val isThundering: Boolean?,
|
||||
|
||||
val minX: Float? = null,
|
||||
val minY: Float? = null,
|
||||
val minZ: Float? = null,
|
||||
val maxX: Float? = null,
|
||||
val maxY: Float? = null,
|
||||
val maxZ: Float? = null,
|
||||
|
||||
val result: String
|
||||
) {
|
||||
/***
|
||||
* Checks if this [BattleStartCondition] can succeed in the context of the provided [PokemonBattle].
|
||||
*
|
||||
* @author whatsy
|
||||
* @since April 9th, 2024
|
||||
*/
|
||||
fun matches(battle: PokemonBattle): Boolean {
|
||||
val player = battle.players.first()
|
||||
val world = player.world ?: return false
|
||||
if (!world.gameRules.getBoolean(CobblemonGameRules.WEATHER_AFFECTS_BATTLES)) return false
|
||||
val pos = player.blockPos ?: return false
|
||||
val biomeRegistry: Registry<Biome> by lazy { world.registryManager.get(RegistryKeys.BIOME) }
|
||||
val biome = world.getBiome(pos).value()
|
||||
|
||||
if (biomes.isNotEmpty() && biomes.none { condition -> condition.fits(biome, biomeRegistry) }) {
|
||||
return false
|
||||
} else if (timeRange != null && !timeRange.contains((world.timeOfDay % 24000).toInt())) {
|
||||
return false
|
||||
} else if (world.isRaining != isRaining && isRaining != null) {
|
||||
return false
|
||||
} else if (world.isThundering != isThundering && isThundering != null) {
|
||||
return false
|
||||
} else if (pos.x < minX.orMin() || pos.x > maxX.orMax()) {
|
||||
return false
|
||||
} else if (pos.y < minY.orMin() || pos.y > maxY.orMax()) {
|
||||
return false
|
||||
} else if (pos.z < minZ.orMin() || pos.z > maxZ.orMax()) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.cobblemon.mod.common.api.battles.effects
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.api.spawning.TimeRange
|
||||
import com.cobblemon.mod.common.util.adapters.BiomeLikeConditionAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IntRangesAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.resource.ResourceType
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
object BattleStartConditions : JsonDataRegistry<BattleStartCondition> {
|
||||
|
||||
override val id = cobblemonResource("start_conditions")
|
||||
override val type = ResourceType.SERVER_DATA
|
||||
override val observable = SimpleObservable<BattleStartConditions>()
|
||||
|
||||
override val gson = GsonBuilder()
|
||||
.disableHtmlEscaping()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(TimeRange::class.java, IntRangesAdapter(TimeRange.timeRanges) { TimeRange(*it) })
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
||||
.create()
|
||||
|
||||
override val typeToken = TypeToken.get(BattleStartCondition::class.java)
|
||||
override val resourcePath = "start_conditions"
|
||||
|
||||
private val conditions = hashMapOf<Identifier, BattleStartCondition>()
|
||||
|
||||
override fun reload(data: Map<Identifier, BattleStartCondition>) {
|
||||
this.conditions.clear()
|
||||
data.forEach { id, condition ->
|
||||
try {
|
||||
condition.identifier = id
|
||||
this.conditions[id] = condition
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.error("Skipped loading battle start condition: {}", condition.identifier)
|
||||
}
|
||||
Cobblemon.LOGGER.info("Loaded {} battle start conditions", this.conditions.size)
|
||||
this.observable.emit(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayerEntity) {
|
||||
// no need for the client to know about these since it's all handled server-side
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all loaded [BattleStartCondition]s.
|
||||
*/
|
||||
fun all() = this.conditions.values.toList()
|
||||
|
||||
}
|
||||
+1
-1
@@ -170,7 +170,7 @@ class BattleMessage(rawMessage: String) {
|
||||
*/
|
||||
fun pnxAndUuid(index: Int): Pair<String, String>? {
|
||||
val argument = this.argumentAt(index)?.takeIf { it.length >= 2 }?.split(":")?.takeIf { it.size == 2 } ?: return null
|
||||
val pnx = argument[0].takeIf { it.matches(PNX_MATCHER) || it.matches(PN_MATCHER) } ?: return null
|
||||
val pnx = argument[0].takeIf { it.matches(PNX_MATCHER) } ?: return null
|
||||
val uuid = argument[1].trim()
|
||||
return pnx to uuid
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
|
||||
import com.cobblemon.mod.common.battles.interpreter.ContextManager
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.battles.runner.ShowdownService
|
||||
import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
|
||||
import com.cobblemon.mod.common.battles.ForfeitActionResponse
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
|
||||
@@ -45,11 +46,15 @@ import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgre
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.evolution.requirements.DefeatRequirement
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
import net.minecraft.entity.Entity
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.world.World
|
||||
import java.util.concurrent.ConcurrentLinkedDeque
|
||||
|
||||
/**
|
||||
@@ -65,7 +70,7 @@ open class PokemonBattle(
|
||||
val side2: BattleSide
|
||||
) {
|
||||
/** Whether logging will be silenced for this battle. */
|
||||
var mute = true
|
||||
var mute = false
|
||||
|
||||
init {
|
||||
side1.battle = this
|
||||
@@ -119,6 +124,47 @@ open class PokemonBattle(
|
||||
val minorBattleActions = hashMapOf<UUID, BattleMessage>()
|
||||
val contextManager = ContextManager()
|
||||
|
||||
var bedrockEntity: GenericBedrockEntity? = null
|
||||
val world: World
|
||||
get() = this.players.first().world
|
||||
|
||||
val pokemonPositions: Set<Vec3d>
|
||||
get() {
|
||||
val vectors = mutableSetOf<Vec3d>()
|
||||
activePokemon.forEach {
|
||||
if (it.position != null) vectors.add(it.position!!.second)
|
||||
}
|
||||
return vectors
|
||||
}
|
||||
|
||||
fun getOrCreateBedrockEntity(): GenericBedrockEntity {
|
||||
return if (bedrockEntity != null) {
|
||||
bedrockEntity!!
|
||||
} else {
|
||||
bedrockEntity = GenericBedrockEntity(world = world)
|
||||
bedrockEntity!!.apply {
|
||||
category = cobblemonResource("field_particles")
|
||||
syncAge = false
|
||||
if (pokemonPositions.isNotEmpty()) setPosition(getPosForBedrockEntity(pokemonPositions))
|
||||
}
|
||||
world.spawnEntity(bedrockEntity)
|
||||
bedrockEntity!!
|
||||
}
|
||||
}
|
||||
|
||||
fun getPosForBedrockEntity(vectors: Set<Vec3d>): Vec3d {
|
||||
var sumX = 0.0
|
||||
var sumZ = 0.0
|
||||
for (vector in vectors) {
|
||||
sumX += vector.x
|
||||
sumZ += vector.z
|
||||
}
|
||||
val count = vectors.size
|
||||
val y = vectors.maxByOrNull { it.y }?.y ?: 0.0
|
||||
|
||||
return Vec3d(sumX / count, y + 5.0, sumZ / count)
|
||||
}
|
||||
|
||||
/** Whether or not there is one side with at least one player, and the other only has wild Pokémon. */
|
||||
val isPvW: Boolean
|
||||
get() {
|
||||
@@ -217,6 +263,7 @@ open class PokemonBattle(
|
||||
|
||||
fun end() {
|
||||
ended = true
|
||||
bedrockEntity?.remove(Entity.RemovalReason.DISCARDED)
|
||||
this.actors.forEach { actor ->
|
||||
val faintedPokemons = actor.pokemonList.filter { it.health <= 0 }
|
||||
actor.getSide().getOppositeSide().actors.forEach { opponent ->
|
||||
@@ -396,6 +443,8 @@ open class PokemonBattle(
|
||||
return
|
||||
}
|
||||
|
||||
bedrockEntity?.setPosition(getPosForBedrockEntity(pokemonPositions))
|
||||
|
||||
if (started) {
|
||||
ticks++
|
||||
if (isPvW && !ended && dispatches.isEmpty()) checkFlee()
|
||||
@@ -497,4 +546,4 @@ open class PokemonBattle(
|
||||
|
||||
return queryStruct
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ object Berries : JsonDataRegistry<Berry> {
|
||||
.disableHtmlEscaping()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(MulchVariant::class.java, MulchVariantAdapter)
|
||||
.registerTypeAdapter(NumberRange.DoubleRange::class.java, FloatNumberRangeAdapter)
|
||||
.registerTypeAdapter(NumberRange.FloatRange::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,6 +11,7 @@ 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
|
||||
@@ -47,7 +48,7 @@ class Fossil(
|
||||
}
|
||||
|
||||
return this.fossils.all { fossil ->
|
||||
ingredients.any { fossil.test(it) }
|
||||
ingredients.any { fossil.item.fits(it.item, Registries.ITEM) && fossil.nbt.test(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ class Fossil(
|
||||
|
||||
return ingredients.all { ingredient ->
|
||||
ingredients.count { item -> ingredient.itemMatches(item.registryEntry) } <=
|
||||
this.fossils.count { fossil -> fossil.test(ingredient) }
|
||||
this.fossils.count { fossil -> fossil.item.fits(ingredient.item, Registries.ITEM) && fossil.nbt.test(ingredient) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +74,7 @@ class Fossil(
|
||||
* @return True if the [ItemStack] is an ingredient, false otherwise.
|
||||
*/
|
||||
fun isIngredient(itemStack: ItemStack): Boolean {
|
||||
return this.fossils.any { it.test(itemStack) }
|
||||
return this.fossils.any { it.item.fits(itemStack.item, Registries.ITEM) && it.nbt.test(itemStack) }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,10 +47,10 @@ abstract class ParentWidget(
|
||||
super.mouseMoved(pMouseX, pMouseY)
|
||||
}
|
||||
|
||||
override fun mouseScrolled(mouseX: Double, mouseY: Double, horizontalAmount: Double, verticalAmount: Double): Boolean {
|
||||
override fun mouseScrolled(pMouseX: Double, pMouseY: Double, pDelta: Double): Boolean {
|
||||
return children.any {
|
||||
it.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)
|
||||
} || super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)
|
||||
it.mouseScrolled(pMouseX, pMouseY, pDelta)
|
||||
} || super.mouseScrolled(pMouseX, pMouseY, pDelta)
|
||||
}
|
||||
|
||||
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.effectiveName().string }
|
||||
stringify = { it.entityName }
|
||||
)
|
||||
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.DoubleRange::class.java, FloatNumberRangeAdapter)
|
||||
.registerTypeAdapter(NumberRange.FloatRange::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.lengthX.pow(2)) + 1.5F + sqrt(2 * target.boundingBox.lengthX.pow(2))).toFloat()
|
||||
val proximity = this.proximity.takeIf { it != -1F } ?: (sqrt(2 * user.boundingBox.xLength.pow(2)) + 1.5F + sqrt(2 * target.boundingBox.xLength.pow(2))).toFloat()
|
||||
|
||||
if (target.distanceTo(user) !in proximity..20F) {
|
||||
future.complete(Unit)
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
package com.cobblemon.mod.common.api.multiblock
|
||||
|
||||
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
|
||||
import net.minecraft.block.BlockRenderType
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.BlockWithEntity
|
||||
import net.minecraft.block.*
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
@@ -21,8 +19,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]
|
||||
@@ -61,15 +59,14 @@ 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?): BlockState {
|
||||
val result = super.onBreak(world, pos, state, player)
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
|
||||
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? {
|
||||
@@ -81,11 +78,11 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
|
||||
return BlockRenderType.MODEL
|
||||
}
|
||||
|
||||
override fun getPickStack(world: WorldView, pos: BlockPos, state: BlockState): ItemStack {
|
||||
override fun getPickStack(world: BlockView, 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)
|
||||
fun markRemoved(world: World):Unit
|
||||
fun onTriggerEvent(state: BlockState?, world: ServerWorld?, pos: BlockPos?, random: Random?)
|
||||
}
|
||||
@@ -27,7 +27,6 @@ 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
|
||||
@@ -55,11 +54,6 @@ 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()
|
||||
@@ -502,7 +496,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.Serialization.toJsonString(it)) }
|
||||
nickname?.let { nbt.putString(DataKeys.POKEMON_NICKNAME, Text.Serializer.toJson(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) }
|
||||
@@ -530,7 +524,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.Serialization.fromJson(tag.getString(DataKeys.POKEMON_NICKNAME)) else null
|
||||
nickname = if (tag.contains(DataKeys.POKEMON_NICKNAME)) Text.Serializer.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
|
||||
@@ -560,7 +554,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.Serialization.toJsonString(it)) }
|
||||
nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, Text.Serializer.toJson(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) }
|
||||
@@ -589,7 +583,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.Serialization.fromJson(it) }
|
||||
nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let { Text.Serializer.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
|
||||
@@ -677,4 +671,4 @@ open class PokemonProperties {
|
||||
return potentialAbility.template.create(false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,8 +123,10 @@ class RotateYCameraMode : ParticleCameraMode {
|
||||
viewDirection: Vec3d
|
||||
): Quaternionf {
|
||||
val i = if (angle == 0F) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
|
||||
val q2 = RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw)
|
||||
|
||||
val q2 = RotationAxis.POSITIVE_Y.rotationDegrees(/*180 - */cameraYaw)
|
||||
q2.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees(i))
|
||||
|
||||
return q2
|
||||
}
|
||||
|
||||
@@ -189,10 +191,9 @@ class LookAtY : ParticleCameraMode {
|
||||
cameraPitch: Float,
|
||||
viewDirection: Vec3d
|
||||
): Quaternionf {
|
||||
val i = if (angle == 0F) 0F else MathHelper.lerp(deltaTicks, prevAngle, angle)
|
||||
val q2 = RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw)
|
||||
q2.hamiltonProduct(RotationAxis.POSITIVE_Z.rotationDegrees(i))
|
||||
return q2
|
||||
val rotation = Quaternionf(0F, 0F, 0F, 1F)
|
||||
rotation.hamiltonProduct(RotationAxis.POSITIVE_Y.rotationDegrees(-cameraYaw))
|
||||
return rotation
|
||||
}
|
||||
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
|
||||
@@ -65,7 +65,7 @@ class DynamicParticleRotation(
|
||||
override val type = ParticleRotationType.DYNAMIC
|
||||
override fun <T> encode(ops: DynamicOps<T>) = CODEC.encodeStart(ops, this)
|
||||
override fun getInitialRotation(runtime: MoLangRuntime) = runtime.resolveDouble(startRotation)
|
||||
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = runtime.resolveDouble(speed) / 20
|
||||
override fun getInitialAngularVelocity(runtime: MoLangRuntime) = runtime.resolveDouble(speed)
|
||||
override fun getAngularAcceleration(runtime: MoLangRuntime, angularVelocity: Double): Double {
|
||||
val acceleration = runtime.resolveDouble(acceleration)
|
||||
val nextVelocity = angularVelocity + acceleration
|
||||
|
||||
@@ -39,7 +39,8 @@ class TimeRange : IntRanges {
|
||||
"dusk" to TimeRange(11834..13701),
|
||||
"twilight" to TimeRange(11834..13701, 22300..23999, 0..166),
|
||||
"morning" to TimeRange(0..4999),
|
||||
"afternoon" to TimeRange(7000..12039)
|
||||
"afternoon" to TimeRange(7000..12039),
|
||||
"midday" to TimeRange(1000..11000)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ class ReforgedConversion(val base: Path) : CobblemonConverter<NbtCompound> {
|
||||
return null
|
||||
}
|
||||
|
||||
val nbt = NbtIo.read(target)
|
||||
val nbt = NbtIo.read(target.toFile())
|
||||
if(nbt != null) {
|
||||
return (if (extension == "pk") party(uuid, nbt) else pc(uuid, nbt)) as T
|
||||
}
|
||||
|
||||
+2
-3
@@ -14,7 +14,6 @@ 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
|
||||
@@ -30,7 +29,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.toPath())
|
||||
override fun save(file: File, serialized: NbtCompound) = NbtIo.writeCompressed(serialized, file)
|
||||
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)
|
||||
@@ -38,7 +37,7 @@ open class NBTStoreAdapter(
|
||||
storeClass.getConstructor(UUID::class.java).newInstance(uuid)
|
||||
}
|
||||
return try {
|
||||
val nbt = NbtIo.readCompressed(file.toPath(), NbtSizeTracker.ofUnlimitedBytes())
|
||||
val nbt = NbtIo.readCompressed(file)
|
||||
store.loadFromNBT(nbt)
|
||||
store
|
||||
} catch (e: Exception) {
|
||||
|
||||
+4
-5
@@ -16,7 +16,6 @@ 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 {
|
||||
@@ -62,13 +61,13 @@ object NbtMoLangDataStoreFactory : MoLangDataStoreFactory {
|
||||
cache[uuid]!!
|
||||
else {
|
||||
val file = this.file(uuid)
|
||||
if (!file.toFile().exists()) {
|
||||
if (!file.exists()) {
|
||||
val data = VariableStruct()
|
||||
cache[uuid] = data
|
||||
return data
|
||||
}
|
||||
|
||||
val nbt = NbtIo.readCompressed(file(uuid), NbtSizeTracker.ofUnlimitedBytes())
|
||||
val nbt = NbtIo.readCompressed(file(uuid))
|
||||
|
||||
// If it's not a VariableStruct then someone's fucked around and will subsequently find out
|
||||
val data = readMoValueFromNBT(nbt) as VariableStruct
|
||||
@@ -81,10 +80,10 @@ object NbtMoLangDataStoreFactory : MoLangDataStoreFactory {
|
||||
val file = file(uuid)
|
||||
val data = cache[uuid] ?: return
|
||||
val nbt = writeMoValueToNBT(data)!! as NbtCompound
|
||||
file.toFile().parentFile.mkdirs()
|
||||
file.parentFile.mkdirs()
|
||||
NbtIo.writeCompressed(nbt, file)
|
||||
dirty -= uuid
|
||||
}
|
||||
|
||||
private fun file(uuid: UUID) = savePath.resolve("playermolangdata/${uuid.toString().substring(0, 2)}/$uuid.dat")
|
||||
private fun file(uuid: UUID) = savePath.resolve("playermolangdata/${uuid.toString().substring(0, 2)}/$uuid.dat").toFile()
|
||||
}
|
||||
+6
-5
@@ -10,6 +10,7 @@ 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
|
||||
@@ -62,7 +63,7 @@ open class PlayerPartyStore(
|
||||
pokemon.refreshOriginalTrainer()
|
||||
|
||||
return if (super.add(pokemon)) {
|
||||
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, this) }
|
||||
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, PartyCheckContext(this)) }
|
||||
true
|
||||
} else {
|
||||
val player = playerUUID.getPlayer()
|
||||
@@ -178,21 +179,21 @@ open class PlayerPartyStore(
|
||||
if (pokemon1 != null && pokemon2 != null) {
|
||||
val player = pokemon1.getOwnerPlayer()
|
||||
if (player != null) {
|
||||
CobblemonCriteria.PARTY_CHECK.trigger(player, this)
|
||||
CobblemonCriteria.PARTY_CHECK.trigger(player, PartyCheckContext(this))
|
||||
}
|
||||
} else if (pokemon1 != null || pokemon2 != null) {
|
||||
var player = pokemon1?.getOwnerPlayer()
|
||||
if (player != null) {
|
||||
CobblemonCriteria.PARTY_CHECK.trigger(player, this)
|
||||
CobblemonCriteria.PARTY_CHECK.trigger(player, PartyCheckContext(this))
|
||||
} else {
|
||||
player = pokemon2!!.getOwnerPlayer()
|
||||
CobblemonCriteria.PARTY_CHECK.trigger(player!!, this)
|
||||
CobblemonCriteria.PARTY_CHECK.trigger(player!!, PartyCheckContext(this))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun set(position: PartyPosition, pokemon: Pokemon) {
|
||||
super.set(position, pokemon)
|
||||
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, this) }
|
||||
pokemon.getOwnerPlayer()?.let { CobblemonCriteria.PARTY_CHECK.trigger(it, PartyCheckContext(this)) }
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.storage.player
|
||||
|
||||
import com.cobblemon.mod.common.advancement.criterion.AspectCriterion
|
||||
import com.cobblemon.mod.common.advancement.criterion.AspectCriterionCondition
|
||||
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.value.criteria.values }
|
||||
.flatMap { it.criteria.values }
|
||||
.mapNotNull { it.conditions }
|
||||
.filterIsInstance<AspectCriterion>()
|
||||
.filterIsInstance<AspectCriterionCondition>()
|
||||
|
||||
val trackedAspects = aspectConditions
|
||||
.filter { it.pokemon == pokemon.species.resourceIdentifier }
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
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
|
||||
@@ -17,15 +18,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
|
||||
@@ -169,8 +170,8 @@ interface BattleStartError {
|
||||
fun getMessageFor(entity: Entity): MutableText
|
||||
|
||||
companion object {
|
||||
fun alreadyInBattle(player: ServerPlayerEntity) = AlreadyInBattleError(player.uuid, player.effectiveName())
|
||||
fun alreadyInBattle(pokemonEntity: PokemonEntity) = AlreadyInBattleError(pokemonEntity.uuid, pokemonEntity.effectiveName())
|
||||
fun alreadyInBattle(player: ServerPlayerEntity) = AlreadyInBattleError(player.uuid, player.displayName)
|
||||
fun alreadyInBattle(pokemonEntity: PokemonEntity) = AlreadyInBattleError(pokemonEntity.uuid, pokemonEntity.displayName)
|
||||
fun alreadyInBattle(actor: BattleActor) = AlreadyInBattleError(actor.uuid, actor.getName())
|
||||
|
||||
fun targetIsBusy(targetName: MutableText) = BusyError(targetName)
|
||||
@@ -210,7 +211,7 @@ class InsufficientPokemonError(
|
||||
} else {
|
||||
battleLang(
|
||||
"error.insufficient_pokemon",
|
||||
player.effectiveName(),
|
||||
player.displayName,
|
||||
requiredCount,
|
||||
hadCount
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.battles
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.battles.effects.BattleStartConditions
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleStartedPostEvent
|
||||
@@ -146,10 +147,16 @@ object BattleRegistry {
|
||||
}
|
||||
|
||||
private fun startShowdown(battle: PokemonBattle) {
|
||||
// Check for battle start condition
|
||||
val effect = BattleStartConditions.all().firstOrNull { it.matches(battle) }
|
||||
|
||||
// Build request message
|
||||
val messages = mutableListOf<String>()
|
||||
messages.add(">start { \"format\": ${battle.format.toFormatJSON()} }")
|
||||
if (effect != null) {
|
||||
messages.add(">start { \"format\": ${battle.format.toFormatJSON()}, \"defaultWeather\": \"${effect.result}\" }")
|
||||
} else {
|
||||
messages.add(">start { \"format\": ${battle.format.toFormatJSON()} }")
|
||||
}
|
||||
|
||||
/*
|
||||
* Showdown IDs are like p1, p2, p3, etc. Showdown uses these keys to identify who is doing what to whom.
|
||||
|
||||
@@ -104,7 +104,7 @@ object ShowdownInterpreter {
|
||||
updateInstructionParser["-swapboost"] = { _, _, message, _ -> SwapBoostInstruction(message) }
|
||||
updateInstructionParser["-swapsideconditions"] = { _, _, message, _ -> SwapSideConditionsInstruction(message) }
|
||||
updateInstructionParser["-terastallize"] = { _, _, message, _ -> TerastallizeInstruction(message) }
|
||||
updateInstructionParser["-transform"] = { battle, _, message, _ -> TransformInstruction(battle, message) }
|
||||
updateInstructionParser["-transform"] = { _, _, message, _ -> TransformInstruction(message) }
|
||||
updateInstructionParser["turn"] = { _, _, message, _ -> TurnInstruction(message) }
|
||||
updateInstructionParser["-unboost"] = { _, instructionSet, message, remainingLines -> BoostInstruction(instructionSet, message, remainingLines, false) }
|
||||
updateInstructionParser["upkeep"] = { _, _, _, _ -> UpkeepInstruction() }
|
||||
|
||||
+1
-2
@@ -33,7 +33,6 @@ class DragInstruction(val instructionSet: InstructionSet, val battleActor: Battl
|
||||
val (pnx, _) = publicMessage.pnxAndUuid(0)!!
|
||||
val (_, activePokemon) = battle.getActorAndActiveSlotFromPNX(pnx)
|
||||
|
||||
val imposter = instructionSet.getNextInstruction<TransformInstruction>(this)?.expectedTarget != null
|
||||
val illusion = publicMessage.battlePokemonFromOptional(battle , "is")
|
||||
val pokemon = publicMessage.battlePokemon(0, battle) ?: return@dispatchInsert emptySet()
|
||||
|
||||
@@ -48,7 +47,7 @@ class DragInstruction(val instructionSet: InstructionSet, val battleActor: Battl
|
||||
setOf(
|
||||
BattleDispatch {
|
||||
if (entity != null) {
|
||||
SwitchInstruction.createEntitySwitch(battle, battleActor, entity, pnx, activePokemon, pokemon, illusion, imposter)
|
||||
SwitchInstruction.createEntitySwitch(battle, battleActor, entity, pnx, activePokemon, pokemon, illusion)
|
||||
} else {
|
||||
SwitchInstruction.createNonEntitySwitch(battle, battleActor, pnx, activePokemon, pokemon, illusion)
|
||||
}
|
||||
|
||||
+3
-3
@@ -27,12 +27,12 @@ class FieldStartInstruction(val message: BattleMessage): InterpreterInstruction
|
||||
|
||||
override fun invoke(battle: PokemonBattle) {
|
||||
val effect = message.effectAt(0) ?: return
|
||||
val source = message.battlePokemonFromOptional(battle)
|
||||
source?.let { ShowdownInterpreter.broadcastOptionalAbility(battle, message.effect(), source) }
|
||||
val user = message.battlePokemonFromOptional(battle)
|
||||
user?.let { ShowdownInterpreter.broadcastOptionalAbility(battle, effect, user) }
|
||||
|
||||
battle.dispatchWaiting(1.5F) {
|
||||
// Note persistent is a CAP ability only we can ignore the flag
|
||||
val lang = battleLang("fieldstart.${effect.id}", source?.getName() ?: Text.literal("UNKNOWN"))
|
||||
val lang = battleLang("fieldstart.${effect.id}", user?.getName() ?: Text.literal("UNKNOWN"))
|
||||
battle.broadcastChatMessage(lang)
|
||||
|
||||
val type = BattleContext.Type.valueOf(effect.rawData.substringAfterLast(" ").uppercase())
|
||||
|
||||
+3
-16
@@ -40,7 +40,6 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
val (actor, activePokemon) = battle.getActorAndActiveSlotFromPNX(pnx)
|
||||
val entity = if (actor is EntityBackedBattleActor<*>) actor.entity else null
|
||||
|
||||
val imposter = instructionSet.getNextInstruction<TransformInstruction>(this)?.expectedTarget != null
|
||||
val illusion = publicMessage.battlePokemonFromOptional(battle, "is")
|
||||
val pokemon = publicMessage.battlePokemon(0, battle) ?: return
|
||||
|
||||
@@ -88,7 +87,7 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
setOf(
|
||||
BattleDispatch {
|
||||
if (entity != null) {
|
||||
createEntitySwitch(battle, actor, entity, pnx, activePokemon, pokemon, illusion, imposter)
|
||||
createEntitySwitch(battle, actor, entity, pnx, activePokemon, pokemon, illusion)
|
||||
} else {
|
||||
createNonEntitySwitch(battle, actor, pnx, activePokemon, pokemon, illusion)
|
||||
}
|
||||
@@ -99,21 +98,10 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
}
|
||||
|
||||
companion object{
|
||||
fun createEntitySwitch(
|
||||
battle: PokemonBattle,
|
||||
actor: BattleActor,
|
||||
entity: LivingEntity,
|
||||
pnx: String,
|
||||
activePokemon: ActiveBattlePokemon,
|
||||
newPokemon: BattlePokemon,
|
||||
illusion: BattlePokemon? = null,
|
||||
imposter: Boolean = false
|
||||
): DispatchResult {
|
||||
fun createEntitySwitch(battle: PokemonBattle, actor: BattleActor, entity: LivingEntity, pnx: String, activePokemon: ActiveBattlePokemon, newPokemon: BattlePokemon, illusion: BattlePokemon? = null): DispatchResult {
|
||||
val pokemonEntity = activePokemon.battlePokemon?.entity
|
||||
// If we can't find the entity for some reason then we're going to skip the recall animation
|
||||
val sendOutFuture = CompletableFuture<Unit>()
|
||||
// skip if handled by respective EntityEffect
|
||||
val doCry = illusion == null && !imposter
|
||||
(pokemonEntity?.recallWithAnimation() ?: CompletableFuture.completedFuture(Unit)).thenApply {
|
||||
// Queue actual swap and send-in after the animation has ended
|
||||
actor.pokemonList.swap(actor.activePokemon.indexOf(activePokemon), actor.pokemonList.indexOf(newPokemon))
|
||||
@@ -122,7 +110,7 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
battle.sendSidedUpdate(actor, BattleSwitchPokemonPacket(pnx, newPokemon, true, illusion), BattleSwitchPokemonPacket(pnx, newPokemon, false, illusion))
|
||||
if (newPokemon.entity != null) {
|
||||
illusion?.let { IllusionEffect(it.effectedPokemon).start(newPokemon.entity!!) }
|
||||
if (doCry) newPokemon.entity?.cry()
|
||||
newPokemon.entity?.cry()
|
||||
sendOutFuture.complete(Unit)
|
||||
} else {
|
||||
val lastPosition = activePokemon.position
|
||||
@@ -134,7 +122,6 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
battleId = battle.battleId,
|
||||
level = world,
|
||||
position = pos,
|
||||
doCry = doCry,
|
||||
illusion = illusion?.let { IllusionEffect(it.effectedPokemon) }
|
||||
).thenAccept { sendOutFuture.complete(Unit) }
|
||||
}
|
||||
|
||||
+4
-8
@@ -10,11 +10,12 @@ package com.cobblemon.mod.common.battles.interpreter.instructions
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.ShowdownInterpreter
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.battles.dispatch.GO
|
||||
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
|
||||
import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
|
||||
import com.cobblemon.mod.common.entity.pokemon.effects.TransformEffect
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleInitializePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleTransformPokemonPacket
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
|
||||
@@ -25,9 +26,7 @@ import com.cobblemon.mod.common.util.battleLang
|
||||
* @author jeffw773
|
||||
* @since November 28th, 2023
|
||||
*/
|
||||
class TransformInstruction(val battle: PokemonBattle, val message: BattleMessage): InterpreterInstruction {
|
||||
|
||||
val expectedTarget = message.battlePokemon(0, battle)
|
||||
class TransformInstruction(val message: BattleMessage): InterpreterInstruction {
|
||||
|
||||
override fun invoke(battle: PokemonBattle) {
|
||||
|
||||
@@ -36,12 +35,9 @@ class TransformInstruction(val battle: PokemonBattle, val message: BattleMessage
|
||||
val pokemon = message.battlePokemon(0, battle) ?: return
|
||||
val targetPokemon = message.battlePokemon(1, battle) ?: return
|
||||
|
||||
val effect = message.effect()
|
||||
ShowdownInterpreter.broadcastOptionalAbility(battle, effect, pokemon)
|
||||
|
||||
battle.dispatch {
|
||||
val entity = pokemon.entity ?: return@dispatch GO
|
||||
val future = TransformEffect(targetPokemon.effectedPokemon, battle.started).start(entity)
|
||||
val future = TransformEffect(targetPokemon.effectedPokemon).start(entity)
|
||||
UntilDispatch { future?.isDone != false }
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.battles.interpreter.instructions
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.effects.BattleStartConditions
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.scheduling.afterOnServer
|
||||
@@ -32,9 +33,6 @@ import com.cobblemon.mod.common.util.battleLang
|
||||
*/
|
||||
class TurnInstruction(val message: BattleMessage) : InterpreterInstruction {
|
||||
override fun invoke(battle: PokemonBattle) {
|
||||
// TODO maybe tell the client that the turn number has changed
|
||||
val turnNumber = message.argumentAt(0)?.toInt() ?: return
|
||||
|
||||
if (!battle.started) {
|
||||
battle.started = true
|
||||
battle.actors.filterIsInstance<PlayerBattleActor>().forEach { actor ->
|
||||
@@ -58,6 +56,20 @@ class TurnInstruction(val message: BattleMessage) : InterpreterInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO maybe tell the client that the turn number has changed
|
||||
val turnNumber = message.argumentAt(0)?.toInt() ?: return
|
||||
|
||||
// Try to apply battle start conditions
|
||||
if (turnNumber == 1) {
|
||||
val effect = BattleStartConditions.all().firstOrNull { it.matches(battle) }
|
||||
if (effect != null) {
|
||||
battle.writeShowdownAction(">eval battle.field.setWeather('${effect.result}', 'debug')")
|
||||
afterOnServer(0, 2.5F) {
|
||||
battle.getOrCreateBedrockEntity()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
battle.dispatch {
|
||||
battle.sendToActors(BattleMakeChoicePacket())
|
||||
battle.broadcastChatMessage(battleLang("turn", turnNumber).aqua())
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@ class WeatherInstruction(val message: BattleMessage): InterpreterInstruction {
|
||||
|
||||
override fun invoke(battle: PokemonBattle) {
|
||||
val weather = message.effectAt(0)?.id ?: return
|
||||
val source = message.battlePokemonFromOptional(battle)
|
||||
source?.let { ShowdownInterpreter.broadcastOptionalAbility(battle, message.effect(), source) }
|
||||
val user = message.battlePokemonFromOptional(battle) ?: return
|
||||
ShowdownInterpreter.broadcastOptionalAbility(battle, message.effect(), user)
|
||||
|
||||
battle.dispatchWaiting(1.5F) {
|
||||
val lang = when {
|
||||
|
||||
@@ -26,7 +26,7 @@ import net.minecraft.world.biome.Biome
|
||||
* @since December 2nd, 2022
|
||||
*/
|
||||
class BiomeDownfallGrowthFactor(
|
||||
val range: NumberRange.DoubleRange,
|
||||
val range: NumberRange.FloatRange,
|
||||
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.DoubleRange,
|
||||
val range: NumberRange.FloatRange,
|
||||
val bonusYield: IntRange
|
||||
) : GrowthFactor {
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ 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
|
||||
@@ -113,7 +111,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) = state.get(AGE) < MAX_AGE
|
||||
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState, isClient: Boolean) = state.get(AGE) < MAX_AGE
|
||||
|
||||
override fun canGrow(world: World, random: Random, pos: BlockPos, state: BlockState) = true
|
||||
|
||||
@@ -145,7 +143,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: WorldView, pos: BlockPos, state: BlockState) = ItemStack(this.apricorn.item())
|
||||
override fun getPickStack(world: BlockView, 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)
|
||||
@@ -190,15 +188,7 @@ 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,20 +10,5 @@ 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, 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) }
|
||||
}
|
||||
|
||||
}
|
||||
class ApricornSaplingBlock(properties : Settings, apricorn: Apricorn) : SaplingBlock(ApricornTreeGrower(apricorn), properties)
|
||||
@@ -19,8 +19,6 @@ 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
|
||||
@@ -70,21 +68,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): BlockState {
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
|
||||
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) }
|
||||
}
|
||||
return super.onBreak(world, pos, state, player)
|
||||
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) = !this.isMaxAge(state)
|
||||
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState, isClient: Boolean) = !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>? = validateTicker(blockWithEntityType, CobblemonBlockEntities.BERRY, BerryBlockEntity.TICKER)
|
||||
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, blockWithEntityType: BlockEntityType<T>): BlockEntityTicker<T>? = checkType(blockWithEntityType, CobblemonBlockEntities.BERRY, BerryBlockEntity.TICKER)
|
||||
|
||||
init {
|
||||
defaultState = this.stateManager.defaultState
|
||||
@@ -194,10 +192,6 @@ 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
|
||||
@@ -216,7 +210,7 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
|
||||
builder.add(MULCH)
|
||||
}
|
||||
|
||||
override fun getPickStack(world: WorldView?, pos: BlockPos?, state: BlockState?): ItemStack {
|
||||
override fun getPickStack(world: BlockView?, pos: BlockPos?, state: BlockState?): ItemStack {
|
||||
val berryItem = this.berry()?.item() ?: return ItemStack.EMPTY
|
||||
return ItemStack(berryItem)
|
||||
}
|
||||
@@ -238,11 +232,6 @@ 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
|
||||
@@ -323,4 +312,4 @@ class BerryBlock(private val berryIdentifier: Identifier, settings: Settings) :
|
||||
world.setBlockState(pos, state.with(MULCH, mulch))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
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
|
||||
@@ -41,14 +39,10 @@ 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,19 +8,13 @@
|
||||
|
||||
package com.cobblemon.mod.common.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.block.*
|
||||
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
|
||||
@@ -57,10 +51,6 @@ 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,
|
||||
@@ -80,10 +70,5 @@ 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,7 +10,6 @@ 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
|
||||
@@ -37,6 +36,10 @@ 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
|
||||
@@ -92,12 +95,12 @@ class DisplayCaseBlock(settings: Settings) : BlockWithEntity(settings) {
|
||||
return result
|
||||
}
|
||||
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity): BlockState {
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
|
||||
val entity = world.getBlockEntity(pos) as DisplayCaseBlockEntity
|
||||
if (!entity.getStack().isEmpty && !player.isCreative) {
|
||||
ItemScatterer.spawn(world, pos, entity.inv)
|
||||
}
|
||||
return super.onBreak(world, pos, state, player)
|
||||
super.onBreak(world, pos, state, player)
|
||||
}
|
||||
|
||||
override fun getRenderType(state: BlockState?) = BlockRenderType.MODEL
|
||||
@@ -112,15 +115,7 @@ 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,8 +10,6 @@ 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
|
||||
@@ -29,14 +27,10 @@ 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,11 +14,9 @@ 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
|
||||
@@ -43,15 +41,11 @@ 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>? = validateTicker(type, CobblemonBlockEntities.FOSSIL_ANALYZER, FossilMultiblockStructure.TICKER::tick)
|
||||
): BlockEntityTicker<T>? = checkType(type, CobblemonBlockEntities.FOSSIL_ANALYZER, FossilMultiblockStructure.TICKER::tick)
|
||||
|
||||
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
|
||||
return defaultState.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing)
|
||||
@@ -74,7 +68,5 @@ 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,
|
||||
val xzOffset: Int,
|
||||
xzOffset: Int,
|
||||
val nextStage: Block?
|
||||
) : FacingBlock(settings) {
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ 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
|
||||
@@ -48,8 +47,6 @@ 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),
|
||||
@@ -96,10 +93,6 @@ 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
|
||||
}
|
||||
@@ -197,7 +190,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>? = validateTicker(blockWithEntityType, CobblemonBlockEntities.HEALING_MACHINE, HealingMachineBlockEntity.TICKER::tick)
|
||||
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, blockWithEntityType: BlockEntityType<T>): BlockEntityTicker<T>? = checkType(blockWithEntityType, CobblemonBlockEntities.HEALING_MACHINE, HealingMachineBlockEntity.TICKER::tick)
|
||||
|
||||
override fun getRenderType(blockState: BlockState): BlockRenderType {
|
||||
return BlockRenderType.MODEL
|
||||
@@ -208,4 +201,4 @@ class HealingMachineBlock(properties: Settings) : BlockWithEntity(properties) {
|
||||
tooltip.add("block.${Cobblemon.MODID}.healing_machine.tooltip2".asTranslated().gray())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ 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
|
||||
@@ -51,7 +50,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?): Boolean = !this.isMature(state)
|
||||
override fun isFertilizable(world: WorldView?, pos: BlockPos?, state: BlockState?, isClient: Boolean): 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)
|
||||
@@ -71,12 +70,7 @@ 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,13 +11,7 @@ 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 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.block.*
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemConvertible
|
||||
import net.minecraft.registry.tag.BlockTags
|
||||
@@ -25,7 +19,6 @@ 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
|
||||
@@ -81,12 +74,8 @@ 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 : StringIdentifiable {
|
||||
enum class MintType {
|
||||
|
||||
RED,
|
||||
BLUE,
|
||||
@@ -122,18 +111,9 @@ 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
|
||||
@@ -159,4 +139,4 @@ class MintBlock(private val mintType: MintType, settings: Settings) : CropBlock(
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,8 @@ 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
|
||||
@@ -44,10 +42,6 @@ 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)
|
||||
}
|
||||
@@ -90,8 +84,6 @@ 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,7 +59,6 @@ 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")
|
||||
@@ -209,7 +208,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?): BlockState {
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
|
||||
if (!world.isClient && player?.isCreative == true) {
|
||||
var blockPos: BlockPos = BlockPos.ORIGIN
|
||||
var blockState: BlockState = state
|
||||
@@ -220,11 +219,9 @@ class PCBlock(properties: Settings): BlockWithEntity(properties), Waterloggable
|
||||
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, blockPos, getRawIdFromState(blockState))
|
||||
}
|
||||
}
|
||||
return super.onBreak(world, pos, state, player)
|
||||
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
|
||||
|
||||
@@ -286,7 +283,7 @@ class PCBlock(properties: Settings): BlockWithEntity(properties), Waterloggable
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, BlockWithEntityType: BlockEntityType<T>) = validateTicker(BlockWithEntityType, CobblemonBlockEntities.PC, PCBlockEntity.TICKER::tick)
|
||||
override fun <T : BlockEntity> getTicker(world: World, blockState: BlockState, BlockWithEntityType: BlockEntityType<T>) = checkType(BlockWithEntityType, CobblemonBlockEntities.PC, PCBlockEntity.TICKER::tick)
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun getRenderType(blockState: BlockState): BlockRenderType {
|
||||
|
||||
@@ -21,7 +21,6 @@ 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
|
||||
@@ -65,8 +64,6 @@ 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")
|
||||
@@ -177,10 +174,6 @@ 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>) {
|
||||
@@ -200,7 +193,7 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?): BlockState {
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
|
||||
checkBreakEntity(world, state, pos)
|
||||
if (!world.isClient && player?.isCreative == true) {
|
||||
var blockPos: BlockPos = BlockPos.ORIGIN
|
||||
@@ -213,7 +206,7 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
|
||||
world.syncWorldEvent(player, WorldEvents.BLOCK_BROKEN, blockPos, getRawIdFromState(blockState))
|
||||
}
|
||||
}
|
||||
return super.onBreak(world, pos, state, player)
|
||||
super.onBreak(world, pos, state, player)
|
||||
}
|
||||
|
||||
override fun whenExploded(world: World, state: BlockState, pos: BlockPos) {
|
||||
@@ -222,7 +215,7 @@ class PastureBlock(properties: Settings): BlockWithEntity(properties), Waterlogg
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity?> getTicker(world: World, state: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? {
|
||||
return validateTicker(type, CobblemonBlockEntities.PASTURE, PokemonPastureBlockEntity.TICKER::tick)
|
||||
return checkType(type, CobblemonBlockEntities.PASTURE, PokemonPastureBlockEntity.TICKER::tick)
|
||||
}
|
||||
|
||||
override fun onPlaced(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity?, itemStack: ItemStack?) {
|
||||
|
||||
@@ -14,7 +14,6 @@ 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
|
||||
@@ -52,6 +51,7 @@ 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,16 +70,13 @@ 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?): BlockState {
|
||||
val result = super.onBreak(world, pos, state, player)
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity?) {
|
||||
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(
|
||||
@@ -225,15 +222,9 @@ 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,7 +124,6 @@ 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) = this.canSpread(world, pos, state)
|
||||
override fun isFertilizable(world: WorldView, pos: BlockPos, state: BlockState, isClient: Boolean) = 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,11 +9,6 @@
|
||||
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
|
||||
@@ -25,9 +20,10 @@ 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
|
||||
@@ -42,24 +38,16 @@ 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> =
|
||||
@@ -74,10 +62,6 @@ 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,7 +9,6 @@
|
||||
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
|
||||
@@ -30,12 +29,7 @@ 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,8 +16,6 @@ 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
|
||||
@@ -35,13 +33,7 @@ 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.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.*
|
||||
import net.minecraft.util.hit.BlockHitResult
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Direction
|
||||
@@ -61,11 +53,6 @@ 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")
|
||||
@@ -137,16 +124,13 @@ 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): BlockState {
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
|
||||
if (isFake()) {
|
||||
if (player is ServerPlayerEntity) {
|
||||
spawnPokemon(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)
|
||||
world.setBlockState(pos, if (state.fluidState.isOf(Fluids.WATER)) Blocks.WATER.defaultState else Blocks.AIR.defaultState)
|
||||
} else super.onBreak(world, pos, state, player)
|
||||
}
|
||||
|
||||
private fun spawnPokemon(world: World, pos: BlockPos, state: BlockState, player: ServerPlayerEntity) : ActionResult {
|
||||
@@ -248,7 +232,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): StringIdentifiable {
|
||||
enum class Type(val poserId: Identifier) {
|
||||
RED(cobblemonResource("gilded_chest")),
|
||||
BLUE(cobblemonResource("blue_gilded_chest")),
|
||||
GREEN(cobblemonResource("green_gilded_chest")),
|
||||
@@ -256,15 +240,7 @@ 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"));
|
||||
|
||||
override fun asString(): String {
|
||||
return name.lowercase()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val CODEC = StringIdentifiable.createBasicCodec(::values)
|
||||
}
|
||||
FAKE(cobblemonResource("gilded_chest"))
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
@@ -272,10 +248,6 @@ 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,8 +73,6 @@ 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)
|
||||
@@ -103,6 +101,8 @@ 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 (!writeLootTable(nbt)) {
|
||||
if (!serializeLootTable(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 (!readLootTable(nbt)) {
|
||||
if (!deserializeLootTable(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.toVec3d(), maxRoamPos.toVec3d())
|
||||
val box = Box(minRoamPos, maxRoamPos)
|
||||
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.lengthX
|
||||
val width = entity.boundingBox.xLength
|
||||
|
||||
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,12 +9,18 @@
|
||||
package com.cobblemon.mod.common.block.grower
|
||||
|
||||
import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import net.minecraft.block.SaplingGenerator
|
||||
import java.util.Optional
|
||||
import com.cobblemon.mod.common.world.feature.CobblemonConfiguredFeatures
|
||||
import net.minecraft.block.sapling.SaplingGenerator
|
||||
import net.minecraft.util.math.random.Random
|
||||
|
||||
class ApricornTreeGrower(apricorn: Apricorn) : SaplingGenerator(
|
||||
apricorn.asString(),
|
||||
Optional.empty(),
|
||||
Optional.of(apricorn.configuredFeature()),
|
||||
Optional.empty()
|
||||
)
|
||||
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
|
||||
}
|
||||
}
|
||||
+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))
|
||||
.state(StatePredicate.Builder.create().exactMatch(RestorationTankBlock.PART, RestorationTankBlock.TankPart.BOTTOM).build())
|
||||
.build()
|
||||
//lol thanks mojang for not allowing nbt puts to be chained
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -205,10 +205,10 @@ class FossilMultiblockStructure (
|
||||
return ActionResult.PASS
|
||||
}
|
||||
|
||||
fun spawn(world: World, pos: BlockPos, directionToBehind: Direction, pokemon: Pokemon) : Boolean {
|
||||
public fun spawn(world: World, pos: BlockPos, directionToBehind: Direction, pokemon: Pokemon) : Boolean {
|
||||
val entity = PokemonEntity(world, pokemon = pokemon)
|
||||
entity.calculateDimensions()
|
||||
val width = entity.boundingBox.lengthX
|
||||
val width = entity.boundingBox.xLength
|
||||
|
||||
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(woodType, settings) {
|
||||
class CobblemonHangingSignBlock(settings: Settings, woodType: WoodType) : HangingSignBlock(settings, woodType) {
|
||||
|
||||
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(woodType, settings) {
|
||||
class CobblemonSignBlock(settings: Settings, woodType: WoodType) : SignBlock(settings, woodType) {
|
||||
|
||||
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(woodType, settings) {
|
||||
class CobblemonWallHangingSignBlock(settings: Settings, woodType: WoodType) : WallHangingSignBlock(settings, woodType) {
|
||||
|
||||
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(woodType, settings) {
|
||||
class CobblemonWallSignBlock(settings: Settings, woodType: WoodType) : WallSignBlock(settings, woodType) {
|
||||
|
||||
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ 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
|
||||
@@ -238,10 +237,10 @@ object CobblemonClient {
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
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>>
|
||||
fun onAddLayer(skinMap: Map<String, EntityRenderer<out PlayerEntity>>?) {
|
||||
var renderer: LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>? = skinMap?.get("default") as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>
|
||||
renderer?.addFeature(PokemonOnShoulderRenderer(renderer))
|
||||
renderer = skinMap[SkinTextures.Model.SLIM] as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>?
|
||||
renderer = skinMap["slim"] as LivingEntityRenderer<PlayerEntity, PlayerEntityModel<PlayerEntity>>?
|
||||
renderer?.addFeature(PokemonOnShoulderRenderer(renderer))
|
||||
}
|
||||
|
||||
@@ -307,4 +306,4 @@ object CobblemonClient {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -25,7 +25,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntitySt
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PrimaryAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.StatefulAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
|
||||
import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer.Companion.ease
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
@@ -86,8 +85,6 @@ class PokemonClientDelegate : PoseableEntityState<PokemonEntity>(), PokemonSideD
|
||||
val identifier = Identifier(currentEntity.dataTracker.get(PokemonEntity.SPECIES))
|
||||
currentPose = null
|
||||
currentEntity.pokemon.species = PokemonSpecies.getByIdentifier(identifier)!! // TODO exception handling
|
||||
// force a model update - handles edge case where the PoseableEntityState's tracked PoseableEntityModel isn't updated until the LivingEntityRenderer render is run
|
||||
currentModel = PokemonModelRepository.getPoser(identifier, currentEntity.aspects)
|
||||
} else if (data == PokemonEntity.DYING_EFFECTS_STARTED) {
|
||||
val isDying = currentEntity.dataTracker.get(PokemonEntity.DYING_EFFECTS_STARTED)
|
||||
if (isDying) {
|
||||
@@ -265,10 +262,10 @@ class PokemonClientDelegate : PoseableEntityState<PokemonEntity>(), PokemonSideD
|
||||
return@Function StringValue(currentEntity.pokemon.form.name)
|
||||
},
|
||||
"width" to java.util.function.Function {
|
||||
return@Function DoubleValue(currentEntity.boundingBox.lengthX)
|
||||
return@Function DoubleValue(currentEntity.boundingBox.xLength)
|
||||
},
|
||||
"height" to java.util.function.Function {
|
||||
return@Function DoubleValue(currentEntity.boundingBox.lengthY)
|
||||
return@Function DoubleValue(currentEntity.boundingBox.yLength)
|
||||
},
|
||||
"weight" to java.util.function.Function {
|
||||
return@Function DoubleValue(currentEntity.pokemon.species.weight.toDouble())
|
||||
|
||||
@@ -13,6 +13,7 @@ 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(
|
||||
@@ -28,7 +29,7 @@ class ExitButton(
|
||||
private val iconResource = cobblemonResource("textures/gui/common/back_button_icon.png")
|
||||
}
|
||||
|
||||
override fun renderWidget(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
|
||||
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
|
||||
blitk(
|
||||
matrixStack = context.matrices,
|
||||
texture = buttonResource,
|
||||
@@ -55,4 +56,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,7 +32,6 @@ 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
|
||||
|
||||
@@ -65,7 +64,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(),
|
||||
AdvancementToast.TEXTURE,
|
||||
Toast.TEXTURE,
|
||||
-1F,
|
||||
0
|
||||
)
|
||||
@@ -87,7 +86,7 @@ class PartyOverlay : InGameHud(MinecraftClient.getInstance(), MinecraftClient.ge
|
||||
if (!screenExemptions.contains(minecraft.currentScreen?.javaClass as Class<out Screen>))
|
||||
return
|
||||
}
|
||||
if (minecraft.debugHud.shouldShowDebugHud()) {
|
||||
if (minecraft.options.debugEnabled) {
|
||||
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,14 +82,12 @@ 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()
|
||||
@@ -142,10 +140,6 @@ 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)
|
||||
|
||||
+3
-2
@@ -10,6 +10,8 @@ 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
|
||||
@@ -23,7 +25,6 @@ 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
|
||||
@@ -90,7 +91,7 @@ class BattleGeneralActionSelection(
|
||||
)
|
||||
}
|
||||
|
||||
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
override fun renderButton(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 renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
moveTiles.forEach {
|
||||
it.render(context, mouseX, mouseY, delta)
|
||||
}
|
||||
|
||||
+4
-4
@@ -9,8 +9,7 @@
|
||||
package com.cobblemon.mod.common.client.gui.battle.subscreen
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.battles.ShowdownPokemon
|
||||
import com.cobblemon.mod.common.battles.SwitchActionResponse
|
||||
import com.cobblemon.mod.common.battles.*
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.battle.SingleActionRequest
|
||||
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
|
||||
@@ -23,8 +22,9 @@ 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 renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
if (opacity <= 0.05F) {
|
||||
return
|
||||
}
|
||||
|
||||
+8
-8
@@ -44,6 +44,14 @@ 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)
|
||||
@@ -54,12 +62,4 @@ 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)
|
||||
}
|
||||
|
||||
}
|
||||
+23
-11
@@ -16,6 +16,7 @@ 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
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,7 @@ class BattleMessagePane(
|
||||
TEXT_BOX_WIDTH, // width
|
||||
TEXT_BOX_HEIGHT, // height
|
||||
1, // top
|
||||
1 + TEXT_BOX_HEIGHT, // bottom
|
||||
LINE_HEIGHT
|
||||
) {
|
||||
var opacity = 1F
|
||||
@@ -43,7 +45,9 @@ class BattleMessagePane(
|
||||
|
||||
init {
|
||||
correctSize()
|
||||
setRenderHorizontalShadows(false)
|
||||
setRenderBackground(false)
|
||||
setRenderSelection(false)
|
||||
|
||||
messageQueue.subscribe {
|
||||
val fullyScrolledDown = maxScroll - scrollAmount < 10
|
||||
@@ -56,8 +60,8 @@ class BattleMessagePane(
|
||||
|
||||
private fun correctSize() {
|
||||
val textBoxHeight = if (expanded) TEXT_BOX_HEIGHT * 2 else TEXT_BOX_HEIGHT
|
||||
setDimensionsAndPosition(TEXT_BOX_WIDTH, textBoxHeight, appropriateY + 6, appropriateY + 6)
|
||||
this.x = appropriateX
|
||||
updateSize(TEXT_BOX_WIDTH, textBoxHeight, appropriateY + 6, appropriateY + 6 + textBoxHeight)
|
||||
setLeftPos(appropriateX)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -84,15 +88,23 @@ class BattleMessagePane(
|
||||
}
|
||||
|
||||
override fun getScrollbarPositionX(): Int {
|
||||
return this.x + 154
|
||||
return left + 154
|
||||
}
|
||||
|
||||
override fun renderWidget(context: DrawContext, mouseX: Int, mouseY: Int, partialTicks: Float) {
|
||||
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) {
|
||||
correctSize()
|
||||
blitk(
|
||||
matrixStack = context.matrices,
|
||||
texture = if (expanded) battleMessagePaneFrameExpandedResource else battleMessagePaneFrameResource,
|
||||
x = this.x,
|
||||
x = left,
|
||||
y = appropriateY,
|
||||
height = if (expanded) FRAME_EXPANDED_HEIGHT else FRAME_HEIGHT,
|
||||
width = FRAME_WIDTH,
|
||||
@@ -101,18 +113,18 @@ class BattleMessagePane(
|
||||
|
||||
val textBoxHeight = if (expanded) TEXT_BOX_HEIGHT * 2 else TEXT_BOX_HEIGHT
|
||||
context.enableScissor(
|
||||
this.x + 5,
|
||||
left + 5,
|
||||
appropriateY + 6,
|
||||
this.x + 5 + width,
|
||||
left + 5 + width,
|
||||
appropriateY + 6 + textBoxHeight
|
||||
)
|
||||
super.renderWidget(context, mouseX, mouseY, partialTicks)
|
||||
super.render(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 > (this.x + 160) && mouseX < (this.x + 160 + EXPAND_TOGGLE_SIZE) && mouseY > (appropriateY + toggleOffsetY) && mouseY < (appropriateY + toggleOffsetY + EXPAND_TOGGLE_SIZE)) {
|
||||
if (mouseX > (left + 160) && mouseX < (left + 160 + EXPAND_TOGGLE_SIZE) && mouseY > (appropriateY + toggleOffsetY) && mouseY < (appropriateY + toggleOffsetY + EXPAND_TOGGLE_SIZE)) {
|
||||
expanded = !expanded
|
||||
}
|
||||
|
||||
@@ -127,7 +139,7 @@ class BattleMessagePane(
|
||||
|
||||
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
|
||||
if (scrolling) {
|
||||
if (mouseY < this.y) {
|
||||
if (mouseY < top) {
|
||||
scrollAmount = 0.0
|
||||
} else if (mouseY > bottom) {
|
||||
scrollAmount = maxScroll.toDouble()
|
||||
@@ -141,7 +153,7 @@ class BattleMessagePane(
|
||||
private fun updateScrollingState(mouseX: Double, mouseY: Double) {
|
||||
scrolling = mouseX >= this.scrollbarPositionX.toDouble()
|
||||
&& mouseX < (this.scrollbarPositionX + 3).toDouble()
|
||||
&& mouseY >= this.y
|
||||
&& mouseY >= top
|
||||
&& mouseY < bottom
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@ 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.
|
||||
@@ -59,7 +58,7 @@ class PlayerRenderableFace(val playerId: UUID) : RenderableFace {
|
||||
val size = 37
|
||||
val xOffset = 0
|
||||
val yOffset = 75
|
||||
InventoryScreen.drawEntity(drawContext, xOffset.toFloat(), yOffset.toFloat(), size, Vector3f(), quaternionf, quaternionf2, entity)
|
||||
InventoryScreen.drawEntity(drawContext, xOffset, yOffset, size, quaternionf, quaternionf2, entity)
|
||||
// Resets the entity
|
||||
entity.bodyYaw = oldBodyYaw
|
||||
entity.setYaw(oldEntityYaw)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user