Merge branch 'licious/a-sign-of-boats-to-come' into 'main'

Implement Apricorn boats & signs

See merge request cable-mc/cobblemon!725
This commit is contained in:
Hiroku
2023-11-02 08:14:26 +00:00
86 changed files with 1310 additions and 92 deletions
+1
View File
@@ -10,6 +10,7 @@
- Berries can now be used in recipes from [Farmer's Delight](https://modrinth.com/mod/farmers-delight) and [Farmer's Delight (Fabric)](https://modrinth.com/mod/farmers-delight-fabric), as well as any other mods using the same berry tags.
- The nature of cobblemon will now be displayed italicized when a mint has been applied. Hovering over the nature will display the mint that was applied. This is the intended behaviour, because the original nature and taste of the Cobblemon does not change when a mint is applied.
- Giving Pokémon items now plays a sound
- A boat, sign and hanging sign is now craftable with Apricorn wood. The recipes are the same shape as Minecraft' equivalent with Apricorn planks as replacements.
- Added the Cleanse Tag held item.
### Fixes
@@ -0,0 +1,23 @@
/*
* 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.mixin.accessor;
import net.minecraft.entity.vehicle.BoatEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(BoatEntity.class)
public interface BoatEntityAccessor {
@Accessor
void setFallVelocity(double fallVelocity);
@Accessor
BoatEntity.Location getLocation();
}
@@ -8,10 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
import com.cobblemon.mod.common.block.entity.PCBlockEntity
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
import com.cobblemon.mod.common.block.entity.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.registry.Registries
@@ -31,5 +28,9 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
val BERRY = this.create("berry", BlockEntityType.Builder.create(::BerryBlockEntity, *CobblemonBlocks.berries().values.toTypedArray()).build(null))
@JvmField
val PASTURE: BlockEntityType<PokemonPastureBlockEntity> = this.create("pasture", BlockEntityType.Builder.create(::PokemonPastureBlockEntity, CobblemonBlocks.PASTURE).build(null))
@JvmField
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.create(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN).build(null))
@JvmField
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.create(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN).build(null))
}
@@ -19,6 +19,10 @@ import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import net.minecraft.block.*
import net.minecraft.block.piston.PistonBehavior
import net.minecraft.entity.effect.StatusEffects
@@ -107,9 +111,14 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD), APRICORN_BLOCK_SET_TYPE))
// Tag was removed be sure to add it back when implemented
//val APRICORN_SIGN = queue("apricorn_sign") { StandingSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE) }
//val APRICORN_WALL_SIGN = queue("apricorn_wall_sign") { WallSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD).dropsLike(APRICORN_SIGN), APRICORN_WOOD_TYPE) }
@JvmField
val APRICORN_SIGN = this.create("apricorn_sign", CobblemonSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_WALL_SIGN = this.create("apricorn_wall_sign", CobblemonWallSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_WALL_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_HANGING_SIGN = this.create("apricorn_hanging_sign", CobblemonHangingSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_WALL_HANGING_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_WALL_HANGING_SIGN = this.create("apricorn_wall_hanging_sign", CobblemonWallHangingSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common
import java.util.function.Supplier
import net.minecraft.block.Block
import net.minecraft.block.entity.BlockEntity
import net.minecraft.block.entity.BlockEntityType
@@ -19,11 +18,14 @@ import net.minecraft.client.particle.ParticleFactory
import net.minecraft.client.particle.SpriteProvider
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.model.EntityModelLayer
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.item.Item
import net.minecraft.particle.ParticleEffect
import net.minecraft.particle.ParticleType
import net.minecraft.resource.SynchronousResourceReloader
import java.util.function.Supplier
interface CobblemonClientImplementation {
fun registerLayer(modelLayer: EntityModelLayer, supplier: Supplier<TexturedModelData>)
@@ -38,5 +40,7 @@ interface CobblemonClientImplementation {
fun registerBlockColors(provider: BlockColorProvider, vararg blocks: Block)
fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<T>, factory: BlockEntityRendererFactory<T>)
fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<out T>, factory: BlockEntityRendererFactory<T>)
fun <T : Entity> registerEntityRenderer(type: EntityType<out T>, factory: EntityRendererFactory<T>)
}
@@ -9,6 +9,8 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonChestBoatEntity
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.platform.PlatformRegistry
@@ -45,6 +47,24 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, RegistryKey
.build(EMPTY_POKEBALL_KEY.toString())
)
@JvmField
val BOAT_KEY = cobblemonResource("boat")
@JvmField
val BOAT: EntityType<CobblemonBoatEntity> = this.create(
BOAT_KEY.path,
EntityType.Builder.create(::CobblemonBoatEntity, SpawnGroup.MISC).setDimensions(1.375F, 0.5625F).maxTrackingRange(10)
.build(BOAT_KEY.toString())
)
@JvmField
val CHEST_BOAT_KEY = cobblemonResource("chest_boat")
@JvmField
val CHEST_BOAT: EntityType<CobblemonChestBoatEntity> = this.create(
CHEST_BOAT_KEY.path,
EntityType.Builder.create(::CobblemonChestBoatEntity, SpawnGroup.MISC).setDimensions(1.375F, 0.5625F).maxTrackingRange(10)
.build(CHEST_BOAT_KEY.toString())
)
fun registerAttributes(consumer: (EntityType<out LivingEntity>, DefaultAttributeContainer.Builder) -> Unit) {
consumer(POKEMON, PokemonEntity.createAttributes())
}
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.MintBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.item.*
import com.cobblemon.mod.common.item.battle.DireHitItem
import com.cobblemon.mod.common.item.battle.GuardSpecItem
@@ -123,19 +124,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val VIVICHOKE_SEEDS = compostableItem("vivichoke_seeds", VivichokeItem(CobblemonBlocks.VIVICHOKE_SEEDS))
@JvmField
val RED_APRICORN = apricronItem("red", ApricornItem(CobblemonBlocks.RED_APRICORN))
val RED_APRICORN = apricornItem("red", ApricornItem(CobblemonBlocks.RED_APRICORN))
@JvmField
val YELLOW_APRICORN = apricronItem("yellow", ApricornItem(CobblemonBlocks.YELLOW_APRICORN))
val YELLOW_APRICORN = apricornItem("yellow", ApricornItem(CobblemonBlocks.YELLOW_APRICORN))
@JvmField
val GREEN_APRICORN = apricronItem("green", ApricornItem(CobblemonBlocks.GREEN_APRICORN))
val GREEN_APRICORN = apricornItem("green", ApricornItem(CobblemonBlocks.GREEN_APRICORN))
@JvmField
val BLUE_APRICORN = apricronItem("blue", ApricornItem(CobblemonBlocks.BLUE_APRICORN))
val BLUE_APRICORN = apricornItem("blue", ApricornItem(CobblemonBlocks.BLUE_APRICORN))
@JvmField
val PINK_APRICORN = apricronItem("pink", ApricornItem(CobblemonBlocks.PINK_APRICORN))
val PINK_APRICORN = apricornItem("pink", ApricornItem(CobblemonBlocks.PINK_APRICORN))
@JvmField
val BLACK_APRICORN = apricronItem("black", ApricornItem(CobblemonBlocks.BLACK_APRICORN))
val BLACK_APRICORN = apricornItem("black", ApricornItem(CobblemonBlocks.BLACK_APRICORN))
@JvmField
val WHITE_APRICORN = apricronItem("white", ApricornItem(CobblemonBlocks.WHITE_APRICORN))
val WHITE_APRICORN = apricornItem("white", ApricornItem(CobblemonBlocks.WHITE_APRICORN))
@JvmField
val RED_APRICORN_SEED = apricronSeedItem("red", ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING))
@@ -164,6 +165,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val APRICORN_PLANKS = blockItem("apricorn_planks", CobblemonBlocks.APRICORN_PLANKS)
@JvmField
val APRICORN_LEAVES = compostableBlockItem("apricorn_leaves", CobblemonBlocks.APRICORN_LEAVES)
@JvmField
val APRICORN_BOAT = create("apricorn_boat", CobblemonBoatItem(CobblemonBoatType.APRICORN, false, Item.Settings().maxCount(1)))
@JvmField
val APRICORN_CHEST_BOAT = create("apricorn_chest_boat", CobblemonBoatItem(CobblemonBoatType.APRICORN, true, Item.Settings().maxCount(1)))
@JvmField
val APRICORN_DOOR = blockItem("apricorn_door", CobblemonBlocks.APRICORN_DOOR)
@@ -177,12 +182,14 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val APRICORN_BUTTON = blockItem("apricorn_button", CobblemonBlocks.APRICORN_BUTTON)
@JvmField
val APRICORN_PRESSURE_PLATE = blockItem("apricorn_pressure_plate", CobblemonBlocks.APRICORN_PRESSURE_PLATE)
//@JvmField
// val APRICORN_SIGN = create("apricorn_sign", SignItem(Item.Properties().stacksTo(16).tab(CreativeModeTab.TAB_DECORATIONS), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
@JvmField
val APRICORN_SLAB = blockItem("apricorn_slab", CobblemonBlocks.APRICORN_SLAB)
@JvmField
val APRICORN_STAIRS = blockItem("apricorn_stairs", CobblemonBlocks.APRICORN_STAIRS)
@JvmField
val APRICORN_SIGN = this.create("apricorn_sign", SignItem(Item.Settings().maxCount(16), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
@JvmField
val APRICORN_HANGING_SIGN = this.create("apricorn_hanging_sign", HangingSignItem(CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN, Item.Settings().maxCount(16)))
@JvmField
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE)
@@ -721,7 +728,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
return item
}
private fun apricronItem(name: String, apricornItem: ApricornItem): ApricornItem {
private fun apricornItem(name: String, apricornItem: ApricornItem): ApricornItem {
val finalName = "${name}_apricorn"
val item = this.create(finalName, apricornItem)
compostable(item, .65f)
@@ -22,6 +22,8 @@ import net.minecraft.registry.tag.TagKey
@Suppress("HasPlatformType", "unused")
object CobblemonBlockTags {
@JvmField val ALL_HANGING_SIGNS = createTag("all_hanging_signs")
@JvmField val ALL_SIGNS = createTag("all_signs")
@JvmField val APRICORN_LEAVES = createTag("apricorn_leaves")
@JvmField val APRICORN_LOGS = createTag("apricorn_logs")
@JvmField val APRICORN_SAPLINGS = createTag("apricorn_saplings")
@@ -29,6 +31,7 @@ object CobblemonBlockTags {
@JvmField val BERRY_WILD_SOIL = createTag("berry_wild_soil")
@JvmField val BERRY_SOIL = createTag("berry_soil")
@JvmField val BERRY_REPLACEABLE = createTag("berry_replaceable")
@JvmField val CEILING_HANGING_SIGNS = createTag("ceiling_hanging_signs")
@JvmField val CROPS = createTag("crops")
@JvmField val DRIPSTONE_GROWABLE = createTag("dripstone_growable")
@JvmField val DRIPSTONE_REPLACEABLES = createTag("dripstone_replaceables")
@@ -36,10 +39,15 @@ object CobblemonBlockTags {
@JvmField val MEDICINAL_LEEK_PLANTABLE = createTag("medicinal_leek_plantable")
@JvmField val MINTS = createTag("mints")
@JvmField val ROOTS_SPREADABLE = createTag("roots_spreadable")
@JvmField val SIGNS = createTag("signs")
@JvmField val SMALL_FLOWERS = createTag("small_flowers")
@JvmField val SEES_SKY = createTag("sees_sky")
@JvmField val SNOW_BLOCK = createTag("snow_block")
@JvmField val ROOTS = createTag("roots")
@JvmField val STANDING_SIGNS = createTag("standing_signs")
@JvmField val WALL_HANGING_SIGNS = createTag("wall_hanging_signs")
@JvmField val WALL_SIGNS = createTag("wall_signs")
private fun createTag(name: String) = TagKey.of(RegistryKeys.BLOCK, cobblemonResource(name))
}
@@ -9,15 +9,17 @@
package com.cobblemon.mod.common.api.tags
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.tag.TagKey
/**
* A collection of the Cobblemon [TagKey]s related to the [Registry.ENTITY_TYPE].
* A collection of the Cobblemon [TagKey]s related to the [Registries.ENTITY_TYPE].
*
* @author Licious
* @since March 6th, 2023
*/
@Suppress("HasPlatformType", "unused")
object CobblemonEntityTypeTags {
@@ -27,6 +29,9 @@ object CobblemonEntityTypeTags {
@JvmField
val CANNOT_HAVE_NAME_TAG = create("cannot_have_name_tag")
@JvmField
val BOATS = create("boats")
private fun create(path: String) = TagKey.of(RegistryKeys.ENTITY_TYPE, cobblemonResource(path))
}
@@ -9,16 +9,17 @@
package com.cobblemon.mod.common.api.tags
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.registry.Registry
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.tag.TagKey
/**
* A collection of the Cobblemon [TagKey]s related to the [Registry.ITEM].
* A collection of the Cobblemon [TagKey]s related to the [Registries.ITEM].
*
* @author Licious
* @since January 8th, 2023
*/
@Suppress("unused", "HasPlatformType")
object CobblemonItemTags {
@JvmField
@@ -27,11 +28,47 @@ object CobblemonItemTags {
val APRICORN_SEEDS = create("apricorn_seeds")
@JvmField
val APRICORNS = create("apricorns")
/**
* This tag is only used for a Torterra aspect based easter egg evolution at the moment.
* It simply includes the 'minecraft:azalea' and 'minecraft:flowering_azalea' items by default.
*/
@JvmField
val AZALEA_TREE = create("azalea_tree")
@JvmField
val BERRIES = create("berries")
@JvmField
val BOATS = create("boats")
@JvmField
val COBBLEMON_SEEDS = create("cobblemon_seeds")
@JvmField
val EVOLUTION_ITEMS = create("evolution_items")
@JvmField
val EVOLUTION_STONES = create("evolution_stones")
@JvmField
val EXPERIENCE_CANDIES = create("experience_candies")
@JvmField
val HANGING_SIGNS = create("hanging_signs")
@JvmField
val HERBS = create("herbs")
@JvmField
val MINT_LEAF = create("mint_leaf")
@JvmField
val MINTS = create("mints")
@JvmField
val MUTATED_BERRIES = create("mutated_berries")
@JvmField
val PLANTS = create("plants")
@JvmField
val POKEBALLS = create("poke_balls")
@JvmField
val PROTEIN_INGREDIENTS = create("protein_ingredients")
@JvmField
val SEEDS = create("seeds")
@JvmField
val SIGNS = create("signs")
@JvmField
val ZINC_INGREDIENTS = create("zinc_ingredients")
@JvmField
val ANY_HELD_ITEM = create("held/is_held_item")
@JvmField
val EXPERIENCE_SHARE = create("held/experience_share")
@@ -53,20 +90,6 @@ object CobblemonItemTags {
val POWER_LENS = create("held/power_lens")
@JvmField
val POWER_WEIGHT = create("held/power_weight")
@JvmField
val EVOLUTION_STONES = create("evolution_stones")
@JvmField
val EVOLUTION_ITEMS = create("evolution_items")
@JvmField
val MINTS = create("mints")
@JvmField
val MINT_LEAVES = create("mint_leaves")
/**
* This tag is only used for a Torterra aspect based easter egg evolution at the moment.
* It simply includes the 'minecraft:azalea' and 'minecraft:flowering_azalea' items by default.
*/
val AZALEA_TREE = create("azalea_tree")
private fun create(path: String) = TagKey.of(RegistryKeys.ITEM, cobblemonResource(path))
@@ -0,0 +1,21 @@
/*
* 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.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import net.minecraft.block.BlockState
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.block.entity.HangingSignBlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonHangingSignBlockEntity(pos: BlockPos, state: BlockState) : HangingSignBlockEntity(pos, state) {
override fun getType(): BlockEntityType<*> = CobblemonBlockEntities.HANGING_SIGN
}
@@ -0,0 +1,21 @@
/*
* 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.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import net.minecraft.block.BlockState
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.block.entity.SignBlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonSignBlockEntity(pos: BlockPos, state: BlockState) : SignBlockEntity(pos, state) {
override fun getType(): BlockEntityType<*> = CobblemonBlockEntities.SIGN
}
@@ -0,0 +1,22 @@
/*
* 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.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonHangingSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.HangingSignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonHangingSignBlock(settings: Settings, woodType: WoodType) : HangingSignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonHangingSignBlockEntity(pos, state)
}
@@ -0,0 +1,22 @@
/*
* 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.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.SignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonSignBlock(settings: Settings, woodType: WoodType) : SignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
}
@@ -0,0 +1,22 @@
/*
* 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.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonHangingSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.WallHangingSignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonWallHangingSignBlock(settings: Settings, woodType: WoodType) : WallHangingSignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonHangingSignBlockEntity(pos, state)
}
@@ -0,0 +1,22 @@
/*
* 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.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.WallSignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonWallSignBlock(settings: Settings, woodType: WoodType) : WallSignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
}
@@ -18,10 +18,12 @@ import com.cobblemon.mod.common.client.gui.battle.BattleOverlay
import com.cobblemon.mod.common.client.particle.BedrockParticleEffectRepository
import com.cobblemon.mod.common.client.render.block.BerryBlockRenderer
import com.cobblemon.mod.common.client.render.block.HealingMachineRenderer
import com.cobblemon.mod.common.client.render.boat.CobblemonBoatRenderer
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokeBallModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
import com.cobblemon.mod.common.client.render.pokeball.PokeBallRenderer
@@ -30,16 +32,19 @@ import com.cobblemon.mod.common.client.starter.ClientPlayerData
import com.cobblemon.mod.common.client.storage.ClientStorageManager
import com.cobblemon.mod.common.client.trade.ClientTrade
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.item.PokeBallItem
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.asTranslated
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.block.entity.HangingSignBlockEntityRenderer
import net.minecraft.client.render.block.entity.SignBlockEntityRenderer
import net.minecraft.client.render.entity.EntityRenderer
import net.minecraft.client.render.entity.EntityRendererFactory
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.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
@@ -83,12 +88,11 @@ object CobblemonClient {
PlatformEvents.CLIENT_PLAYER_LOGIN.subscribe { onLogin() }
PlatformEvents.CLIENT_PLAYER_LOGOUT.subscribe { onLogout() }
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HEALING_MACHINE, ::HealingMachineRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.BERRY, ::BerryBlockRenderer)
this.registerBlockEntityRenderers()
registerBlockRenderTypes()
//registerColors()
registerFlywheelRenderers()
this.registerEntityRenderers()
LOGGER.info("Registering custom BuiltinItemRenderers")
CobblemonBuiltinItemRendererRegistry.register(CobblemonItems.POKEMON_MODEL, PokemonItemRenderer())
@@ -143,6 +147,10 @@ object CobblemonClient {
RenderLayer.getCutout(),
CobblemonBlocks.APRICORN_DOOR,
CobblemonBlocks.APRICORN_TRAPDOOR,
CobblemonBlocks.APRICORN_SIGN,
CobblemonBlocks.APRICORN_WALL_SIGN,
CobblemonBlocks.APRICORN_HANGING_SIGN,
CobblemonBlocks.APRICORN_WALL_HANGING_SIGN,
CobblemonBlocks.BLACK_APRICORN_SAPLING,
CobblemonBlocks.BLUE_APRICORN_SAPLING,
CobblemonBlocks.GREEN_APRICORN_SAPLING,
@@ -176,6 +184,8 @@ object CobblemonClient {
CobblemonBlocks.REVIVAL_HERB,
*CobblemonBlocks.berries().values.toTypedArray()
)
this.createBoatModelLayers()
}
fun beforeChatRender(context: DrawContext, partialDeltaTicks: Float) {
@@ -194,14 +204,22 @@ object CobblemonClient {
renderer?.addFeature(PokemonOnShoulderRenderer(renderer))
}
fun registerPokemonRenderer(context: EntityRendererFactory.Context): PokemonRenderer {
LOGGER.info("Registering Pokémon renderer")
return PokemonRenderer(context)
private fun registerBlockEntityRenderers() {
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HEALING_MACHINE, ::HealingMachineRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.BERRY, ::BerryBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.SIGN, ::SignBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HANGING_SIGN, ::HangingSignBlockEntityRenderer)
}
fun registerPokeBallRenderer(context: EntityRendererFactory.Context): PokeBallRenderer {
private fun registerEntityRenderers() {
LOGGER.info("Registering Pokémon renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.POKEMON, ::PokemonRenderer)
LOGGER.info("Registering PokéBall renderer")
return PokeBallRenderer(context)
this.implementation.registerEntityRenderer(CobblemonEntities.EMPTY_POKEBALL, ::PokeBallRenderer)
LOGGER.info("Registering Boat renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.BOAT) { ctx -> CobblemonBoatRenderer(ctx, false) }
LOGGER.info("Registering Boat with Chest renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.CHEST_BOAT) { ctx -> CobblemonBoatRenderer(ctx, true) }
}
fun reloadCodedAssets(resourceManager: ResourceManager) {
@@ -215,7 +233,6 @@ object CobblemonClient {
PokeBallModelRepository.reload(resourceManager)
BerryModelRepository.reload(resourceManager)
LOGGER.info("Loaded assets")
// PokeBallModelRepository.reload(resourceManager)
}
fun endBattle() {
@@ -230,4 +247,11 @@ object CobblemonClient {
return "${stack.translationKey}.tooltip"
}
private fun createBoatModelLayers() {
CobblemonBoatType.values().forEach { type ->
this.implementation.registerLayer(CobblemonBoatRenderer.createBoatModelLayer(type, false), BoatEntityModel::getTexturedModelData)
this.implementation.registerLayer(CobblemonBoatRenderer.createBoatModelLayer(type, true), ChestBoatEntityModel::getTexturedModelData)
}
}
}
@@ -0,0 +1,90 @@
/*
* 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.client.render.boat
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.render.OverlayTexture
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.entity.EntityRenderer
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.model.BoatEntityModel
import net.minecraft.client.render.entity.model.ChestBoatEntityModel
import net.minecraft.client.render.entity.model.EntityModelLayer
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.Identifier
import net.minecraft.util.math.MathHelper
import net.minecraft.util.math.RotationAxis
import org.joml.Quaternionf
class CobblemonBoatRenderer(ctx: EntityRendererFactory.Context, private val hasChest: Boolean) : EntityRenderer<CobblemonBoatEntity>(ctx) {
private val boatModels = hashMapOf<CobblemonBoatType, Pair<Identifier, BoatEntityModel>>()
init {
this.shadowRadius = 0.8F
CobblemonBoatType.values().forEach { type ->
this.boatModels[type] = generateTextureIdentifier(type, this.hasChest) to generateBoatModel(ctx, type, this.hasChest)
}
}
override fun getTexture(entity: CobblemonBoatEntity): Identifier = this.boatModels[entity.boatType]!!.first
override fun render(entity: CobblemonBoatEntity, yaw: Float, tickDelta: Float, matrices: MatrixStack, vertexConsumers: VertexConsumerProvider, light: Int) {
matrices.push()
matrices.translate(0F, 0.375F, 0F)
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180F - yaw))
val h = entity.damageWobbleTicks - tickDelta
val j = (entity.damageWobbleStrength - tickDelta).coerceAtLeast(0F)
if (h > 0F) {
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(MathHelper.sin(h) * h * j / 10F * entity.damageWobbleSide))
}
val k = entity.interpolateBubbleWobble(tickDelta)
if (!MathHelper.approximatelyEquals(k, 0F)) {
matrices.multiply(Quaternionf().setAngleAxis(entity.interpolateBubbleWobble(tickDelta) * 0.017453292F, 1F, 0F, 1F))
}
val (identifier, entityModel) = this.boatModels[entity.boatType]!!
matrices.scale(-1F, -1F, 1F)
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90F))
entityModel.setAngles(entity, tickDelta, 0F, -0.1F, 0F, 0F)
val vertexConsumer = vertexConsumers.getBuffer(entityModel.getLayer(identifier))
entityModel.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 1F, 1F, 1F, 1F)
if (!entity.isSubmergedInWater) {
val vertexConsumer2 = vertexConsumers.getBuffer(RenderLayer.getWaterMask())
entityModel.waterPatch.render(matrices, vertexConsumer2, light, OverlayTexture.DEFAULT_UV)
}
matrices.pop()
super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light)
}
companion object {
private fun generateTextureIdentifier(type: CobblemonBoatType, hasChest: Boolean): Identifier {
val boatSubPath = if (hasChest) "chest_boat" else "boat"
val path = "textures/entity/$boatSubPath/${type.name.lowercase()}.png"
return cobblemonResource(path)
}
private fun generateBoatModel(ctx: EntityRendererFactory.Context, type: CobblemonBoatType, hasChest: Boolean): BoatEntityModel {
val modelLayer = this.createBoatModelLayer(type, hasChest)
val modelPart = ctx.getPart(modelLayer)
return if (hasChest) ChestBoatEntityModel(modelPart) else BoatEntityModel(modelPart)
}
internal fun createBoatModelLayer(type: CobblemonBoatType, hasChest: Boolean): EntityModelLayer {
val boatSubPath = if (hasChest) "chest_boat" else "boat"
val path = "$boatSubPath/${type.name.lowercase()}"
return EntityModelLayer(cobblemonResource(path), "main")
}
}
}
@@ -0,0 +1,137 @@
/*
* 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.entity.boat
import com.cobblemon.mod.common.CobblemonEntities
import com.cobblemon.mod.common.mixin.accessor.BoatEntityAccessor
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.WoodType
import net.minecraft.entity.EntityType
import net.minecraft.entity.data.DataTracker
import net.minecraft.entity.data.TrackedDataHandlerRegistry
import net.minecraft.entity.vehicle.BoatEntity
import net.minecraft.item.Item
import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtString
import net.minecraft.network.listener.ClientPlayPacketListener
import net.minecraft.network.packet.Packet
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket
import net.minecraft.registry.tag.FluidTags
import net.minecraft.text.Text
import net.minecraft.util.math.BlockPos
import net.minecraft.world.GameRules
import net.minecraft.world.World
@Suppress("unused")
open class CobblemonBoatEntity(entityType: EntityType<out BoatEntity>, world: World) : BoatEntity(entityType, world) {
constructor(world: World) : this(CobblemonEntities.BOAT, world)
// This exists cause super passes in vanilla boat entity type
constructor(world: World, x: Double, y: Double, z: Double) : this(CobblemonEntities.BOAT, world) {
this.setPosition(x, y, z)
this.prevX = x
this.prevY = y
this.prevZ = z
}
/**
* The [CobblemonBoatType] of this boat.
*/
var boatType: CobblemonBoatType
get() = CobblemonBoatType.ofOrdinal(this.dataTracker.get(TYPE_TRACKED_DATA))
set(value) {
this.dataTracker.set(TYPE_TRACKED_DATA, value.ordinal)
}
/**
* The [WoodType] that represents this boat.
*/
val woodType: WoodType get() = this.boatType.woodType
/**
* The [Block] that represents the base material for this boat.
*/
val baseBlock: Block get() = this.boatType.baseBlock
override fun asItem(): Item = this.boatType.boatItem
override fun createSpawnPacket(): Packet<ClientPlayPacketListener> = EntitySpawnS2CPacket(this)
override fun initDataTracker() {
super.initDataTracker()
this.dataTracker.startTracking(TYPE_TRACKED_DATA, CobblemonBoatType.APRICORN.ordinal)
}
override fun getDefaultName(): Text = EntityType.BOAT.name
override fun readCustomDataFromNbt(nbt: NbtCompound) {
if (nbt.contains(TYPE_KEY, NbtElement.STRING_TYPE.toInt())) {
this.boatType = CobblemonBoatType.valueOf(nbt.getString(TYPE_KEY))
}
}
override fun writeCustomDataToNbt(nbt: NbtCompound) {
nbt.put(TYPE_KEY, NbtString.of(this.boatType.name))
}
override fun setVariant(type: Type) {
throw UnsupportedOperationException("The vanilla boat type is not present in the Cobblemon implementation use the type property")
}
override fun getVariant(): Type {
throw UnsupportedOperationException("The vanilla boat type is not present in the Cobblemon implementation use the type property")
}
override fun getMountedHeightOffset(): Double = this.boatType.mountedOffset
override fun fall(heightDifference: Double, onGround: Boolean, state: BlockState, landedPosition: BlockPos) {
val accessor = this.accessor()
accessor.setFallVelocity(this.velocity.y)
if (!this.hasVehicle()) {
return
}
if (!this.world.getFluidState(this.blockPos.down()).isIn(FluidTags.WATER) && heightDifference < 0.0) {
this.fallDistance -= heightDifference.toFloat()
}
if (!onGround) {
return
}
if (this.fallDistance < 3F || accessor.location != Location.ON_LAND) {
this.onLanding()
return
}
this.handleFallDamage(this.fallDistance, 1F, this.damageSources.fall())
if (this.world.isClient || this.isRemoved) {
return
}
this.kill()
if (this.world.gameRules.getBoolean(GameRules.DO_ENTITY_DROPS)) {
repeat(3) {
this.dropItem(this.boatType.baseBlock)
}
repeat(2) {
this.dropItem(Items.STICK)
}
}
}
protected fun accessor(): BoatEntityAccessor = this as BoatEntityAccessor
companion object {
private const val TYPE_KEY = "type"
private val TYPE_TRACKED_DATA = DataTracker.registerData(CobblemonBoatEntity::class.java, TrackedDataHandlerRegistry.INTEGER)
}
}
@@ -0,0 +1,62 @@
/*
* 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.entity.boat
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import net.minecraft.block.Block
import net.minecraft.block.WoodType
import net.minecraft.item.Item
import net.minecraft.util.StringIdentifiable
/**
* Represents the various wooden boats in Cobblemon.
*
*/
enum class CobblemonBoatType(val mountedOffset: Double) : StringIdentifiable {
APRICORN(-0.1);
/**
* The base [Item] form of this [CobblemonBoatType].
*/
val boatItem: Item get() = when (this) {
APRICORN -> CobblemonItems.APRICORN_BOAT
}
/**
* The base [Item] form of this [CobblemonBoatType] with a chest.
*/
val chestBoatItem: Item get() = when (this) {
APRICORN -> CobblemonItems.APRICORN_CHEST_BOAT
}
/**
* The base [Block] form of this [CobblemonBoatType].
*/
val baseBlock: Block get() = when (this) {
APRICORN -> CobblemonBlocks.APRICORN_PLANKS
}
/**
* The [WoodType] form of this [CobblemonBoatType].
*/
val woodType: WoodType get() = when (this) {
APRICORN -> CobblemonBlocks.APRICORN_WOOD_TYPE
}
override fun asString(): String = this.name.lowercase()
companion object {
internal fun ofOrdinal(ordinal: Int) = CobblemonBoatType.values()[ordinal]
}
}
@@ -0,0 +1,104 @@
/*
* 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.entity.boat
import com.cobblemon.mod.common.CobblemonEntities
import net.minecraft.entity.EntityType
import net.minecraft.entity.RideableInventory
import net.minecraft.entity.mob.PiglinBrain
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.entity.vehicle.VehicleInventory
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.screen.GenericContainerScreenHandler
import net.minecraft.screen.ScreenHandler
import net.minecraft.util.Identifier
import net.minecraft.util.collection.DefaultedList
import net.minecraft.world.World
import net.minecraft.world.event.GameEvent
@Suppress("unused")
class CobblemonChestBoatEntity(entityType: EntityType<CobblemonChestBoatEntity>, world: World) : CobblemonBoatEntity(entityType, world), RideableInventory, VehicleInventory {
constructor(world: World) : this(CobblemonEntities.CHEST_BOAT, world)
// This exists cause super passes in vanilla boat entity type
constructor(world: World, x: Double, y: Double, z: Double) : this(CobblemonEntities.CHEST_BOAT, world) {
this.setPosition(x, y, z)
this.prevX = x
this.prevY = y
this.prevZ = z
}
private var inventory = this.emptyInventory()
private var lootTableId: Identifier? = null
private var lootTableSeed = 0L
override fun openInventory(player: PlayerEntity) {
player.openHandledScreen(this)
if (!player.world.isClient) {
this.emitGameEvent(GameEvent.CONTAINER_OPEN, player)
PiglinBrain.onGuardedBlockInteracted(player, true)
}
}
override fun clear() = this.clearInventory()
override fun size(): Int = INVENTORY_SLOTS
override fun getStack(slot: Int): ItemStack = this.getInventoryStack(slot)
override fun removeStack(slot: Int, amount: Int): ItemStack = this.removeInventoryStack(slot, amount)
override fun removeStack(slot: Int): ItemStack = this.removeInventoryStack(slot)
override fun setStack(slot: Int, stack: ItemStack) = this.setInventoryStack(slot, stack)
override fun markDirty() {}
override fun canPlayerUse(player: PlayerEntity): Boolean = this.canPlayerAccess(player)
override fun createMenu(syncId: Int, playerInventory: PlayerInventory, player: PlayerEntity): ScreenHandler? {
if (this.lootTableId != null && player.isSpectator) {
return null
}
this.generateInventoryLoot(playerInventory.player)
return GenericContainerScreenHandler.createGeneric9x3(syncId, playerInventory, this)
}
override fun getLootTableId(): Identifier? = this.lootTableId
override fun setLootTableId(lootTableId: Identifier?) {
this.lootTableId = lootTableId
}
override fun getLootTableSeed(): Long = this.lootTableSeed
override fun setLootTableSeed(lootTableSeed: Long) {
this.lootTableSeed = lootTableSeed
}
override fun getInventory(): DefaultedList<ItemStack> = this.inventory
override fun resetInventory() {
this.inventory = this.emptyInventory()
}
override fun asItem(): Item = this.boatType.chestBoatItem
private fun emptyInventory(): DefaultedList<ItemStack> = DefaultedList.ofSize(INVENTORY_SLOTS, ItemStack.EMPTY)
companion object {
private const val INVENTORY_SLOTS = 27
}
}
@@ -0,0 +1,75 @@
/*
* 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.item
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.entity.boat.CobblemonChestBoatEntity
import net.minecraft.entity.Entity
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.predicate.entity.EntityPredicates
import net.minecraft.stat.Stats
import net.minecraft.util.Hand
import net.minecraft.util.TypedActionResult
import net.minecraft.util.hit.HitResult
import net.minecraft.world.RaycastContext.FluidHandling
import net.minecraft.world.World
import net.minecraft.world.event.GameEvent
class CobblemonBoatItem(val boatType: CobblemonBoatType, val hasChest: Boolean, settings: Settings) : CobblemonItem(settings) {
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
val stack = user.getStackInHand(hand)
val hitResult = raycast(world, user, FluidHandling.ANY)
if (hitResult.type == HitResult.Type.MISS) {
return TypedActionResult.pass(stack)
}
val vec3d = user.getRotationVec(1F)
val eyePos = user.eyePos
world.getOtherEntities(user, user.boundingBox.stretch(vec3d.multiply(5.0)).expand(1.0), RIDERS).forEach { entity ->
val box = entity.boundingBox.expand(entity.targetingMargin.toDouble())
if (box.contains(eyePos)) {
return TypedActionResult.pass(stack)
}
}
if (hitResult.type != HitResult.Type.BLOCK) {
return TypedActionResult.pass(stack)
}
val boatEntity = this.createBoat(world, hitResult)
boatEntity.boatType = this.boatType
boatEntity.yaw = user.yaw
if (!world.isSpaceEmpty(boatEntity, boatEntity.boundingBox)) {
return TypedActionResult.fail(stack)
}
if (!world.isClient) {
world.spawnEntity(boatEntity)
world.emitGameEvent(user, GameEvent.ENTITY_PLACE, hitResult.pos)
if (!user.abilities.creativeMode) {
stack.decrement(1)
}
}
user.incrementStat(Stats.USED.getOrCreateStat(this))
return TypedActionResult.success(stack, world.isClient)
}
private fun createBoat(world: World, hitResult: HitResult): CobblemonBoatEntity {
if (this.hasChest) {
return CobblemonChestBoatEntity(world, hitResult.pos.x, hitResult.pos.y, hitResult.pos.z)
}
return CobblemonBoatEntity(world, hitResult.pos.x, hitResult.pos.y, hitResult.pos.z)
}
companion object {
private val RIDERS = EntityPredicates.EXCEPT_SPECTATOR.and(Entity::canHit)
}
}
@@ -10,10 +10,11 @@ package com.cobblemon.mod.common.item.group
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.item.Item
import net.minecraft.item.ItemConvertible
import net.minecraft.item.ItemGroup
import net.minecraft.item.ItemGroup.*
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKey
import net.minecraft.text.Text
@@ -25,7 +26,7 @@ object CobblemonItemGroups {
// See https://docs.google.com/spreadsheets/d/1QgaIlW-S9A-Blqhc-5G7OO3igaQdEAiYQqVEPnEBFmc/edit#gid=978365418 for what goes what
private val ALL = arrayListOf<ItemGroupHolder>()
private val INJECTORS = arrayListOf<ItemGroupInjector>()
private val INJECTORS = hashMapOf<RegistryKey<ItemGroup>, (injector: Injector) -> Unit>()
@JvmStatic val BLOCKS_KEY = this.create("blocks", this::blockEntries) { ItemStack(CobblemonItems.PC) }
@JvmStatic val POKEBALLS_KEY = this.create("pokeball", this::pokeballentries) { ItemStack(CobblemonItems.POKE_BALL) }
@@ -42,15 +43,18 @@ object CobblemonItemGroups {
@JvmStatic val EVOLUTION_ITEMS get() = Registries.ITEM_GROUP.get(EVOLUTION_ITEMS_KEY)
@JvmStatic val FOOD_INJECTIONS = this.inject(RegistryKey.of(Registries.ITEM_GROUP.key, Identifier("food_and_drinks")), this::foodInjections)
@JvmStatic val TOOLS_AND_UTILITIES_INJECTIONS = this.inject(RegistryKey.of(Registries.ITEM_GROUP.key, Identifier("tools_and_utilities")), this::toolsAndUtilitiesInjections)
fun register(consumer: (holder: ItemGroupHolder) -> ItemGroup) {
ALL.forEach(consumer::invoke)
}
fun inject(consumer: (injector: ItemGroupInjector) -> Unit) {
INJECTORS.forEach(consumer)
fun inject(tabKey: RegistryKey<ItemGroup>, injector: Injector) {
INJECTORS[tabKey]?.invoke(injector)
}
fun injectorKeys(): Collection<RegistryKey<ItemGroup>> = this.INJECTORS.keys
data class ItemGroupHolder(
val key: RegistryKey<ItemGroup>,
val displayIconProvider: () -> ItemStack,
@@ -58,21 +62,15 @@ object CobblemonItemGroups {
val displayName: Text = Text.translatable("itemGroup.${key.value.namespace}.${key.value.path}")
)
data class ItemGroupInjector(
val key: RegistryKey<ItemGroup>,
val entryInjector: (displayContext: DisplayContext) -> List<Item>,
)
private fun create(name: String, entryCollector: EntryCollector, displayIconProvider: () -> ItemStack): RegistryKey<ItemGroup> {
val key = RegistryKey.of(Registries.ITEM_GROUP.key, cobblemonResource(name))
this.ALL += ItemGroupHolder(key, displayIconProvider, entryCollector)
return key
}
private fun inject(key: RegistryKey<ItemGroup>, entryInjector: (displayContext: DisplayContext) -> List<Item>): ItemGroupInjector {
val injector = ItemGroupInjector(key, entryInjector)
this.INJECTORS += injector
return injector
private fun inject(key: RegistryKey<ItemGroup>, consumer: (injector: Injector) -> Unit): (injector: Injector) -> Unit {
this.INJECTORS[key] = consumer
return consumer
}
private fun agricultureEntries(displayContext: DisplayContext, entries: Entries) {
@@ -146,6 +144,8 @@ object CobblemonItemGroups {
entries.add(CobblemonItems.APRICORN_TRAPDOOR)
entries.add(CobblemonItems.APRICORN_BUTTON)
entries.add(CobblemonItems.APRICORN_PRESSURE_PLATE)
entries.add(CobblemonItems.APRICORN_SIGN)
entries.add(CobblemonItems.APRICORN_HANGING_SIGN)
entries.add(CobblemonItems.APRICORN_LEAVES)
entries.add(CobblemonItems.DAWN_STONE_ORE)
entries.add(CobblemonItems.DEEPSLATE_DAWN_STONE_ORE)
@@ -362,11 +362,56 @@ object CobblemonItemGroups {
CobblemonItems.pokeBalls.forEach(entries::add)
}
private fun foodInjections(displayContext: DisplayContext): List<Item> = arrayListOf(
CobblemonItems.ROASTED_LEEK,
CobblemonItems.LEEK_AND_POTATO_STEW,
CobblemonItems.BRAISED_VIVICHOKE,
CobblemonItems.VIVICHOKE_DIP
)
private fun foodInjections(injector: Injector) {
injector.putLast(CobblemonItems.ROASTED_LEEK)
injector.putLast(CobblemonItems.LEEK_AND_POTATO_STEW)
injector.putLast(CobblemonItems.BRAISED_VIVICHOKE)
injector.putLast(CobblemonItems.VIVICHOKE_DIP)
}
private fun toolsAndUtilitiesInjections(injector: Injector) {
injector.putAfter(CobblemonItems.APRICORN_BOAT, Items.BAMBOO_CHEST_RAFT)
injector.putAfter(CobblemonItems.APRICORN_CHEST_BOAT, CobblemonItems.APRICORN_BOAT)
}
/**
* The abstract behaviour of injecting into existing [ItemGroup]s in specific positions.
* Each platform has to implement the behaviour.
*/
interface Injector {
/**
* Places the given [item] at the start of a creative tab.
*
* @param item The [ItemConvertible] being added at the start of a tab.
*/
fun putFirst(item: ItemConvertible)
/**
* Places the given [item] before the [target].
* If the [target] is not present behaves as [putLast].
*
* @param item The [ItemConvertible] being added before [target].
* @param target The [ItemConvertible] being targeted.
*/
fun putBefore(item: ItemConvertible, target: ItemConvertible)
/**
* Places the given [item] after the [target].
* If the [target] is not present behaves as [putLast].
*
* @param item The [ItemConvertible] being added after [target].
* @param target The [ItemConvertible] being targeted.
*/
fun putAfter(item: ItemConvertible, target: ItemConvertible)
/**
* Places the given [item] at the end of a creative tab.
*
* @param item The [ItemConvertible] being added at the end of a tab.
*/
fun putLast(item: ItemConvertible)
}
}
@@ -0,0 +1,9 @@
{
"sources": [
{
"type": "directory",
"source": "entity/signs",
"prefix": "entity/signs/"
}
]
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/apricorn_hanging_sign"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "cobblemon:block/apricorn_hanging_sign"
}
}
}
@@ -48,6 +48,9 @@
"item.cobblemon.vivichoke_seeds": "Vivichoke Seeds",
"item.cobblemon.vivichoke": "Vivichoke",
"item.cobblemon.apricorn_boat": "Apricorn Boat",
"item.cobblemon.apricorn_chest_boat": "Apricorn Boat with Chest",
"item.cobblemon.link_cable": "Link Cable",
"item.cobblemon.dragon_scale": "Dragon Scale",
"item.cobblemon.kings_rock": "Kings Rock",
@@ -292,6 +295,7 @@
"block.cobblemon.apricorn_leaves": "Apricorn Leaves",
"block.cobblemon.apricorn_fence": "Apricorn Fence",
"block.cobblemon.apricorn_sign": "Apricorn Sign",
"block.cobblemon.apricorn_hanging_sign": "Apricorn Hanging Sign",
"block.cobblemon.apricorn_stairs": "Apricorn Stairs",
"block.cobblemon.apricorn_pressure_plate": "Apricorn Pressure Plate",
"block.cobblemon.apricorn_button": "Apricorn Button",
@@ -0,0 +1,5 @@
{
"textures": {
"particle": "cobblemon:block/stripped_apricorn_log"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/apricorn_boat"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/apricorn_chest_boat"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/apricorn_hanging_sign"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

@@ -0,0 +1,35 @@
{
"parent": "cobblemon:recipes/root",
"criteria": {
"has_stripped_logs": {
"conditions": {
"items": [
{
"items": [
"cobblemon:stripped_apricorn_log"
]
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "cobblemon:apricorn_hanging_sign"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_stripped_logs",
"has_the_recipe"
]
],
"rewards": {
"recipes": [
"cobblemon:apricorn_hanging_sign"
]
},
"sends_telemetry_event": false
}
@@ -0,0 +1,35 @@
{
"parent": "cobblemon:recipes/root",
"criteria": {
"has_planks": {
"conditions": {
"items": [
{
"items": [
"cobblemon:apricorn_planks"
]
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "cobblemon:apricorn_sign"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_planks",
"has_the_recipe"
]
],
"rewards": {
"recipes": [
"cobblemon:apricorn_sign"
]
},
"sends_telemetry_event": false
}
@@ -0,0 +1,29 @@
{
"parent": "cobblemon:recipes/root",
"criteria": {
"has_the_recipe": {
"conditions": {
"recipe": "cobblemon:apricorn_boat"
},
"trigger": "minecraft:recipe_unlocked"
},
"in_water": {
"conditions": {
"block": "minecraft:water"
},
"trigger": "minecraft:enter_block"
}
},
"requirements": [
[
"in_water",
"has_the_recipe"
]
],
"rewards": {
"recipes": [
"cobblemon:apricorn_boat"
]
},
"sends_telemetry_event": false
}
@@ -0,0 +1,33 @@
{
"parent": "cobblemon:recipes/root",
"criteria": {
"has_boat": {
"conditions": {
"items": [
{
"tag": "minecraft:boats"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "cobblemon:apricorn_chest_boat"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_boat",
"has_the_recipe"
]
],
"rewards": {
"recipes": [
"cobblemon:apricorn_chest_boat"
]
},
"sends_telemetry_event": false
}
@@ -0,0 +1,18 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"group": "boat",
"key": {
"#": {
"item": "cobblemon:apricorn_planks"
}
},
"pattern": [
"# #",
"###"
],
"result": {
"item": "cobblemon:apricorn_boat"
},
"show_notification": true
}
@@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shapeless",
"category": "misc",
"group": "chest_boat",
"ingredients": [
{
"item": "minecraft:chest"
},
{
"item": "cobblemon:apricorn_boat"
}
],
"result": {
"item": "cobblemon:apricorn_chest_boat"
}
}
@@ -0,0 +1,23 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"group": "hanging_sign",
"key": {
"#": {
"item": "cobblemon:stripped_apricorn_log"
},
"X": {
"item": "minecraft:chain"
}
},
"pattern": [
"X X",
"###",
"###"
],
"result": {
"count": 6,
"item": "cobblemon:apricorn_hanging_sign"
},
"show_notification": true
}
@@ -0,0 +1,23 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"group": "wooden_sign",
"key": {
"#": {
"item": "cobblemon:apricorn_planks"
},
"X": {
"item": "minecraft:stick"
}
},
"pattern": [
"###",
"###",
" X "
],
"result": {
"count": 3,
"item": "cobblemon:apricorn_sign"
},
"show_notification": true
}
@@ -0,0 +1,6 @@
{
"values": [
"#cobblemon:ceiling_hanging_signs",
"#cobblemon:wall_hanging_signs"
]
}
@@ -0,0 +1,6 @@
{
"values": [
"#cobblemon:signs",
"#cobblemon:all_hanging_signs"
]
}
@@ -0,0 +1,5 @@
{
"values": [
"cobblemon:apricorn_hanging_sign"
]
}
@@ -0,0 +1,6 @@
{
"values": [
"#cobblemon:standing_signs",
"#cobblemon:wall_signs"
]
}
@@ -0,0 +1,5 @@
{
"values": [
"cobblemon:apricorn_sign"
]
}
@@ -0,0 +1,5 @@
{
"values": [
"cobblemon:apricorn_wall_hanging_sign"
]
}
@@ -0,0 +1,5 @@
{
"values": [
"cobblemon:apricorn_wall_sign"
]
}
@@ -0,0 +1,6 @@
{
"values": [
"cobblemon:boat",
"cobblemon:chest_boat"
]
}
@@ -0,0 +1,6 @@
{
"values": [
"cobblemon:apricorn_boat",
"cobblemon:apricorn_chest_boat"
]
}
@@ -0,0 +1,5 @@
{
"values": [
"cobblemon:apricorn_hanging_sign"
]
}
@@ -0,0 +1,5 @@
{
"values": [
"cobblemon:apricorn_sign"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:all_hanging_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:all_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:ceiling_hanging_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:standing_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:wall_hanging_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:wall_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:hanging_signs"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:signs"
]
}
@@ -22,8 +22,13 @@
"MinecraftDedicatedServerMixin",
"PlayerMixin",
"PointedDripstoneBlockMixin",
"PotionSlotMixin",
"ShearsDispenserBehaviorMixin",
"StructurePoolAccessor",
"StructurePoolGeneratorMixin",
"StructureProcessorListMixin",
"accessor.AccessorEntity",
"accessor.BoatEntityAccessor",
"accessor.StatusEffectInstanceAccessor",
"entity.TameableEntityMixin",
"invoker.BlocksInvoker",
@@ -41,6 +41,7 @@ import net.fabricmc.fabric.api.event.player.UseBlockCallback
import net.fabricmc.fabric.api.event.player.UseEntityCallback
import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents
import net.fabricmc.fabric.api.loot.v2.LootTableEvents
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents
@@ -198,7 +199,6 @@ object CobblemonFabric : CobblemonImplementation {
CobblemonSounds.register { identifier, sound -> Registry.register(CobblemonSounds.registry, identifier, sound) }
}
@Suppress("UnstableApiUsage")
override fun registerItems() {
CobblemonItems.register { identifier, item -> Registry.register(CobblemonItems.registry, identifier, item) }
CobblemonItemGroups.register { provider ->
@@ -208,9 +208,11 @@ object CobblemonFabric : CobblemonImplementation {
.entries(provider.entryCollector)
.build())
}
CobblemonItemGroups.inject { injector ->
ItemGroupEvents.modifyEntriesEvent(injector.key).register { content ->
injector.entryInjector(content.context).forEach(content::add)
CobblemonItemGroups.injectorKeys().forEach { key ->
ItemGroupEvents.modifyEntriesEvent(key).register { content ->
val fabricInjector = FabricItemGroupInjector(content)
CobblemonItemGroups.inject(key, fabricInjector)
}
}
CobblemonTradeOffers.tradeOffersForAll().forEach { tradeOffer -> TradeOfferHelper.registerVillagerOffers(tradeOffer.profession, tradeOffer.requiredLevel) { factories -> factories.addAll(tradeOffer.tradeOffers) } }
@@ -353,4 +355,24 @@ object CobblemonFabric : CobblemonImplementation {
override fun getFabricDependencies(): MutableCollection<Identifier> = this.dependencies.toMutableList()
}
@Suppress("UnstableApiUsage")
private class FabricItemGroupInjector(private val fabricItemGroupEntries: FabricItemGroupEntries) : CobblemonItemGroups.Injector {
override fun putFirst(item: ItemConvertible) {
this.fabricItemGroupEntries.prepend(item)
}
override fun putBefore(item: ItemConvertible, target: ItemConvertible) {
this.fabricItemGroupEntries.addBefore(target, item)
}
override fun putAfter(item: ItemConvertible, target: ItemConvertible) {
this.fabricItemGroupEntries.addAfter(target, item)
}
override fun putLast(item: ItemConvertible) {
this.fabricItemGroupEntries.add(item)
}
}
}
@@ -9,11 +9,10 @@
package com.cobblemon.mod.fabric.client
import com.cobblemon.mod.common.CobblemonClientImplementation
import com.cobblemon.mod.common.CobblemonEntities
import com.cobblemon.mod.common.client.render.CobblemonAtlases
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonClient.reloadCodedAssets
import com.cobblemon.mod.common.client.keybind.CobblemonKeyBinds
import com.cobblemon.mod.common.client.render.CobblemonAtlases
import com.cobblemon.mod.common.particle.CobblemonParticles
import com.cobblemon.mod.common.particle.SnowstormParticleType
import com.cobblemon.mod.common.platform.events.ClientPlayerEvent
@@ -22,7 +21,6 @@ import com.cobblemon.mod.common.platform.events.ItemTooltipEvent
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.fabric.CobblemonFabric
import java.util.function.Supplier
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
@@ -35,7 +33,6 @@ import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener
import net.fabricmc.fabric.api.resource.ResourceManagerHelper
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener
import net.minecraft.block.Block
import net.minecraft.block.entity.BlockEntity
import net.minecraft.block.entity.BlockEntityType
@@ -47,7 +44,10 @@ import net.minecraft.client.particle.SpriteProvider
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.model.EntityModelLayer
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.item.Item
import net.minecraft.particle.ParticleEffect
import net.minecraft.particle.ParticleType
@@ -55,10 +55,9 @@ import net.minecraft.resource.ResourceManager
import net.minecraft.resource.ResourceReloader
import net.minecraft.resource.ResourceType
import net.minecraft.util.profiler.Profiler
import net.minecraft.util.profiling.jfr.event.WorldLoadFinishedEvent
import net.minecraft.world.WorldEvents
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
import java.util.function.Supplier
class CobblemonFabricClient: ClientModInitializer, CobblemonClientImplementation {
override fun onInitializeClient() {
@@ -67,8 +66,6 @@ class CobblemonFabricClient: ClientModInitializer, CobblemonClientImplementation
CobblemonFabric.networkManager.registerClientBound()
EntityRendererRegistry.register(CobblemonEntities.POKEMON) { CobblemonClient.registerPokemonRenderer(it) }
EntityRendererRegistry.register(CobblemonEntities.EMPTY_POKEBALL) { CobblemonClient.registerPokeBallRenderer(it) }
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(object : IdentifiableResourceReloadListener {
override fun reload(
@@ -123,7 +120,11 @@ class CobblemonFabricClient: ClientModInitializer, CobblemonClientImplementation
ColorProviderRegistry.BLOCK.register(provider, *blocks)
}
override fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<T>, factory: BlockEntityRendererFactory<T>) {
override fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<out T>, factory: BlockEntityRendererFactory<T>) {
BlockEntityRendererFactories.register(type, factory)
}
override fun <T : Entity> registerEntityRenderer(type: EntityType<out T>, factory: EntityRendererFactory<T>) {
EntityRendererRegistry.register(type, factory)
}
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:boats"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:boats"
]
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.forge.client
import com.cobblemon.mod.common.CobblemonClientImplementation
import com.cobblemon.mod.common.CobblemonEntities
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.client.render.CobblemonAtlases
import com.cobblemon.mod.common.client.CobblemonClient
@@ -31,17 +30,20 @@ import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.RenderLayers
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.EntityRenderers
import net.minecraft.client.render.entity.model.EntityModelLayer
import net.minecraft.client.util.ModelIdentifier
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.item.Item
import net.minecraft.item.ItemConvertible
import net.minecraft.item.ItemGroup
import net.minecraft.item.ItemStack
import net.minecraft.particle.ParticleEffect
import net.minecraft.particle.ParticleType
import net.minecraft.resource.ReloadableResourceManagerImpl
import net.minecraft.resource.ResourceManager
import net.minecraft.resource.ResourceReloader
import net.minecraft.resource.SynchronousResourceReloader
import net.minecraft.util.profiler.Profiler
import net.minecraftforge.client.ForgeHooksClient
import net.minecraftforge.client.event.ModelEvent
import net.minecraftforge.client.event.RegisterClientReloadListenersEvent
@@ -50,11 +52,11 @@ import net.minecraftforge.client.event.RegisterParticleProvidersEvent
import net.minecraftforge.client.event.RenderGuiOverlayEvent
import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.common.util.MutableHashedLinkedMap
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import thedarkcolour.kotlinforforge.forge.MOD_BUS
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
import java.util.function.Supplier
object CobblemonForgeClient : CobblemonClientImplementation {
@@ -74,8 +76,6 @@ object CobblemonForgeClient : CobblemonClientImplementation {
private fun onClientSetup(event: FMLClientSetupEvent) {
event.enqueueWork {
CobblemonClient.initialize(this)
EntityRenderers.register(CobblemonEntities.POKEMON) { CobblemonClient.registerPokemonRenderer(it) }
EntityRenderers.register(CobblemonEntities.EMPTY_POKEBALL) { CobblemonClient.registerPokeBallRenderer(it) }
}
ForgeClientPlatformEventHandler.register()
}
@@ -129,10 +129,14 @@ object CobblemonForgeClient : CobblemonClientImplementation {
MinecraftClient.getInstance().blockColors.registerColorProvider(provider, *blocks)
}
override fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<T>, factory: BlockEntityRendererFactory<T>) {
override fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<out T>, factory: BlockEntityRendererFactory<T>) {
BlockEntityRendererFactories.register(type, factory)
}
override fun <T : Entity> registerEntityRenderer(type: EntityType<out T>, factory: EntityRendererFactory<T>) {
EntityRenderers.register(type, factory)
}
private fun register3dPokeballModels(event: ModelEvent.RegisterAdditional) {
PokeBalls.all().forEach { pokeball ->
event.register(ModelIdentifier(pokeball.model3d, "inventory"))
@@ -166,11 +170,28 @@ object CobblemonForgeClient : CobblemonClientImplementation {
}
private fun onBuildContents(e: BuildCreativeModeTabContentsEvent) {
CobblemonItemGroups.inject { injector ->
if (e.tabKey == injector.key) {
injector.entryInjector(e.parameters).forEach(e::add)
}
val forgeInject = ForgeItemGroupInject(e.entries)
CobblemonItemGroups.inject(e.tabKey, forgeInject)
}
private class ForgeItemGroupInject(private val entries: MutableHashedLinkedMap<ItemStack, ItemGroup.StackVisibility>) : CobblemonItemGroups.Injector {
override fun putFirst(item: ItemConvertible) {
this.entries.putFirst(ItemStack(item), ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS)
}
override fun putBefore(item: ItemConvertible, target: ItemConvertible) {
this.entries.putBefore(ItemStack(target), ItemStack(item), ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS)
}
override fun putAfter(item: ItemConvertible, target: ItemConvertible) {
this.entries.putAfter(ItemStack(target), ItemStack(item), ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS)
}
override fun putLast(item: ItemConvertible) {
this.entries.put(ItemStack(item), ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS)
}
}
}
@@ -20,6 +20,7 @@ import net.minecraftforge.event.TickEvent
import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.eventbus.api.SubscribeEvent
@OnlyIn(Dist.CLIENT)
object ForgeClientPlatformEventHandler {
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:boats"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#cobblemon:boats"
]
}