forked from mirrors/cobblemon
Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a077e74bf2 | ||
|
|
763f1de793 | ||
|
|
62a95b93c5 | ||
|
|
7991f70c09 | ||
|
|
70d393a899 | ||
|
|
5bace46aa6 | ||
|
|
c5fb411636 | ||
|
|
9a8159ee30 | ||
|
|
acc6f119e1 | ||
|
|
932a2c375c | ||
|
|
142eebe9e6 | ||
|
|
36f19c9180 | ||
|
|
beb8fed6bd | ||
|
|
142284a17c | ||
|
|
f1ea86362a | ||
|
|
ec3361ad91 | ||
|
|
ca7c36ce15 | ||
|
|
f7c73728d7 | ||
|
|
1992a23edc | ||
|
|
dad28135cc | ||
|
|
e41d13dd53 | ||
|
|
64cae53d82 | ||
|
|
c9bf0bd8d7 | ||
|
|
97d2047aee | ||
|
|
811f8abed7 | ||
|
|
ab02a54f28 | ||
|
|
6e0c1aefcc | ||
|
|
e887b6c43c | ||
|
|
25172c2bc9 | ||
|
|
929b90173a | ||
|
|
70a65f6ffe | ||
|
|
db7d3f01d8 |
+1
-4
@@ -33,7 +33,4 @@ common/src/main/resources/assets/cobblemon/showdown
|
||||
# Generated files
|
||||
*/generated/resources/*
|
||||
/fabric/src/generated/resources/cobblemon-common.accesswidener
|
||||
/.ignored/
|
||||
|
||||
# MacOS
|
||||
.DS_Store
|
||||
/.ignored/
|
||||
@@ -20,14 +20,6 @@
|
||||
- Added effects for many Poké Balls when sending out Pokémon or capturing.
|
||||
- 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 Gilded Chests, available in all Apricorn colors.
|
||||
- Added Relic Coins, Relic Coin Pouches, and Relic Coin Sacks.
|
||||
- Added Gimmighoul.
|
||||
- Using Relic Coins, you can increase Gimmighoul's Coin Stash. Upon reaching 999, it can be evolved into Gholdengo.
|
||||
- Additionally, if you give Gimmighoul a Netherite Scrap, you can increase its Netherite Stash. Who knows what might happen if it fills up?
|
||||
|
||||
### Changes
|
||||
- Pokémon now transition more smoothly between different poses.
|
||||
@@ -40,8 +32,6 @@
|
||||
- Updated movesets to add Gen 9 DLC moves.
|
||||
- Apricorn Sprouts can now be planted directly on Apricorn leaves to create a new Apricorn of the same color.
|
||||
- Added tooltips to interaction GUIs to make it clearer what they do.
|
||||
- Poké Ball recipes now use tags for their center ingredient, rather than specificied Copper Ingot, Iron Ingot, Gold Ingot, and Diamond, allowing for further datapack customisation.
|
||||
- Using the run button in battle will now actually flee the battle.
|
||||
|
||||
### Fixes
|
||||
- Re-added the recipe for the Iron Vitamin.
|
||||
@@ -56,12 +46,6 @@
|
||||
- Fixed Poké Balls freezing in an open state if you look away when it's meant to close.
|
||||
- Adds a translation string name to the Empty Pokeball entity.
|
||||
- Fixed very many issues with Bedrock particle effects.
|
||||
- Fixed Arbok patterns not being as specific in spawning as they were intended.
|
||||
- Fixed Pokémon not avoiding danger at all when pathfinding.
|
||||
- Fixed Sobble line not being able to swim or breathe underwater.
|
||||
- Fixed incompatibility with [Just Enough Resources](https://modrinth.com/mod/just-enough-resources-jer).
|
||||
- Fixed incompatibility with [Visual Overhaul](https://modrinth.com/mod/visual-overhaul).
|
||||
- Fixed an issue that allowed Pokemon to spawn on rails.
|
||||
|
||||
### Developer
|
||||
- Significantly changed the way properties in PokemonEntity work. This could break some plugins (not in a big way, but changes will be needed).
|
||||
@@ -73,7 +57,6 @@
|
||||
- Made PokemonProperties.parse more interoperable with Java.
|
||||
- Added the ``HeldItemEvent``, this comes with 2 implementation ``HeldItemEvent.Pre`` and ``HeldItemEvent.Post``.
|
||||
- API to support dynamic lighting in any mod that implements this feature has been added to all Species & Forms, see LightingData class for details.
|
||||
- Added a Mixin for the BrewingStandScreenHandler to fix the incorrect handling of quickMove in Fabric.
|
||||
|
||||
### Datapack & Resourcepack Creators
|
||||
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
|
||||
|
||||
@@ -1,33 +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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import net.minecraft.entity.mob.PiglinBrain;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
|
||||
@Mixin(PiglinBrain.class)
|
||||
public class PiglinBarterMixin {
|
||||
|
||||
@Inject(method = "acceptsForBarter", at = @At(value = "RETURN"), cancellable = true)
|
||||
private static void cobblemon$acceptsForBarter(ItemStack stack, CallbackInfoReturnable<Boolean> ci) {
|
||||
if(!ci.getReturnValue()) {
|
||||
//TODO: Make a tag?
|
||||
if(stack.isOf(CobblemonItems.RELIC_COIN_POUCH))
|
||||
ci.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,26 +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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import net.minecraft.entity.mob.PiglinEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(PiglinEntity.class)
|
||||
public class PiglinEntityMixin {
|
||||
@Redirect(method = "equipToOffHand", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z"))
|
||||
public boolean cobblemon$isValidBarteringItem(ItemStack stack, Item item) {
|
||||
//TODO: Make a tag?
|
||||
return stack.isOf(item) || stack.isOf(CobblemonItems.RELIC_COIN_POUCH);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import com.cobblemon.mod.common.api.drop.ItemDropEntry
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.BATTLE_VICTORY
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.EVOLUTION_COMPLETE
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.HELD_ITEM_UPDATED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.LEVEL_UP_EVENT
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.POKEMON_CAPTURED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.TRADE_COMPLETED
|
||||
@@ -35,7 +34,9 @@ import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffectRegistry
|
||||
import com.cobblemon.mod.common.api.pokemon.experience.ExperienceCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.experience.ExperienceGroups
|
||||
import com.cobblemon.mod.common.api.pokemon.experience.StandardExperienceCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.*
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.ChoiceSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.FlagSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.helditem.HeldItemProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.EvCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Generation8EvCalculator
|
||||
@@ -45,8 +46,13 @@ import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningProspector
|
||||
import com.cobblemon.mod.common.api.spawning.WorldSlice
|
||||
import com.cobblemon.mod.common.api.spawning.context.AreaContextResolver
|
||||
import com.cobblemon.mod.common.api.spawning.context.AreaSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.calculators.AreaSpawningContextCalculator
|
||||
import com.cobblemon.mod.common.api.spawning.context.calculators.AreaSpawningInput
|
||||
import com.cobblemon.mod.common.api.spawning.prospecting.SpawningProspector
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import com.cobblemon.mod.common.api.starter.StarterHandler
|
||||
import com.cobblemon.mod.common.api.storage.PokemonStoreManager
|
||||
import com.cobblemon.mod.common.api.storage.adapter.conversions.ReforgedConversion
|
||||
@@ -93,7 +99,6 @@ import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
|
||||
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.pokemon.misc.GimmighoulStashHandler
|
||||
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
|
||||
@@ -101,13 +106,7 @@ import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
||||
import com.cobblemon.mod.common.sherds.CobblemonSherds
|
||||
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
||||
import com.cobblemon.mod.common.trade.TradeManager
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.ifDedicatedServer
|
||||
import com.cobblemon.mod.common.util.isLaterVersion
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.removeAmountIf
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
|
||||
import com.cobblemon.mod.common.world.feature.ore.CobblemonOrePlacedFeatures
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
|
||||
@@ -130,8 +129,8 @@ import net.minecraft.entity.data.TrackedDataHandlerRegistry
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.item.NameTagItem
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.util.WorldSavePath
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import org.apache.logging.log4j.LogManager
|
||||
|
||||
@@ -254,7 +253,6 @@ object Cobblemon {
|
||||
|
||||
SpeciesFeatures.types["choice"] = ChoiceSpeciesFeatureProvider::class.java
|
||||
SpeciesFeatures.types["flag"] = FlagSpeciesFeatureProvider::class.java
|
||||
SpeciesFeatures.types["integer"] = IntSpeciesFeatureProvider::class.java
|
||||
|
||||
SpeciesFeatures.register(
|
||||
DataKeys.CAN_BE_MILKED,
|
||||
|
||||
@@ -45,18 +45,6 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
@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))
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST: BlockEntityType<GildedChestBlockEntity> = this.create("chest", BlockEntityType.Builder.create(::GildedChestBlockEntity,
|
||||
CobblemonBlocks.GILDED_CHEST,
|
||||
CobblemonBlocks.BLUE_GILDED_CHEST,
|
||||
CobblemonBlocks.YELLOW_GILDED_CHEST,
|
||||
CobblemonBlocks.PINK_GILDED_CHEST,
|
||||
CobblemonBlocks.BLACK_GILDED_CHEST,
|
||||
CobblemonBlocks.WHITE_GILDED_CHEST,
|
||||
CobblemonBlocks.GREEN_GILDED_CHEST,
|
||||
CobblemonBlocks.GIMMIGHOUL_CHEST
|
||||
).build(null))
|
||||
|
||||
@JvmField
|
||||
val FOSSIL_MULTIBLOCK: BlockEntityType<FossilMultiblockEntity> = this.create("fossil_multiblock",
|
||||
BlockEntityType.Builder.create({ pos, state -> FossilMultiblockEntity(pos, state, FossilMultiblockBuilder(pos)) },
|
||||
@@ -77,4 +65,10 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
CobblemonBlocks.FOSSIL_ANALYZER
|
||||
).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val DYNITE_ORE: BlockEntityType<DyniteOreBlockEntity> = this.create("dynite_ore",
|
||||
BlockEntityType.Builder.create(::DyniteOreBlockEntity, CobblemonBlocks.DYNITE_ORE)
|
||||
.build(null)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ 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.chest.GildedChestBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
|
||||
@@ -97,6 +96,15 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
@JvmField
|
||||
val DEEPSLATE_WATER_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_water_stone_ore")
|
||||
|
||||
@JvmField
|
||||
val DYNITE_ORE = this.create("dynite_ore", DyniteOreBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.mapColor(MapColor.BRIGHT_RED)
|
||||
.strength(4.5f, 3f)
|
||||
.requiresTool()
|
||||
.sounds(BlockSoundGroup.METAL)
|
||||
))
|
||||
|
||||
// Apricorns
|
||||
@JvmField
|
||||
val APRICORN_LOG = log("apricorn_log", arg2 = MapColor.BROWN)
|
||||
@@ -152,11 +160,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
val YELLOW_APRICORN_SAPLING = this.create("yellow_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.YELLOW))
|
||||
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DULL_RED).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
|
||||
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DULL_RED).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DIRT_BROWN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.ENERGY_ROOT_SOUNDS)))
|
||||
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DIRT_BROWN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.ROOTS)))
|
||||
@JvmField
|
||||
val BIG_ROOT = this.create("big_root", BigRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.BIG_ROOT_SOUNDS)))
|
||||
val BIG_ROOT = this.create("big_root", BigRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.ROOTS)))
|
||||
@JvmField
|
||||
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).mapColor(MapColor.DARK_GREEN).burnable().noCollision().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
|
||||
@@ -192,7 +200,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
.mapColor(MapColor.TERRACOTTA_ORANGE)
|
||||
.strength(1.0F)
|
||||
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
|
||||
.requiresTool()
|
||||
.instrument(Instrument.BASEDRUM)
|
||||
))
|
||||
@JvmField
|
||||
@@ -200,7 +207,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
.mapColor(MapColor.LIGHT_BLUE)
|
||||
.strength(1.0F)
|
||||
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
|
||||
.requiresTool()
|
||||
.instrument(Instrument.BASEDRUM)
|
||||
))
|
||||
@JvmField
|
||||
@@ -208,7 +214,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
.mapColor(MapColor.TERRACOTTA_BLACK)
|
||||
.strength(1.0F)
|
||||
.sounds(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
|
||||
.requiresTool()
|
||||
.instrument(Instrument.BASEDRUM)
|
||||
))
|
||||
|
||||
@@ -227,99 +232,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
@JvmField
|
||||
val YELLOW_APRICORN = apricornBlock("yellow_apricorn", Apricorn.YELLOW)
|
||||
|
||||
@JvmField
|
||||
val RELIC_COIN_POUCH = create(
|
||||
"relic_coin_pouch",
|
||||
CoinPouchBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.sounds(CobblemonSounds.COIN_POUCH_SOUNDS)
|
||||
.pistonBehavior(PistonBehavior.DESTROY)
|
||||
.strength(0.4f)
|
||||
.nonOpaque(), true
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val RELIC_COIN_SACK = create(
|
||||
"relic_coin_sack",
|
||||
CoinPouchBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.sounds(CobblemonSounds.COIN_POUCH_SOUNDS)
|
||||
.pistonBehavior(PistonBehavior.DESTROY)
|
||||
.strength(0.4f), false
|
||||
))
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST = create(
|
||||
"gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.RED
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val BLUE_GILDED_CHEST = create(
|
||||
"blue_gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.BLUE
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val BLACK_GILDED_CHEST = create(
|
||||
"black_gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.BLACK
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val YELLOW_GILDED_CHEST = create(
|
||||
"yellow_gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.YELLOW
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val WHITE_GILDED_CHEST = create(
|
||||
"white_gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.WHITE
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val GREEN_GILDED_CHEST = create(
|
||||
"green_gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.GREEN
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val PINK_GILDED_CHEST = create(
|
||||
"pink_gilded_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.PINK
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val GIMMIGHOUL_CHEST = create(
|
||||
"gimmighoul_chest",
|
||||
GildedChestBlock(
|
||||
AbstractBlock.Settings.copy(Blocks.CHEST).nonOpaque().sounds(CobblemonSounds.GILDED_CHEST_SOUNDS),
|
||||
GildedChestBlock.Type.FAKE
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val MONITOR = create(
|
||||
"monitor",
|
||||
@@ -352,7 +264,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
RestorationTankBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.mapColor(MapColor.IRON_GRAY)
|
||||
.sounds(BlockSoundGroup.GLASS)
|
||||
.sounds(BlockSoundGroup.METAL)
|
||||
.pistonBehavior(PistonBehavior.BLOCK)
|
||||
.requiresTool()
|
||||
.strength(5.0F, 6.0F)
|
||||
@@ -387,17 +299,17 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val RED_MINT = create("red_mint", MintBlock(MintType.RED, AbstractBlock.Settings.create().mapColor(MapColor.RED).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
|
||||
val RED_MINT = create("red_mint", MintBlock(MintType.RED, AbstractBlock.Settings.create().mapColor(MapColor.RED).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val BLUE_MINT = create("blue_mint", MintBlock(MintType.BLUE, AbstractBlock.Settings.create().mapColor(MapColor.BLUE).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
|
||||
val BLUE_MINT = create("blue_mint", MintBlock(MintType.BLUE, AbstractBlock.Settings.create().mapColor(MapColor.BLUE).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val CYAN_MINT = create("cyan_mint", MintBlock(MintType.CYAN, AbstractBlock.Settings.create().mapColor(MapColor.CYAN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
|
||||
val CYAN_MINT = create("cyan_mint", MintBlock(MintType.CYAN, AbstractBlock.Settings.create().mapColor(MapColor.CYAN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val PINK_MINT = create("pink_mint", MintBlock(MintType.PINK, AbstractBlock.Settings.create().mapColor(MapColor.PINK).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
|
||||
val PINK_MINT = create("pink_mint", MintBlock(MintType.PINK, AbstractBlock.Settings.create().mapColor(MapColor.PINK).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val GREEN_MINT = create("green_mint", MintBlock(MintType.GREEN, AbstractBlock.Settings.create().mapColor(MapColor.GREEN).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
|
||||
val GREEN_MINT = create("green_mint", MintBlock(MintType.GREEN, AbstractBlock.Settings.create().mapColor(MapColor.GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val WHITE_MINT = create("white_mint", MintBlock(MintType.WHITE, AbstractBlock.Settings.create().mapColor(MapColor.WHITE).noCollision().ticksRandomly().breakInstantly().sounds(CobblemonSounds.MINT_SOUNDS)))
|
||||
val WHITE_MINT = create("white_mint", MintBlock(MintType.WHITE, AbstractBlock.Settings.create().mapColor(MapColor.WHITE).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
|
||||
@JvmField
|
||||
val PASTURE = create(
|
||||
@@ -538,7 +450,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
|
||||
|
||||
private fun berryBlock(name: String): BerryBlock {
|
||||
val identifier = cobblemonResource("${name}_berry")
|
||||
val block = this.create(identifier.path, BerryBlock(identifier, AbstractBlock.Settings.copy(Blocks.WHEAT).dynamicBounds().sounds(CobblemonSounds.BERRY_BUSH_SOUNDS).strength(0.2F)))
|
||||
val block = this.create(identifier.path, BerryBlock(identifier, AbstractBlock.Settings.copy(Blocks.WHEAT).dynamicBounds().sounds(BlockSoundGroup.CROP).strength(0.2F)))
|
||||
this.berries[identifier] = block
|
||||
return block
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ 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.fallingstar.FallingStarEntity
|
||||
import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
|
||||
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
@@ -75,6 +77,24 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, RegistryKey
|
||||
.build(GENERIC_BEDROCK_ENTITY_KEY.toString())
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val FALLING_STAR_ENTITY_KEY = cobblemonResource("falling_star")
|
||||
@JvmField
|
||||
val FALLING_STAR_ENTITY: EntityType<FallingStarEntity> = this.create(
|
||||
FALLING_STAR_ENTITY_KEY.path,
|
||||
EntityType.Builder.create({ _, world -> FallingStarEntity(world) }, SpawnGroup.MISC)
|
||||
.build(FALLING_STAR_ENTITY_KEY.toString())
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val POKE_BOBBER_KEY = cobblemonResource("poke_bobber")
|
||||
@JvmField
|
||||
val POKE_BOBBER: EntityType<PokeRodFishingBobberEntity> = this.create(
|
||||
POKE_BOBBER_KEY.path,
|
||||
EntityType.Builder.create(::PokeRodFishingBobberEntity, SpawnGroup.MISC).setDimensions(0.5F, 0.5F).maxTrackingRange(10)
|
||||
.build(POKE_BOBBER_KEY.toString())
|
||||
)
|
||||
|
||||
fun registerAttributes(consumer: (EntityType<out LivingEntity>, DefaultAttributeContainer.Builder) -> Unit) {
|
||||
consumer(POKEMON, PokemonEntity.createAttributes())
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.cobblemon.mod.common.item.berry.PortionHealingBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.StatusCuringBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.VolatileCuringBerryItem
|
||||
import com.cobblemon.mod.common.item.interactive.*
|
||||
import com.cobblemon.mod.common.item.interactive.PotionItem
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
@@ -37,6 +38,7 @@ import net.minecraft.block.Block
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.effect.StatusEffectInstance
|
||||
import net.minecraft.entity.effect.StatusEffects
|
||||
import net.minecraft.item.*
|
||||
import net.minecraft.item.BlockItem
|
||||
import net.minecraft.item.FoodComponent
|
||||
import net.minecraft.item.HangingSignItem
|
||||
@@ -229,22 +231,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
|
||||
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 GILDED_CHEST = this.create("gilded_chest", BlockItem(CobblemonBlocks.GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val BLUE_GILDED_CHEST = this.create("blue_gilded_chest", BlockItem(CobblemonBlocks.BLUE_GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val YELLOW_GILDED_CHEST = this.create("yellow_gilded_chest", BlockItem(CobblemonBlocks.YELLOW_GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val PINK_GILDED_CHEST = this.create("pink_gilded_chest", BlockItem(CobblemonBlocks.PINK_GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val BLACK_GILDED_CHEST = this.create("black_gilded_chest", BlockItem(CobblemonBlocks.BLACK_GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val WHITE_GILDED_CHEST = this.create("white_gilded_chest", BlockItem(CobblemonBlocks.WHITE_GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val GREEN_GILDED_CHEST = this.create("green_gilded_chest", BlockItem(CobblemonBlocks.GREEN_GILDED_CHEST, Item.Settings()))
|
||||
@JvmField
|
||||
val GIMMIGHOUL_CHEST = this.create("gimmighoul_chest", BlockItem(CobblemonBlocks.GIMMIGHOUL_CHEST, Item.Settings()))
|
||||
|
||||
@JvmField
|
||||
val RESTORATION_TANK = blockItem("restoration_tank", CobblemonBlocks.RESTORATION_TANK)
|
||||
@@ -396,18 +382,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
|
||||
@JvmField
|
||||
val ZINC = create("zinc", VitaminItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField
|
||||
val GENIUS_FEATHER = create("genius_feather", FeatherItem(Stats.SPECIAL_ATTACK))
|
||||
@JvmField
|
||||
val SWIFT_FEATHER = create("swift_feather", FeatherItem(Stats.SPEED))
|
||||
@JvmField
|
||||
val HEALTH_FEATHER = create("health_feather", FeatherItem(Stats.HP))
|
||||
@JvmField
|
||||
val RESIST_FEATHER = create("resist_feather", FeatherItem(Stats.DEFENCE))
|
||||
@JvmField
|
||||
val MUSCLE_FEATHER = create("muscle_feather", FeatherItem(Stats.ATTACK))
|
||||
@JvmField
|
||||
val CLEVER_FEATHER = create("clever_feather", FeatherItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK = create("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Settings().food(FoodComponent.Builder().snack().hunger(1).saturationModifier(0.2f).build())))
|
||||
@JvmField
|
||||
val ROASTED_LEEK = create("roasted_leek", Item(Item.Settings().food(FoodComponent.Builder().snack().hunger(3).saturationModifier(0.3f).build())))
|
||||
@@ -606,6 +580,9 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
|
||||
@JvmField
|
||||
val NETHER_FIRE_STONE_ORE = blockItem("nether_fire_stone_ore", CobblemonBlocks.NETHER_FIRE_STONE_ORE)
|
||||
|
||||
@JvmField
|
||||
val DYNITE_ORE = blockItem("dynite_ore", CobblemonBlocks.DYNITE_ORE)
|
||||
|
||||
@JvmField
|
||||
val DAWN_STONE = noSettingsItem("dawn_stone")
|
||||
@JvmField
|
||||
@@ -761,19 +738,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
|
||||
@JvmField
|
||||
val ARMOR_FOSSIL = noSettingsItem("armor_fossil")
|
||||
@JvmField
|
||||
val FOSSILIZED_BIRD = noSettingsItem("fossilized_bird")
|
||||
val BIRD_FOSSIL = noSettingsItem("bird_fossil")
|
||||
@JvmField
|
||||
val CLAW_FOSSIL = noSettingsItem("claw_fossil")
|
||||
@JvmField
|
||||
val COVER_FOSSIL = noSettingsItem("cover_fossil")
|
||||
@JvmField
|
||||
val FOSSILIZED_DINO = noSettingsItem("fossilized_dino")
|
||||
val DINO_FOSSIL = noSettingsItem("dino_fossil")
|
||||
@JvmField
|
||||
val DOME_FOSSIL = noSettingsItem("dome_fossil")
|
||||
@JvmField
|
||||
val FOSSILIZED_DRAKE = noSettingsItem("fossilized_drake")
|
||||
val DRAKE_FOSSIL = noSettingsItem("drake_fossil")
|
||||
@JvmField
|
||||
val FOSSILIZED_FISH = noSettingsItem("fossilized_fish")
|
||||
val FISH_FOSSIL = noSettingsItem("fish_fossil")
|
||||
@JvmField
|
||||
val HELIX_FOSSIL = noSettingsItem("helix_fossil")
|
||||
@JvmField
|
||||
@@ -849,53 +826,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
|
||||
SmithingTemplateItem.of(CobblemonArmorTrims.AUTOMATON)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val POKEROD = pokerodItem("pokerod")
|
||||
|
||||
// Misc
|
||||
@JvmField
|
||||
val POKEMON_MODEL = this.create("pokemon_model", PokemonItem())
|
||||
@JvmField
|
||||
val RELIC_COIN = noSettingsItem("relic_coin")
|
||||
@JvmField
|
||||
val RELIC_COIN_POUCH = blockItem("relic_coin_pouch", CobblemonBlocks.RELIC_COIN_POUCH)
|
||||
@JvmField
|
||||
val RELIC_COIN_SACK = blockItem("relic_coin_sack", CobblemonBlocks.RELIC_COIN_SACK)
|
||||
|
||||
// Type Gems
|
||||
@JvmField
|
||||
val NORMAL_GEM = noSettingsItem("normal_gem")
|
||||
@JvmField
|
||||
val FIRE_GEM = noSettingsItem("fire_gem")
|
||||
@JvmField
|
||||
val WATER_GEM = noSettingsItem("water_gem")
|
||||
@JvmField
|
||||
val GRASS_GEM = noSettingsItem("grass_gem")
|
||||
@JvmField
|
||||
val ELECTRIC_GEM = noSettingsItem("electric_gem")
|
||||
@JvmField
|
||||
val ICE_GEM = noSettingsItem("ice_gem")
|
||||
@JvmField
|
||||
val FIGHTING_GEM = noSettingsItem("fighting_gem")
|
||||
@JvmField
|
||||
val POISON_GEM = noSettingsItem("poison_gem")
|
||||
@JvmField
|
||||
val GROUND_GEM = noSettingsItem("ground_gem")
|
||||
@JvmField
|
||||
val FLYING_GEM = noSettingsItem("flying_gem")
|
||||
@JvmField
|
||||
val PSYCHIC_GEM = noSettingsItem("psychic_gem")
|
||||
@JvmField
|
||||
val BUG_GEM = noSettingsItem("bug_gem")
|
||||
@JvmField
|
||||
val ROCK_GEM = noSettingsItem("rock_gem")
|
||||
@JvmField
|
||||
val GHOST_GEM = noSettingsItem("ghost_gem")
|
||||
@JvmField
|
||||
val DRAGON_GEM = noSettingsItem("dragon_gem")
|
||||
@JvmField
|
||||
val DARK_GEM = noSettingsItem("dark_gem")
|
||||
@JvmField
|
||||
val STEEL_GEM = noSettingsItem("steel_gem")
|
||||
@JvmField
|
||||
val FAIRY_GEM = noSettingsItem("fairy_gem")
|
||||
|
||||
private fun blockItem(name: String, block: Block): BlockItem = this.create(name, BlockItem(block, Item.Settings()))
|
||||
|
||||
@@ -914,6 +850,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
|
||||
|
||||
private fun candyItem(name: String, calculator: CandyItem.Calculator): CandyItem = this.create(name, CandyItem(calculator))
|
||||
|
||||
private fun pokerodItem(name: String): PokerodItem {
|
||||
var settings = Item.Settings()
|
||||
val item = create(name, PokerodItem(settings))
|
||||
return item
|
||||
}
|
||||
|
||||
private fun heldItem(name: String, remappedName: String? = null): CobblemonItem = create(
|
||||
name,
|
||||
CobblemonItem(Item.Settings()).also {
|
||||
|
||||
@@ -82,12 +82,9 @@ import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPa
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyMoveCallbackPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.AbilityRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.BerryRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.GlobalSpeciesFeatureSyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.MovesRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PropertiesCompletionRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesFeatureAssignmentSyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.StandardSpeciesFeatureSyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.UnlockReloadPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
|
||||
@@ -135,7 +132,6 @@ import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.*
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.FleeBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
|
||||
@@ -171,7 +167,6 @@ import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.FleeBattlePacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
|
||||
@@ -253,7 +248,6 @@ object CobblemonNetwork : NetworkManager {
|
||||
this.createClientBound(PokemonStateUpdatePacket.ID, PokemonStateUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(TetheringUpdatePacket.ID, TetheringUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(TradeableUpdatePacket.ID, TradeableUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(SpeciesFeatureUpdatePacket.ID, SpeciesFeatureUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(OriginalTrainerUpdatePacket.ID, OriginalTrainerUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
|
||||
// Evolution start
|
||||
@@ -320,9 +314,6 @@ object CobblemonNetwork : NetworkManager {
|
||||
this.createClientBound(PropertiesCompletionRegistrySyncPacket.ID, PropertiesCompletionRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(UnlockReloadPacket.ID, UnlockReloadPacket::decode, UnlockReloadPacketHandler)
|
||||
this.createClientBound(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(StandardSpeciesFeatureSyncPacket.ID, StandardSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(GlobalSpeciesFeatureSyncPacket.ID, GlobalSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(SpeciesFeatureAssignmentSyncPacket.ID, SpeciesFeatureAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(NaturalMaterialRegistrySyncPacket.ID, NaturalMaterialRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(FossilRegistrySyncPacket.ID, FossilRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
|
||||
@@ -409,7 +400,6 @@ object CobblemonNetwork : NetworkManager {
|
||||
this.createServerBound(BattleSelectActionsPacket.ID, BattleSelectActionsPacket::decode, BattleSelectActionsHandler)
|
||||
this.createServerBound(SpectateBattlePacket.ID, SpectateBattlePacket::decode, SpectateBattleHandler)
|
||||
this.createServerBound(RemoveSpectatorPacket.ID, RemoveSpectatorPacket::decode, RemoveSpectatorHandler)
|
||||
this.createServerBound(FleeBattlePacket.ID, FleeBattlePacket::decode, FleeBattlePacketHandler)
|
||||
|
||||
// Trade
|
||||
this.createServerBound(AcceptTradeRequestPacket.ID, AcceptTradeRequestPacket::decode, AcceptTradeRequestHandler)
|
||||
|
||||
@@ -16,7 +16,6 @@ import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.sound.BlockSoundGroup
|
||||
import net.minecraft.sound.SoundEvent
|
||||
import net.minecraft.sound.SoundEvents
|
||||
|
||||
object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Registry<SoundEvent>>, SoundEvent>() {
|
||||
|
||||
@@ -85,8 +84,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
|
||||
val MEDICINE_PILLS_USE = this.create("medicine_pills.use")
|
||||
@JvmField
|
||||
val MEDICINE_SPRAY_USE = this.create("medicine_spray.use")
|
||||
@JvmField
|
||||
val MEDICINE_FEATHER_USE = this.create("medicine_feather.use")
|
||||
|
||||
@JvmField
|
||||
val BERRY_HARVEST = this.create("berry.harvest")
|
||||
@@ -121,14 +118,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
|
||||
@JvmField
|
||||
val FOSSIL_MACHINE_UNPROTECTED = this.create("fossilmachine.unprotected")
|
||||
|
||||
@JvmField
|
||||
val COIN_POUCH_BREAK = this.create("coin_pouch.break")
|
||||
@JvmField
|
||||
val COIN_POUCH_HIT = this.create("coin_pouch.hit")
|
||||
@JvmField
|
||||
val COIN_POUCH_STEP = this.create("coin_pouch.step")
|
||||
@JvmField
|
||||
val COIN_POUCH_PLACE = this.create("coin_pouch.place")
|
||||
@JvmField
|
||||
val TUMBLESTONE_BREAK = this.create("tumblestone.break")
|
||||
@JvmField
|
||||
@@ -140,52 +129,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
|
||||
@JvmField
|
||||
val TUMBLESTONE_STEP = this.create("tumblestone.step")
|
||||
|
||||
@JvmField
|
||||
val GIMMIGHOUL_GIVE_ITEM_SMALL = this.create("gimmighoul.give_item_small")
|
||||
@JvmField
|
||||
val GIMMIGHOUL_REVEAL = this.create("gimmighoul.reveal")
|
||||
|
||||
@JvmField
|
||||
val BERRY_BUSH_BREAK = this.create("berry_bush.break")
|
||||
@JvmField
|
||||
val BERRY_BUSH_PLACE = this.create("berry_bush.place")
|
||||
|
||||
@JvmField
|
||||
val BIG_ROOT_BREAK = this.create("big_root.break")
|
||||
@JvmField
|
||||
val ENERGY_ROOT_PLACE = this.create("energy_root.place")
|
||||
|
||||
@JvmField
|
||||
val MINT_BREAK = this.create("mint.break")
|
||||
@JvmField
|
||||
val MINT_PLACE = this.create("mint.place")
|
||||
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK_BREAK = this.create("medicinal_leek.break")
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK_PLACE = this.create("medicinal_leek.plant")
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST_OPEN = this.create("gilded_chest.open")
|
||||
@JvmField
|
||||
val GILDED_CHEST_CLOSE = this.create("gilded_chest.close")
|
||||
@JvmField
|
||||
val GILDED_CHEST_STEP = this.create("gilded_chest.step")
|
||||
@JvmField
|
||||
val GILDED_CHEST_HIT = this.create("gilded_chest.hit")
|
||||
@JvmField
|
||||
val GILDED_CHEST_BREAK = this.create("gilded_chest.break")
|
||||
@JvmField
|
||||
val GILDED_CHEST_PLACE = this.create("gilded_chest.place")
|
||||
|
||||
@JvmField
|
||||
val COIN_POUCH_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
COIN_POUCH_BREAK,
|
||||
COIN_POUCH_STEP,
|
||||
COIN_POUCH_PLACE,
|
||||
COIN_POUCH_HIT,
|
||||
COIN_POUCH_STEP
|
||||
)
|
||||
@JvmField
|
||||
val IMPACT_NORMAL = this.create("impact.normal")
|
||||
@JvmField
|
||||
@@ -241,59 +184,5 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Regi
|
||||
TUMBLESTONE_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val BERRY_BUSH_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
BERRY_BUSH_BREAK,
|
||||
SoundEvents.BLOCK_GRASS_STEP,
|
||||
BERRY_BUSH_PLACE,
|
||||
SoundEvents.BLOCK_GRASS_HIT,
|
||||
SoundEvents.BLOCK_GRASS_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val BIG_ROOT_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
BIG_ROOT_BREAK,
|
||||
SoundEvents.BLOCK_ROOTS_STEP,
|
||||
SoundEvents.BLOCK_ROOTS_PLACE,
|
||||
SoundEvents.BLOCK_ROOTS_HIT,
|
||||
SoundEvents.BLOCK_ROOTS_FALL
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val ENERGY_ROOT_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
SoundEvents.BLOCK_ROOTS_BREAK,
|
||||
SoundEvents.BLOCK_ROOTS_STEP,
|
||||
ENERGY_ROOT_PLACE,
|
||||
SoundEvents.BLOCK_ROOTS_HIT,
|
||||
SoundEvents.BLOCK_ROOTS_FALL
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
MEDICINAL_LEEK_BREAK,
|
||||
SoundEvents.BLOCK_GRASS_STEP,
|
||||
MEDICINAL_LEEK_PLACE,
|
||||
SoundEvents.BLOCK_GRASS_HIT,
|
||||
SoundEvents.BLOCK_GRASS_FALL
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val MINT_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
MINT_BREAK,
|
||||
SoundEvents.BLOCK_GRASS_STEP,
|
||||
MINT_PLACE,
|
||||
SoundEvents.BLOCK_GRASS_HIT,
|
||||
SoundEvents.BLOCK_GRASS_FALL
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST_SOUNDS = BlockSoundGroup(1f, 1f,
|
||||
GILDED_CHEST_BREAK,
|
||||
GILDED_CHEST_STEP,
|
||||
GILDED_CHEST_PLACE,
|
||||
GILDED_CHEST_HIT,
|
||||
GILDED_CHEST_STEP
|
||||
)
|
||||
|
||||
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.of(cobblemonResource(name)))
|
||||
}
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.drop
|
||||
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.LOOT_DROPPED
|
||||
import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
@@ -89,8 +88,6 @@ class DropTable {
|
||||
amount: IntRange = this.amount
|
||||
) {
|
||||
val drops = getDrops(amount).toMutableList()
|
||||
val heldItem = (entity as PokemonEntity).pokemon.heldItemNoCopy()
|
||||
if (!heldItem.isEmpty) entity.dropItem(heldItem.item)
|
||||
LOOT_DROPPED.postThen(
|
||||
event = LootDroppedEvent(this, player, entity, drops),
|
||||
ifSucceeded = { it.drops.forEach { it.drop(entity, world, pos, player) } }
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEv
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionDisplayEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.HeldItemUpdatedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
|
||||
import com.cobblemon.mod.common.api.events.starter.StarterChosenEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
|
||||
@@ -67,8 +66,6 @@ object CobblemonEvents {
|
||||
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
|
||||
@JvmField
|
||||
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
|
||||
@JvmField
|
||||
val HELD_ITEM_UPDATED = CancelableObservable<HeldItemUpdatedEvent>()
|
||||
|
||||
@JvmField
|
||||
val THROWN_POKEBALL_HIT = CancelableObservable<ThrownPokeballHitEvent>()
|
||||
|
||||
-36
@@ -1,36 +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.api.events.pokemon.interaction
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
/**
|
||||
* Event published when a held item is being updated on a [Pokemon].
|
||||
* Cancelling the event will prevent any action from being taken on
|
||||
* the Pokémon.
|
||||
*
|
||||
* [newItem] differs from [originalStack] in that the former is a
|
||||
* one-sized version of the original (Pokémon cannot hold stacks) and
|
||||
* changing it in any way will not affect the original item held by
|
||||
* the player.
|
||||
*
|
||||
* @author Whatsy, Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
data class HeldItemUpdatedEvent(
|
||||
val cause: LivingEntity?,
|
||||
val pokemon: Pokemon,
|
||||
val originalStack: ItemStack,
|
||||
val decrement: Boolean,
|
||||
val oldItem: ItemStack,
|
||||
val newItem: ItemStack
|
||||
) : Cancelable()
|
||||
@@ -19,7 +19,6 @@ 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
|
||||
|
||||
/**
|
||||
@@ -78,11 +77,6 @@ abstract class MultiblockBlock(properties: Settings) : BlockWithEntity(propertie
|
||||
return BlockRenderType.MODEL
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
-6
@@ -34,10 +34,4 @@ interface PassiveEvolution : Evolution {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* If the evolution will disappear once the conditions are no longer met.
|
||||
*/
|
||||
val permanent: Boolean
|
||||
|
||||
|
||||
}
|
||||
+6
-39
@@ -11,12 +11,10 @@ package com.cobblemon.mod.common.api.pokemon.feature
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
|
||||
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.substitute
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* A [SpeciesFeatureProvider] which is a string value selected from a fixed list of choices. Parameters exist
|
||||
@@ -26,46 +24,15 @@ import net.minecraft.network.PacketByteBuf
|
||||
* @since November 30th, 2022
|
||||
*/
|
||||
open class ChoiceSpeciesFeatureProvider(
|
||||
override var keys: List<String>,
|
||||
override val keys: List<String>,
|
||||
var default: String? = null,
|
||||
var choices: List<String> = listOf(),
|
||||
var isAspect: Boolean = true,
|
||||
var aspectFormat: String = "{{choice}}"
|
||||
) : SynchronizedSpeciesFeatureProvider<StringSpeciesFeature>, CustomPokemonPropertyType<StringSpeciesFeature>, AspectProvider {
|
||||
override var needsKey = true
|
||||
override var visible = false
|
||||
) : SpeciesFeatureProvider<StringSpeciesFeature>, CustomPokemonPropertyType<StringSpeciesFeature>, AspectProvider {
|
||||
override val needsKey = true
|
||||
fun getAspect(feature: StringSpeciesFeature) = aspectFormat.substitute("choice", feature.value)
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeCollection(keys) { _, value -> buffer.writeString(value) }
|
||||
buffer.writeNullable(default) { _, value -> buffer.writeString(value) }
|
||||
buffer.writeCollection(choices) { _, value -> buffer.writeString(value) }
|
||||
buffer.writeBoolean(isAspect)
|
||||
buffer.writeString(aspectFormat)
|
||||
buffer.writeBoolean(needsKey)
|
||||
}
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
keys = buffer.readList { buffer.readString() }
|
||||
default = buffer.readNullable { buffer.readString() }
|
||||
choices = buffer.readList { buffer.readString() }
|
||||
isAspect = buffer.readBoolean()
|
||||
aspectFormat = buffer.readString()
|
||||
needsKey = buffer.readBoolean()
|
||||
}
|
||||
|
||||
override fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<StringSpeciesFeature>? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun invoke(buffer: PacketByteBuf, name: String): StringSpeciesFeature? {
|
||||
return if (name in keys) {
|
||||
StringSpeciesFeature(name, "").also { it.decode(buffer) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllAspects(): MutableList<String> {
|
||||
val aspects = choices.toMutableList()
|
||||
choices.forEach {
|
||||
@@ -78,10 +45,10 @@ open class ChoiceSpeciesFeatureProvider(
|
||||
|
||||
internal constructor(): this(emptyList())
|
||||
|
||||
override fun get(pokemon: Pokemon) = pokemon.getFeature<StringSpeciesFeature>(keys.first())
|
||||
fun get(pokemon: Pokemon) = pokemon.getFeature<StringSpeciesFeature>(keys.first())
|
||||
|
||||
override fun invoke(pokemon: Pokemon): StringSpeciesFeature? {
|
||||
val existing = get(pokemon)
|
||||
val existing = pokemon.getFeature<StringSpeciesFeature>(keys.first())
|
||||
return if (existing != null && existing.value in choices) {
|
||||
existing
|
||||
} else {
|
||||
@@ -121,7 +88,7 @@ open class ChoiceSpeciesFeatureProvider(
|
||||
|
||||
override fun provide(pokemon: Pokemon): Set<String> {
|
||||
return if (isAspect) {
|
||||
get(pokemon)?.let { setOf(getAspect(it)) } ?: emptySet()
|
||||
pokemon.getFeature<StringSpeciesFeature>(keys.first())?.let { setOf(getAspect(it)) } ?: emptySet()
|
||||
} else {
|
||||
emptySet()
|
||||
}
|
||||
|
||||
+5
-43
@@ -12,12 +12,10 @@ import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
|
||||
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.google.gson.JsonObject
|
||||
import kotlin.random.Random
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* A simple [SpeciesFeature] that is a true/false flag value. It implements [CustomPokemonProperty] for use in
|
||||
@@ -28,7 +26,7 @@ import net.minecraft.network.PacketByteBuf
|
||||
* @author Hiroku
|
||||
* @since May 13th, 2022
|
||||
*/
|
||||
open class FlagSpeciesFeature(override val name: String) : SynchronizedSpeciesFeature, CustomPokemonProperty {
|
||||
open class FlagSpeciesFeature(override val name: String) : SpeciesFeature, CustomPokemonProperty {
|
||||
constructor(name: String, enabled: Boolean): this(name) {
|
||||
this.enabled = enabled
|
||||
}
|
||||
@@ -55,14 +53,6 @@ open class FlagSpeciesFeature(override val name: String) : SynchronizedSpeciesFe
|
||||
return this
|
||||
}
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeBoolean(enabled)
|
||||
}
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
enabled = buffer.readBoolean()
|
||||
}
|
||||
|
||||
override fun asString() = "$name=$enabled"
|
||||
|
||||
override fun apply(pokemon: Pokemon) {
|
||||
@@ -81,37 +71,11 @@ open class FlagSpeciesFeature(override val name: String) : SynchronizedSpeciesFe
|
||||
override fun matches(pokemon: Pokemon) = pokemon.getFeature<FlagSpeciesFeature>(name)?.enabled == enabled
|
||||
}
|
||||
|
||||
class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpeciesFeature>, CustomPokemonPropertyType<FlagSpeciesFeature>, AspectProvider {
|
||||
override var keys: List<String> = emptyList()
|
||||
// Uses get() = true because that way there's no backing field. It MUST be true, this way no JSON trickery will overwrite it
|
||||
class FlagSpeciesFeatureProvider : SpeciesFeatureProvider<FlagSpeciesFeature>, CustomPokemonPropertyType<FlagSpeciesFeature>, AspectProvider {
|
||||
override val keys: List<String>
|
||||
override val needsKey get() = true
|
||||
var default: String? = null
|
||||
var isAspect = true
|
||||
override var visible: Boolean = false
|
||||
|
||||
override fun invoke(buffer: PacketByteBuf, name: String): FlagSpeciesFeature? {
|
||||
return if (name in keys) {
|
||||
FlagSpeciesFeature(name).also { it.decode(buffer) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeCollection(keys) { _, value -> buffer.writeString(value) }
|
||||
buffer.writeNullable(default) { _, value -> buffer.writeString(value) }
|
||||
buffer.writeBoolean(isAspect)
|
||||
}
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
keys = buffer.readList { it.readString() }
|
||||
default = buffer.readNullable { it.readString() }
|
||||
isAspect = buffer.readBoolean()
|
||||
}
|
||||
|
||||
override fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<FlagSpeciesFeature>? {
|
||||
return null
|
||||
}
|
||||
val isAspect = true
|
||||
|
||||
override fun examples() = setOf("true", "false")
|
||||
|
||||
@@ -130,10 +94,8 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
|
||||
|
||||
constructor(vararg keys: String) : this(keys.toList())
|
||||
|
||||
override fun get(pokemon: Pokemon) = pokemon.getFeature<FlagSpeciesFeature>(keys.first())
|
||||
|
||||
override fun invoke(pokemon: Pokemon): FlagSpeciesFeature? {
|
||||
return get(pokemon)
|
||||
return pokemon.getFeature(keys.first())
|
||||
?: when (default) {
|
||||
"random" -> FlagSpeciesFeature(keys.first(), Random.Default.nextBoolean())
|
||||
in setOf("true", "false") -> FlagSpeciesFeature(keys.first(), default.toBoolean())
|
||||
|
||||
+1
-14
@@ -8,17 +8,13 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.pokemon.feature
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.GlobalSpeciesFeatureSyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.SpeciesFeatureProviderAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.Vec3dAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
@@ -28,7 +24,6 @@ import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.resource.ResourceType
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
/**
|
||||
* A registry very similar to [SpeciesFeatures] but the [SpeciesFeatureProvider] contained within it
|
||||
@@ -47,15 +42,11 @@ object GlobalSpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(SpeciesFeatureProvider::class.java, SpeciesFeatureProviderAdapter)
|
||||
.registerTypeAdapter(Vec3d::class.java, Vec3dAdapter)
|
||||
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
|
||||
.create()
|
||||
override val typeToken: TypeToken<SpeciesFeatureProvider<*>> = TypeToken.get(SpeciesFeatureProvider::class.java)
|
||||
override val resourcePath: String = "global_species_features"
|
||||
|
||||
override fun sync(player: ServerPlayerEntity) {
|
||||
player.sendPacket(GlobalSpeciesFeatureSyncPacket(codeFeatures + resourceFeatures))
|
||||
}
|
||||
override fun sync(player: ServerPlayerEntity) {}
|
||||
|
||||
override fun reload(data: Map<Identifier, SpeciesFeatureProvider<*>>) {
|
||||
resourceFeatures.keys.toList().forEach(this::unregister)
|
||||
@@ -68,10 +59,6 @@ object GlobalSpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
|
||||
|
||||
fun getFeatures() = (resourceFeatures.keys + codeFeatures.keys).mapNotNull(this::getFeature)
|
||||
|
||||
fun loadOnClient(entries: Collection<Map.Entry<String, SpeciesFeatureProvider<*>>>) {
|
||||
codeFeatures.putAll(entries.map { it.toPair() })
|
||||
}
|
||||
|
||||
private fun register(name: String, provider: SpeciesFeatureProvider<*>, isCoded: Boolean) {
|
||||
val mapping = if (isCoded) codeFeatures else resourceFeatures
|
||||
if (provider is AspectProvider) {
|
||||
|
||||
-181
@@ -1,181 +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.api.pokemon.feature
|
||||
|
||||
import com.cobblemon.mod.common.api.net.Decodable
|
||||
import com.cobblemon.mod.common.api.net.Encodable
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
|
||||
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.BarSummarySpeciesFeatureRenderer
|
||||
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
/**
|
||||
* A species feature value that's just an integer. Complex stuff.
|
||||
* @author Hiroku
|
||||
*/
|
||||
class IntSpeciesFeature(override var name: String) : SynchronizedSpeciesFeature, CustomPokemonProperty {
|
||||
var value = 0
|
||||
|
||||
constructor(): this("")
|
||||
constructor(name: String, value: Int): this(name) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
override fun saveToNBT(pokemonNBT: NbtCompound): NbtCompound {
|
||||
pokemonNBT.putInt(name, value)
|
||||
return pokemonNBT
|
||||
}
|
||||
|
||||
override fun loadFromNBT(pokemonNBT: NbtCompound): SynchronizedSpeciesFeature {
|
||||
value = pokemonNBT.getInt(name)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun saveToJSON(pokemonJSON: JsonObject): JsonObject {
|
||||
pokemonJSON.addProperty(name, value)
|
||||
return pokemonJSON
|
||||
}
|
||||
|
||||
override fun loadFromJSON(pokemonJSON: JsonObject): SpeciesFeature {
|
||||
value = pokemonJSON.get(name).asInt
|
||||
return this
|
||||
}
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeInt(value)
|
||||
}
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
value = buffer.readInt()
|
||||
}
|
||||
|
||||
override fun asString() = "$name=$value"
|
||||
override fun apply(pokemon: Pokemon) {
|
||||
val featureProvider = SpeciesFeatures.getFeature(name) ?: return
|
||||
if (featureProvider in SpeciesFeatures.getFeaturesFor(pokemon.species)) {
|
||||
val existingFeature = pokemon.getFeature<IntSpeciesFeature>(name)
|
||||
if (existingFeature != null) {
|
||||
existingFeature.value = value
|
||||
} else {
|
||||
pokemon.features.add(IntSpeciesFeature(name, value))
|
||||
}
|
||||
pokemon.updateAspects()
|
||||
}
|
||||
}
|
||||
|
||||
override fun matches(pokemon: Pokemon) = pokemon.getFeature<IntSpeciesFeature>(name)?.value == value
|
||||
}
|
||||
|
||||
class IntSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<IntSpeciesFeature>, CustomPokemonPropertyType<IntSpeciesFeature> {
|
||||
class DisplayData : Encodable, Decodable {
|
||||
var name: String = ""
|
||||
@SerializedName(value = "colour" /* fuck you we use real english */, alternate = ["color"])
|
||||
var colour = Vec3d(255.0, 255.0, 255.0)
|
||||
var underlay: Identifier? = null
|
||||
var overlay: Identifier? = null
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
name = buffer.readString()
|
||||
colour = Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble())
|
||||
underlay = buffer.readNullable { buffer.readIdentifier() }
|
||||
overlay = buffer.readNullable { buffer.readIdentifier() }
|
||||
}
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeString(name)
|
||||
buffer.writeDouble(colour.x)
|
||||
buffer.writeDouble(colour.y)
|
||||
buffer.writeDouble(colour.z)
|
||||
buffer.writeNullable(underlay) { _, value -> buffer.writeIdentifier(value) }
|
||||
buffer.writeNullable(overlay) { _, value -> buffer.writeIdentifier(value) }
|
||||
}
|
||||
}
|
||||
|
||||
override var keys = listOf<String>()
|
||||
// Uses get() = true because that way there's no backing field. It MUST be true, this way no JSON trickery will overwrite it
|
||||
override val needsKey get() = true
|
||||
override var visible = false
|
||||
var default: Int? = null
|
||||
var min = 0
|
||||
var max = 100
|
||||
var display: DisplayData? = null
|
||||
|
||||
override fun fromString(value: String?) = value?.toIntOrNull()?.takeIf { it in min..max }?.let { IntSpeciesFeature(keys.first(), it) }
|
||||
|
||||
override fun examples() = emptyList<String>()
|
||||
override fun invoke(buffer: PacketByteBuf, name: String): IntSpeciesFeature? {
|
||||
return if (name in keys) {
|
||||
IntSpeciesFeature(name, buffer.readInt())
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun invoke(pokemon: Pokemon): IntSpeciesFeature? {
|
||||
return get(pokemon) ?: default?.let { IntSpeciesFeature(keys.first(), it) }
|
||||
}
|
||||
|
||||
override fun invoke(nbt: NbtCompound): IntSpeciesFeature? {
|
||||
return if (nbt.contains(keys.first())) {
|
||||
IntSpeciesFeature(keys.first(), nbt.getInt(keys.first()))
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun invoke(json: JsonObject): IntSpeciesFeature? {
|
||||
return if (json.has(keys.first())) {
|
||||
IntSpeciesFeature(keys.first(), json.get(keys.first()).asInt)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun get(pokemon: Pokemon) = pokemon.features.filterIsInstance<IntSpeciesFeature>().find { it.name in keys }
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeCollection(keys) { _, value -> buffer.writeString(value) }
|
||||
buffer.writeNullable(default) { _, value -> buffer.writeInt(value) }
|
||||
buffer.writeInt(min)
|
||||
buffer.writeInt(max)
|
||||
buffer.writeNullable(display) { _, value -> value.encode(buffer) }
|
||||
}
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
keys = buffer.readList { buffer.readString() }
|
||||
default = buffer.readNullable { buffer.readInt() }
|
||||
min = buffer.readInt()
|
||||
max = buffer.readInt()
|
||||
display = buffer.readNullable { DisplayData().also { it.decode(buffer) } }
|
||||
}
|
||||
|
||||
override fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<IntSpeciesFeature>? {
|
||||
return display?.let {
|
||||
BarSummarySpeciesFeatureRenderer(
|
||||
name = keys.first(),
|
||||
displayName = it.name.asTranslated(),
|
||||
min = min,
|
||||
max = max,
|
||||
colour = it.colour,
|
||||
underlay = it.underlay ?: cobblemonResource("textures/gui/summary/summary_stats_other_bar.png"),
|
||||
overlay = it.overlay ?: cobblemonResource("textures/gui/summary/summary_stats_generic_overlay.png"),
|
||||
pokemon = pokemon
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-14
@@ -8,13 +8,10 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.pokemon.feature
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesFeatureAssignmentSyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
@@ -41,24 +38,17 @@ object SpeciesFeatureAssignments : JsonDataRegistry<SpeciesFeatureAssignment> {
|
||||
override val typeToken = TypeToken.get(SpeciesFeatureAssignment::class.java)
|
||||
override val resourcePath = "species_feature_assignments"
|
||||
|
||||
private val assignments = mutableMapOf<Identifier, MutableSet<String>>()
|
||||
private val assignments = mutableMapOf<String, MutableSet<String>>()
|
||||
|
||||
override fun sync(player: ServerPlayerEntity) {
|
||||
player.sendPacket(SpeciesFeatureAssignmentSyncPacket(assignments))
|
||||
}
|
||||
override fun sync(player: ServerPlayerEntity) {}
|
||||
override fun reload(data: Map<Identifier, SpeciesFeatureAssignment>) {
|
||||
data.values.forEach {
|
||||
it.pokemon.forEach { pokemon ->
|
||||
assignments.getOrPut(pokemon.asIdentifierDefaultingNamespace()) { mutableSetOf() }.addAll(it.features)
|
||||
assignments.getOrPut(pokemon) { mutableSetOf() }.addAll(it.features)
|
||||
}
|
||||
}
|
||||
this.observable.emit(this)
|
||||
}
|
||||
|
||||
fun loadOnClient(data: Map<Identifier, MutableSet<String>>) {
|
||||
this.assignments.clear()
|
||||
this.assignments.putAll(data)
|
||||
}
|
||||
|
||||
fun getFeatures(species: Species) = assignments[species.resourceIdentifier] ?: emptySet()
|
||||
fun getFeatures(species: Species) = assignments[species.showdownId()] ?: emptySet()
|
||||
}
|
||||
-1
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.pokemon.feature
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* A provider of [SpeciesFeature]s. These must be registered via [SpeciesFeatures] either programmatically or
|
||||
|
||||
+1
-13
@@ -8,17 +8,13 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.pokemon.feature
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.pokemon.aspect.AspectProvider
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.StandardSpeciesFeatureSyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.SpeciesFeatureProviderAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.Vec3dAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
@@ -26,7 +22,6 @@ 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.util.math.Vec3d
|
||||
|
||||
/**
|
||||
* A registry for [SpeciesFeatureProvider]s. This is the backbone of species-specific data such as
|
||||
@@ -53,15 +48,11 @@ object SpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(SpeciesFeatureProvider::class.java, SpeciesFeatureProviderAdapter)
|
||||
.registerTypeAdapter(Vec3d::class.java, Vec3dAdapter)
|
||||
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
|
||||
.create()
|
||||
override val typeToken: TypeToken<SpeciesFeatureProvider<*>> = TypeToken.get(SpeciesFeatureProvider::class.java)
|
||||
override val resourcePath: String = "species_features"
|
||||
|
||||
override fun sync(player: ServerPlayerEntity) {
|
||||
player.sendPacket(StandardSpeciesFeatureSyncPacket(codeFeatures + resourceFeatures))
|
||||
}
|
||||
override fun sync(player: ServerPlayerEntity) {}
|
||||
|
||||
override fun reload(data: Map<Identifier, SpeciesFeatureProvider<*>>) {
|
||||
resourceFeatures.keys.toList().forEach(this::unregister)
|
||||
@@ -71,9 +62,6 @@ object SpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
|
||||
fun getCodeFeature(name: String) = resourceFeatures[name]
|
||||
fun getResourceFeature(name: String) = codeFeatures[name]
|
||||
fun getFeature(name: String) = getCodeFeature(name) ?: getResourceFeature(name)
|
||||
fun loadOnClient(entries: Collection<Map.Entry<String, SpeciesFeatureProvider<*>>>) {
|
||||
codeFeatures.putAll(entries.map { it.toPair() })
|
||||
}
|
||||
|
||||
fun getFeatures() = (resourceFeatures.keys + codeFeatures.keys).mapNotNull(this::getFeature)
|
||||
fun getFeaturesFor(species: Species): List<SpeciesFeatureProvider<*>> {
|
||||
|
||||
+1
-10
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* A species feature value that is a string value.
|
||||
@@ -23,7 +22,7 @@ import net.minecraft.network.PacketByteBuf
|
||||
class StringSpeciesFeature(
|
||||
override val name: String,
|
||||
var value: String
|
||||
) : SynchronizedSpeciesFeature, CustomPokemonProperty {
|
||||
) : SpeciesFeature, CustomPokemonProperty {
|
||||
override fun saveToNBT(pokemonNBT: NbtCompound): NbtCompound {
|
||||
pokemonNBT.putString(name, value)
|
||||
return pokemonNBT
|
||||
@@ -44,14 +43,6 @@ class StringSpeciesFeature(
|
||||
return this
|
||||
}
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeString(value)
|
||||
}
|
||||
|
||||
override fun decode(buffer: PacketByteBuf) {
|
||||
value = buffer.readString()
|
||||
}
|
||||
|
||||
override fun asString() = "$name=$value"
|
||||
|
||||
override fun apply(pokemon: Pokemon) {
|
||||
|
||||
-20
@@ -1,20 +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.api.pokemon.feature
|
||||
|
||||
import com.cobblemon.mod.common.api.net.Decodable
|
||||
import com.cobblemon.mod.common.api.net.Encodable
|
||||
|
||||
/**
|
||||
* A species feature that can be synchronized to the client. These must be managed by a [SynchronizedSpeciesFeatureProvider].
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
interface SynchronizedSpeciesFeature : SpeciesFeature, Encodable, Decodable
|
||||
-33
@@ -1,33 +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.api.pokemon.feature
|
||||
|
||||
import com.cobblemon.mod.common.api.net.Decodable
|
||||
import com.cobblemon.mod.common.api.net.Encodable
|
||||
import com.cobblemon.mod.common.client.gui.summary.featurerenderers.SummarySpeciesFeatureRenderer
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* A species feature provider that will be synchronized to the client. For it to be renderable in the summary
|
||||
* screen of a Pokémon it must also provide a [SummarySpeciesFeatureRenderer] in [getRenderer]. Note that you
|
||||
* really don't want to initialize a renderer outside of that function call because if the server ever initializes
|
||||
* it then you're going to get crashes on dedicated servers (this is a bad thing).
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
interface SynchronizedSpeciesFeatureProvider<T : SynchronizedSpeciesFeature> : SpeciesFeatureProvider<T>, Encodable, Decodable {
|
||||
var visible: Boolean
|
||||
operator fun invoke(buffer: PacketByteBuf, name: String): T?
|
||||
/** Gets the feature from this Pokémon, if it has been created yet. */
|
||||
fun get(pokemon: Pokemon): T?
|
||||
/** Only run this from the client. */
|
||||
fun getRenderer(pokemon: Pokemon): SummarySpeciesFeatureRenderer<T>?
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import net.minecraft.util.math.Vec3d
|
||||
* @since January 4th, 2023
|
||||
*/
|
||||
class BedrockParticle(
|
||||
var texture: Identifier = Identifier("minecraft:textures/particles/bubble.png"),
|
||||
var texture: Identifier = Identifier("minecraft:textures/particle/bubble.png"),
|
||||
var material: ParticleMaterial = ParticleMaterial.ALPHA,
|
||||
var uvMode: ParticleUVMode = StaticParticleUVMode(),
|
||||
var sizeX: Expression = NumberExpression(0.15),
|
||||
|
||||
@@ -10,19 +10,8 @@ package com.cobblemon.mod.common.api.spawning
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.entity.Despawner
|
||||
import com.cobblemon.mod.common.api.spawning.condition.AreaSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.BasicSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.GroundedSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SubmergedSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SurfaceSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.context.AreaContextResolver
|
||||
import com.cobblemon.mod.common.api.spawning.context.GroundedSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.LavafloorSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.SeafloorSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.SubmergedSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.SurfaceSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.condition.*
|
||||
import com.cobblemon.mod.common.api.spawning.context.*
|
||||
import com.cobblemon.mod.common.api.spawning.context.calculators.GroundedSpawningContextCalculator
|
||||
import com.cobblemon.mod.common.api.spawning.context.calculators.LavafloorSpawningContextCalculator
|
||||
import com.cobblemon.mod.common.api.spawning.context.calculators.SeafloorSpawningContextCalculator
|
||||
@@ -32,6 +21,8 @@ import com.cobblemon.mod.common.api.spawning.context.calculators.SurfaceSpawning
|
||||
import com.cobblemon.mod.common.api.spawning.detail.PokemonSpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnAction
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.fallingstar.FallingStarSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.preset.BasicSpawnDetailPreset
|
||||
import com.cobblemon.mod.common.api.spawning.preset.BestSpawnerConfig
|
||||
@@ -83,6 +74,8 @@ object BestSpawner {
|
||||
var config = BestSpawnerConfig()
|
||||
val spawnerManagers = mutableListOf<SpawnerManager>(CobblemonWorldSpawnerManager)
|
||||
var defaultPokemonDespawner: Despawner<PokemonEntity> = CobblemonAgingDespawner(getAgeTicks = { it.ticksLived })
|
||||
lateinit var fishingSpawner: FishingSpawner
|
||||
lateinit var starSpawner: FallingStarSpawner
|
||||
|
||||
fun loadConfig() {
|
||||
LOGGER.info("Starting the Best Spawner...")
|
||||
@@ -91,6 +84,8 @@ object BestSpawner {
|
||||
SpawningCondition.register(SubmergedSpawningCondition.NAME, SubmergedSpawningCondition::class.java)
|
||||
SpawningCondition.register(GroundedSpawningCondition.NAME, GroundedSpawningCondition::class.java)
|
||||
SpawningCondition.register(SurfaceSpawningCondition.NAME, SurfaceSpawningCondition::class.java)
|
||||
SpawningCondition.register(FishingSpawningCondition.NAME, FishingSpawningCondition::class.java)
|
||||
SpawningCondition.register(FallingStarSpawningCondition.NAME, FallingStarSpawningCondition::class.java)
|
||||
|
||||
LOGGER.info("Loaded ${SpawningCondition.conditionTypes.size} spawning condition types.")
|
||||
SpawningContextCalculator.register(GroundedSpawningContextCalculator)
|
||||
@@ -104,6 +99,8 @@ object BestSpawner {
|
||||
SpawningContext.register(name = "lavafloor", clazz = LavafloorSpawningContext::class.java, defaultCondition = GroundedSpawningCondition.NAME)
|
||||
SpawningContext.register(name = "submerged", clazz = SubmergedSpawningContext::class.java, defaultCondition = SubmergedSpawningCondition.NAME)
|
||||
SpawningContext.register(name = "surface", clazz = SurfaceSpawningContext::class.java, defaultCondition = SurfaceSpawningCondition.NAME)
|
||||
SpawningContext.register(name = "fishing", clazz = FishingSpawningContext::class.java, defaultCondition = FishingSpawningCondition.NAME)
|
||||
SpawningContext.register(name = "fallingstar", clazz = FallingStarSpawningContext::class.java, defaultCondition = FallingStarSpawningCondition.NAME)
|
||||
|
||||
LOGGER.info("Loaded ${SpawningContext.contexts.size} spawning context types.")
|
||||
|
||||
@@ -118,5 +115,7 @@ object BestSpawner {
|
||||
|
||||
fun onServerStarted() {
|
||||
spawnerManagers.forEach(SpawnerManager::onServerStarted)
|
||||
fishingSpawner = FishingSpawner()
|
||||
starSpawner = FallingStarSpawner()
|
||||
}
|
||||
}
|
||||
+23
@@ -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.api.spawning.condition
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.context.FallingStarSpawningContext
|
||||
|
||||
class FallingStarSpawningCondition: SpawningCondition<FallingStarSpawningContext>() {
|
||||
override fun contextClass() = FallingStarSpawningContext::class.java
|
||||
|
||||
override fun fits(ctx: FallingStarSpawningContext): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NAME = "fallingstar"
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.api.spawning.condition
|
||||
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.spawning.context.FishingSpawningContext
|
||||
import com.cobblemon.mod.common.util.itemRegistry
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.item.Item
|
||||
|
||||
/**
|
||||
* A spawning condition that applies to [FishingSpawningContext]s.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 3rd, 2024
|
||||
*/
|
||||
class FishingSpawningCondition: SpawningCondition<FishingSpawningContext>() {
|
||||
override fun contextClass() = FishingSpawningContext::class.java
|
||||
|
||||
var rod: RegistryLikeCondition<Item>? = null
|
||||
var neededNearbyBlocks: MutableList<RegistryLikeCondition<Block>>? = null
|
||||
|
||||
override fun fits(ctx: FishingSpawningContext): Boolean {
|
||||
if (!super.fits(ctx)) {
|
||||
return false
|
||||
} else if (rod != null && !rod!!.fits(ctx.rodItem ?: return false, ctx.world.itemRegistry)) {
|
||||
return false
|
||||
} else if (neededNearbyBlocks != null && neededNearbyBlocks!!.none { cond -> ctx.nearbyBlockTypes.any { cond.fits(it, ctx.blockRegistry) } }) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NAME = "fishing"
|
||||
}
|
||||
}
|
||||
+47
@@ -76,4 +76,51 @@ interface AreaContextResolver {
|
||||
|
||||
return contexts
|
||||
}
|
||||
|
||||
// fun resolveFishing(
|
||||
// spawner: Spawner,
|
||||
// contextCalculators: List<AreaSpawningContextCalculator<*>>,
|
||||
// slice: WorldSlice
|
||||
// ): List<AreaSpawningContext> {
|
||||
// var pos = BlockPos.Mutable(1, 2, 3)
|
||||
// val input = AreaSpawningInput(spawner, pos, slice)
|
||||
// val contexts = mutableListOf<AreaSpawningContext>()
|
||||
//
|
||||
// var x = slice.baseX
|
||||
// var y = slice.baseY
|
||||
// var z = slice.baseZ
|
||||
//
|
||||
// while (x < slice.baseX + slice.length) {
|
||||
// while (y < slice.baseY + slice.height) {
|
||||
// while (z < slice.baseZ + slice.width) {
|
||||
// pos.set(x, y, z)
|
||||
// val vec = pos.toVec3d()
|
||||
// if (slice.nearbyEntityPositions.none { it.isInRange(vec, 50.0) && it != slice.cause.entity }) {
|
||||
// val fittedContextCalculator = contextCalculators
|
||||
// .firstOrNull { calc -> calc.fits(input) && input.spawner.influences.none { !it.isAllowedPosition(input.world, input.position, calc) } }
|
||||
// if (fittedContextCalculator != null) {
|
||||
// val context = fittedContextCalculator.calculate(input)
|
||||
// if (context != null) {
|
||||
// contexts.add(context)
|
||||
// // The position BlockPos has been used in a context, editing the same one
|
||||
// // will cause entities to spawn at the wrong location (buried in walls, usually)
|
||||
// // I made it so that our context calculators specifically take a copy of the
|
||||
// // BlockPos but it'd still be exposed in custom contexts so fixing it here too.
|
||||
// pos = BlockPos.Mutable(1, 2, 3)
|
||||
// input.position = pos
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// z++
|
||||
// }
|
||||
// y++
|
||||
// z = slice.baseZ
|
||||
// }
|
||||
// x++
|
||||
// y = slice.baseY
|
||||
// z = slice.baseZ
|
||||
// }
|
||||
//
|
||||
// return contexts
|
||||
// }
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.api.spawning.context
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.fallingstar.FallingStarSpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
class FallingStarSpawningContext(
|
||||
cause: FallingStarSpawnCause,
|
||||
world: ServerWorld,
|
||||
pos: BlockPos,
|
||||
influences: MutableList<SpawningInfluence>
|
||||
) : TriggerSpawningContext(
|
||||
cause = cause,
|
||||
world = world,
|
||||
position = pos,
|
||||
light = world.getLightLevel(pos),
|
||||
skyLight = world.getLightLevel(pos.up()),
|
||||
canSeeSky = world.isSkyVisibleAllowingSea(pos),
|
||||
influences = influences
|
||||
) {
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.api.spawning.context
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.util.getBlockStates
|
||||
import com.cobblemon.mod.common.util.toVec3d
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Box
|
||||
|
||||
/**
|
||||
* A spawning context that was generated for a fishing action.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 3rd, 2024
|
||||
*/
|
||||
class FishingSpawningContext(
|
||||
cause: FishingSpawnCause,
|
||||
world: ServerWorld,
|
||||
pos: BlockPos,
|
||||
influences: MutableList<SpawningInfluence>
|
||||
) : TriggerSpawningContext(
|
||||
cause = cause,
|
||||
world = world,
|
||||
position = pos,
|
||||
light = world.getLightLevel(pos),
|
||||
skyLight = world.getLightLevel(pos.up()),
|
||||
canSeeSky = world.isSkyVisibleAllowingSea(pos),
|
||||
influences = influences
|
||||
) {
|
||||
val nearbyBlocks = world.getBlockStates(Box.of(pos.toVec3d(), 10.0, 10.0, 10.0))
|
||||
val nearbyBlockTypes: List<Block> by lazy { nearbyBlocks.mapNotNull { it.block }.distinct() }
|
||||
val rodStack = cause.rodStack
|
||||
val rodItem = cause.rodItem
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.api.spawning.context
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
/**
|
||||
* A spawning context relating to triggered spawning. Uses a single-point structure cache which is
|
||||
* the only contribution of this implementation.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 3rd, 2024
|
||||
*/
|
||||
open class TriggerSpawningContext(
|
||||
override val cause: SpawnCause,
|
||||
override val world: ServerWorld,
|
||||
override val position: BlockPos,
|
||||
override val light: Int,
|
||||
override val skyLight: Int,
|
||||
override val canSeeSky: Boolean,
|
||||
override val influences: MutableList<SpawningInfluence>
|
||||
) : SpawningContext() {
|
||||
val triggerStructureCache = StructureChunkCache()
|
||||
override fun getStructureCache(pos: BlockPos) = triggerStructureCache
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.api.spawning.fallingstar
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import net.minecraft.entity.Entity
|
||||
|
||||
class FallingStarSpawnCause(
|
||||
spawner: Spawner,
|
||||
bucket: SpawnBucket,
|
||||
entity: Entity?
|
||||
) : SpawnCause(spawner, bucket, entity)
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.api.spawning.fallingstar
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawnPools
|
||||
import com.cobblemon.mod.common.api.spawning.context.FallingStarSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.TriggerSpawner
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
open class FallingStarSpawner(
|
||||
override val name: String = "fallingstar",
|
||||
pool: SpawnPool = CobblemonSpawnPools.WORLD_SPAWN_POOL
|
||||
) : TriggerSpawner<FallingStarSpawnCause>(name, pool) {
|
||||
override fun parseContext(cause: FallingStarSpawnCause, world: ServerWorld, pos: BlockPos): FallingStarSpawningContext? {
|
||||
return FallingStarSpawningContext(cause, world, pos, influences)
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.api.spawning.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.FishingRodItem
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
/**
|
||||
* A spawning cause that is embellished with fishing information. Could probably also
|
||||
* have the bobber entity or something.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 3rd, 2024
|
||||
*/
|
||||
class FishingSpawnCause(
|
||||
spawner: Spawner,
|
||||
bucket: SpawnBucket,
|
||||
entity: Entity?,
|
||||
val rodStack: ItemStack
|
||||
) : SpawnCause(spawner, bucket, entity) {
|
||||
val rodItem = rodStack.item as? FishingRodItem
|
||||
}
|
||||
+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.api.spawning.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawnPools
|
||||
import com.cobblemon.mod.common.api.spawning.context.FishingSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.TriggerSpawner
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
/**
|
||||
* A spawner that takes in a [FishingSpawnCause] and spawns things.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 3rd, 2024
|
||||
*/
|
||||
open class FishingSpawner(
|
||||
override val name: String = "fishing",
|
||||
pool: SpawnPool = CobblemonSpawnPools.WORLD_SPAWN_POOL
|
||||
) : TriggerSpawner<FishingSpawnCause>(name, pool) {
|
||||
override fun parseContext(cause: FishingSpawnCause, world: ServerWorld, pos: BlockPos): FishingSpawningContext? {
|
||||
// Maybe confirm that it's water we're fishing in?
|
||||
val ctx = FishingSpawningContext(
|
||||
cause = cause,
|
||||
world = world,
|
||||
pos = pos,
|
||||
influences = influences
|
||||
)
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +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.api.spawning.influence
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
|
||||
import net.minecraft.registry.tag.BlockTags
|
||||
|
||||
/**
|
||||
* Implements a [SpawningInfluence] that prevents Pokémon spawning on certain blocks.
|
||||
* This ensures that Pokémon don't spawn in areas that could disrupt player-built structures or mechanisms.
|
||||
* The influence checks the block directly above the potential spawn location; if the block is in the restricted list,
|
||||
* the spawn is disallowed.
|
||||
*
|
||||
* @author Aethen
|
||||
* @since February 20th, 2024
|
||||
*/
|
||||
open class RestrictedSpawnBlocksInfluence
|
||||
: SpawningInfluence {
|
||||
|
||||
// The list of blocks that Pokémon are not allowed to spawn on.
|
||||
private val restrictedBlocks = BlockTags.RAILS
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Affects the spawnable status of a Pokémon spawn detail.
|
||||
* If the block directly above the spawn location is in the restricted list, the spawn is disallowed.
|
||||
*
|
||||
* @param detail The Pokémon spawn detail to be affected.
|
||||
* @param ctx The context of the spawning event.
|
||||
* @return `true` if the spawn is allowed, `false` if it is disallowed.
|
||||
*/
|
||||
override fun affectSpawnable(detail: SpawnDetail, ctx: SpawningContext): Boolean {
|
||||
// If the spawn detail is not a Pokémon, it is not affected by this influence.
|
||||
if (detail.type != "pokemon") return true
|
||||
|
||||
// Get the position of the potential spawn location.
|
||||
val pokemonSpawnPos = ctx.position
|
||||
|
||||
// Examine the block immediately above the spawn block to check for a rail
|
||||
// Potentially need a refactor if we ever want to check the spawn block itself.
|
||||
return ctx.world.getBlockState(pokemonSpawnPos.withY(pokemonSpawnPos.y + 1)).isIn(restrictedBlocks).not()
|
||||
}
|
||||
}
|
||||
+3
-22
@@ -13,10 +13,8 @@ import com.cobblemon.mod.common.api.spawning.CobblemonSpawnRules
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnerManager
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.influence.PlayerLevelRangeInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.influence.RestrictedSpawnBlocksInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.rules.SpawnRule
|
||||
import com.cobblemon.mod.common.util.mutableLazy
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
|
||||
/**
|
||||
@@ -28,31 +26,14 @@ import net.minecraft.server.network.ServerPlayerEntity
|
||||
* @since February 14th, 2022
|
||||
*/
|
||||
object PlayerSpawnerFactory {
|
||||
var spawns: SpawnPool by mutableLazy {
|
||||
CobblemonSpawnPools.WORLD_SPAWN_POOL
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of influences for a new [PlayerSpawner].
|
||||
* The influences will be added to the spawner in the order they are added to this list.
|
||||
*
|
||||
* [PlayerLevelRangeInfluence] adjusts the level range of Pokémon that can spawn based on the player's level.
|
||||
* [RestrictedSpawnBlocksInfluence] prevents Pokémon from spawning on certain blocks.
|
||||
*/
|
||||
var influenceBuilders = mutableListOf<(player: ServerPlayerEntity) -> SpawningInfluence?>({
|
||||
PlayerLevelRangeInfluence(
|
||||
it,
|
||||
variation = 5
|
||||
)
|
||||
}, { RestrictedSpawnBlocksInfluence() })
|
||||
var spawns: SpawnPool = CobblemonSpawnPools.WORLD_SPAWN_POOL
|
||||
var influenceBuilders = mutableListOf<(player: ServerPlayerEntity) -> SpawningInfluence?>({ PlayerLevelRangeInfluence(it, variation = 5) })
|
||||
|
||||
fun create(spawnerManager: SpawnerManager, player: ServerPlayerEntity): PlayerSpawner {
|
||||
val influences = influenceBuilders.mapNotNull { it(player) }
|
||||
return PlayerSpawner(player, spawns, spawnerManager).also {
|
||||
it.influences.addAll(influences)
|
||||
it.influences.addAll(
|
||||
CobblemonSpawnRules.rules.values.filter(SpawnRule::enabled).flatMap(SpawnRule::components)
|
||||
)
|
||||
it.influences.addAll(CobblemonSpawnRules.rules.values.filter(SpawnRule::enabled).flatMap(SpawnRule::components))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.api.spawning.spawner
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.selection.FlatContextWeightedSelector
|
||||
import com.cobblemon.mod.common.api.spawning.selection.SpawningSelector
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
/**
|
||||
* A type of spawner that occurs at a single point and provides its own means of generating a
|
||||
* context from a particular cause and position. The trigger spawner must be directly called to
|
||||
* spawn things (almost as if it was being triggered) as opposed to being scheduled on a ticker.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 3rd, 2024
|
||||
*/
|
||||
abstract class TriggerSpawner<T : SpawnCause>(override val name: String, var spawns: SpawnPool) : Spawner {
|
||||
private var selector: SpawningSelector = FlatContextWeightedSelector()
|
||||
override val influences = mutableListOf<SpawningInfluence>()
|
||||
|
||||
open fun run(cause: T, world: ServerWorld, pos: BlockPos): CompletableFuture<*>? {
|
||||
val context = parseContext(cause, world, pos) ?: return null
|
||||
selector.select(this, listOf(context))?.let { (_, spawn) ->
|
||||
val action = spawn.doSpawn(context)
|
||||
action.complete()
|
||||
return action.future
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Parses a context, if possible, from the given cause and position. */
|
||||
abstract fun parseContext(cause: T, world: ServerWorld, pos: BlockPos): SpawningContext?
|
||||
|
||||
override fun canSpawn() = true
|
||||
override fun getSpawningSelector() = selector
|
||||
override fun setSpawningSelector(selector: SpawningSelector) { this.selector = selector }
|
||||
override fun getSpawnPool() = spawns
|
||||
override fun setSpawnPool(spawnPool: SpawnPool) { spawns = spawnPool }
|
||||
}
|
||||
@@ -11,14 +11,12 @@ 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
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.pokemon.OriginalTrainerType
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.activestate.ShoulderedState
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
@@ -125,12 +123,6 @@ open class PlayerPartyStore(
|
||||
|
||||
// Passive evolutions
|
||||
pokemon.evolutions.filterIsInstance<PassiveEvolution>().forEach { it.attemptEvolution(pokemon) }
|
||||
val removeList = mutableListOf<Evolution>()
|
||||
pokemon.evolutionProxy.server().forEach {
|
||||
if (!it.test(pokemon) && it is LevelUpEvolution && !it.permanent)
|
||||
removeList.add(it)
|
||||
}
|
||||
removeList.forEach { pokemon.evolutionProxy.server().remove(it) }
|
||||
}
|
||||
// Friendship
|
||||
// ToDo expand this down the line just a very basic implementation for the first releases
|
||||
|
||||
+11
-20
@@ -21,7 +21,6 @@ import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
|
||||
import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
|
||||
import com.cobblemon.mod.common.net.messages.client.animation.PlayPoseableAnimationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleHealthChangePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.DamageTakenEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.RecoilEvolutionProgress
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
@@ -71,26 +70,18 @@ class DamageInstruction(
|
||||
}
|
||||
|
||||
battle.dispatch {
|
||||
val pokemonEntity = battlePokemon.entity
|
||||
if (!causedFaint && pokemonEntity != null) {
|
||||
val pkt = PlayPoseableAnimationPacket(pokemonEntity.id, setOf("recoil"), emptySet())
|
||||
pkt.sendToPlayersAround(
|
||||
x = pokemonEntity.x,
|
||||
y = pokemonEntity.y,
|
||||
z = pokemonEntity.z,
|
||||
worldKey = pokemonEntity.world.registryKey,
|
||||
distance = 50.0
|
||||
)
|
||||
}
|
||||
if (!causedFaint) {
|
||||
|
||||
if (pokemonEntity != null) {
|
||||
RunPosableMoLangPacket(pokemonEntity.id, setOf("q.particle('cobblemon:hit', 'target')")).sendToPlayersAround(
|
||||
x = pokemonEntity.x,
|
||||
y = pokemonEntity.y,
|
||||
z = pokemonEntity.z,
|
||||
worldKey = pokemonEntity.world.registryKey,
|
||||
distance = 50.0
|
||||
)
|
||||
battlePokemon.entity?.let { pokemonEntity ->
|
||||
val pkt = PlayPoseableAnimationPacket(pokemonEntity.id, setOf("recoil"), emptySet())
|
||||
pkt.sendToPlayersAround(
|
||||
x = pokemonEntity.x,
|
||||
y = pokemonEntity.y,
|
||||
z = pokemonEntity.z,
|
||||
worldKey = pokemonEntity.world.registryKey,
|
||||
distance = 50.0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,74 +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.block
|
||||
|
||||
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
|
||||
|
||||
class CoinPouchBlock(settings: Settings, val small: Boolean) : HorizontalFacingBlock(settings) {
|
||||
|
||||
init {
|
||||
this.defaultState = this.stateManager.defaultState
|
||||
.with(NATURAL, false)
|
||||
.with(FACING, Direction.NORTH)
|
||||
}
|
||||
|
||||
override fun getOutlineShape(
|
||||
state: BlockState?,
|
||||
world: BlockView?,
|
||||
pos: BlockPos?,
|
||||
context: ShapeContext?
|
||||
) = if (!small) super.getOutlineShape(state, world, pos, context) else {
|
||||
VoxelShapes.cuboid(0.3125, 0.0, 0.3125, 0.6875, 0.3125, 0.6875)
|
||||
}
|
||||
|
||||
override fun getPlacementState(ctx: ItemPlacementContext): BlockState? {
|
||||
var blockState = defaultState
|
||||
val worldView = ctx.world
|
||||
val blockPos = ctx.blockPos
|
||||
ctx.placementDirections.forEach { direction ->
|
||||
if (direction.axis.isHorizontal) {
|
||||
blockState = blockState.with(FACING, direction.opposite) as BlockState
|
||||
if (blockState.canPlaceAt(worldView, blockPos)) {
|
||||
return blockState
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun getStateForNeighborUpdate(
|
||||
state: BlockState,
|
||||
direction: Direction,
|
||||
neighborState: BlockState,
|
||||
world: WorldAccess,
|
||||
pos: BlockPos,
|
||||
neighborPos: BlockPos
|
||||
): BlockState {
|
||||
return if (direction == state.get(FACING) && !state.canPlaceAt(world, pos)) Blocks.AIR.defaultState
|
||||
else super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
|
||||
builder.add(FACING, NATURAL)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val NATURAL: BooleanProperty = BooleanProperty.of("natural")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.block.entity.DyniteOreBlockEntity
|
||||
import net.minecraft.block.BlockRenderType
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.BlockWithEntity
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.block.entity.BlockEntityTicker
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
|
||||
class DyniteOreBlock(settings: Settings) : BlockWithEntity(settings) {
|
||||
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity {
|
||||
return DyniteOreBlockEntity(pos, state)
|
||||
}
|
||||
|
||||
override fun getRenderType(state: BlockState?) = BlockRenderType.MODEL
|
||||
|
||||
override fun <T : BlockEntity> getTicker(
|
||||
world: World,
|
||||
state: BlockState,
|
||||
type: BlockEntityType<T>
|
||||
): BlockEntityTicker<T>? {
|
||||
return checkType(type, CobblemonBlockEntities.DYNITE_ORE, DyniteOreBlockEntity.TICKER::tick)
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ import com.cobblemon.mod.common.block.entity.RestorationTankBlockEntity
|
||||
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
|
||||
import net.minecraft.block.*
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.ai.pathing.NavigationType
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.inventory.SidedInventory
|
||||
import net.minecraft.item.ItemPlacementContext
|
||||
@@ -217,11 +216,6 @@ class RestorationTankBlock(properties: Settings) : MultiblockBlock(properties),
|
||||
override fun asString() = label
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun canPathfindThrough(state: BlockState?, world: BlockView?, pos: BlockPos?, type: NavigationType?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
val PART = EnumProperty.of("part", TankPart::class.java)
|
||||
val TRIGGERED = Properties.TRIGGERED
|
||||
|
||||
@@ -1,228 +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.block.chest
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.scheduling.afterOnServer
|
||||
import com.cobblemon.mod.common.block.entity.GildedChestBlockEntity
|
||||
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 net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockRenderType
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.BlockWithEntity
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.block.HorizontalFacingBlock
|
||||
import net.minecraft.block.ShapeContext
|
||||
import net.minecraft.entity.ai.pathing.NavigationType
|
||||
import net.minecraft.entity.mob.PiglinBrain
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.item.ItemPlacementContext
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.state.StateManager
|
||||
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.hit.BlockHitResult
|
||||
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.World
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
class GildedChestBlock(settings: Settings, val type: Type = Type.RED) : BlockWithEntity(settings) {
|
||||
|
||||
init {
|
||||
defaultState = defaultState.with(Properties.HORIZONTAL_FACING, Direction.SOUTH)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val POKEMON_ARGS = "gimmighoul"
|
||||
val LEVEL_RANGE = 5..30
|
||||
|
||||
val SOUTH_OUTLINE = VoxelShapes.union(
|
||||
VoxelShapes.cuboid(0.0, 0.0, 0.25, 1.0, 1.0, 0.9375)
|
||||
)
|
||||
val NORTH_OUTLINE = VoxelShapes.union(
|
||||
VoxelShapes.cuboid(0.0, 0.0, 0.0625, 1.0, 1.0, 0.75)
|
||||
)
|
||||
val WEST_OUTLINE = VoxelShapes.union(
|
||||
VoxelShapes.cuboid(0.0625, 0.0, 0.0, 0.75, 1.0, 1.0)
|
||||
)
|
||||
val EAST_OUTLINE = VoxelShapes.union(
|
||||
VoxelShapes.cuboid(0.25, 0.0, 0.0, 0.9375, 1.0, 1.0)
|
||||
)
|
||||
}
|
||||
|
||||
override fun createBlockEntity(pos: BlockPos, state: BlockState) = GildedChestBlockEntity(pos, state, type)
|
||||
|
||||
override fun getOutlineShape(
|
||||
state: BlockState,
|
||||
world: BlockView,
|
||||
pos: BlockPos,
|
||||
context: ShapeContext
|
||||
): VoxelShape {
|
||||
return when (state.get(HorizontalFacingBlock.FACING)) {
|
||||
Direction.NORTH -> NORTH_OUTLINE
|
||||
Direction.SOUTH -> SOUTH_OUTLINE
|
||||
Direction.WEST -> WEST_OUTLINE
|
||||
else -> EAST_OUTLINE
|
||||
}
|
||||
}
|
||||
|
||||
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
|
||||
super.appendProperties(builder)
|
||||
builder.add(Properties.HORIZONTAL_FACING)
|
||||
}
|
||||
|
||||
private val facingToYaw: HashMap<Direction, Float> = hashMapOf(
|
||||
Direction.NORTH to -179.0F,
|
||||
Direction.WEST to 90.0F,
|
||||
Direction.SOUTH to 0.0F,
|
||||
Direction.EAST to -90.0F
|
||||
)
|
||||
|
||||
override fun getName(): MutableText {
|
||||
return if (isFake()) Text.translatable("block.cobblemon.gilded_chest") else super.getName()
|
||||
}
|
||||
|
||||
fun isFake() = (type == Type.FAKE)
|
||||
|
||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
|
||||
if (isFake()) {
|
||||
if (player is ServerPlayerEntity) {
|
||||
spawnPokemon(world, pos, state, player)
|
||||
}
|
||||
world.setBlockState(pos, Blocks.AIR.defaultState)
|
||||
} else super.onBreak(world, pos, state, player)
|
||||
}
|
||||
|
||||
private fun spawnPokemon(world: World, pos: BlockPos, state: BlockState, player: ServerPlayerEntity) : ActionResult {
|
||||
val properties = "$POKEMON_ARGS lvl=${LEVEL_RANGE.random()}"
|
||||
val pokemon = PokemonProperties.parse(properties)
|
||||
val entity = pokemon.createEntity(world)
|
||||
|
||||
// The yaw based on the block's facing direction
|
||||
val yaw = facingToYaw[state[HorizontalFacingBlock.FACING]] ?: 0.0F
|
||||
|
||||
entity.dataTracker.set(PokemonEntity.SPAWN_DIRECTION, facingToYaw[state[HorizontalFacingBlock.FACING]])
|
||||
val offsetDir = state[HorizontalFacingBlock.FACING]
|
||||
val vec = pos.toVec3d().add(offsetDir.offsetX * 0.1 + 0.5, 0.0, offsetDir.offsetZ * 0.1 + 0.5)
|
||||
entity.refreshPositionAndAngles(vec.x, vec.y, vec.z, yaw, entity.pitch)
|
||||
world.spawnEntity(entity)
|
||||
|
||||
world.removeBlock(pos, false)
|
||||
afterOnServer(ticks = 2) {
|
||||
if (player !in player.world.players) {
|
||||
return@afterOnServer
|
||||
}
|
||||
val party = player.party()
|
||||
if (!player.isCreative) {
|
||||
entity.forceBattle(player)
|
||||
} else {
|
||||
world.playSound(null, pos, CobblemonSounds.GIMMIGHOUL_REVEAL, SoundCategory.NEUTRAL)
|
||||
}
|
||||
}
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun onUse(
|
||||
state: BlockState,
|
||||
world: World,
|
||||
pos: BlockPos,
|
||||
player: PlayerEntity,
|
||||
hand: Hand,
|
||||
hit: BlockHitResult
|
||||
): ActionResult {
|
||||
if (isFake()) {
|
||||
if (player is ServerPlayerEntity) {
|
||||
return spawnPokemon(world, pos, state, player)
|
||||
} else {
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
}
|
||||
val entity = world.getBlockEntity(pos) as? GildedChestBlockEntity ?: return ActionResult.FAIL
|
||||
if (world.getBlockState(pos.up()).isSolidBlock(world, pos.up())) return ActionResult.FAIL
|
||||
player.openHandledScreen(entity)
|
||||
if (!player.world.isClient) {
|
||||
PiglinBrain.onGuardedBlockInteracted(player, true)
|
||||
}
|
||||
val state = entity.poseableState
|
||||
state.currentModel?.let {
|
||||
it.moveToPose(null, state, it.getPose("OPEN")!!)
|
||||
}
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun onStateReplaced(
|
||||
state: BlockState,
|
||||
world: World,
|
||||
pos: BlockPos,
|
||||
newState: BlockState,
|
||||
moved: Boolean
|
||||
) {
|
||||
if (!state.isOf(newState.block)) {
|
||||
val chest = world.getBlockEntity(pos) as GildedChestBlockEntity
|
||||
ItemScatterer.spawn(world, pos, chest.inventoryContents)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRenderType(state: BlockState?) = BlockRenderType.ENTITYBLOCK_ANIMATED
|
||||
|
||||
override fun getPlacementState(blockPlaceContext: ItemPlacementContext): BlockState? {
|
||||
// val abovePosition = blockPlaceContext.blockPos.up()
|
||||
// val world = blockPlaceContext.world
|
||||
// if (world.getBlockState(abovePosition).canReplace(blockPlaceContext) && !world.isOutOfHeightLimit(abovePosition)) {
|
||||
return defaultState.with(HorizontalFacingBlock.FACING, blockPlaceContext.horizontalPlayerFacing.opposite)
|
||||
// }
|
||||
// return null
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun rotate(state: BlockState, rotation: BlockRotation): BlockState {
|
||||
return state.with(
|
||||
Properties.HORIZONTAL_FACING, rotation.rotate(
|
||||
state.get(Properties.HORIZONTAL_FACING) as Direction
|
||||
)
|
||||
) as BlockState
|
||||
}
|
||||
|
||||
override fun mirror(state: BlockState, mirror: BlockMirror): BlockState {
|
||||
return state.rotate(mirror.getRotation(state.get(Properties.HORIZONTAL_FACING) as Direction))
|
||||
}
|
||||
|
||||
enum class Type(val poserId: Identifier) {
|
||||
RED(cobblemonResource("gilded_chest")),
|
||||
BLUE(cobblemonResource("blue_gilded_chest")),
|
||||
GREEN(cobblemonResource("green_gilded_chest")),
|
||||
PINK(cobblemonResource("pink_gilded_chest")),
|
||||
WHITE(cobblemonResource("white_gilded_chest")),
|
||||
BLACK(cobblemonResource("black_gilded_chest")),
|
||||
YELLOW(cobblemonResource("yellow_gilded_chest")),
|
||||
FAKE(cobblemonResource("gilded_chest"))
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun canPathfindThrough(state: BlockState?, world: BlockView?, pos: BlockPos?, type: NavigationType?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +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.block.chest
|
||||
|
||||
import com.cobblemon.mod.common.api.scheduling.SchedulingTracker
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
|
||||
import net.minecraft.entity.Entity
|
||||
|
||||
class GildedState : PoseableEntityState<Entity>() {
|
||||
override fun getEntity() = null
|
||||
|
||||
init {
|
||||
setPose("CLOSED")
|
||||
}
|
||||
|
||||
override fun updatePartialTicks(partialTicks: Float) {
|
||||
this.currentPartialTicks += partialTicks
|
||||
}
|
||||
|
||||
override val schedulingTracker = SchedulingTracker()
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.BlockEntity
|
||||
import net.minecraft.block.entity.BlockEntityTicker
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
class DyniteOreBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(CobblemonBlockEntities.DYNITE_ORE, pos, state) {
|
||||
|
||||
companion object {
|
||||
internal val TICKER = BlockEntityTicker<DyniteOreBlockEntity> { world, pos, state, blockEntity ->
|
||||
if (world.isClient) return@BlockEntityTicker
|
||||
// idk if i'll actually need this but i already made it
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-149
@@ -1,149 +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.block.entity
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.block.chest.GildedChestBlock.Type
|
||||
import com.cobblemon.mod.common.block.chest.GildedState
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.block.entity.LootableContainerBlockEntity
|
||||
import net.minecraft.block.entity.ViewerCountManager
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.entity.player.PlayerInventory
|
||||
import net.minecraft.inventory.DoubleInventory
|
||||
import net.minecraft.inventory.Inventories
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.screen.GenericContainerScreenHandler
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.state.property.Properties
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.collection.DefaultedList
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
|
||||
class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type = Type.RED) : LootableContainerBlockEntity(CobblemonBlockEntities.GILDED_CHEST, pos, state) {
|
||||
var inventoryContents: DefaultedList<ItemStack> = DefaultedList.ofSize(NUM_SLOTS, ItemStack.EMPTY)
|
||||
val poseableState: GildedState = GildedState()
|
||||
|
||||
private val stateManager: ViewerCountManager = object : ViewerCountManager() {
|
||||
override fun onContainerOpen(world: World, pos: BlockPos, state: BlockState) {
|
||||
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_OPEN)
|
||||
}
|
||||
|
||||
override fun onContainerClose(world: World, pos: BlockPos, state: BlockState) {
|
||||
playSound(world, pos, state, CobblemonSounds.GILDED_CHEST_CLOSE)
|
||||
}
|
||||
|
||||
override fun onViewerCountUpdate(
|
||||
world: World,
|
||||
pos: BlockPos,
|
||||
state: BlockState,
|
||||
oldViewerCount: Int,
|
||||
newViewerCount: Int
|
||||
) {
|
||||
this@GildedChestBlockEntity.onViewerCountUpdate(world, pos, state, oldViewerCount, newViewerCount)
|
||||
}
|
||||
|
||||
override fun isPlayerViewing(player: PlayerEntity): Boolean {
|
||||
if (player.currentScreenHandler is GenericContainerScreenHandler) {
|
||||
val inventory = (player.currentScreenHandler as GenericContainerScreenHandler).inventory
|
||||
return inventory === this@GildedChestBlockEntity || inventory is DoubleInventory && inventory.isPart(
|
||||
this@GildedChestBlockEntity
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun getType(): BlockEntityType<*> = CobblemonBlockEntities.GILDED_CHEST
|
||||
override fun size() = NUM_SLOTS
|
||||
|
||||
override fun getContainerName() = Text.translatable("block.cobblemon.gilded_chest")
|
||||
override fun createScreenHandler(syncId: Int, playerInventory: PlayerInventory?) =
|
||||
GenericContainerScreenHandler.createGeneric9x3(syncId, playerInventory, this);
|
||||
|
||||
override fun onOpen(player: PlayerEntity) {
|
||||
if (!this.removed && !player.isSpectator && type != Type.FAKE) {
|
||||
stateManager.openContainer(player, this.getWorld(), this.getPos(), this.cachedState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClose(player: PlayerEntity) {
|
||||
if (!this.removed && !player.isSpectator) {
|
||||
stateManager.closeContainer(player, this.getWorld(), this.getPos(), this.cachedState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getInvStackList(): DefaultedList<ItemStack> = inventoryContents
|
||||
|
||||
override fun setInvStackList(list: DefaultedList<ItemStack>) {
|
||||
inventoryContents = list
|
||||
}
|
||||
|
||||
companion object {
|
||||
val NUM_SLOTS = 27
|
||||
fun playSound(world: World, pos: BlockPos, state: BlockState, sound: net.minecraft.sound.SoundEvent) {
|
||||
var d = pos.x.toDouble() + 0.5
|
||||
val e = pos.y.toDouble() + 0.5
|
||||
var f = pos.z.toDouble() + 0.5
|
||||
val direction = state.get(Properties.HORIZONTAL_FACING)
|
||||
d += direction.offsetX.toDouble() * 0.5
|
||||
f += direction.offsetZ.toDouble() * 0.5
|
||||
world.playSound(
|
||||
null,
|
||||
d,
|
||||
e,
|
||||
f,
|
||||
sound,
|
||||
SoundCategory.BLOCKS,
|
||||
0.5f,
|
||||
world.random.nextFloat() * 0.1f + 0.9f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSyncedBlockEvent(type: Int, data: Int): Boolean {
|
||||
if (type == 1) {
|
||||
val isNowOpen = data > 0
|
||||
val wasOpen = poseableState.currentPose == "OPEN"
|
||||
val model = poseableState.currentModel ?: return true
|
||||
if (isNowOpen && !wasOpen) {
|
||||
model.moveToPose(null, poseableState, model.getPose("OPEN")!!)
|
||||
} else if (!isNowOpen && wasOpen) {
|
||||
model.moveToPose(null, poseableState, model.getPose("CLOSED")!!)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return super.onSyncedBlockEvent(type, data)
|
||||
}
|
||||
|
||||
fun onViewerCountUpdate(world: World, pos: BlockPos, state: BlockState, oldViewerCount: Int, newViewerCount: Int) {
|
||||
val block = state.block
|
||||
world.addSyncedBlockEvent(pos, block, 1, newViewerCount)
|
||||
}
|
||||
override fun writeNbt(nbt: NbtCompound?) {
|
||||
super.writeNbt(nbt)
|
||||
if (!serializeLootTable(nbt)) {
|
||||
Inventories.writeNbt(nbt, inventoryContents)
|
||||
}
|
||||
}
|
||||
|
||||
override fun readNbt(nbt: NbtCompound?) {
|
||||
super.readNbt(nbt)
|
||||
inventoryContents= DefaultedList.ofSize(
|
||||
size(), ItemStack.EMPTY
|
||||
)
|
||||
if (!deserializeLootTable(nbt)) {
|
||||
Inventories.readNbt(nbt, inventoryContents)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -128,7 +128,7 @@ class RestorationTankBlockEntity(
|
||||
val canUtilize = stack?.let { NaturalMaterials.isNaturalMaterial(it) } == true
|
||||
&& structure.organicMaterialInside < FossilMultiblockStructure.MATERIAL_TO_START
|
||||
&& structure.createdPokemon == null
|
||||
val returnItem = NaturalMaterials.getReturnItem(stack!!) ?: return canUtilize
|
||||
val returnItem = NaturalMaterials.getReturnItem(stack!!) ?: return false
|
||||
if(canUtilize) {
|
||||
// See if there's room
|
||||
for (i in items.indices ) {
|
||||
|
||||
+2
-2
@@ -328,8 +328,8 @@ class FossilMultiblockStructure (
|
||||
tankBaseEntity.masterBlockPos = null
|
||||
tankTopEntity.masterBlockPos = null
|
||||
|
||||
// Drop fossils from machine as long as the machine is not started or near completion
|
||||
if (this.timeRemaining == -1 || this.timeRemaining >= 20) {
|
||||
// Drop fossils from machine as long as the machine is not running
|
||||
if (this.timeRemaining == TIME_TO_TAKE || this.timeRemaining == -1) {
|
||||
this.fossilInventory.forEach {
|
||||
val stack = ItemStack(it.item, 1)
|
||||
ItemScatterer.spawn(world, pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble(), stack)
|
||||
|
||||
@@ -25,15 +25,15 @@ 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.FossilAnalyzerRenderer
|
||||
import com.cobblemon.mod.common.client.render.block.RestorationTankRenderer
|
||||
import com.cobblemon.mod.common.client.render.block.GildedChestBlockRenderer
|
||||
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.entity.PokeBobberEntityRenderer
|
||||
import com.cobblemon.mod.common.client.render.entity.FallingStarRenderer
|
||||
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.BlockEntityModelRepository
|
||||
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
|
||||
@@ -164,7 +164,6 @@ object CobblemonClient {
|
||||
|
||||
this.implementation.registerBlockRenderType(
|
||||
RenderLayer.getCutout(),
|
||||
CobblemonBlocks.GILDED_CHEST,
|
||||
CobblemonBlocks.FOSSIL_ANALYZER,
|
||||
CobblemonBlocks.APRICORN_DOOR,
|
||||
CobblemonBlocks.APRICORN_TRAPDOOR,
|
||||
@@ -218,7 +217,6 @@ object CobblemonClient {
|
||||
CobblemonBlocks.MEDIUM_BUDDING_SKY_TUMBLESTONE,
|
||||
CobblemonBlocks.LARGE_BUDDING_SKY_TUMBLESTONE,
|
||||
CobblemonBlocks.SKY_TUMBLESTONE_CLUSTER,
|
||||
CobblemonBlocks.GIMMIGHOUL_CHEST
|
||||
)
|
||||
|
||||
this.createBoatModelLayers()
|
||||
@@ -248,7 +246,6 @@ object CobblemonClient {
|
||||
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HANGING_SIGN, ::HangingSignBlockEntityRenderer)
|
||||
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.FOSSIL_ANALYZER, ::FossilAnalyzerRenderer)
|
||||
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.RESTORATION_TANK, ::RestorationTankRenderer)
|
||||
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.GILDED_CHEST, ::GildedChestBlockRenderer)
|
||||
}
|
||||
|
||||
private fun registerEntityRenderers() {
|
||||
@@ -260,6 +257,10 @@ object CobblemonClient {
|
||||
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) }
|
||||
LOGGER.info("Registering Falling Star renderer")
|
||||
this.implementation.registerEntityRenderer(CobblemonEntities.FALLING_STAR_ENTITY) { ctx -> FallingStarRenderer(ctx) }
|
||||
LOGGER.info("Registering PokeRod Bobber renderer")
|
||||
this.implementation.registerEntityRenderer(CobblemonEntities.POKE_BOBBER) { ctx -> PokeBobberEntityRenderer(ctx) }
|
||||
}
|
||||
|
||||
fun reloadCodedAssets(resourceManager: ResourceManager) {
|
||||
@@ -267,13 +268,12 @@ object CobblemonClient {
|
||||
BedrockParticleEffectRepository.loadEffects(resourceManager)
|
||||
BedrockAnimationRepository.loadAnimations(
|
||||
resourceManager = resourceManager,
|
||||
directories = PokemonModelRepository.animationDirectories + PokeBallModelRepository.animationDirectories + FossilModelRepository.animationDirectories + BlockEntityModelRepository.animationDirectories
|
||||
directories = PokemonModelRepository.animationDirectories + PokeBallModelRepository.animationDirectories + FossilModelRepository.animationDirectories
|
||||
)
|
||||
PokemonModelRepository.reload(resourceManager)
|
||||
PokeBallModelRepository.reload(resourceManager)
|
||||
BerryModelRepository.reload(resourceManager)
|
||||
FossilModelRepository.reload(resourceManager)
|
||||
BlockEntityModelRepository.reload(resourceManager)
|
||||
MiscModelRepository.reload(resourceManager)
|
||||
LOGGER.info("Loaded assets")
|
||||
}
|
||||
|
||||
+3
-2
@@ -14,7 +14,6 @@ import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.battle.SingleActionRequest
|
||||
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
|
||||
import com.cobblemon.mod.common.client.gui.battle.widgets.BattleOptionTile
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.FleeBattlePacket
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
@@ -22,6 +21,7 @@ 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.text.MutableText
|
||||
import net.minecraft.util.Identifier
|
||||
class BattleGeneralActionSelection(
|
||||
@@ -61,8 +61,9 @@ class BattleGeneralActionSelection(
|
||||
}
|
||||
|
||||
addOption(rank++, battleLang("ui.run"), BattleGUI.runResource) {
|
||||
CobblemonClient.battle?.minimised = true
|
||||
MinecraftClient.getInstance().player?.sendMessage(battleLang("run_prompt"), false)
|
||||
playDownSound(MinecraftClient.getInstance().soundManager)
|
||||
FleeBattlePacket(battle.battleId).sendToServer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-12
@@ -46,7 +46,7 @@ import net.minecraft.text.Text
|
||||
* @author Qu
|
||||
* @since 2022-06-18
|
||||
*/
|
||||
class StarterSelectionScreen(private val categories: List<RenderableStarterCategory>): Screen("cobblemon.ui.starter.title".asTranslated()) {
|
||||
class StarterSelectionScreen private constructor(): Screen("cobblemon.ui.starter.title".asTranslated()) {
|
||||
|
||||
companion object {
|
||||
// Size of UI at scale 1
|
||||
@@ -63,14 +63,22 @@ class StarterSelectionScreen(private val categories: List<RenderableStarterCateg
|
||||
private val doubleTypeBackground = cobblemonResource("textures/gui/starterselection/starterselection_type_slot2.png")
|
||||
}
|
||||
|
||||
private var currentSelection = 0
|
||||
private lateinit var currentCategory: RenderableStarterCategory
|
||||
private lateinit var modelWidget: ModelWidget
|
||||
private lateinit var currentPokemon: RenderablePokemon
|
||||
private lateinit var typeWidget: TypeWidget
|
||||
private lateinit var starterRoundaboutCenter: StarterRoundabout
|
||||
private lateinit var starterRoundaboutLeft: StarterRoundabout
|
||||
private lateinit var starterRoundaboutRight: StarterRoundabout
|
||||
lateinit var categories: List<RenderableStarterCategory>
|
||||
lateinit var currentCategory: RenderableStarterCategory
|
||||
lateinit var modelWidget: ModelWidget
|
||||
lateinit var currentPokemon: RenderablePokemon
|
||||
var currentSelection = 0
|
||||
lateinit var rightButton: ArrowButton
|
||||
lateinit var leftButton: ArrowButton
|
||||
lateinit var typeWidget: TypeWidget
|
||||
lateinit var selectionButton: SelectionButton
|
||||
lateinit var starterRoundaboutCenter: StarterRoundabout
|
||||
lateinit var starterRoundaboutLeft: StarterRoundabout
|
||||
lateinit var starterRoundaboutRight: StarterRoundabout
|
||||
|
||||
constructor(categories: List<RenderableStarterCategory>) : this() {
|
||||
this.categories = categories
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
@@ -94,7 +102,7 @@ class StarterSelectionScreen(private val categories: List<RenderableStarterCateg
|
||||
)
|
||||
)
|
||||
|
||||
val rightButton = ArrowButton(
|
||||
rightButton = ArrowButton(
|
||||
pX = x + 183, pY = y + 151,
|
||||
pWidth = 9, pHeight = 14,
|
||||
right = true
|
||||
@@ -102,7 +110,7 @@ class StarterSelectionScreen(private val categories: List<RenderableStarterCateg
|
||||
right()
|
||||
}
|
||||
|
||||
val leftButton = ArrowButton(
|
||||
leftButton = ArrowButton(
|
||||
pX = x + 72, pY = y + 151,
|
||||
pWidth = 9, pHeight = 14,
|
||||
right = false
|
||||
@@ -129,7 +137,7 @@ class StarterSelectionScreen(private val categories: List<RenderableStarterCateg
|
||||
|
||||
addDrawableChild(modelWidget)
|
||||
|
||||
val selectionButton = SelectionButton(
|
||||
selectionButton = SelectionButton(
|
||||
pX = x + 106, pY = y + 124,
|
||||
pWidth = SelectionButton.BUTTON_WIDTH, pHeight = SelectionButton.BUTTON_HEIGHT
|
||||
) {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.summary
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.moves.Move
|
||||
@@ -60,7 +59,7 @@ import net.minecraft.text.Text
|
||||
*
|
||||
* @param selection The index the [party] will have as the base [selectedPokemon].
|
||||
*/
|
||||
class Summary private constructor(party: Collection<Pokemon?>, private val editable: Boolean, private val selection: Int): Screen(Text.translatable("cobblemon.ui.summary.title")), Schedulable {
|
||||
class Summary private constructor(party: Collection<Pokemon?>, private val editable: Boolean, selection: Int): Screen(Text.translatable("cobblemon.ui.summary.title")), Schedulable {
|
||||
|
||||
companion object {
|
||||
const val BASE_WIDTH = 331
|
||||
@@ -107,27 +106,24 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
|
||||
override val schedulingTracker = SchedulingTracker()
|
||||
|
||||
internal lateinit var selectedPokemon: Pokemon
|
||||
internal var selectedPokemon: Pokemon
|
||||
private lateinit var mainScreen: ClickableWidget
|
||||
lateinit var sideScreen: Element
|
||||
private lateinit var modelWidget: ModelWidget
|
||||
private lateinit var nicknameEntryWidget: NicknameEntryWidget
|
||||
lateinit var modelWidget: ModelWidget
|
||||
lateinit var nicknameEntryWidget: NicknameEntryWidget
|
||||
private val summaryTabs = mutableListOf<SummaryTab>()
|
||||
private var mainScreenIndex = INFO
|
||||
var sideScreenIndex = PARTY
|
||||
private val party = ArrayList(party)
|
||||
|
||||
/**
|
||||
* Initializes the Summary Screen
|
||||
*/
|
||||
override fun init() {
|
||||
super.init()
|
||||
init {
|
||||
if (this.party.isEmpty()) {
|
||||
throw IllegalArgumentException("Summary UI cannot display zero Pokemon")
|
||||
}
|
||||
if (this.party.size > 6) {
|
||||
throw IllegalArgumentException("Summary UI cannot display more than six Pokemon")
|
||||
}
|
||||
|
||||
val idealSelected = this.party[selection]
|
||||
if (idealSelected == null) {
|
||||
this.selectedPokemon = this.party.first { it != null }!!
|
||||
@@ -135,6 +131,14 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
this.selectedPokemon = idealSelected
|
||||
}
|
||||
this.listenToMoveSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Summary Screen
|
||||
*/
|
||||
public override fun init() {
|
||||
clearChildren()
|
||||
super.init()
|
||||
|
||||
val x = (width - BASE_WIDTH) / 2
|
||||
val y = (height - BASE_HEIGHT) / 2
|
||||
@@ -241,7 +245,6 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
rotationY = 325F,
|
||||
offsetY = -10.0
|
||||
)
|
||||
addDrawable(this.modelWidget)
|
||||
}
|
||||
|
||||
fun swapPartySlot(sourceIndex: Int, targetIndex: Int) {
|
||||
@@ -278,12 +281,8 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
listenToMoveSet()
|
||||
displayMainScreen(mainScreenIndex)
|
||||
children().find { it is EvolutionSelectScreen }?.let(this::remove)
|
||||
if (this::modelWidget.isInitialized) {
|
||||
this.modelWidget.pokemon = selectedPokemon.asRenderablePokemon()
|
||||
}
|
||||
if (this::nicknameEntryWidget.isInitialized) {
|
||||
this.nicknameEntryWidget.setSelectedPokemon(selectedPokemon)
|
||||
}
|
||||
modelWidget.pokemon = selectedPokemon.asRenderablePokemon()
|
||||
nicknameEntryWidget.setSelectedPokemon(selectedPokemon)
|
||||
}
|
||||
|
||||
private var moveSetSubscription: ObservableSubscription<MoveSet>? = null
|
||||
@@ -310,7 +309,7 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
*/
|
||||
private fun displayMainScreen(screen: Int) {
|
||||
// Get stat tab index if currently displaying stat screen
|
||||
val subIndex = if (mainScreenIndex == STATS && mainScreen is StatWidget) (mainScreen as StatWidget).statTabIndex else 0
|
||||
var subIndex = if (mainScreenIndex == STATS && mainScreen is StatWidget) (mainScreen as StatWidget).statTabIndex else 0
|
||||
|
||||
mainScreenIndex = screen
|
||||
if (::mainScreen.isInitialized) remove(mainScreen)
|
||||
@@ -409,10 +408,10 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
}
|
||||
}
|
||||
|
||||
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
//this.renderBackground(context)
|
||||
override fun render(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
|
||||
renderBackground(context)
|
||||
|
||||
schedulingTracker.update(delta / 20F)
|
||||
schedulingTracker.update(pPartialTicks / 20F)
|
||||
|
||||
val x = (width - BASE_WIDTH) / 2
|
||||
val y = (height - BASE_HEIGHT) / 2
|
||||
@@ -428,7 +427,7 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
height = PORTRAIT_SIZE
|
||||
)
|
||||
|
||||
//modelWidget.render(context, pMouseX, pMouseY, pPartialTicks)
|
||||
modelWidget.render(context, pMouseX, pMouseY, pPartialTicks)
|
||||
|
||||
// Render Base Resource
|
||||
blitk(
|
||||
@@ -577,29 +576,29 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
)
|
||||
|
||||
// Render all added Widgets
|
||||
super.render(context, mouseX, mouseY, delta)
|
||||
super.render(context, pMouseX, pMouseY, pPartialTicks)
|
||||
|
||||
// Render Item Tooltip
|
||||
if (!heldItem.isEmpty) {
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.drawItemTooltip(MinecraftClient.getInstance().textRenderer, heldItem, mouseX, mouseY)
|
||||
val itemHovered = pMouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && pMouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.drawItemTooltip(MinecraftClient.getInstance().textRenderer, heldItem, pMouseX, pMouseY)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this Screen should pause the Game in SinglePlayer
|
||||
*/
|
||||
override fun shouldPause(): Boolean = false
|
||||
override fun shouldPause(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double): Boolean {
|
||||
return children().any { it.mouseScrolled(mouseX, mouseY, amount) }
|
||||
}
|
||||
|
||||
/*
|
||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
return children().any { it.mouseClicked(mouseX, mouseY, button) }
|
||||
}
|
||||
*/
|
||||
|
||||
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
|
||||
if (sideScreenIndex == MOVE_SWAP || sideScreenIndex == EVOLVE) sideScreen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
|
||||
@@ -607,17 +606,17 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
}
|
||||
|
||||
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
||||
if ((keyCode == InputUtil.GLFW_KEY_ENTER || keyCode == InputUtil.GLFW_KEY_KP_ENTER)
|
||||
&& this::nicknameEntryWidget.isInitialized
|
||||
&& this.nicknameEntryWidget.isFocused
|
||||
) {
|
||||
this.focused = null
|
||||
if ((keyCode == InputUtil.GLFW_KEY_ENTER || keyCode == InputUtil.GLFW_KEY_KP_ENTER) && nicknameEntryWidget.isFocused) { // Enter pressed
|
||||
nicknameEntryWidget.isFocused = false
|
||||
}
|
||||
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||
return nicknameEntryWidget.keyPressed(keyCode, scanCode, modifiers) || super.keyPressed(keyCode, scanCode, modifiers)
|
||||
}
|
||||
|
||||
override fun charTyped(chr: Char, modifiers: Int): Boolean {
|
||||
return nicknameEntryWidget.charTyped(chr, modifiers) || super.charTyped(chr, modifiers)
|
||||
}
|
||||
|
||||
fun playSound(soundEvent: SoundEvent) {
|
||||
MinecraftClient.getInstance().soundManager.play(PositionedSoundInstance.master(soundEvent, 1.0F))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-12
@@ -19,7 +19,6 @@ import net.minecraft.client.gui.widget.ButtonWidget
|
||||
import net.minecraft.client.sound.PositionedSoundInstance
|
||||
import net.minecraft.client.sound.SoundManager
|
||||
import net.minecraft.text.MutableText
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class SummaryButton(
|
||||
@@ -28,7 +27,7 @@ class SummaryButton(
|
||||
val buttonWidth: Number,
|
||||
val buttonHeight: Number,
|
||||
val clickAction: PressAction,
|
||||
private val text: MutableText = Text.empty(),
|
||||
private val text: MutableText? = null,
|
||||
private val resource: Identifier,
|
||||
private val activeResource: Identifier? = null,
|
||||
private val renderRequirement: ((button: SummaryButton) -> Boolean) = { true },
|
||||
@@ -69,16 +68,18 @@ class SummaryButton(
|
||||
)
|
||||
|
||||
// Render Text
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = if (largeText) CobblemonResources.DEFAULT_LARGE else null,
|
||||
text = if (boldText) text.bold() else text,
|
||||
x = buttonX + (buttonWidth.toFloat() / 2),
|
||||
y = buttonY + (buttonHeight.toFloat() / 2) - ((TEXT_HEIGHT / 2) * textScale),
|
||||
scale = textScale,
|
||||
centered = true,
|
||||
shadow = true
|
||||
)
|
||||
if (text != null) {
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = if (largeText) CobblemonResources.DEFAULT_LARGE else null,
|
||||
text = if (boldText) text.bold() else text,
|
||||
x = buttonX + (buttonWidth.toFloat() / 2),
|
||||
y = buttonY + (buttonHeight.toFloat() / 2) - ((TEXT_HEIGHT / 2) * textScale),
|
||||
scale = textScale,
|
||||
centered = true,
|
||||
shadow = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
|
||||
-110
@@ -1,110 +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.client.gui.summary.featurerenderers
|
||||
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.text.bold
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.StatWidget
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.text.MutableText
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
/**
|
||||
* Renders an [IntSpeciesFeature] as a bar in the summary screen.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
class BarSummarySpeciesFeatureRenderer(
|
||||
override val name: String,
|
||||
val displayName: MutableText,
|
||||
val min: Int,
|
||||
val max: Int,
|
||||
val colour: Vec3d,
|
||||
val underlay: Identifier,
|
||||
val overlay: Identifier,
|
||||
val pokemon: Pokemon
|
||||
) : SummarySpeciesFeatureRenderer<IntSpeciesFeature> {
|
||||
override fun render(drawContext: DrawContext, x: Float, y: Float, pokemon: Pokemon, feature: IntSpeciesFeature) {
|
||||
val value = feature.value
|
||||
val barRatio = (value - min) / (max - min).toFloat()
|
||||
val barWidth = MathHelper.ceil(barRatio * 108)
|
||||
|
||||
blitk(
|
||||
matrixStack = drawContext.matrices,
|
||||
texture = underlay,
|
||||
x = x,
|
||||
y = y,
|
||||
height = 28,
|
||||
width = 124
|
||||
)
|
||||
|
||||
val red = colour.x / 255F
|
||||
val green = colour.y / 255F
|
||||
val blue = colour.z / 255F
|
||||
|
||||
blitk(
|
||||
matrixStack = drawContext.matrices,
|
||||
texture = CobblemonResources.WHITE,
|
||||
x = x + 8,
|
||||
y = y + 16,
|
||||
height = 10,
|
||||
width = barWidth,
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
|
||||
blitk(
|
||||
matrixStack = drawContext.matrices,
|
||||
texture = overlay,
|
||||
x = x / StatWidget.SCALE,
|
||||
y = (y + 16) / StatWidget.SCALE,
|
||||
height = 20,
|
||||
width = 248,
|
||||
scale = StatWidget.SCALE
|
||||
)
|
||||
|
||||
// Label
|
||||
drawScaledText(
|
||||
context = drawContext,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = displayName.bold(),
|
||||
x = x + 62,
|
||||
y = y + 2.5,
|
||||
centered = true,
|
||||
shadow = true
|
||||
)
|
||||
|
||||
drawScaledText(
|
||||
context = drawContext,
|
||||
text = value.toString().text(),
|
||||
x = x + 11,
|
||||
y = y + 6,
|
||||
scale = StatWidget.SCALE,
|
||||
centered = true
|
||||
)
|
||||
|
||||
drawScaledText(
|
||||
context = drawContext,
|
||||
text = "${MathHelper.floor(barRatio * 100)}%".text(),
|
||||
x = x + 113,
|
||||
y = y + 6,
|
||||
scale = StatWidget.SCALE,
|
||||
centered = true
|
||||
)
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +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.client.gui.summary.featurerenderers
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeature
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
|
||||
/**
|
||||
* A renderer for some kind of [SynchronizedSpeciesFeature] so that it will display
|
||||
* in the summary screen of the Pokémon (under other stats).
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
interface SummarySpeciesFeatureRenderer<T : SynchronizedSpeciesFeature> {
|
||||
/** The name of the feature (so we know where to look to find it in the [Pokemon]) */
|
||||
val name: String
|
||||
/** Draws it at a particular position. */
|
||||
fun render(drawContext: DrawContext, x: Float, y: Float, pokemon: Pokemon, feature: T)
|
||||
fun render(drawContext: DrawContext, x: Float, y: Float, pokemon: Pokemon): Boolean {
|
||||
val feature = pokemon.getFeature<T>(name) ?: return false
|
||||
render(drawContext, x, y, pokemon, feature)
|
||||
return true
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.client.gui.summary.widgets
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
import com.cobblemon.mod.common.client.gui.summary.Summary
|
||||
@@ -22,14 +23,15 @@ import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
|
||||
class PartySlotWidget(
|
||||
pX: Number,
|
||||
pY: Number,
|
||||
private val pX: Number,
|
||||
private val pY: Number,
|
||||
private val partyWidget: PartyWidget,
|
||||
private val summary: Summary,
|
||||
private val pokemon: Pokemon?,
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.gui.summary.widgets
|
||||
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
class TypeDisplayWidget {
|
||||
|
||||
companion object {
|
||||
|
||||
private val TYPES_RESOURCE = cobblemonResource("textures/gui/types.png")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -26,7 +26,9 @@ class InfoBlockWidget(
|
||||
private val font: Identifier,
|
||||
) : SoundlessWidget(pX, pY, blockWidth, blockHeight, Text.literal("InfoBlockWidget")) {
|
||||
|
||||
|
||||
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = font,
|
||||
|
||||
+2
-1
@@ -15,13 +15,14 @@ import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.gui.widget.ButtonWidget
|
||||
import net.minecraft.client.sound.PositionedSoundInstance
|
||||
import net.minecraft.client.sound.SoundManager
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.text.Text
|
||||
|
||||
class ReorderMoveButton(
|
||||
val pX: Int, val pY: Int,
|
||||
private val isUp: Boolean,
|
||||
onPress: PressAction
|
||||
): ButtonWidget((pX - OFFSET_X).toInt(), (pY + (if (isUp) OFFSET_Y_UP else OFFSET_Y_DOWN)), (WIDTH * SCALE).toInt(), (HEIGHT * SCALE).toInt(), Text.empty(), onPress, DEFAULT_NARRATION_SUPPLIER) {
|
||||
): ButtonWidget((pX - OFFSET_X).toInt(), (pY + (if (isUp) OFFSET_Y_UP else OFFSET_Y_DOWN)), (WIDTH * SCALE).toInt(), (HEIGHT * SCALE).toInt(), Text.literal(""), onPress, DEFAULT_NARRATION_SUPPLIER) {
|
||||
|
||||
companion object {
|
||||
private const val WIDTH = 8
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ class SwapMoveButton(
|
||||
var move: MoveTemplate,
|
||||
var movesWidget: MovesWidget,
|
||||
onPress: PressAction
|
||||
): ButtonWidget((pX + OFFSET_X).toInt(), (pY + OFFSET_Y).toInt(), (WIDTH * SCALE).toInt(), (HEIGHT * SCALE).toInt(), Text.empty(), onPress, DEFAULT_NARRATION_SUPPLIER) {
|
||||
): ButtonWidget((pX + OFFSET_X).toInt(), (pY + OFFSET_Y).toInt(), (WIDTH * SCALE).toInt(), (HEIGHT * SCALE).toInt(), Text.literal(""), onPress, DEFAULT_NARRATION_SUPPLIER) {
|
||||
|
||||
override fun mouseDragged(d: Double, e: Double, i: Int, f: Double, g: Double): Boolean {
|
||||
return false
|
||||
|
||||
+51
-94
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.text.bold
|
||||
@@ -56,7 +54,7 @@ class StatWidget(
|
||||
|
||||
private const val WIDTH = 134
|
||||
private const val HEIGHT = 148
|
||||
const val SCALE = 0.5F
|
||||
private const val SCALE = 0.5F
|
||||
|
||||
private const val WHITE = 0x00FFFFFF
|
||||
private const val GREY = 0x00AAAAAA
|
||||
@@ -66,7 +64,6 @@ class StatWidget(
|
||||
private val statsBaseResource = cobblemonResource("textures/gui/summary/summary_stats_chart_base.png")
|
||||
private val statsChartResource = cobblemonResource("textures/gui/summary/summary_stats_chart.png")
|
||||
private val statsOtherBaseResource = cobblemonResource("textures/gui/summary/summary_stats_other_base.png")
|
||||
private val statsOtherBarTemplate = cobblemonResource("textures/gui/summary/summary_stats_other_bar.png")
|
||||
private val friendshipOverlayResource = cobblemonResource("textures/gui/summary/summary_stats_friendship_overlay.png")
|
||||
private val tabMarkerResource = cobblemonResource("textures/gui/summary/summary_stats_tab_marker.png")
|
||||
private val statIncreaseResource = cobblemonResource("textures/gui/summary/summary_stats_icon_increase.png")
|
||||
@@ -87,10 +84,6 @@ class StatWidget(
|
||||
}
|
||||
|
||||
var statTabIndex = tabIndex
|
||||
val renderableFeatures = SpeciesFeatures
|
||||
.getFeaturesFor(pokemon.species)
|
||||
.filterIsInstance<SynchronizedSpeciesFeatureProvider<*>>()
|
||||
.mapNotNull { it.getRenderer(pokemon) }
|
||||
|
||||
private fun drawTriangle(
|
||||
colour: Vector3f,
|
||||
@@ -185,74 +178,6 @@ class StatWidget(
|
||||
// drawTriangle(colour, specialAttackPoint, centerPoint, hpPoint)
|
||||
}
|
||||
|
||||
private fun drawFriendship(moduleX: Int, moduleY: Int, matrices: MatrixStack, context: DrawContext, friendship: Int) {
|
||||
val barRatio = friendship / 255F
|
||||
val barWidth = ceil(barRatio * 108)
|
||||
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = statsOtherBarTemplate,
|
||||
x = moduleX,
|
||||
y = moduleY,
|
||||
height = 28,
|
||||
width = 124
|
||||
)
|
||||
|
||||
val red = 1
|
||||
val green: Number = if (pokemon.friendship >= 160) 0.28 else 0.56
|
||||
val blue: Number = if (pokemon.friendship >= 160) 0.4 else 0.64
|
||||
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = CobblemonResources.WHITE,
|
||||
x = moduleX + 8,
|
||||
y = moduleY + 18,
|
||||
height = 8,
|
||||
width = barWidth,
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = friendshipOverlayResource,
|
||||
x = moduleX / SCALE,
|
||||
y = (moduleY + 16) / SCALE,
|
||||
height = 20,
|
||||
width = 248,
|
||||
scale = SCALE
|
||||
)
|
||||
|
||||
// Label
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = lang("ui.stats.friendship").bold(),
|
||||
x = moduleX + 62,
|
||||
y = moduleY + 2.5,
|
||||
centered = true,
|
||||
shadow = true
|
||||
)
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = friendship.toString().text(),
|
||||
x = moduleX + 11,
|
||||
y = moduleY + 6,
|
||||
scale = SCALE,
|
||||
centered = true
|
||||
)
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = "${floor(barRatio * 100)}%".text(),
|
||||
x = moduleX + 113,
|
||||
y = moduleY + 6,
|
||||
scale = SCALE,
|
||||
centered = true
|
||||
)
|
||||
}
|
||||
|
||||
override fun renderButton(context: DrawContext, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
|
||||
val renderChart = statTabIndex != OTHER
|
||||
@@ -403,28 +328,60 @@ class StatWidget(
|
||||
renderModifiedStatIcon(matrices, nature.decreasedStat, false)
|
||||
}
|
||||
} else {
|
||||
var drawY = y + 11
|
||||
// Friendship
|
||||
val friendshipBarWidthMax = 108
|
||||
val friendshipRatio = pokemon.friendship / 255F
|
||||
val friendshipBarWidth = ceil(friendshipRatio * friendshipBarWidthMax)
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = CobblemonResources.WHITE,
|
||||
x = x + 13,
|
||||
y = y + 27,
|
||||
height = 8,
|
||||
width = friendshipBarWidth,
|
||||
red = 0.92,
|
||||
green = if (pokemon.friendship >= 160) 0.28 else 0.7,
|
||||
blue = if (pokemon.friendship >= 160) 0.4 else 0.28
|
||||
)
|
||||
|
||||
drawFriendship(x + 5, drawY, matrices, context, pokemon.friendship)
|
||||
drawY += 30
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = friendshipOverlayResource,
|
||||
x = (x + 5) / SCALE,
|
||||
y = (y + 26) / SCALE,
|
||||
height = 20,
|
||||
width = 248,
|
||||
scale = SCALE
|
||||
)
|
||||
|
||||
for (renderableFeature in renderableFeatures) {
|
||||
val rendered = renderableFeature.render(
|
||||
drawContext = context,
|
||||
x = x + 5F,
|
||||
y = drawY.toFloat(),
|
||||
pokemon = pokemon
|
||||
)
|
||||
// Label
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = lang("ui.stats.friendship").bold(),
|
||||
x = x + 67,
|
||||
y = y + 12.5,
|
||||
centered = true,
|
||||
shadow = true
|
||||
)
|
||||
|
||||
if (rendered) {
|
||||
drawY += 30
|
||||
}
|
||||
}
|
||||
|
||||
// for (value in summaries) {
|
||||
// drawBarModule(x + 5, drawY, matrices, context, value)
|
||||
// }
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = pokemon.friendship.toString().text(),
|
||||
x = x + 16,
|
||||
y = y + 16,
|
||||
scale = SCALE,
|
||||
centered = true
|
||||
)
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = "${floor(friendshipRatio * 100)}%".text(),
|
||||
x = x + 118,
|
||||
y = y + 16,
|
||||
scale = SCALE,
|
||||
centered = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-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.client.render.block
|
||||
|
||||
import com.cobblemon.mod.common.block.entity.GildedChestBlockEntity
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BlockEntityModelRepository
|
||||
import net.minecraft.client.render.OverlayTexture
|
||||
import net.minecraft.client.render.VertexConsumerProvider
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.state.property.Properties
|
||||
import net.minecraft.util.math.RotationAxis
|
||||
|
||||
class GildedChestBlockRenderer(context: BlockEntityRendererFactory.Context) : BlockEntityRenderer<GildedChestBlockEntity> {
|
||||
override fun render(
|
||||
entity: GildedChestBlockEntity,
|
||||
tickDelta: Float,
|
||||
matrices: MatrixStack,
|
||||
vertexConsumers: VertexConsumerProvider,
|
||||
light: Int,
|
||||
overlay: Int
|
||||
) {
|
||||
val aspects = emptySet<String>()
|
||||
val state = entity.poseableState
|
||||
state.updatePartialTicks(tickDelta)
|
||||
|
||||
val poserId = entity.type.poserId
|
||||
|
||||
val model = BlockEntityModelRepository.getPoser(poserId, aspects)
|
||||
val texture = BlockEntityModelRepository.getTexture(poserId, aspects, state.animationSeconds)
|
||||
val vertexConsumer = vertexConsumers.getBuffer(model.getLayer(texture))
|
||||
model.bufferProvider = vertexConsumers
|
||||
state.currentModel = model
|
||||
|
||||
matrices.push()
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180f))
|
||||
matrices.translate(-0.5, 0.0, 0.5)
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.cachedState.get(Properties.HORIZONTAL_FACING).asRotation()))
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180f))
|
||||
|
||||
model.setupAnimStateful(
|
||||
entity = null,
|
||||
state = state,
|
||||
headYaw = 0F,
|
||||
headPitch = 0F,
|
||||
limbSwing = 0F,
|
||||
limbSwingAmount = 0F,
|
||||
ageInTicks = state.animationSeconds * 20
|
||||
)
|
||||
model.render(matrices, vertexConsumer, light, overlay, 1.0f, 1.0f, 1.0f, 1.0f)
|
||||
model.withLayerContext(vertexConsumers, state, BlockEntityModelRepository.getLayers(poserId, aspects)) {
|
||||
model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 1F, 1F, 1F, 1F)
|
||||
}
|
||||
model.setDefault()
|
||||
matrices.pop()
|
||||
|
||||
}
|
||||
}
|
||||
+21
@@ -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.client.render.entity
|
||||
|
||||
import com.cobblemon.mod.common.entity.fallingstar.FallingStarEntity
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.client.render.entity.EntityRenderer
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class FallingStarRenderer(ctx: EntityRendererFactory.Context?) : EntityRenderer<FallingStarEntity>(ctx) {
|
||||
override fun getTexture(entity: FallingStarEntity): Identifier {
|
||||
return cobblemonResource("textures/red")
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.entity
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.fabricmc.api.EnvType
|
||||
import net.fabricmc.api.Environment
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.client.render.OverlayTexture
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.VertexConsumer
|
||||
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.FishingBobberEntityRenderer
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.entity.projectile.FishingBobberEntity
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.util.Arm
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.util.math.RotationAxis
|
||||
import org.joml.Matrix3f
|
||||
import org.joml.Matrix4f
|
||||
|
||||
/*
|
||||
* Decompiled with CFR 0.2.0 (FabricMC d28b102d).
|
||||
*/
|
||||
@Environment(value = EnvType.CLIENT)
|
||||
class PokeBobberEntityRenderer(context: EntityRendererFactory.Context?) : EntityRenderer<FishingBobberEntity>(context) {
|
||||
override fun render(fishingBobberEntity: FishingBobberEntity, f: Float, g: Float, matrixStack: MatrixStack, vertexConsumerProvider: VertexConsumerProvider, i: Int) {
|
||||
var s: Double
|
||||
val r: Float
|
||||
val q: Double
|
||||
val p: Double
|
||||
val o: Double
|
||||
val playerEntity = fishingBobberEntity.playerOwner ?: return
|
||||
matrixStack.push()
|
||||
matrixStack.push()
|
||||
matrixStack.scale(0.5f, 0.5f, 0.5f)
|
||||
matrixStack.multiply(dispatcher.rotation)
|
||||
matrixStack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0f))
|
||||
val entry = matrixStack.peek()
|
||||
val matrix4f = entry.positionMatrix
|
||||
val matrix3f = entry.normalMatrix
|
||||
val vertexConsumer = vertexConsumerProvider.getBuffer(PokeBobberEntityRenderer.Companion.LAYER)
|
||||
PokeBobberEntityRenderer.Companion.vertex(vertexConsumer, matrix4f, matrix3f, i, 0.0f, 0, 0, 1)
|
||||
PokeBobberEntityRenderer.Companion.vertex(vertexConsumer, matrix4f, matrix3f, i, 1.0f, 0, 1, 1)
|
||||
PokeBobberEntityRenderer.Companion.vertex(vertexConsumer, matrix4f, matrix3f, i, 1.0f, 1, 1, 0)
|
||||
PokeBobberEntityRenderer.Companion.vertex(vertexConsumer, matrix4f, matrix3f, i, 0.0f, 1, 0, 0)
|
||||
matrixStack.pop()
|
||||
var j = if (playerEntity.mainArm == Arm.RIGHT) 1 else -1
|
||||
val itemStack = playerEntity.mainHandStack
|
||||
if (!itemStack.isOf(CobblemonItems.POKEROD)) {
|
||||
j = -j
|
||||
}
|
||||
val h = playerEntity.getHandSwingProgress(g)
|
||||
val k = MathHelper.sin(MathHelper.sqrt(h) * Math.PI.toFloat())
|
||||
val l = MathHelper.lerp(g, playerEntity.prevBodyYaw, playerEntity.bodyYaw) * (Math.PI.toFloat() / 180)
|
||||
val d = MathHelper.sin(l).toDouble()
|
||||
val e = MathHelper.cos(l).toDouble()
|
||||
val m = j.toDouble() * 0.35
|
||||
val n = 0.8
|
||||
if (dispatcher.gameOptions != null && !dispatcher.gameOptions.perspective.isFirstPerson || playerEntity !== MinecraftClient.getInstance().player) {
|
||||
o = MathHelper.lerp(g.toDouble(), playerEntity.prevX, playerEntity.x) - e * m - d * 0.8
|
||||
p = playerEntity.prevY + playerEntity.standingEyeHeight.toDouble() + (playerEntity.y - playerEntity.prevY) * g.toDouble() - 0.45
|
||||
q = MathHelper.lerp(g.toDouble(), playerEntity.prevZ, playerEntity.z) - d * m + e * 0.8
|
||||
r = if (playerEntity.isInSneakingPose) -0.1875f else 0.0f
|
||||
} else {
|
||||
s = 960.0 / dispatcher.gameOptions.fov.value.toDouble()
|
||||
var vec3d = dispatcher.camera.projection.getPosition(j.toFloat() * 0.525f, -0.1f)
|
||||
vec3d = vec3d.multiply(s)
|
||||
vec3d = vec3d.rotateY(k * 0.5f)
|
||||
vec3d = vec3d.rotateX(-k * 0.7f)
|
||||
o = MathHelper.lerp(g.toDouble(), playerEntity.prevX, playerEntity.getX()) + vec3d.x
|
||||
p = MathHelper.lerp(g.toDouble(), playerEntity.prevY, playerEntity.getY()) + vec3d.y
|
||||
q = MathHelper.lerp(g.toDouble(), playerEntity.prevZ, playerEntity.getZ()) + vec3d.z
|
||||
r = playerEntity.getStandingEyeHeight()
|
||||
}
|
||||
s = MathHelper.lerp(g.toDouble(), fishingBobberEntity.prevX, fishingBobberEntity.x)
|
||||
val t = MathHelper.lerp(g.toDouble(), fishingBobberEntity.prevY, fishingBobberEntity.y) + 0.25
|
||||
val u = MathHelper.lerp(g.toDouble(), fishingBobberEntity.prevZ, fishingBobberEntity.z)
|
||||
val v = (o - s).toFloat()
|
||||
val w = (p - t).toFloat() + r
|
||||
val x = (q - u).toFloat()
|
||||
val vertexConsumer2 = vertexConsumerProvider.getBuffer(RenderLayer.getLineStrip())
|
||||
val entry2 = matrixStack.peek()
|
||||
val y = 16
|
||||
for (z in 0..16) {
|
||||
renderFishingLine(v, w, x, vertexConsumer2, entry2, percentage(z, 16), percentage(z + 1, 16))
|
||||
}
|
||||
matrixStack.pop()
|
||||
super.render(fishingBobberEntity, f, g, matrixStack, vertexConsumerProvider, i)
|
||||
}
|
||||
|
||||
override fun getTexture(fishingBobberEntity: FishingBobberEntity): Identifier {
|
||||
return TEXTURE
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TEXTURE = cobblemonResource("textures/item/fishing/pokeball_bobber.png")
|
||||
private val LAYER = RenderLayer.getEntityCutout(TEXTURE)
|
||||
private const val field_33632 = 960.0
|
||||
|
||||
@JvmStatic
|
||||
private fun percentage(value: Int, max: Int): Float {
|
||||
return value.toFloat() / max.toFloat()
|
||||
}
|
||||
|
||||
private fun vertex(buffer: VertexConsumer, matrix: Matrix4f, normalMatrix: Matrix3f, light: Int, x: Float, y: Int, u: Int, v: Int) {
|
||||
buffer.vertex(matrix, x - 0.5f, y.toFloat() - 0.5f, 0.0f).color(255, 255, 255, 255).texture(u.toFloat(), v.toFloat()).overlay(OverlayTexture.DEFAULT_UV).light(light).normal(normalMatrix, 0.0f, 1.0f, 0.0f).next()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun renderFishingLine(x: Float, y: Float, z: Float, buffer: VertexConsumer, matrices: MatrixStack.Entry, segmentStart: Float, segmentEnd: Float) {
|
||||
val f = x * segmentStart
|
||||
val g = y * (segmentStart * segmentStart + segmentStart) * 0.5f + 0.25f
|
||||
val h = z * segmentStart
|
||||
var i = x * segmentEnd - f
|
||||
var j = y * (segmentEnd * segmentEnd + segmentEnd) * 0.5f + 0.25f - g
|
||||
var k = z * segmentEnd - h
|
||||
val l = MathHelper.sqrt(i * i + j * j + k * k)
|
||||
i /= l
|
||||
j /= l
|
||||
k /= l
|
||||
buffer.vertex(matrices.positionMatrix, f, g, h).color(0, 0, 0, 255).normal(matrices.normalMatrix, i, j, k).next()
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.item
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.item.PokerodItem
|
||||
import net.minecraft.client.item.ClampedModelPredicateProvider
|
||||
import net.minecraft.client.item.ModelPredicateProvider
|
||||
import net.minecraft.client.item.ModelPredicateProviderRegistry
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
object CobblemonModelPredicateRegistry {
|
||||
|
||||
fun registerPredicates() {
|
||||
ModelPredicateProviderRegistry.register(CobblemonItems.POKEROD, Identifier("cast"), ClampedModelPredicateProvider { stack: ItemStack, world: ClientWorld?, entity: LivingEntity?, seed: Int ->
|
||||
if (entity == null) {
|
||||
return@ClampedModelPredicateProvider 0.0f
|
||||
} else {
|
||||
val bl = entity.mainHandStack == stack
|
||||
var bl2 = entity.offHandStack == stack
|
||||
if (entity.mainHandStack.item is PokerodItem) {
|
||||
bl2 = false
|
||||
}
|
||||
|
||||
return@ClampedModelPredicateProvider if ((bl || bl2) && entity is PlayerEntity && (entity.fishHook != null)) 1.0f else 0.0f
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -753,7 +753,7 @@ abstract class PoseableEntityModel<T : Entity>(
|
||||
}
|
||||
} else if (transition != null) {
|
||||
val animation = transition(previousPose, desirablePose)
|
||||
val primaryAnimation = if (animation is PrimaryAnimation) animation else PrimaryAnimation(animation, curve = { 1F })
|
||||
val primaryAnimation = PrimaryAnimation(animation, curve = { 1F })
|
||||
state.addPrimaryAnimation(primaryAnimation)
|
||||
afterOnClient(seconds = primaryAnimation.duration) {
|
||||
state.setPose(desirablePose.poseName)
|
||||
|
||||
-44
@@ -1,44 +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.client.render.models.blockbench.blockentity
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.StatelessAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.ModelFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.ModelPart
|
||||
import net.minecraft.entity.Entity
|
||||
|
||||
class BlockEntityModel(val root: Bone) : PoseableEntityModel<Entity>() {
|
||||
val boneName: String = root.children.entries.first().key
|
||||
override val rootPart = (root as ModelPart).registerChildWithAllChildren(boneName)
|
||||
|
||||
override val isForLivingEntityRenderer = false
|
||||
var idleAnimations: Array<StatelessAnimation<Entity, out ModelFrame>> = emptyArray()
|
||||
var maxScale = 1F
|
||||
var yTranslation = 0F
|
||||
override fun registerPoses() {
|
||||
val closedPose = registerPose<ModelFrame>(poseName = "CLOSED", poseType = PoseType.NONE)
|
||||
val openPose = registerPose(
|
||||
poseType = PoseType.OPEN,
|
||||
idleAnimations = arrayOf(bedrock("gilded_chest", "open"))
|
||||
)
|
||||
|
||||
closedPose.transitions[openPose.poseName] = { _, _ ->
|
||||
bedrockStateful("gilded_chest", "opening").andThen { _, state -> state.setPose(openPose.poseName) }
|
||||
}
|
||||
|
||||
openPose.transitions[closedPose.poseName] = { _, _ ->
|
||||
bedrockStateful("gilded_chest", "closing").andThen { _, state -> state.setPose(closedPose.poseName) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getState(entity: Entity) = throw NotImplementedError("This is not supported for the gilded chest")
|
||||
}
|
||||
+1
-1
@@ -19,7 +19,7 @@ import net.minecraft.entity.Entity
|
||||
|
||||
class FossilModel(root: Bone) : PoseableEntityModel<Entity>() {
|
||||
override val isForLivingEntityRenderer = false
|
||||
//TODO: Find a better way to fetch this bone name - Update the BlockEntityModel too when you figure it out
|
||||
//TODO: Find a better way to fetch this bone name
|
||||
val boneName: String = root.children.entries.first().key
|
||||
override val rootPart = (root as ModelPart).registerChildWithAllChildren(boneName)
|
||||
// Represents a very rough middle of the model
|
||||
|
||||
-70
@@ -1,70 +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.client.render.models.blockbench.pokemon.gen9
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.ModelPart
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
class GholdengoModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("gholdengo")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
override val portraitScale = 2.6F
|
||||
override val portraitTranslation = Vec3d(-0.3, 1.4, 0.0)
|
||||
|
||||
override val profileScale = 0.65F
|
||||
override val profileTranslation = Vec3d(0.0, 0.76, 0.0)
|
||||
|
||||
lateinit var standing: PokemonPose
|
||||
lateinit var walk: PokemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("gholdengo", "blink") }
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gholdengo", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gholdengo", "ground_idle"),
|
||||
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
|
||||
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
|
||||
//bedrock("gholdengo", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PoseableEntityState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("gholdengo", "faint") else null
|
||||
}
|
||||
-97
@@ -1,97 +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.client.render.models.blockbench.pokemon.gen9
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import net.minecraft.client.model.ModelPart
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
class GimmighoulChestModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("gimmighoul_chest")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
override val portraitScale = 2.0F
|
||||
override val portraitTranslation = Vec3d(0.3, -0.7, 0.0)
|
||||
|
||||
override val profileScale = 0.65F
|
||||
override val profileTranslation = Vec3d(0.0, 0.76, 0.0)
|
||||
|
||||
lateinit var standing: PokemonPose
|
||||
lateinit var walk: PokemonPose
|
||||
lateinit var closed: PokemonPose
|
||||
lateinit var battle: PokemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("gimmighoul_chest", "blink") }
|
||||
animations["cry"] = "q.bedrock_stateful('gimmighoul_chest', 'cry')".asExpressionLike()
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.ownerUuid != null && !it.isBattling },
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gimmighoul_chest", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
closed = registerPose(
|
||||
poseName = "closed",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.ownerUuid == null && !it.isBattling },
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gimmighoul_chest", "mimic")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gimmighoul_chest", "ground_walk")
|
||||
//bedrock("gimmighoul_chest", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battle = registerPose(
|
||||
poseName = "battle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling },
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gimmighoul_chest", "battle_idle"),
|
||||
)
|
||||
)
|
||||
|
||||
closed.transitions[battle.poseName] = { _, _ ->
|
||||
bedrockStateful("gimmighoul_chest", "surprise").andThen { _, state -> state.setPose(battle.poseName) }
|
||||
}
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PoseableEntityState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("gimmighoul_chest", "faint") else null
|
||||
}
|
||||
-70
@@ -1,70 +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.client.render.models.blockbench.pokemon.gen9
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.ModelPart
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
class GimmighoulRoamingModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("gimmighoul_roaming")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
override val portraitScale = 2.5F
|
||||
override val portraitTranslation = Vec3d(0.0, -1.3, 0.0)
|
||||
|
||||
override val profileScale = 0.7F
|
||||
override val profileTranslation = Vec3d(0.0, 0.76, 0.0)
|
||||
|
||||
lateinit var standing: PokemonPose
|
||||
lateinit var walk: PokemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("gimmighoul_roaming", "blink") }
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gimmighoul_roaming", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
idleAnimations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("gimmighoul_roaming", "ground_idle"),
|
||||
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
|
||||
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
|
||||
//bedrock("gimmighoul_roaming", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PoseableEntityState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("gimmighoul_roaming", "faint") else null
|
||||
}
|
||||
-63
@@ -1,63 +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.client.render.models.blockbench.repository
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.JsonPokemonPoseableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.fromJson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.entity.Entity
|
||||
|
||||
/**
|
||||
* This is specifically for BlockEntities where we want to do more complex animation than what Java Edition already allows
|
||||
* Basically with Java Edition, we can only change the texture applied to a model, if we want to move bones around, need to
|
||||
* do something else, so we use this
|
||||
*/
|
||||
object BlockEntityModelRepository : VaryingModelRepository<Entity, BlockEntityModel>() {
|
||||
override val title = "Block Entity"
|
||||
override val type = "block_entities"
|
||||
override val variationDirectories: List<String> = listOf("bedrock/$type/variations", "bedrock/$type")
|
||||
override val poserDirectories: List<String> = listOf("bedrock/$type/posers")
|
||||
override val modelDirectories: List<String> = listOf("bedrock/$type/models")
|
||||
override val animationDirectories: List<String> = listOf("bedrock/$type/animations")
|
||||
override val fallback = cobblemonResource("substitute")
|
||||
override val isForLivingEntityRenderer = false
|
||||
|
||||
private val gson = GsonBuilder().create()
|
||||
override fun loadJsonPoser(json: String): (Bone) -> BlockEntityModel {
|
||||
val jsonObject = gson.fromJson<JsonObject>(json)
|
||||
val animations = jsonObject.getAsJsonArray("animations")
|
||||
val maxScale = jsonObject.get("maxScale")?.asFloat ?: 1F
|
||||
val yTranslation = jsonObject.get("yTranslation")?.asFloat ?: 0F
|
||||
return { bone ->
|
||||
val model = BlockEntityModel(bone)
|
||||
model.maxScale = maxScale
|
||||
model.yTranslation = yTranslation
|
||||
// I stole all this from FossilModelRepository, so I guess I'll leave the comments here
|
||||
//
|
||||
// Refactor this bullshit to not mention pokemon at all, it should be common to anything using animation factories.
|
||||
// Even better: move to molang functions, this is ass
|
||||
model.idleAnimations = animations.mapNotNull {
|
||||
val animString = it.asString
|
||||
val anim = animString.substringBefore("(")
|
||||
if (JsonPokemonPoseableModel.ANIMATION_FACTORIES.contains(anim)) {
|
||||
return@mapNotNull JsonPokemonPoseableModel.ANIMATION_FACTORIES[anim]!!.stateless(model, animString)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.toTypedArray()
|
||||
model
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerInBuiltPosers() {}
|
||||
}
|
||||
-3
@@ -588,9 +588,6 @@ object PokemonModelRepository : VaryingModelRepository<PokemonEntity, PokemonPos
|
||||
inbuilt("litwick", ::LitwickModel)
|
||||
inbuilt("lampent", ::LampentModel)
|
||||
inbuilt("chandelure", ::ChandelureModel)
|
||||
inbuilt("gimmighoulroaming", ::GimmighoulRoamingModel)
|
||||
inbuilt("gimmighoulchest", ::GimmighoulChestModel)
|
||||
inbuilt("gholdengo", ::GholdengoModel)
|
||||
inbuilt("drifloon", ::DrifloonModel)
|
||||
inbuilt("drifblim", ::DrifblimModel)
|
||||
}
|
||||
|
||||
+19
-8
@@ -16,25 +16,35 @@ import com.cobblemon.mod.common.client.entity.PokemonClientDelegate.Companion.BE
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate.Companion.BEAM_SHRINK_TIME
|
||||
import com.cobblemon.mod.common.client.keybind.boundKey
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding
|
||||
import com.cobblemon.mod.common.client.render.addVertex
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
|
||||
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.models.blockbench.wavefunction.parabolaFunction
|
||||
import com.cobblemon.mod.common.client.render.pokeball.PokeBallPoseableState
|
||||
import com.cobblemon.mod.common.client.render.renderBeaconBeam
|
||||
import com.cobblemon.mod.common.client.settings.ServerSettings
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity.Companion.SPAWN_DIRECTION
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.util.isLookingAt
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.math.DoubleRange
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.util.math.remap
|
||||
import kotlin.math.*
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.client.font.TextRenderer
|
||||
import net.minecraft.client.gl.GlUniform
|
||||
import net.minecraft.client.gl.ShaderProgram
|
||||
import net.minecraft.client.gl.Uniform
|
||||
import net.minecraft.client.render.GameRenderer
|
||||
import net.minecraft.client.render.LightmapTextureManager
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.RenderPhase
|
||||
import net.minecraft.client.render.VertexConsumerProvider
|
||||
import net.minecraft.client.network.ClientPlayerEntity
|
||||
import net.minecraft.client.render.*
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory
|
||||
import net.minecraft.client.render.entity.MobEntityRenderer
|
||||
@@ -42,6 +52,7 @@ import net.minecraft.client.render.entity.model.EntityModel
|
||||
import net.minecraft.client.render.item.ItemRenderer
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
@@ -53,6 +64,12 @@ import org.joml.Math
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
import org.joml.Vector4f
|
||||
import kotlin.math.*
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.tan
|
||||
|
||||
class PokemonRenderer(
|
||||
context: EntityRendererFactory.Context
|
||||
@@ -111,12 +128,6 @@ class PokemonRenderer(
|
||||
// progressUniform?.set((sin(entity.ticksLived/20f) + 1f)/2f)
|
||||
// }
|
||||
// }
|
||||
|
||||
if (entity.ticksLived < 10) {
|
||||
entity.bodyYaw = entity.dataTracker.get(SPAWN_DIRECTION)
|
||||
entity.prevBodyYaw = entity.bodyYaw
|
||||
}
|
||||
|
||||
super.render(entity, entityYaw, partialTicks, poseMatrix, buffer, packedLight)
|
||||
|
||||
modelNow.green = 1F
|
||||
|
||||
@@ -26,15 +26,13 @@ class ClientParty(uuid: UUID, slots: Int) : ClientStorage<PartyPosition>(uuid),
|
||||
|
||||
fun get(slot: Int) = get(PartyPosition(slot))
|
||||
override fun get(position: PartyPosition): Pokemon? {
|
||||
if (position.slot >= slots.size || position.slot == -1) {
|
||||
if (position.slot >= slots.size) {
|
||||
return null
|
||||
}
|
||||
|
||||
return slots[position.slot]
|
||||
}
|
||||
|
||||
fun isEmpty() = (slots.size == 0)
|
||||
|
||||
fun getPosition(pokemonID: UUID) = slots.indexOfFirst { it?.uuid == pokemonID }
|
||||
override fun getPosition(pokemon: Pokemon): PartyPosition? {
|
||||
for (slotNumber in slots.indices) {
|
||||
|
||||
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.command
|
||||
import com.cobblemon.mod.common.api.permission.CobblemonPermissions
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.command.argument.PokemonPropertiesArgumentType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.alias
|
||||
import com.cobblemon.mod.common.util.commandLang
|
||||
import com.cobblemon.mod.common.util.permission
|
||||
@@ -72,7 +71,6 @@ object SpawnPokemon {
|
||||
}
|
||||
val pokemonEntity = properties.createEntity(world)
|
||||
pokemonEntity.refreshPositionAndAngles(pos.x, pos.y, pos.z, pokemonEntity.yaw, pokemonEntity.pitch)
|
||||
pokemonEntity.dataTracker.set(PokemonEntity.SPAWN_DIRECTION, pokemonEntity.random.nextFloat() * 360F)
|
||||
if (world.spawnEntity(pokemonEntity)) {
|
||||
return Command.SINGLE_SUCCESS
|
||||
}
|
||||
|
||||
@@ -13,21 +13,21 @@ import com.cobblemon.mod.common.CobblemonEntities
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.taskBuilder
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.battles.BattleFormat
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.battles.BattleSide
|
||||
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
||||
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.entity.fallingstar.FallingStarEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
|
||||
import com.cobblemon.mod.common.particle.SnowstormParticleReader
|
||||
import com.cobblemon.mod.common.trade.ActiveTrade
|
||||
import com.cobblemon.mod.common.trade.DummyTradeParticipant
|
||||
import com.cobblemon.mod.common.trade.PlayerTradeParticipant
|
||||
import com.cobblemon.mod.common.util.fromJson
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.toPokemon
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.brigadier.Command
|
||||
@@ -57,6 +57,9 @@ object TestCommand {
|
||||
return Command.SINGLE_SUCCESS
|
||||
}
|
||||
|
||||
val player = context.source.player as ServerPlayerEntity
|
||||
player.sendMessageToClient("There are ".text().append(player.world.getChunk(player.pos.toBlockPos()).getDyniteOre().toString().text().append(" blocks of Dynite Ore in this chunk".text())), false)
|
||||
|
||||
try {
|
||||
// readBerryDataFromCSV()
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ enum class PoseType {
|
||||
PROFILE,
|
||||
/** A pose for rendering in the party overlay and in minor spaces like the battle tiles. */
|
||||
PORTRAIT,
|
||||
/** For guilded chest */
|
||||
OPEN,
|
||||
/** A simple type for non-living entities or errant cases. */
|
||||
NONE;
|
||||
|
||||
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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.fallingstar
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonEntities
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.fallingstar.FallingStarSpawnCause
|
||||
import com.cobblemon.mod.common.loot.CobblemonLootTables
|
||||
import com.cobblemon.mod.common.util.math.DoubleRange
|
||||
import com.cobblemon.mod.common.util.nextBetween
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.ItemEntity
|
||||
import net.minecraft.entity.MovementType
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.loot.context.LootContextParameterSet
|
||||
import net.minecraft.loot.context.LootContextParameters
|
||||
import net.minecraft.loot.context.LootContextTypes
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.sound.SoundEvents
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.explosion.Explosion
|
||||
import java.time.Instant
|
||||
import kotlin.random.Random
|
||||
|
||||
class FallingStarEntity(world: World) : Entity(CobblemonEntities.FALLING_STAR_ENTITY, world) {
|
||||
private var particleOne = Identifier("cobblemon:null")
|
||||
private var particleTwo = Identifier("cobblemon:null")
|
||||
private var particleThree = Identifier("cobblemon:null")
|
||||
private var particleAmbient = Identifier("cobblemon:null")
|
||||
private var particleImpact = Identifier("cobblemon:null")
|
||||
private var particleTimer: Instant = Instant.now().plusMillis(50)
|
||||
private var particleAmbientTimer: Instant = Instant.now().plusMillis(1000)
|
||||
|
||||
private var hasFallen = false
|
||||
|
||||
override fun initDataTracker() {
|
||||
}
|
||||
|
||||
override fun readCustomDataFromNbt(nbt: NbtCompound?) {
|
||||
}
|
||||
|
||||
override fun writeCustomDataToNbt(nbt: NbtCompound?) {
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
particleOne = Identifier("cobblemon:meteor_glitter")
|
||||
particleTwo = Identifier("cobblemon:meteor_trail")
|
||||
particleThree = Identifier("cobblemon:meteor_falling")
|
||||
|
||||
if (velocity.y == 0.0) {
|
||||
velocity = Vec3d(Random.nextBetween(VELOCITY_RANGE.start, VELOCITY_RANGE.endInclusive), -1.0, Random.nextBetween(VELOCITY_RANGE.start, VELOCITY_RANGE.endInclusive))
|
||||
particleOne = Identifier("cobblemon:null")
|
||||
particleTwo = Identifier("cobblemon:null")
|
||||
particleThree = Identifier("cobblemon:null")
|
||||
|
||||
if (Instant.now().isAfter(particleAmbientTimer)) {
|
||||
particleAmbient = Identifier("cobblemon:meteor_ambient")
|
||||
particleHandler(particleAmbient, this.pos)
|
||||
particleAmbientTimer = Instant.now().plusMillis(1000)
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.getBlockState(blockPos.down()).isAir) {
|
||||
velocity = Vec3d(0.0, -1.0, 0.0)
|
||||
if (!world.isClient && !hasFallen) {
|
||||
particleImpact = Identifier("cobblemon:meteor_impact")
|
||||
particleHandler(particleImpact, this.pos)
|
||||
(world as ServerWorld).createExplosion(
|
||||
this,
|
||||
x, y, z, // the position of the explosion
|
||||
0.0f, // the power of the explosion
|
||||
World.ExplosionSourceType.MOB
|
||||
)
|
||||
hasFallen = true
|
||||
}
|
||||
}
|
||||
|
||||
move(MovementType.SELF, velocity)
|
||||
|
||||
val player = closestPlayer
|
||||
if (player != null) {
|
||||
reveal(player)
|
||||
kill()
|
||||
}
|
||||
|
||||
if(Instant.now().isAfter(particleTimer)) {
|
||||
particleHandler(particleTwo, this.pos)
|
||||
particleHandler(particleThree, this.pos)
|
||||
particleTimer = Instant.now().plusMillis(50)
|
||||
}
|
||||
|
||||
particleHandler(particleOne, this.pos)
|
||||
|
||||
super.tick()
|
||||
}
|
||||
|
||||
private fun reveal(playerEntity: PlayerEntity) {
|
||||
world.playSound(null, blockPos, SoundEvents.ENTITY_PLAYER_LEVELUP, SoundCategory.AMBIENT)
|
||||
|
||||
val random = random.nextBetween(0, 100)
|
||||
|
||||
if (random <= 50) {
|
||||
spawnPokemon(playerEntity)
|
||||
} else {
|
||||
spawnItem()
|
||||
}
|
||||
}
|
||||
|
||||
private fun spawnItem() {
|
||||
if (world.isClient) return
|
||||
val lootTable = world.server?.lootManager?.getLootTable(CobblemonLootTables.FALLING_STAR) ?: return
|
||||
val stacks = lootTable.generateLoot(LootContextParameterSet.Builder(world as ServerWorld)
|
||||
.add(LootContextParameters.THIS_ENTITY, this)
|
||||
.build(LootContextTypes.BARTER))
|
||||
stacks.forEach { world.spawnEntity(ItemEntity(world, pos.x, pos.y, pos.z, it)) }
|
||||
particleOne = Identifier("cobblemon:masterball/ballsparkle")
|
||||
particleHandler(particleOne, this.pos)
|
||||
}
|
||||
|
||||
private fun spawnPokemon(playerEntity: PlayerEntity) {
|
||||
if (world.isClient) return
|
||||
val spawner = BestSpawner.starSpawner
|
||||
|
||||
val spawnCause = FallingStarSpawnCause(
|
||||
spawner = spawner,
|
||||
bucket = Cobblemon.bestSpawner.config.buckets[0],
|
||||
entity = playerEntity
|
||||
)
|
||||
particleOne = Identifier("cobblemon:confetti")
|
||||
particleHandler(particleOne, this.pos)
|
||||
|
||||
val result = spawner.run(spawnCause, world as ServerWorld, blockPos) ?: return
|
||||
}
|
||||
|
||||
private fun particleHandler(id: Identifier, pos: Vec3d) {
|
||||
val spawnSnowstormParticlePacket = SpawnSnowstormParticlePacket(id, pos)
|
||||
spawnSnowstormParticlePacket.sendToPlayersAround(pos.x, pos.y, pos.z, 128.0, world.registryKey)
|
||||
}
|
||||
|
||||
override fun shouldRender(distance: Double): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private val closestPlayer: PlayerEntity?
|
||||
get() = world.players.firstOrNull { it.pos.distanceTo(pos) < 6.0 }
|
||||
|
||||
companion object {
|
||||
val VELOCITY_RANGE = DoubleRange(-0.25, 0.25)
|
||||
}
|
||||
}
|
||||
+647
@@ -0,0 +1,647 @@
|
||||
/*
|
||||
* 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.fishing
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonEntities
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.spawning.*
|
||||
import com.cobblemon.mod.common.api.spawning.context.AreaContextResolver
|
||||
import com.cobblemon.mod.common.api.spawning.detail.EntitySpawnResult
|
||||
import com.cobblemon.mod.common.api.spawning.detail.PokemonSpawnAction
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SingleEntitySpawnAction
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.influence.PlayerLevelRangeInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.rules.SpawnRule
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.SpawningArea
|
||||
import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.battles.BattleBuilder
|
||||
import com.cobblemon.mod.common.command.SpawnPokemonFromPool
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.commandLang
|
||||
import com.cobblemon.mod.common.util.isServerSide
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.toBlockPos
|
||||
import com.mongodb.internal.connection.Server
|
||||
import net.minecraft.advancement.criterion.Criteria
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.enchantment.Enchantment
|
||||
import net.minecraft.enchantment.Enchantments
|
||||
import net.minecraft.entity.*
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.entity.projectile.FishingBobberEntity
|
||||
import net.minecraft.entity.projectile.ProjectileUtil
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.loot.LootTables
|
||||
import net.minecraft.loot.context.LootContextParameterSet
|
||||
import net.minecraft.loot.context.LootContextParameters
|
||||
import net.minecraft.loot.context.LootContextTypes
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.nbt.NbtList
|
||||
import net.minecraft.nbt.NbtType
|
||||
import net.minecraft.particle.ParticleTypes
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.tag.FluidTags
|
||||
import net.minecraft.registry.tag.ItemTags
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.sound.SoundEvents
|
||||
import net.minecraft.stat.Stats
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.util.math.random.Random
|
||||
import kotlin.random.*
|
||||
import net.minecraft.world.World
|
||||
import java.util.*
|
||||
|
||||
class PokeRodFishingBobberEntity(type: EntityType<out PokeRodFishingBobberEntity>, world: World) : FishingBobberEntity(type, world) {
|
||||
|
||||
private val velocityRandom = Random.create()
|
||||
private val caughtFish = false
|
||||
private var outOfOpenWaterTicks = 0
|
||||
private val field_30665 = 10
|
||||
|
||||
// todo is this needed?
|
||||
//val HOOK_ENTITY_ID = DataTracker.registerData(PokeRodFishingBobberEntity::class.java, TrackedDataHandlerRegistry.INTEGER)
|
||||
//private val CAUGHT_FISH = DataTracker.registerData(PokeRodFishingBobberEntity::class.java, TrackedDataHandlerRegistry.BOOLEAN)
|
||||
|
||||
// todo if so replace these later
|
||||
var HOOK_ENTITY_ID = 0
|
||||
var CAUGHT_FISH = false
|
||||
|
||||
private var removalTimer = 0
|
||||
private var hookCountdown = 0
|
||||
private var waitCountdown = 0
|
||||
private var fishTravelCountdown = 0
|
||||
private var fishAngle = 0f
|
||||
private var inOpenWater = true
|
||||
private var hookedEntity: Entity? = null
|
||||
private var state = State.FLYING
|
||||
private var luckOfTheSeaLevel = 0
|
||||
private var lureLevel = 0
|
||||
private var typeCaught= "ITEM"
|
||||
private var chosenBucket = Cobblemon.bestSpawner.config.buckets[0] // default to first rarity bucket
|
||||
private var rarityCaught = "COMMON"
|
||||
private val pokemonSpawnChance = 70 // chance a Pokemon will be fished up % out of 100
|
||||
|
||||
constructor(thrower: PlayerEntity, world: World, luckOfTheSea: Int, lure: Int) : this(CobblemonEntities.POKE_BOBBER, world) {
|
||||
// Copy pasta a LOT
|
||||
//this(CobblemonEntities.POKE_BOBBER, world, luckOfTheSeaLevel, lureLevel)
|
||||
owner = thrower
|
||||
luckOfTheSeaLevel = luckOfTheSea
|
||||
lureLevel = lure
|
||||
|
||||
val f = thrower.pitch
|
||||
val g = thrower.yaw
|
||||
val h = MathHelper.cos(-g * 0.017453292f - 3.1415927f)
|
||||
val i = MathHelper.sin(-g * 0.017453292f - 3.1415927f)
|
||||
val j = -MathHelper.cos(-f * 0.017453292f)
|
||||
val k = MathHelper.sin(-f * 0.017453292f)
|
||||
val d = thrower.x - i.toDouble() * 0.3
|
||||
val e = thrower.eyeY
|
||||
val l = thrower.z - h.toDouble() * 0.3
|
||||
this.refreshPositionAndAngles(d, e, l, g, f)
|
||||
var vec3d = Vec3d((-i).toDouble(), MathHelper.clamp(-(k / j), -5.0f, 5.0f).toDouble(), (-h).toDouble())
|
||||
val m = vec3d.length()
|
||||
vec3d = vec3d.multiply(0.6 / m + random.nextTriangular(0.5, 0.0103365), 0.6 / m + random.nextTriangular(0.5, 0.0103365), 0.6 / m + random.nextTriangular(0.5, 0.0103365))
|
||||
velocity = vec3d
|
||||
yaw = (MathHelper.atan2(vec3d.x, vec3d.z) * 57.2957763671875).toFloat()
|
||||
pitch = (MathHelper.atan2(vec3d.y, vec3d.horizontalLength()) * 57.2957763671875).toFloat()
|
||||
prevYaw = yaw
|
||||
prevPitch = pitch
|
||||
}
|
||||
|
||||
fun calculateMinMaxCountdown(weight: Float): Pair<Int, Int> {
|
||||
// Constants for the target min and max values at weight extremes
|
||||
val minAtMaxWeight = 20
|
||||
val maxAtMaxWeight = 40
|
||||
val minAtMinWeight = 15
|
||||
val maxAtMinWeight = 20
|
||||
|
||||
// Calculate factors for min and max based on the weight
|
||||
val minFactor = ((minAtMaxWeight - minAtMinWeight) / 100f) * weight + minAtMinWeight
|
||||
val maxFactor = ((maxAtMaxWeight - maxAtMinWeight) / 100f) * weight + maxAtMinWeight
|
||||
|
||||
// Ensure min and max are within the needed bounds
|
||||
val min = minFactor.toInt().coerceIn(minAtMinWeight, minAtMaxWeight)
|
||||
val max = maxFactor.toInt().coerceIn(maxAtMinWeight, maxAtMaxWeight)
|
||||
|
||||
return Pair(min, max)
|
||||
}
|
||||
|
||||
fun chooseAdjustedSpawnBucket(buckets: List<SpawnBucket>, luckOfTheSeaLevel: Int): SpawnBucket {
|
||||
val baseIncreases = listOf(5.0F, 1.0F, 0.2F) // Base increases for the first three buckets beyond the first
|
||||
val adjustedWeights = buckets.mapIndexed { index, bucket ->
|
||||
if (index == 0) {
|
||||
// Placeholder, will be recalculated
|
||||
0.0F
|
||||
} else {
|
||||
val increase = if (index < baseIncreases.size) baseIncreases[index] else baseIncreases.last() + (index - baseIncreases.size + 1) * 0.15F
|
||||
bucket.weight + increase * luckOfTheSeaLevel
|
||||
}
|
||||
}.toMutableList()
|
||||
|
||||
// Recalculate the first bucket's weight to ensure the total is 100%
|
||||
val totalAdjustedWeight = adjustedWeights.sum() - adjustedWeights[0] // Corrected to ensure the list contains Floats
|
||||
adjustedWeights[0] = 100.0F - totalAdjustedWeight + buckets[0].weight
|
||||
|
||||
// Random selection based on adjusted weights
|
||||
val weightSum = adjustedWeights.sum()
|
||||
val chosenSum = kotlin.random.Random.nextDouble(weightSum.toDouble()).toFloat() // Ensure usage of Random from kotlin.random package
|
||||
var sum = 0.0F
|
||||
adjustedWeights.forEachIndexed { index, weight ->
|
||||
sum += weight
|
||||
if (sum >= chosenSum) {
|
||||
return buckets[index]
|
||||
}
|
||||
}
|
||||
|
||||
return buckets.first() // Fallback
|
||||
}
|
||||
|
||||
/*// make more generic version for other enchants. Pass in id of enchant
|
||||
fun getEnchantLevel(enchantment: Enchantment): Int {
|
||||
var pokerodEnchantments: NbtList? = null
|
||||
if (owner?.isPlayer == true) {
|
||||
pokerodEnchantments = (owner as PlayerEntity).mainHandStack?.enchantments
|
||||
}
|
||||
|
||||
val luckOfTheSeaEnchantment = pokerodEnchantments?.filter {
|
||||
if (it is NbtCompound)
|
||||
if (it.getString("id") == Registries.ENCHANTMENT.getEntry(enchantment).key.toString())
|
||||
return@filter true
|
||||
return@filter false
|
||||
}?.first()
|
||||
|
||||
return (luckOfTheSeaEnchantment as? NbtCompound)?.getShort("lvl")?.toInt() ?: 0
|
||||
}*/
|
||||
|
||||
fun isOpenOrWaterAround(pos: BlockPos): Boolean {
|
||||
var positionType = PositionType.INVALID
|
||||
for (i in -1..2) {
|
||||
val positionType2 = this.getPositionType(pos.add(-2, i, -2), pos.add(2, i, 2))
|
||||
when (positionType2) {
|
||||
PositionType.INVALID -> return false
|
||||
PositionType.ABOVE_WATER -> if (positionType == PositionType.INVALID) {
|
||||
return false
|
||||
}
|
||||
|
||||
PositionType.INSIDE_WATER -> if (positionType == PositionType.ABOVE_WATER) {
|
||||
return false
|
||||
}
|
||||
|
||||
else -> return false
|
||||
}
|
||||
positionType = positionType2
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*private fun getPositionType(start: BlockPos, end: BlockPos): PokeRodFishingBobberEntity.PositionType? {
|
||||
return BlockPos.stream(start, end).map { pos: BlockPos? -> this.getPositionType(pos!!) }.reduce { positionType: PokeRodFishingBobberEntity.PositionType, positionType2: PokeRodFishingBobberEntity.PositionType -> if (positionType == positionType2) positionType else PokeRodFishingBobberEntity.PositionType.INVALID } as ((PositionType?, PositionType?) -> PositionType?)?.orElse(PokeRodFishingBobberEntity.PositionType.INVALID) as PokeRodFishingBobberEntity.PositionType
|
||||
}*/
|
||||
|
||||
private fun getPositionType(start: BlockPos, end: BlockPos): PositionType? {
|
||||
return BlockPos.stream(start, end)
|
||||
.map { pos -> this.getPositionType(pos) }
|
||||
.reduce { positionType, positionType2 ->
|
||||
if (positionType == positionType2) positionType else PositionType.INVALID
|
||||
}.orElse(PositionType.INVALID)
|
||||
}
|
||||
|
||||
private fun getPositionType(pos: BlockPos): PositionType {
|
||||
val blockState = world.getBlockState(pos)
|
||||
return if (!blockState.isAir && !blockState.isOf(Blocks.LILY_PAD)) {
|
||||
val fluidState = blockState.fluidState
|
||||
if (fluidState.isIn(FluidTags.WATER) && fluidState.isStill && blockState.getCollisionShape(world, pos).isEmpty) PositionType.INSIDE_WATER else PositionType.INVALID
|
||||
} else {
|
||||
PositionType.ABOVE_WATER
|
||||
}
|
||||
}
|
||||
|
||||
enum class PositionType {
|
||||
ABOVE_WATER,
|
||||
INSIDE_WATER,
|
||||
INVALID
|
||||
}
|
||||
|
||||
private fun setPlayerFishHook(fishingBobber: FishingBobberEntity?) {
|
||||
val playerEntity = this.playerOwner
|
||||
if (playerEntity != null) {
|
||||
playerEntity.fishHook = fishingBobber
|
||||
}
|
||||
}
|
||||
|
||||
internal enum class State {
|
||||
FLYING,
|
||||
HOOKED_IN_ENTITY,
|
||||
BOBBING
|
||||
}
|
||||
|
||||
// todo custom behavior for fishing logic
|
||||
private fun tickFishingLogic(pos: BlockPos) {
|
||||
val serverWorld = world as ServerWorld
|
||||
var i = 1
|
||||
val blockPos = pos.up()
|
||||
if (random.nextFloat() < 0.25f && world.hasRain(blockPos)) {
|
||||
++i
|
||||
}
|
||||
if (random.nextFloat() < 0.5f && !world.isSkyVisible(blockPos)) {
|
||||
--i
|
||||
}
|
||||
if (this.hookCountdown > 0) {
|
||||
--this.hookCountdown
|
||||
if (this.hookCountdown <= 0) {
|
||||
this.waitCountdown = 0
|
||||
this.fishTravelCountdown = 0
|
||||
this.CAUGHT_FISH = false
|
||||
//getDataTracker().set(CAUGHT_FISH, false)
|
||||
}
|
||||
} else if (this.fishTravelCountdown > 0) {
|
||||
this.fishTravelCountdown -= i
|
||||
if (this.fishTravelCountdown > 0) {
|
||||
var j: Double
|
||||
var e: Double
|
||||
this.fishAngle += random.nextTriangular(0.0, 9.188).toFloat()
|
||||
val f = this.fishAngle * (Math.PI.toFloat() / 180)
|
||||
val g = MathHelper.sin(f)
|
||||
val h = MathHelper.cos(f)
|
||||
val d = this.x + (g * this.fishTravelCountdown.toFloat() * 0.1f).toDouble()
|
||||
val blockState = serverWorld.getBlockState(BlockPos.ofFloored(d, (MathHelper.floor(this.y).toFloat() + 1.0f).toDouble().also { e = it } - 1.0, this.z + (h * this.fishTravelCountdown.toFloat() * 0.1f).toDouble().also { j = it }))
|
||||
if (blockState.isOf(Blocks.WATER)) {
|
||||
if (random.nextFloat() < 0.15f) {
|
||||
serverWorld.spawnParticles(ParticleTypes.BUBBLE, d, e - 0.1, j, 1, g.toDouble(), 0.1, h.toDouble(), 0.0)
|
||||
}
|
||||
val k = g * 0.04f
|
||||
val l = h * 0.04f
|
||||
serverWorld.spawnParticles(ParticleTypes.FISHING, d, e, j, 0, l.toDouble(), 0.01, -k.toDouble(), 1.0)
|
||||
serverWorld.spawnParticles(ParticleTypes.FISHING, d, e, j, 0, -l.toDouble(), 0.01, k.toDouble(), 1.0)
|
||||
}
|
||||
} else {
|
||||
playSound(SoundEvents.ENTITY_FISHING_BOBBER_SPLASH, 0.25f, 1.0f + (random.nextFloat() - random.nextFloat()) * 0.4f)
|
||||
val m = this.y + 0.5
|
||||
serverWorld.spawnParticles(ParticleTypes.BUBBLE, this.x, m, this.z, (1.0f + this.width * 20.0f).toInt(), this.width.toDouble(), 0.0, this.width.toDouble(), 0.2)
|
||||
serverWorld.spawnParticles(ParticleTypes.FISHING, this.x, m, this.z, (1.0f + this.width * 20.0f).toInt(), this.width.toDouble(), 0.0, this.width.toDouble(), 0.2)
|
||||
|
||||
// TODO find a way to make luck of the sea environment increase odds of getting better rarity rates
|
||||
if (MathHelper.nextInt(random, 0, 100) < this.pokemonSpawnChance) {
|
||||
// todo do another chance check for rarity and then set typeCaught
|
||||
this.typeCaught = "POKEMON"
|
||||
|
||||
val buckets = Cobblemon.bestSpawner.config.buckets
|
||||
|
||||
// choose a spawn bucket according to weights no matter how many there are
|
||||
chosenBucket = chooseAdjustedSpawnBucket(buckets, luckOfTheSeaLevel)
|
||||
val reactionMinMax = calculateMinMaxCountdown(chosenBucket.weight)
|
||||
|
||||
// set the hook reaction time to be based off the rarity of the bucket chosen
|
||||
this.hookCountdown = MathHelper.nextInt(random, reactionMinMax.first, reactionMinMax.second)
|
||||
|
||||
System.out.println("Player hooked a Pokemon from the bucket: " + chosenBucket.name);
|
||||
|
||||
/*if (MathHelper.nextDouble(random, 0.0, 100.0) < this.commonSpawnChance) {
|
||||
// todo set common spawn
|
||||
this.hookCountdown = MathHelper.nextInt(random, 20, 40)
|
||||
this.rarityCaught = "COMMON"
|
||||
System.out.println("Player hooked a Common Pokemon");
|
||||
}
|
||||
else {
|
||||
if (MathHelper.nextDouble(random, 0.0, 100.0 - this.commonSpawnChance) < this.uncommonSpawnChance) {
|
||||
// todo set uncommon spawn
|
||||
this.hookCountdown = MathHelper.nextInt(random, 20, 35)
|
||||
this.rarityCaught = "UNCOMMON"
|
||||
System.out.println("Player hooked a Uncommon Pokemon");
|
||||
}
|
||||
else {
|
||||
if (MathHelper.nextDouble(random, 0.0, 100.0 - this.commonSpawnChance - this.uncommonSpawnChance) < this.rareSpawnChance) {
|
||||
// todo set rare spawn
|
||||
this.hookCountdown = MathHelper.nextInt(random, 20, 30)
|
||||
this.rarityCaught = "RARE"
|
||||
System.out.println("Player hooked a Rare Pokemon");
|
||||
}
|
||||
else {
|
||||
// todo set ultra-rare spawn chance
|
||||
this.hookCountdown = MathHelper.nextInt(random, 20, 25)
|
||||
this.rarityCaught = "ULTRA-RARE"
|
||||
System.out.println("Player hooked an Ultra-Rare Pokemon");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else {
|
||||
// todo caught item
|
||||
this.typeCaught = "ITEM"
|
||||
this.hookCountdown = MathHelper.nextInt(random, 20, 40)
|
||||
|
||||
}
|
||||
|
||||
//this.hookCountdown = MathHelper.nextInt(random, 20, 40)
|
||||
//getDataTracker().set(CAUGHT_FISH, true)
|
||||
this.CAUGHT_FISH = true
|
||||
}
|
||||
} else if (this.waitCountdown > 0) {
|
||||
this.waitCountdown -= i
|
||||
var f = 0.15f
|
||||
if (this.waitCountdown < 20) {
|
||||
f += (20 - this.waitCountdown).toFloat() * 0.05f
|
||||
} else if (this.waitCountdown < 40) {
|
||||
f += (40 - this.waitCountdown).toFloat() * 0.02f
|
||||
} else if (this.waitCountdown < 60) {
|
||||
f += (60 - this.waitCountdown).toFloat() * 0.01f
|
||||
}
|
||||
if (random.nextFloat() < f) {
|
||||
var j: Double
|
||||
var e: Double
|
||||
val g = MathHelper.nextFloat(random, 0.0f, 360.0f) * (Math.PI.toFloat() / 180)
|
||||
val h = MathHelper.nextFloat(random, 25.0f, 60.0f)
|
||||
val d = this.x + (MathHelper.sin(g) * h).toDouble() * 0.1
|
||||
val blockState = serverWorld.getBlockState(BlockPos.ofFloored(d, (MathHelper.floor(this.y).toFloat() + 1.0f).toDouble().also { e = it } - 1.0, this.z + (MathHelper.cos(g) * h).toDouble() * 0.1.also { j = it }))
|
||||
if (blockState.isOf(Blocks.WATER)) {
|
||||
serverWorld.spawnParticles(ParticleTypes.SPLASH, d, e, j, 2 + random.nextInt(2), 0.1, 0.0, 0.1, 0.0)
|
||||
}
|
||||
}
|
||||
if (this.waitCountdown <= 0) {
|
||||
this.fishAngle = MathHelper.nextFloat(random, 0.0f, 360.0f)
|
||||
this.fishTravelCountdown = MathHelper.nextInt(random, 20, 80)
|
||||
}
|
||||
} else {
|
||||
this.waitCountdown = MathHelper.nextInt(random, 100, 600)
|
||||
this.waitCountdown -= this.lureLevel * 20 * 5
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeIfInvalid(player: PlayerEntity): Boolean {
|
||||
val itemStack = player.mainHandStack
|
||||
val itemStack2 = player.offHandStack
|
||||
val bl = itemStack.isOf(CobblemonItems.POKEROD)
|
||||
val bl2 = itemStack2.isOf(CobblemonItems.POKEROD)
|
||||
if (player.isRemoved || !player.isAlive || !bl && !bl2 || this.squaredDistanceTo(player) > 1024.0) {
|
||||
discard()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun checkForCollision() {
|
||||
val hitResult = ProjectileUtil.getCollision(this) { entity: Entity? -> this.canHit(entity) }
|
||||
onCollision(hitResult)
|
||||
}
|
||||
|
||||
private fun updateHookedEntityId(entity: Entity?) {
|
||||
this.hookedEntity = entity
|
||||
//getDataTracker().set(HOOK_ENTITY_ID, if (entity == null) 0 else entity.id + 1)
|
||||
this.HOOK_ENTITY_ID = if (entity == null) 0 else entity.id + 1
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
velocityRandom.setSeed(getUuid().leastSignificantBits xor world.time)
|
||||
//super.tick()
|
||||
val playerEntity = this.playerOwner
|
||||
if (playerEntity == null) {
|
||||
discard()
|
||||
} else if (world.isClient || !removeIfInvalid(playerEntity)) {
|
||||
if (this.isOnGround) {
|
||||
++removalTimer
|
||||
if (removalTimer >= 1200) {
|
||||
discard()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
removalTimer = 0
|
||||
}
|
||||
var f = 0.0f
|
||||
val blockPos = blockPos
|
||||
val fluidState = world.getFluidState(blockPos)
|
||||
if (fluidState.isIn(FluidTags.WATER)) {
|
||||
f = fluidState.getHeight(world, blockPos)
|
||||
}
|
||||
val bl = f > 0.0f
|
||||
if (state == State.FLYING) {
|
||||
if (hookedEntity != null) {
|
||||
velocity = Vec3d.ZERO
|
||||
state = State.HOOKED_IN_ENTITY
|
||||
return
|
||||
}
|
||||
if (bl) {
|
||||
velocity = velocity.multiply(0.3, 0.2, 0.3)
|
||||
state = State.BOBBING
|
||||
return
|
||||
}
|
||||
checkForCollision()
|
||||
} else {
|
||||
if (state == State.HOOKED_IN_ENTITY) {
|
||||
if (hookedEntity != null) {
|
||||
if (!hookedEntity!!.isRemoved && hookedEntity!!.world.registryKey === world.registryKey) {
|
||||
this.setPosition(hookedEntity!!.x, hookedEntity!!.getBodyY(0.8), hookedEntity!!.z)
|
||||
} else {
|
||||
updateHookedEntityId(null as Entity?)
|
||||
state = State.FLYING
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (state == State.BOBBING) {
|
||||
val vec3d = velocity
|
||||
var d = this.y + vec3d.y - blockPos.y.toDouble() - f.toDouble()
|
||||
if (Math.abs(d) < 0.01) {
|
||||
d += Math.signum(d) * 0.1
|
||||
}
|
||||
this.setVelocity(vec3d.x * 0.9, vec3d.y - d * random.nextFloat().toDouble() * 0.2, vec3d.z * 0.9)
|
||||
if (hookCountdown <= 0 && fishTravelCountdown <= 0) {
|
||||
inOpenWater = true
|
||||
} else {
|
||||
inOpenWater = inOpenWater && outOfOpenWaterTicks < 10 && isOpenOrWaterAround(blockPos)
|
||||
}
|
||||
if (bl) {
|
||||
outOfOpenWaterTicks = Math.max(0, outOfOpenWaterTicks - 1)
|
||||
if (caughtFish) {
|
||||
velocity = velocity.add(0.0, -0.1 * velocityRandom.nextFloat().toDouble() * velocityRandom.nextFloat().toDouble(), 0.0)
|
||||
}
|
||||
if (!world.isClient) {
|
||||
tickFishingLogic(blockPos)
|
||||
}
|
||||
} else {
|
||||
outOfOpenWaterTicks = Math.min(10, outOfOpenWaterTicks + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fluidState.isIn(FluidTags.WATER)) {
|
||||
velocity = velocity.add(0.0, -0.03, 0.0)
|
||||
}
|
||||
move(MovementType.SELF, velocity)
|
||||
this.updateRotation()
|
||||
if (state == State.FLYING && (this.isOnGround || horizontalCollision)) {
|
||||
velocity = Vec3d.ZERO
|
||||
}
|
||||
val e = 0.92 // air friction??
|
||||
velocity = velocity.multiply(0.92)
|
||||
refreshPosition()
|
||||
}
|
||||
}
|
||||
|
||||
override fun use(usedItem: ItemStack): Int {
|
||||
val playerEntity = this.playerOwner
|
||||
|
||||
return if (!world.isClient && playerEntity != null && !removeIfInvalid(playerEntity)) {
|
||||
var i = 0
|
||||
if (this.hookedEntity != null) {
|
||||
pullHookedEntity(this.hookedEntity)
|
||||
Criteria.FISHING_ROD_HOOKED.trigger(playerEntity as ServerPlayerEntity?, usedItem, this, emptyList())
|
||||
world.sendEntityStatus(this, 31.toByte())
|
||||
i = if (this.hookedEntity is ItemEntity) 3 else 5
|
||||
} else if (this.hookCountdown > 0) {
|
||||
// check if thing caught was an item
|
||||
if (this.typeCaught == "ITEM") {
|
||||
val lootContextParameterSet = LootContextParameterSet.Builder(world as ServerWorld).add(LootContextParameters.ORIGIN, pos).add(LootContextParameters.TOOL, usedItem).add(LootContextParameters.THIS_ENTITY, this).luck(this.luckOfTheSeaLevel.toFloat() + playerEntity.luck).build(LootContextTypes.FISHING)
|
||||
val lootTable = world.server!!.lootManager.getLootTable(LootTables.FISHING_GAMEPLAY)
|
||||
val list: List<ItemStack> = lootTable.generateLoot(lootContextParameterSet)
|
||||
Criteria.FISHING_ROD_HOOKED.trigger(playerEntity as ServerPlayerEntity?, usedItem, this, list)
|
||||
val var7: Iterator<*> = list.iterator()
|
||||
while (var7.hasNext()) {
|
||||
val itemStack = var7.next() as ItemStack
|
||||
val itemEntity = ItemEntity(world, this.x, this.y, this.z, itemStack)
|
||||
val d = playerEntity.getX() - this.x
|
||||
val e = playerEntity.getY() - this.y
|
||||
val f = playerEntity.getZ() - this.z
|
||||
val g = 0.1
|
||||
itemEntity.setVelocity(d * 0.1, e * 0.1 + Math.sqrt(Math.sqrt(d * d + e * e + f * f)) * 0.08, f * 0.1)
|
||||
world.spawnEntity(itemEntity)
|
||||
playerEntity.getWorld().spawnEntity(ExperienceOrbEntity(playerEntity.getWorld(), playerEntity.getX(), playerEntity.getY() + 0.5, playerEntity.getZ() + 0.5, random.nextInt(6) + 1))
|
||||
if (itemStack.isIn(ItemTags.FISHES)) {
|
||||
playerEntity.increaseStat(Stats.FISH_CAUGHT, 1)
|
||||
}
|
||||
}
|
||||
i = 1
|
||||
}
|
||||
else { // logic for spawning Pokemon using rarity
|
||||
|
||||
System.out.println("Player reeled in a Pokemon from the bucket: " + chosenBucket.name)
|
||||
|
||||
val bobberOwner = playerOwner as ServerPlayerEntity
|
||||
|
||||
// spawn the pokemon from the chosen bucket at the bobber's location
|
||||
spawnPokemonFromFishing(bobberOwner, this, chosenBucket)
|
||||
|
||||
val serverWorld = world as ServerWorld
|
||||
|
||||
val g = MathHelper.nextFloat(random, 0.0f, 360.0f) * (Math.PI.toFloat() / 180)
|
||||
val h = MathHelper.nextFloat(random, 25.0f, 60.0f)
|
||||
val partX = this.x + (MathHelper.sin(g) * h).toDouble() * 0.1
|
||||
serverWorld.spawnParticles(ParticleTypes.SPLASH, partX, this.y, this.z, 4 + random.nextInt(4), 0.1, 0.0, 0.1, 0.0)
|
||||
playerEntity.getWorld().spawnEntity(ExperienceOrbEntity(playerEntity.getWorld(), playerEntity.getX(), playerEntity.getY() + 0.5, playerEntity.getZ() + 0.5, random.nextInt(6) + 1))
|
||||
val bobberBiome = world.getBiome(this.blockPos) // biome of the bobber. But idk if we need this. Probably not anymore
|
||||
}
|
||||
}
|
||||
if (this.isOnGround) {
|
||||
i = 2
|
||||
}
|
||||
discard()
|
||||
i
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fun spawnPokemonFromFishing(player: PlayerEntity, bobber: PokeRodFishingBobberEntity, chosenBucket: SpawnBucket) {
|
||||
var hookedEntityID: Int? = null
|
||||
var hookedEntity: Entity? = null
|
||||
|
||||
|
||||
val spawner = BestSpawner.fishingSpawner
|
||||
// stealing a ton of stuff from the SpawnFromPool Command
|
||||
|
||||
//val spawnCause = SpawnCause(spawner = spawner, bucket = spawner.chooseBucket(), entity = spawner.getCauseEntity())
|
||||
val spawnCause = FishingSpawnCause(
|
||||
spawner = spawner,
|
||||
bucket = chosenBucket,
|
||||
entity = player,
|
||||
rodStack = player.mainHandStack // Crab, you should probably parse in the rod item connected to the bobber so we can check enchants in spawn conditions
|
||||
)
|
||||
|
||||
val result = spawner.run(spawnCause, world as ServerWorld, pos.toBlockPos())
|
||||
|
||||
if (result == null) {
|
||||
// This has a chance to fail, if the position has no suitability for a fishing context
|
||||
// it could also just be a miss which
|
||||
// means two attempts to spawn in the same location can have differing results (which is expected for
|
||||
// randomness).
|
||||
player.sendMessage("Not even a nibble".red())
|
||||
}
|
||||
|
||||
var spawnedPokemon: PokemonEntity? = null
|
||||
val resultingSpawn = result?.get()
|
||||
|
||||
if (resultingSpawn is EntitySpawnResult) {
|
||||
for (entity in resultingSpawn.entities) {
|
||||
player.sendMessage(commandLang("spawnpokemonfrompool.success", entity.displayName).green())
|
||||
//pokemon.uuid = it.uuid
|
||||
hookedEntityID = entity.id
|
||||
spawnedPokemon = (entity as PokemonEntity)
|
||||
|
||||
// if spawned pokemon is a magikarp then lift it up into the air and over the player
|
||||
if (spawnedPokemon.pokemon.species.name.equals("magikarp", ignoreCase = true)) {
|
||||
// Direction and position calculations as before
|
||||
val rad = Math.toRadians(player.yaw.toDouble() + 180)
|
||||
val behindDirection = Vec3d(-Math.sin(rad), 0.0, Math.cos(rad))
|
||||
val targetPos = player.pos.add(behindDirection.multiply(2.0))
|
||||
val diff = targetPos.subtract(entity.pos)
|
||||
val distance = diff.horizontalLength()
|
||||
|
||||
// Simple empirical mapping of distance to launch angle and initial velocity
|
||||
val angle = when {
|
||||
distance < 5 -> 60 // Closer targets, higher arc
|
||||
distance < 10 -> 45 // Moderate distance, moderate arc
|
||||
else -> 30 // Farther targets, lower arc
|
||||
}
|
||||
|
||||
// Adjust velocity based on distance and angle
|
||||
// These are placeholder values; you'll need to adjust based on testing
|
||||
val velocityMultiplier = when {
|
||||
distance < 5 -> 0.3
|
||||
distance < 10 -> 0.5
|
||||
distance < 20 -> .8
|
||||
else -> 1.2
|
||||
}
|
||||
|
||||
val velocityX = diff.x / distance * velocityMultiplier
|
||||
val velocityZ = diff.z / distance * velocityMultiplier
|
||||
// Calculate Y velocity component based on chosen angle, simplified
|
||||
val velocityY = when {
|
||||
distance < 5 -> 0.4
|
||||
distance < 10 -> 0.5
|
||||
distance < 20 -> 0.8
|
||||
else -> 0.9
|
||||
}
|
||||
|
||||
val tossVelocity = Vec3d(velocityX, velocityY, velocityZ)
|
||||
entity.setVelocity(tossVelocity)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// What if it isn't an entity though
|
||||
hookedEntity = world.getEntityById(hookedEntityID!!)
|
||||
|
||||
//val spawnedPokemon = spawnAction.entity
|
||||
if (spawnedPokemon != null) {
|
||||
BattleBuilder.pve((player as ServerPlayerEntity), spawnedPokemon).ifErrored { it.sendTo(player) { it.red() } }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.entity.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.*
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacketToServer
|
||||
import com.cobblemon.mod.common.api.drop.DropTable
|
||||
import com.cobblemon.mod.common.api.entity.Despawner
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
@@ -33,7 +32,6 @@ import com.cobblemon.mod.common.api.types.ElementalTypes.FIRE
|
||||
import com.cobblemon.mod.common.battles.BagItems
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.Poseable
|
||||
@@ -46,7 +44,6 @@ import com.cobblemon.mod.common.net.messages.client.animation.PlayPoseableAnimat
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler.SEND_OUT_DURATION
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
@@ -132,7 +129,6 @@ open class PokemonEntity(
|
||||
@JvmStatic val HIDE_LABEL = DataTracker.registerData(PokemonEntity::class.java, TrackedDataHandlerRegistry.BOOLEAN)
|
||||
@JvmStatic val UNBATTLEABLE = DataTracker.registerData(PokemonEntity::class.java, TrackedDataHandlerRegistry.BOOLEAN)
|
||||
@JvmStatic val COUNTS_TOWARDS_SPAWN_CAP = DataTracker.registerData(PokemonEntity::class.java, TrackedDataHandlerRegistry.BOOLEAN)
|
||||
@JvmStatic val SPAWN_DIRECTION = DataTracker.registerData(PokemonEntity::class.java, TrackedDataHandlerRegistry.FLOAT)
|
||||
|
||||
const val BATTLE_LOCK = "battle"
|
||||
|
||||
@@ -236,7 +232,6 @@ open class PokemonEntity(
|
||||
dataTracker.startTracking(LABEL_LEVEL, 1)
|
||||
dataTracker.startTracking(HIDE_LABEL, false)
|
||||
dataTracker.startTracking(UNBATTLEABLE, false)
|
||||
dataTracker.startTracking(SPAWN_DIRECTION, world.random.nextFloat() * 360F)
|
||||
}
|
||||
|
||||
override fun onTrackedDataSet(data: TrackedData<*>) {
|
||||
@@ -304,13 +299,6 @@ open class PokemonEntity(
|
||||
this.updateEyeHeight()
|
||||
}
|
||||
|
||||
if (ticksLived <= 20) {
|
||||
clearPositionTarget()
|
||||
val spawnDirection = dataTracker.get(SPAWN_DIRECTION)
|
||||
setBodyYaw(spawnDirection)
|
||||
prevBodyYaw = spawnDirection
|
||||
}
|
||||
|
||||
if (this.tethering != null && !this.tethering!!.box.contains(this.x, this.y, this.z)) {
|
||||
this.tethering = null
|
||||
this.pokemon.recall()
|
||||
@@ -836,7 +824,7 @@ open class PokemonEntity(
|
||||
player.sendMessage(lang("held_item.already_holding", this.pokemon.getDisplayName(), stack.name))
|
||||
return true
|
||||
}
|
||||
val returned = this.pokemon.swapHeldItem(stack = stack, decrement = !player.isCreative)
|
||||
val returned = this.pokemon.swapHeldItem(stack, !player.isCreative)
|
||||
val text = when {
|
||||
giving.isEmpty -> lang("held_item.take", returned.name, this.pokemon.getDisplayName())
|
||||
returned.isEmpty -> lang("held_item.give", this.pokemon.getDisplayName(), giving.name)
|
||||
@@ -1040,21 +1028,6 @@ open class PokemonEntity(
|
||||
dataTracker.set(NICKNAME_VISIBLE, visible)
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to force initiate a battle with this Pokémon.
|
||||
*
|
||||
* @param player The player to attempt a battle with.
|
||||
* @return Whether the battle was successfully started.
|
||||
*/
|
||||
fun forceBattle(player: PlayerEntity): Boolean {
|
||||
if (!canBattle(player)) return false
|
||||
if (CobblemonClient.storage.myParty.isEmpty()) return false
|
||||
val selectedPokemon = CobblemonClient.storage.myParty.get(CobblemonClient.storage.selectedSlot) ?: return false
|
||||
if (selectedPokemon.isFainted()) return false
|
||||
sendPacketToServer(BattleChallengePacket(this.id, selectedPokemon.uuid))
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* In the context of a Pokémon entity this checks if the Pokémon is currently set to displaying its nickname.
|
||||
*
|
||||
|
||||
@@ -142,10 +142,10 @@ object CobblemonItemGroups {
|
||||
entries.add(CobblemonItems.PLUME_FOSSIL)
|
||||
entries.add(CobblemonItems.JAW_FOSSIL)
|
||||
entries.add(CobblemonItems.SAIL_FOSSIL)
|
||||
entries.add(CobblemonItems.FOSSILIZED_BIRD)
|
||||
entries.add(CobblemonItems.FOSSILIZED_FISH)
|
||||
entries.add(CobblemonItems.FOSSILIZED_DRAKE)
|
||||
entries.add(CobblemonItems.FOSSILIZED_DINO)
|
||||
entries.add(CobblemonItems.BIRD_FOSSIL)
|
||||
entries.add(CobblemonItems.FISH_FOSSIL)
|
||||
entries.add(CobblemonItems.DRAKE_FOSSIL)
|
||||
entries.add(CobblemonItems.DINO_FOSSIL)
|
||||
|
||||
entries.add(CobblemonItems.TUMBLESTONE)
|
||||
entries.add(CobblemonItems.BLACK_TUMBLESTONE)
|
||||
@@ -179,37 +179,6 @@ object CobblemonItemGroups {
|
||||
entries.add(CobblemonItems.SUSPICIOUS_SHERD)
|
||||
|
||||
entries.add(CobblemonItems.AUTOMATON_ARMOR_TRIM_SMITHING_TEMPLATE)
|
||||
|
||||
entries.add(CobblemonItems.RELIC_COIN)
|
||||
entries.add(CobblemonItems.RELIC_COIN_POUCH)
|
||||
entries.add(CobblemonItems.RELIC_COIN_SACK)
|
||||
entries.add(CobblemonItems.GILDED_CHEST)
|
||||
entries.add(CobblemonItems.YELLOW_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.GREEN_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.BLUE_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.PINK_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.BLACK_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.WHITE_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.GIMMIGHOUL_CHEST)
|
||||
|
||||
entries.add(CobblemonItems.NORMAL_GEM)
|
||||
entries.add(CobblemonItems.FIRE_GEM)
|
||||
entries.add(CobblemonItems.WATER_GEM)
|
||||
entries.add(CobblemonItems.GRASS_GEM)
|
||||
entries.add(CobblemonItems.ELECTRIC_GEM)
|
||||
entries.add(CobblemonItems.ICE_GEM)
|
||||
entries.add(CobblemonItems.FIGHTING_GEM)
|
||||
entries.add(CobblemonItems.POISON_GEM)
|
||||
entries.add(CobblemonItems.GROUND_GEM)
|
||||
entries.add(CobblemonItems.FLYING_GEM)
|
||||
entries.add(CobblemonItems.PSYCHIC_GEM)
|
||||
entries.add(CobblemonItems.BUG_GEM)
|
||||
entries.add(CobblemonItems.ROCK_GEM)
|
||||
entries.add(CobblemonItems.GHOST_GEM)
|
||||
entries.add(CobblemonItems.DRAGON_GEM)
|
||||
entries.add(CobblemonItems.DARK_GEM)
|
||||
entries.add(CobblemonItems.STEEL_GEM)
|
||||
entries.add(CobblemonItems.FAIRY_GEM)
|
||||
}
|
||||
|
||||
private fun blockEntries(displayContext: DisplayContext, entries: Entries) {
|
||||
@@ -219,18 +188,6 @@ object CobblemonItemGroups {
|
||||
entries.add(CobblemonItems.PC)
|
||||
entries.add(CobblemonItems.HEALING_MACHINE)
|
||||
entries.add(CobblemonItems.PASTURE)
|
||||
|
||||
entries.add(CobblemonItems.GILDED_CHEST)
|
||||
entries.add(CobblemonItems.YELLOW_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.GREEN_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.BLUE_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.PINK_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.BLACK_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.WHITE_GILDED_CHEST)
|
||||
entries.add(CobblemonItems.GIMMIGHOUL_CHEST)
|
||||
entries.add(CobblemonItems.RELIC_COIN_POUCH)
|
||||
entries.add(CobblemonItems.RELIC_COIN_SACK)
|
||||
|
||||
entries.add(CobblemonItems.APRICORN_LOG)
|
||||
entries.add(CobblemonItems.APRICORN_WOOD)
|
||||
entries.add(CobblemonItems.STRIPPED_APRICORN_LOG)
|
||||
@@ -274,6 +231,7 @@ object CobblemonItemGroups {
|
||||
entries.add(CobblemonItems.DEEPSLATE_THUNDER_STONE_ORE)
|
||||
entries.add(CobblemonItems.WATER_STONE_ORE)
|
||||
entries.add(CobblemonItems.DEEPSLATE_WATER_STONE_ORE)
|
||||
entries.add(CobblemonItems.DYNITE_ORE)
|
||||
}
|
||||
|
||||
private fun consumableEntries(displayContext: DisplayContext, entries: Entries) {
|
||||
@@ -320,13 +278,6 @@ object CobblemonItemGroups {
|
||||
entries.add(CobblemonItems.DIRE_HIT)
|
||||
entries.add(CobblemonItems.GUARD_SPEC)
|
||||
|
||||
entries.add(CobblemonItems.HEALTH_FEATHER)
|
||||
entries.add(CobblemonItems.MUSCLE_FEATHER)
|
||||
entries.add(CobblemonItems.RESIST_FEATHER)
|
||||
entries.add(CobblemonItems.GENIUS_FEATHER)
|
||||
entries.add(CobblemonItems.CLEVER_FEATHER)
|
||||
entries.add(CobblemonItems.SWIFT_FEATHER)
|
||||
|
||||
entries.add(CobblemonItems.HP_UP)
|
||||
entries.add(CobblemonItems.PROTEIN)
|
||||
entries.add(CobblemonItems.IRON)
|
||||
@@ -474,36 +425,18 @@ object CobblemonItemGroups {
|
||||
entries.add(CobblemonItems.TWISTED_SPOON)
|
||||
entries.add(CobblemonItems.WHITE_HERB)
|
||||
entries.add(CobblemonItems.WISE_GLASSES)
|
||||
|
||||
entries.add(CobblemonItems.NORMAL_GEM)
|
||||
entries.add(CobblemonItems.FIRE_GEM)
|
||||
entries.add(CobblemonItems.WATER_GEM)
|
||||
entries.add(CobblemonItems.GRASS_GEM)
|
||||
entries.add(CobblemonItems.ELECTRIC_GEM)
|
||||
entries.add(CobblemonItems.ICE_GEM)
|
||||
entries.add(CobblemonItems.FIGHTING_GEM)
|
||||
entries.add(CobblemonItems.POISON_GEM)
|
||||
entries.add(CobblemonItems.GROUND_GEM)
|
||||
entries.add(CobblemonItems.FLYING_GEM)
|
||||
entries.add(CobblemonItems.PSYCHIC_GEM)
|
||||
entries.add(CobblemonItems.BUG_GEM)
|
||||
entries.add(CobblemonItems.ROCK_GEM)
|
||||
entries.add(CobblemonItems.GHOST_GEM)
|
||||
entries.add(CobblemonItems.DRAGON_GEM)
|
||||
entries.add(CobblemonItems.DARK_GEM)
|
||||
entries.add(CobblemonItems.STEEL_GEM)
|
||||
entries.add(CobblemonItems.FAIRY_GEM)
|
||||
}
|
||||
|
||||
private fun pokeballentries(displayContext: DisplayContext, entries: Entries) {
|
||||
CobblemonItems.pokeBalls.forEach(entries::add)
|
||||
entries.add(CobblemonItems.POKEROD)
|
||||
}
|
||||
|
||||
private fun foodInjections(injector: Injector) {
|
||||
injector.putLast(CobblemonItems.ROASTED_LEEK)
|
||||
injector.putAfter(CobblemonItems.LEEK_AND_POTATO_STEW, CobblemonItems.ROASTED_LEEK)
|
||||
injector.putAfter(CobblemonItems.BRAISED_VIVICHOKE, CobblemonItems.LEEK_AND_POTATO_STEW)
|
||||
injector.putAfter(CobblemonItems.VIVICHOKE_DIP, CobblemonItems.BRAISED_VIVICHOKE)
|
||||
injector.putLast(CobblemonItems.LEEK_AND_POTATO_STEW)
|
||||
injector.putLast(CobblemonItems.BRAISED_VIVICHOKE)
|
||||
injector.putLast(CobblemonItems.VIVICHOKE_DIP)
|
||||
}
|
||||
|
||||
private fun toolsAndUtilitiesInjections(injector: Injector) {
|
||||
|
||||
@@ -1,57 +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.item.interactive
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.item.PokemonSelectingItem
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.item.CobblemonItem
|
||||
import com.cobblemon.mod.common.pokemon.EVs
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.util.Hand
|
||||
import net.minecraft.util.TypedActionResult
|
||||
import net.minecraft.world.World
|
||||
|
||||
class FeatherItem(val stat: Stat) : CobblemonItem(Settings()), PokemonSelectingItem {
|
||||
|
||||
companion object {
|
||||
const val EV_YIELD = 1
|
||||
}
|
||||
|
||||
override val bagItem = null
|
||||
override fun canUseOnPokemon(pokemon: Pokemon) = pokemon.evs.getOrDefault(stat) < EVs.MAX_STAT_VALUE
|
||||
|
||||
override fun applyToPokemon(
|
||||
player: ServerPlayerEntity,
|
||||
stack: ItemStack,
|
||||
pokemon: Pokemon
|
||||
): TypedActionResult<ItemStack> {
|
||||
val evsGained = pokemon.evs.add(stat, EV_YIELD)
|
||||
return if (evsGained > 0) {
|
||||
player.playSound(CobblemonSounds.MEDICINE_FEATHER_USE, SoundCategory.PLAYERS, 1F, 1F)
|
||||
if (!player.isCreative) {
|
||||
stack.decrement(1)
|
||||
}
|
||||
TypedActionResult.success(stack)
|
||||
} else {
|
||||
TypedActionResult.fail(stack)
|
||||
}
|
||||
}
|
||||
|
||||
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
|
||||
if (user is ServerPlayerEntity) {
|
||||
return use(user, user.getStackInHand(hand))
|
||||
}
|
||||
return TypedActionResult.success(user.getStackInHand(hand))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
//
|
||||
// Source code recreated from a .class file by IntelliJ IDEA
|
||||
// (powered by FernFlower decompiler)
|
||||
//
|
||||
package com.cobblemon.mod.common.item
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.item.CobblemonItem
|
||||
import net.minecraft.enchantment.EnchantmentHelper
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.item.FishingRodItem
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.Item.Settings
|
||||
import net.minecraft.entity.projectile.FishingBobberEntity
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.sound.SoundEvents
|
||||
import net.minecraft.stat.Stats
|
||||
import net.minecraft.util.Hand
|
||||
import net.minecraft.util.TypedActionResult
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.event.GameEvent
|
||||
|
||||
class PokerodItem(settings: Settings?) : FishingRodItem(settings) {
|
||||
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
|
||||
val itemStack = user.getStackInHand(hand)
|
||||
val i: Int
|
||||
if (user.fishHook != null) { // if the bobber is out yet
|
||||
if (!world.isClient) {
|
||||
i = user.fishHook!!.use(itemStack)
|
||||
itemStack.damage(i, user) { p: PlayerEntity -> p.sendToolBreakStatus(hand) }
|
||||
}
|
||||
world.playSound(null as PlayerEntity?, user.x, user.y, user.z, SoundEvents.ENTITY_FISHING_BOBBER_RETRIEVE, SoundCategory.NEUTRAL, 1.0f, 0.4f / (world.getRandom().nextFloat() * 0.4f + 0.8f))
|
||||
user.emitGameEvent(GameEvent.ITEM_INTERACT_FINISH)
|
||||
} else { // if the bobber is not out yet
|
||||
world.playSound(null as PlayerEntity?, user.x, user.y, user.z, SoundEvents.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5f, 0.4f / (world.getRandom().nextFloat() * 0.4f + 0.8f))
|
||||
if (!world.isClient) {
|
||||
i = EnchantmentHelper.getLure(itemStack)
|
||||
val j = EnchantmentHelper.getLuckOfTheSea(itemStack)
|
||||
world.spawnEntity(PokeRodFishingBobberEntity(user, world, j, i))
|
||||
}
|
||||
user.incrementStat(Stats.USED.getOrCreateStat(this))
|
||||
user.emitGameEvent(GameEvent.ITEM_INTERACT_START)
|
||||
}
|
||||
return TypedActionResult.success(itemStack, world.isClient())
|
||||
}
|
||||
|
||||
// todo Round 2
|
||||
/*override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
|
||||
val itemStack = user.getStackInHand(hand)
|
||||
|
||||
// Play the throw sound
|
||||
world.playSound(null as PlayerEntity?, user.x, user.y, user.z, SoundEvents.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5f, 0.4f / (world.getRandom().nextFloat() * 0.4f + 0.8f))
|
||||
|
||||
// Spawn the FishingBobberEntity directly without checking for an existing one
|
||||
if (!world.isClient) {
|
||||
val i = EnchantmentHelper.getLure(itemStack)
|
||||
val j = EnchantmentHelper.getLuckOfTheSea(itemStack)
|
||||
world.spawnEntity(PokeBobberEntity(user, world, j, i))
|
||||
}
|
||||
|
||||
|
||||
// Record the usage of the item
|
||||
user.incrementStat(Stats.USED.getOrCreateStat(this))
|
||||
user.emitGameEvent(GameEvent.ITEM_INTERACT_START)
|
||||
|
||||
return TypedActionResult.success(itemStack, world.isClient())
|
||||
}*/
|
||||
|
||||
// todo Round 3 Best so far
|
||||
/*override fun use(world: World, player: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
|
||||
if (!world.isClient) {
|
||||
val itemStack = player.getStackInHand(hand)
|
||||
|
||||
// Calculate initial position and velocity for PokeBobberEntity
|
||||
val currentPose = player.pose
|
||||
val eyeHeight = player.getEyeHeight(currentPose)
|
||||
val spawnPos = player.pos.add(0.0, eyeHeight.toDouble(), 0.0)
|
||||
val direction = player.getRotationVec(1.0f)
|
||||
val velocity = direction.multiply(1.5)
|
||||
|
||||
System.out.println("Spawn Position: " + spawnPos);
|
||||
System.out.println("Velocity: " + velocity);
|
||||
|
||||
// Create and spawn PokeBobberEntity
|
||||
val pokeBobber = PokeRodFishingBobberEntity(player, world, 0, 0)
|
||||
|
||||
pokeBobber.setPos(spawnPos.x, spawnPos.y, spawnPos.z)
|
||||
pokeBobber.setVelocity(velocity.x, velocity.y, velocity.z)
|
||||
//pokeBobber.use(ItemStack(CobblemonItems.POKEROD))
|
||||
world.spawnEntity(pokeBobber)
|
||||
//pokeBobber.use(ItemStack(Items.FISHING_ROD))
|
||||
pokeBobber.use(itemStack)
|
||||
|
||||
}
|
||||
return TypedActionResult.success(player.getStackInHand(hand))
|
||||
}*/
|
||||
|
||||
override fun getEnchantability(): Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.cobblemon.mod.common.loot
|
||||
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
|
||||
object CobblemonLootTables {
|
||||
|
||||
val FALLING_STAR = cobblemonResource("entities/fallingstar")
|
||||
|
||||
}
|
||||
@@ -16,13 +16,9 @@ import com.cobblemon.mod.common.api.net.Encodable
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.net.IntSize
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.SpeciesFeatureUpdatePacket
|
||||
import com.cobblemon.mod.common.pokemon.*
|
||||
import com.cobblemon.mod.common.pokemon.activestate.PokemonState
|
||||
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
|
||||
@@ -75,8 +71,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
var dmaxLevel = 0
|
||||
var gmaxFactor = false
|
||||
var tradeable = true
|
||||
// var features: List<SynchronizedSpeciesFeature> = emptyList()
|
||||
lateinit var featuresBuffer: PacketByteBuf
|
||||
var originalTrainerType: OriginalTrainerType = OriginalTrainerType.NONE
|
||||
var originalTrainer: String? = null
|
||||
var originalTrainerName: String? = null
|
||||
@@ -114,15 +108,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
this.dmaxLevel = pokemon.dmaxLevel
|
||||
this.gmaxFactor = pokemon.gmaxFactor
|
||||
this.tradeable = pokemon.tradeable
|
||||
this.featuresBuffer = PacketByteBuf(Unpooled.buffer())
|
||||
val visibleFeatures = pokemon.features
|
||||
.filterIsInstance<SynchronizedSpeciesFeature>()
|
||||
.filter { (SpeciesFeatures.getFeature(it.name)!! as SynchronizedSpeciesFeatureProvider<*>).visible }
|
||||
featuresBuffer.writeCollection(visibleFeatures) { _, value ->
|
||||
featuresBuffer.writeString(value.name)
|
||||
value.encode(featuresBuffer)
|
||||
}
|
||||
|
||||
this.originalTrainerType = pokemon.originalTrainerType
|
||||
this.originalTrainer = pokemon.originalTrainer
|
||||
this.originalTrainerName = pokemon.originalTrainerName
|
||||
@@ -163,10 +148,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
buffer.writeInt(dmaxLevel)
|
||||
buffer.writeBoolean(gmaxFactor)
|
||||
buffer.writeBoolean(tradeable)
|
||||
val featureByteCount = featuresBuffer.readableBytes()
|
||||
buffer.writeSizedInt(IntSize.U_SHORT, featureByteCount)
|
||||
buffer.writeBytes(featuresBuffer)
|
||||
featuresBuffer.release()
|
||||
buffer.writeString(originalTrainerType.name)
|
||||
buffer.writeNullable(originalTrainer) { _, v -> buffer.writeString(v) }
|
||||
buffer.writeNullable(originalTrainerName) { _, v -> buffer.writeString(v) }
|
||||
@@ -208,9 +189,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
dmaxLevel = buffer.readInt()
|
||||
gmaxFactor = buffer.readBoolean()
|
||||
tradeable = buffer.readBoolean()
|
||||
|
||||
val featureBytesToRead = buffer.readSizedInt(IntSize.U_SHORT)
|
||||
featuresBuffer = PacketByteBuf(buffer.readBytes(featureBytesToRead))
|
||||
originalTrainerType = OriginalTrainerType.valueOf(buffer.readString())
|
||||
originalTrainer = buffer.readNullable { buffer.readString() }
|
||||
originalTrainerName = buffer.readNullable { buffer.readString() }
|
||||
@@ -226,6 +204,7 @@ class PokemonDTO : Encodable, Decodable {
|
||||
it.experience = experience
|
||||
it.level = level
|
||||
it.setFriendship(friendship)
|
||||
it.currentHealth = currentHealth
|
||||
it.gender = gender
|
||||
ivs.forEach { stat ->
|
||||
it.setIV(stat.key, stat.value)
|
||||
@@ -233,7 +212,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
evs.forEach { stat ->
|
||||
it.setEV(stat.key, stat.value)
|
||||
}
|
||||
it.currentHealth = currentHealth
|
||||
it.moveSet.clear()
|
||||
for (move in moveSet) {
|
||||
it.moveSet.add(move)
|
||||
@@ -263,17 +241,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
it.dmaxLevel = dmaxLevel
|
||||
it.gmaxFactor = gmaxFactor
|
||||
it.tradeable = tradeable
|
||||
repeat(times = featuresBuffer.readSizedInt(IntSize.U_BYTE)) { _ ->
|
||||
val species = PokemonSpecies.getByIdentifier(this.species)!!
|
||||
val speciesFeatureName = featuresBuffer.readString()
|
||||
val featureProviders = SpeciesFeatures
|
||||
.getFeaturesFor(species)
|
||||
.filterIsInstance<SynchronizedSpeciesFeatureProvider<*>>()
|
||||
val feature = featureProviders.firstNotNullOfOrNull { it(featuresBuffer, speciesFeatureName) } as? SynchronizedSpeciesFeature
|
||||
?: throw IllegalArgumentException("Couldn't find a feature provider to deserialize this feature. Something's wrong.")
|
||||
it.features.removeIf { it.name == feature.name }
|
||||
it.features.add(feature)
|
||||
}
|
||||
when (originalTrainerType)
|
||||
{
|
||||
OriginalTrainerType.NONE -> {
|
||||
|
||||
-30
@@ -1,30 +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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.GlobalSpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* Syncs a species feature provider that was registered under [GlobalSpeciesFeatures].
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
class GlobalSpeciesFeatureSyncPacket(speciesFeatures: Map<String, SpeciesFeatureProvider<*>>) : SpeciesFeatureSyncPacket(speciesFeatures) {
|
||||
override val id = ID
|
||||
override fun synchronizeDecoded(entries: Collection<Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>>>) = GlobalSpeciesFeatures.loadOnClient(entries)
|
||||
companion object {
|
||||
val ID = cobblemonResource("global_species_feature_sync")
|
||||
fun decode(buffer: PacketByteBuf) = GlobalSpeciesFeatureSyncPacket(emptyMap()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatureAssignments
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* A registry sync packet for the [SpeciesFeatureAssignments] registry.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
class SpeciesFeatureAssignmentSyncPacket(
|
||||
data: Map<Identifier, MutableSet<String>>
|
||||
) : DataRegistrySyncPacket<Map.Entry<Identifier, MutableSet<String>>, SpeciesFeatureAssignmentSyncPacket>(data.entries) {
|
||||
override val id = ID
|
||||
override fun decodeEntry(buffer: PacketByteBuf): Map.Entry<Identifier, MutableSet<String>> {
|
||||
val key = buffer.readIdentifier()
|
||||
val assignments = buffer.readList { buffer.readString() }.toMutableSet()
|
||||
return object : Map.Entry<Identifier, MutableSet<String>> {
|
||||
override val key = key
|
||||
override val value = assignments
|
||||
}
|
||||
}
|
||||
|
||||
override fun encodeEntry(buffer: PacketByteBuf, entry: Map.Entry<Identifier, MutableSet<String>>) {
|
||||
buffer.writeIdentifier(entry.key)
|
||||
buffer.writeCollection(entry.value) { _, value -> buffer.writeString(value) }
|
||||
}
|
||||
|
||||
override fun synchronizeDecoded(entries: Collection<Map.Entry<Identifier, MutableSet<String>>>) {
|
||||
SpeciesFeatureAssignments.loadOnClient(entries.associate { it.toPair() })
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("species_feature_assignment_sync")
|
||||
fun decode(buffer: PacketByteBuf) = SpeciesFeatureAssignmentSyncPacket(emptyMap()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
* Base class for a registry sync packet that synchronizes [SynchronizedSpeciesFeatureProvider]s.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
abstract class SpeciesFeatureSyncPacket(
|
||||
speciesFeatureProviders: Map<String, SpeciesFeatureProvider<*>>
|
||||
) : DataRegistrySyncPacket<Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>>, SpeciesFeatureSyncPacket>(
|
||||
speciesFeatureProviders.entries.filterIsInstance<Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>>>().filter { it.value.visible }
|
||||
) {
|
||||
override fun encodeEntry(buffer: PacketByteBuf, entry: Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>>) {
|
||||
|
||||
val typeName = SpeciesFeatures.types.entries.find { it.value.isInstance(entry.value) }?.key
|
||||
val value = entry.value
|
||||
if (typeName == null) {
|
||||
buffer.writeBoolean(false)
|
||||
return
|
||||
} else {
|
||||
buffer.writeBoolean(true)
|
||||
}
|
||||
buffer.writeString(entry.key)
|
||||
buffer.writeString(typeName)
|
||||
value.encode(buffer)
|
||||
}
|
||||
|
||||
override fun decodeEntry(buffer: PacketByteBuf): Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>>? {
|
||||
if (!buffer.readBoolean()) {
|
||||
return null
|
||||
}
|
||||
val name = buffer.readString()
|
||||
val typeName = buffer.readString()
|
||||
val typeClass = SpeciesFeatures.types[typeName]
|
||||
?: throw IllegalStateException(
|
||||
"""
|
||||
A custom species feature provider, $typeName with encoding implementations was registered on the server and
|
||||
not the client, and therefore cannot be synced. Remove the implementation or install it
|
||||
on the client.
|
||||
""".trimIndent()
|
||||
)
|
||||
val instance = typeClass.getConstructor().newInstance()
|
||||
if (instance !is SynchronizedSpeciesFeatureProvider) {
|
||||
throw IllegalStateException("Somehow a non-SynchronizedSpeciesFeatureProvider was sent to the client. Version mismatch?")
|
||||
} else {
|
||||
instance.decode(buffer)
|
||||
}
|
||||
|
||||
return object : Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>> {
|
||||
override val key: String = name
|
||||
override val value: SynchronizedSpeciesFeatureProvider<*> = instance
|
||||
}
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* Syncs a species feature provider that was registered under [SpeciesFeatures].
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
class StandardSpeciesFeatureSyncPacket(providers: Map<String, SpeciesFeatureProvider<*>>) : SpeciesFeatureSyncPacket(providers) {
|
||||
override val id: Identifier = ID
|
||||
override fun synchronizeDecoded(entries: Collection<Map.Entry<String, SynchronizedSpeciesFeatureProvider<*>>>) = SpeciesFeatures.loadOnClient(entries)
|
||||
companion object {
|
||||
val ID = cobblemonResource("standard_species_feature_sync")
|
||||
fun decode(buffer: PacketByteBuf) = StandardSpeciesFeatureSyncPacket(emptyMap()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +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.net.messages.client.pokemon.update
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* Updates the state of a particular [SynchronizedSpeciesFeature].
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since November 13th, 2023
|
||||
*/
|
||||
class SpeciesFeatureUpdatePacket(pokemon: () -> Pokemon, val species: Identifier, speciesFeature: SynchronizedSpeciesFeature) : SingleUpdatePacket<SynchronizedSpeciesFeature, SpeciesFeatureUpdatePacket>(pokemon, speciesFeature) {
|
||||
companion object {
|
||||
val ID = cobblemonResource("species_feature_update")
|
||||
fun decode(buffer: PacketByteBuf): SpeciesFeatureUpdatePacket {
|
||||
val pokemon = decodePokemon(buffer)
|
||||
val speciesIdentifier = buffer.readIdentifier()
|
||||
val species = PokemonSpecies.getByIdentifier(speciesIdentifier)
|
||||
?: throw IllegalStateException("Pokémon unable to be found during species feature update packet: $speciesIdentifier")
|
||||
val speciesFeatureName = buffer.readString()
|
||||
val featureProviders = SpeciesFeatures.getFeaturesFor(species).filterIsInstance<SynchronizedSpeciesFeatureProvider<*>>()
|
||||
val feature = featureProviders.firstNotNullOfOrNull { it(buffer, speciesFeatureName) } as? SynchronizedSpeciesFeature
|
||||
?: throw IllegalArgumentException("Couldn't find a feature provider to deserialize this feature. Something's wrong.")
|
||||
return SpeciesFeatureUpdatePacket(pokemon, speciesIdentifier, feature)
|
||||
}
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encodeValue(buffer: PacketByteBuf) {
|
||||
buffer.writeIdentifier(species)
|
||||
buffer.writeString(value.name)
|
||||
value.encode(buffer)
|
||||
}
|
||||
|
||||
override fun set(pokemon: Pokemon, value: SynchronizedSpeciesFeature) {
|
||||
pokemon.features.removeIf { it.name == value.name }
|
||||
pokemon.features.add(value)
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
@@ -38,7 +39,6 @@ class SpawnPokemonPacket(
|
||||
private val unbattlable: Boolean,
|
||||
private val hideLabel: Boolean,
|
||||
private val caughtBall: Identifier,
|
||||
private val spawnYaw: Float,
|
||||
vanillaSpawnPacket: EntitySpawnS2CPacket
|
||||
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
|
||||
|
||||
@@ -59,7 +59,6 @@ class SpawnPokemonPacket(
|
||||
entity.dataTracker.get(PokemonEntity.UNBATTLEABLE),
|
||||
entity.dataTracker.get(PokemonEntity.HIDE_LABEL),
|
||||
entity.pokemon.caughtBall.name,
|
||||
entity.dataTracker.get(PokemonEntity.SPAWN_DIRECTION),
|
||||
vanillaSpawnPacket
|
||||
)
|
||||
|
||||
@@ -78,7 +77,6 @@ class SpawnPokemonPacket(
|
||||
buffer.writeBoolean(this.unbattlable)
|
||||
buffer.writeBoolean(this.hideLabel)
|
||||
buffer.writeIdentifier(this.caughtBall)
|
||||
buffer.writeFloat(this.spawnYaw)
|
||||
}
|
||||
|
||||
override fun applyData(entity: PokemonEntity) {
|
||||
@@ -100,7 +98,6 @@ class SpawnPokemonPacket(
|
||||
entity.dataTracker.set(PokemonEntity.POSE_TYPE, poseType)
|
||||
entity.dataTracker.set(PokemonEntity.UNBATTLEABLE, unbattlable)
|
||||
entity.dataTracker.set(PokemonEntity.HIDE_LABEL, hideLabel)
|
||||
entity.dataTracker.set(PokemonEntity.SPAWN_DIRECTION, spawnYaw)
|
||||
}
|
||||
|
||||
override fun checkType(entity: Entity): Boolean = entity is PokemonEntity
|
||||
@@ -123,10 +120,8 @@ class SpawnPokemonPacket(
|
||||
val unbattlable = buffer.readBoolean()
|
||||
val hideLabel = buffer.readBoolean()
|
||||
val caughtBall = buffer.readIdentifier()
|
||||
val spawnAngle = buffer.readFloat()
|
||||
val vanillaPacket = decodeVanillaPacket(buffer)
|
||||
|
||||
return SpawnPokemonPacket(ownerId, scaleModifier, species, form, aspects, battleId, phasingTargetId, beamModeEmitter, nickname, labelLevel, poseType, unbattlable, hideLabel, caughtBall, spawnAngle, vanillaPacket)
|
||||
return SpawnPokemonPacket(ownerId, scaleModifier, species, form, aspects, battleId, phasingTargetId, beamModeEmitter, nickname, labelLevel, poseType, unbattlable, hideLabel, caughtBall, vanillaPacket)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-32
@@ -1,32 +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.net.messages.server.battle
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import java.util.UUID
|
||||
|
||||
class FleeBattlePacket(val battleId: UUID) : NetworkPacket<FleeBattlePacket> {
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeUuid(battleId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("flee_battle")
|
||||
|
||||
fun decode(buffer: PacketByteBuf): FleeBattlePacket {
|
||||
return FleeBattlePacket(buffer.readUuid())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +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.net.serverhandling.battle
|
||||
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.FleeBattlePacket
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
|
||||
object FleeBattlePacketHandler : ServerNetworkPacketHandler<FleeBattlePacket> {
|
||||
|
||||
override fun handle(packet: FleeBattlePacket, server: MinecraftServer, player: ServerPlayerEntity) {
|
||||
val battle = BattleRegistry.getBattle(packet.battleId) ?: return
|
||||
player.sendMessage(battleLang("flee"))
|
||||
battle.end()
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,8 @@ import com.cobblemon.mod.common.api.abilities.Ability
|
||||
import com.cobblemon.mod.common.api.data.ShowdownIdentifiable
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.FRIENDSHIP_UPDATED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.HELD_ITEM_UPDATED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.POKEMON_FAINTED
|
||||
import com.cobblemon.mod.common.api.events.pokemon.*
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.HeldItemUpdatedEvent
|
||||
import com.cobblemon.mod.common.api.moves.*
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
@@ -34,7 +32,6 @@ import com.cobblemon.mod.common.api.pokemon.experience.ExperienceGroup
|
||||
import com.cobblemon.mod.common.api.pokemon.experience.ExperienceSource
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.friendship.FriendshipMutationCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.labels.CobblemonPokemonLabels
|
||||
import com.cobblemon.mod.common.api.pokemon.moves.LearnsetQuery
|
||||
@@ -62,7 +59,6 @@ import com.cobblemon.mod.common.pokemon.evolution.CobblemonEvolutionProxy
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.DamageTakenEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.RecoilEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.feature.SeasonFeatureHandler
|
||||
import com.cobblemon.mod.common.pokemon.misc.GimmighoulStashHandler
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
|
||||
import com.cobblemon.mod.common.pokemon.status.PersistentStatusContainer
|
||||
@@ -113,11 +109,9 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
}
|
||||
val quotient = clamp(currentHealth / hp.toFloat(), 0F, 1F)
|
||||
field = value
|
||||
if (!isClient) {
|
||||
val newFeatures = SpeciesFeatures.getFeaturesFor(species).mapNotNull { it.invoke(this) }
|
||||
features.clear()
|
||||
features.addAll(newFeatures)
|
||||
}
|
||||
val newFeatures = SpeciesFeatures.getFeaturesFor(species).mapNotNull { it.invoke(this) }
|
||||
features.clear()
|
||||
features.addAll(newFeatures)
|
||||
this.evolutionProxy.current().clear()
|
||||
updateAspects()
|
||||
updateForm()
|
||||
@@ -259,7 +253,6 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
_friendship.emit(it.newFriendship)
|
||||
}
|
||||
}
|
||||
|
||||
var state: PokemonState = InactivePokemonState()
|
||||
set(value) {
|
||||
field = value
|
||||
@@ -692,9 +685,7 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
}
|
||||
this.heldItem = giving
|
||||
this._heldItem.emit(giving)
|
||||
CobblemonEvents.HELD_ITEM_POST.post(HeldItemEvent.Post(this, this.heldItem(), event.returning.copy(), event.decrement)) {
|
||||
GimmighoulStashHandler.giveHeldItem(it)
|
||||
}
|
||||
CobblemonEvents.HELD_ITEM_POST.post(HeldItemEvent.Post(this, this.heldItem(), event.returning.copy(), event.decrement))
|
||||
return event.returning
|
||||
})
|
||||
return stack
|
||||
@@ -1420,14 +1411,11 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
storeCoordinates.get()?.run { sendPacketToPlayers(store.getObservingPlayers(), packet) }
|
||||
}
|
||||
|
||||
fun <T> registerObservable(observable: SimpleObservable<T>, notifyPacket: ((T) -> PokemonUpdatePacket<*>?)? = null): SimpleObservable<T> {
|
||||
fun <T> registerObservable(observable: SimpleObservable<T>, notifyPacket: ((T) -> PokemonUpdatePacket<*>)? = null): SimpleObservable<T> {
|
||||
observables.add(observable)
|
||||
observable.subscribe {
|
||||
if (notifyPacket != null && storeCoordinates.get() != null) {
|
||||
val packet = notifyPacket(it)
|
||||
if (packet != null) {
|
||||
notify(packet)
|
||||
}
|
||||
notify(notifyPacket(it))
|
||||
}
|
||||
anyChangeObservable.emit(this)
|
||||
}
|
||||
@@ -1517,13 +1505,7 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
private val _gmaxFactor = registerObservable(SimpleObservable<Boolean>()) { GmaxFactorUpdatePacket({ this }, it) }
|
||||
private val _originalTrainerName = registerObservable(SimpleObservable<String?>()) { OriginalTrainerUpdatePacket({ this }, it) }
|
||||
|
||||
private val _features = registerObservable(SimpleObservable<SpeciesFeature>()) {
|
||||
if (it is SynchronizedSpeciesFeature) {
|
||||
SpeciesFeatureUpdatePacket({ this }, species.resourceIdentifier, it)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
private val _features = registerObservable(SimpleObservable<SpeciesFeature>())
|
||||
|
||||
companion object {
|
||||
/**
|
||||
|
||||
@@ -199,7 +199,6 @@ class Species : ClientDataSynchronizer<Species>, ShowdownIdentifiable {
|
||||
buffer.writeCollection(this.pokedex) { pb, line -> pb.writeString(line) }
|
||||
buffer.writeCollection(this.forms) { pb, form -> form.encode(pb) }
|
||||
buffer.writeIdentifier(this.battleTheme)
|
||||
buffer.writeCollection(this.features) { pb, feature -> pb.writeString(feature) }
|
||||
buffer.writeNullable(this.lightingData) { pb, data ->
|
||||
pb.writeInt(data.lightLevel)
|
||||
pb.writeEnumConstant(data.liquidGlowMode)
|
||||
@@ -227,8 +226,6 @@ class Species : ClientDataSynchronizer<Species>, ShowdownIdentifiable {
|
||||
this.forms.clear()
|
||||
this.forms += buffer.readList{ pb -> FormData().apply { decode(pb) } }.filterNotNull()
|
||||
this.battleTheme = buffer.readIdentifier()
|
||||
this.features.clear()
|
||||
this.features += buffer.readList { pb -> pb.readString() }
|
||||
this.lightingData = buffer.readNullable { pb -> LightingData(pb.readInt(), pb.readEnumConstant(LightingData.LiquidGlowMode::class.java)) }
|
||||
this.initialize()
|
||||
}
|
||||
@@ -251,7 +248,6 @@ class Species : ClientDataSynchronizer<Species>, ShowdownIdentifiable {
|
||||
// We only sync level up moves atm
|
||||
|| this.moves.shouldSynchronize(other.moves)
|
||||
|| other.battleTheme != this.battleTheme
|
||||
|| other.features != this.features
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user