mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-20 22:26:24 -04:00
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 |
@@ -46,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
|
||||
@@ -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
|
||||
@@ -131,6 +130,7 @@ import net.minecraft.item.Items
|
||||
import net.minecraft.item.NameTagItem
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.util.WorldSavePath
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import org.apache.logging.log4j.LogManager
|
||||
|
||||
|
||||
@@ -65,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)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -96,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)
|
||||
|
||||
@@ -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
|
||||
@@ -578,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
|
||||
@@ -821,6 +826,9 @@ 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())
|
||||
@@ -842,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 {
|
||||
|
||||
@@ -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
@@ -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 }
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,8 @@ 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.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
|
||||
@@ -255,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) {
|
||||
|
||||
+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
@@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
package com.cobblemon.mod.common.client.sound
|
||||
|
||||
import net.minecraft.client.MinecraftClient
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
+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() } }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -231,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) {
|
||||
@@ -428,6 +429,7 @@ object CobblemonItemGroups {
|
||||
|
||||
private fun pokeballentries(displayContext: DisplayContext, entries: Entries) {
|
||||
CobblemonItems.pokeBalls.forEach(entries::add)
|
||||
entries.add(CobblemonItems.POKEROD)
|
||||
}
|
||||
|
||||
private fun foodInjections(injector: Injector) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
}
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
package com.cobblemon.mod.common.util
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.CobblemonBlocks
|
||||
import com.cobblemon.mod.common.block.entity.DyniteOreBlockEntity
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
@@ -24,6 +27,7 @@ import net.minecraft.util.math.MathHelper.floor
|
||||
import net.minecraft.world.BlockView
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.biome.Biome
|
||||
import net.minecraft.world.chunk.Chunk
|
||||
|
||||
fun World.playSoundServer(
|
||||
position: Vec3d,
|
||||
@@ -124,3 +128,15 @@ val World.itemRegistry: Registry<Item>
|
||||
get() = registryManager.get(RegistryKeys.ITEM)
|
||||
val World.biomeRegistry: Registry<Biome>
|
||||
get() = registryManager.get(RegistryKeys.BIOME)
|
||||
|
||||
/**
|
||||
* @return The amount of Dynite Ore in this chunk
|
||||
* @author whatsy
|
||||
*/
|
||||
fun Chunk.getDyniteOre(): Int {
|
||||
var count = 0
|
||||
this.blockEntityPositions.forEach {
|
||||
if (getBlockEntity(it) is DyniteOreBlockEntity) count++
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:meteor_ambient",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/shiny"
|
||||
}
|
||||
},
|
||||
"curves": {
|
||||
"variable.size": {
|
||||
"type": "linear",
|
||||
"input": "v.particle_age * 2",
|
||||
"horizontal_range": "v.particle_lifetime",
|
||||
"nodes": [0.5, 1, 0]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_looping": {
|
||||
"active_time": 1
|
||||
},
|
||||
"minecraft:emitter_shape_sphere": {
|
||||
"offset": [0, 0.3, 0],
|
||||
"radius": 0.3,
|
||||
"direction": "outwards"
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 1
|
||||
},
|
||||
"minecraft:particle_initial_speed": 0,
|
||||
"minecraft:particle_motion_dynamic": {},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["math.clamp(variable.particle_random_3,0.05,0.1) * variable.size", "math.clamp(variable.particle_random_3,0.05,0.1) * variable.size"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 8,
|
||||
"texture_height": 16,
|
||||
"uv": [0, 0],
|
||||
"uv_size": [8, 8]
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "variable.particle_random_3 * 1.2",
|
||||
"gradient": {
|
||||
"0.0": "#FFFFF9D3",
|
||||
"0.25": "#FFDFFFCA",
|
||||
"0.5": "#FFBCFCFF",
|
||||
"0.74": "#FFFFB7B7",
|
||||
"1.0": "#FFD7BDFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:meteor_fallen",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/bigsparkle"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 1
|
||||
},
|
||||
"minecraft:emitter_shape_point": {},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 1
|
||||
},
|
||||
"minecraft:particle_initial_spin": {
|
||||
"rotation": 13
|
||||
},
|
||||
"minecraft:particle_initial_speed": 0,
|
||||
"minecraft:particle_motion_dynamic": {},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": [0.8, 0.8],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 16,
|
||||
"texture_height": 96,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [16, 16],
|
||||
"step_UV": [0, 16],
|
||||
"frames_per_second": 6,
|
||||
"max_frame": 6,
|
||||
"loop": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "(v.particle_age / v.particle_lifetime) * variable.particle_random_3",
|
||||
"gradient": {
|
||||
"0.0": "#FFFFEBB8",
|
||||
"0.27": "#FFC3FFC1",
|
||||
"0.5": "#FFA2F3FF",
|
||||
"0.77": "#FFB2A9FF",
|
||||
"1.0": "#FFFF9A9A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:meteor_falling",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/bigsparkle"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 0.13
|
||||
},
|
||||
"minecraft:emitter_shape_point": {},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 0.13
|
||||
},
|
||||
"minecraft:particle_initial_spin": {
|
||||
"rotation": 13
|
||||
},
|
||||
"minecraft:particle_initial_speed": 0,
|
||||
"minecraft:particle_motion_dynamic": {},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": [0.8, 0.8],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 16,
|
||||
"texture_height": 96,
|
||||
"uv": [0, 48],
|
||||
"uv_size": [16, 16]
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "(v.particle_age / v.particle_lifetime) * variable.particle_random_3",
|
||||
"gradient": {
|
||||
"0.0": "#FFFFEBB8",
|
||||
"0.27": "#FFC3FFC1",
|
||||
"0.5": "#FFA2F3FF",
|
||||
"0.77": "#FFB2A9FF",
|
||||
"1.0": "#FFFF9A9A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:meteor_glitter",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_opaque",
|
||||
"texture": "textures/particles/pokeball_sparkle_yellow"
|
||||
}
|
||||
},
|
||||
"curves": {
|
||||
"variable.size": {
|
||||
"type": "linear",
|
||||
"input": "v.particle_age",
|
||||
"horizontal_range": "v.particle_lifetime",
|
||||
"nodes": [1, 1]
|
||||
},
|
||||
"variable.radius": {
|
||||
"type": "linear",
|
||||
"input": "v.particle_age",
|
||||
"horizontal_range": "v.particle_lifetime",
|
||||
"nodes": [1, 4]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_steady": {
|
||||
"spawn_rate": 20,
|
||||
"max_particles": 100
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 0.5
|
||||
},
|
||||
"minecraft:emitter_shape_sphere": {
|
||||
"radius": "0.8 * variable.radius",
|
||||
"direction": "outwards"
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 0.5
|
||||
},
|
||||
"minecraft:particle_initial_spin": {
|
||||
"rotation": "math.random(-360,360)"
|
||||
},
|
||||
"minecraft:particle_initial_speed": 2,
|
||||
"minecraft:particle_motion_dynamic": {
|
||||
"linear_drag_coefficient": 1.8
|
||||
},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["0.5*variable.size", "0.5*variable.size"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 8,
|
||||
"texture_height": 32,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [8, 8],
|
||||
"step_UV": [0, 8],
|
||||
"frames_per_second": 12,
|
||||
"max_frame": 5,
|
||||
"stretch_to_lifetime": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "v.particle_age / v.particle_lifetime",
|
||||
"gradient": {
|
||||
"0.0": "#FF98F1FD",
|
||||
"0.26": "#FFFFFDAE",
|
||||
"0.5": "#FFFFB1FB",
|
||||
"0.74": "#FF8EFFA7",
|
||||
"1.0": "#ffffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:meteor_impact",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/star"
|
||||
}
|
||||
},
|
||||
"curves": {
|
||||
"variable.size": {
|
||||
"type": "linear",
|
||||
"input": "v.particle_age * 1.2",
|
||||
"horizontal_range": "v.particle_lifetime",
|
||||
"nodes": [0, 1, 0]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 5
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 1
|
||||
},
|
||||
"minecraft:emitter_shape_point": {
|
||||
"offset": [0, 0.1, 0],
|
||||
"direction": ["math.random(-2,2)", 3, "math.random(-2,2)"]
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 2
|
||||
},
|
||||
"minecraft:particle_initial_spin": {
|
||||
"rotation": "math.random(0,360)",
|
||||
"rotation_rate": "variable.particle_random_3 * 360"
|
||||
},
|
||||
"minecraft:particle_initial_speed": 7,
|
||||
"minecraft:particle_motion_dynamic": {
|
||||
"linear_acceleration": [0, -8, 0],
|
||||
"linear_drag_coefficient": 2
|
||||
},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["math.clamp(variable.particle_random_3,0.2,0.3) * variable.size", "math.clamp(variable.particle_random_3,0.2,0.3) * variable.size"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 16,
|
||||
"texture_height": 32,
|
||||
"uv": [0, 0],
|
||||
"uv_size": [16, 16]
|
||||
}
|
||||
},
|
||||
"minecraft:particle_motion_collision": {
|
||||
"collision_drag": 0.1,
|
||||
"coefficient_of_restitution": 0.7,
|
||||
"collision_radius": 0.1
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "variable.particle_random_2",
|
||||
"gradient": {
|
||||
"0.0": "#FFFFFBD3",
|
||||
"0.19": "#FFFFCDCD",
|
||||
"0.5": "#FFBCFFC1",
|
||||
"0.71": "#FFBECAFF",
|
||||
"1.0": "#FFDFBCFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:meteor_trail",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_opaque",
|
||||
"texture": "textures/particles/impact-fairy"
|
||||
}
|
||||
},
|
||||
"curves": {
|
||||
"variable.size": {
|
||||
"type": "linear",
|
||||
"input": "v.particle_age",
|
||||
"horizontal_range": "v.particle_lifetime",
|
||||
"nodes": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_steady": {
|
||||
"spawn_rate": 30,
|
||||
"max_particles": 100
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 1
|
||||
},
|
||||
"minecraft:emitter_shape_sphere": {
|
||||
"radius": 0.3,
|
||||
"direction": "outwards"
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 0.5
|
||||
},
|
||||
"minecraft:particle_initial_spin": {
|
||||
"rotation": "math.random(-360,360)"
|
||||
},
|
||||
"minecraft:particle_initial_speed": 1,
|
||||
"minecraft:particle_motion_dynamic": {
|
||||
"linear_drag_coefficient": 1.7
|
||||
},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["0.2 * variable.size", "0.2 * variable.size"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 8,
|
||||
"texture_height": 56,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [8, 8],
|
||||
"step_UV": [0, 8],
|
||||
"frames_per_second": 12,
|
||||
"max_frame": 7,
|
||||
"stretch_to_lifetime": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "variable.particle_random_2",
|
||||
"gradient": {
|
||||
"0.0": "#FFFA9999",
|
||||
"0.23": "#FFFFF5BA",
|
||||
"0.5": "#FFBCFF9A",
|
||||
"0.74": "#FF5FE1FF",
|
||||
"1.0": "#FFFFFFFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "cobblemon:block/dynite_ore"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,8 @@
|
||||
"item.cobblemon.ancient_jet_ball": "Ancient Jet Ball",
|
||||
"item.cobblemon.ancient_origin_ball": "Ancient Origin Ball",
|
||||
|
||||
"item.cobblemon.pokerod": "Pokérod",
|
||||
|
||||
"item.cobblemon.black_apricorn_seed": "Black Apricorn Sprout",
|
||||
"item.cobblemon.blue_apricorn_seed": "Blue Apricorn Sprout",
|
||||
"item.cobblemon.green_apricorn_seed": "Green Apricorn Sprout",
|
||||
@@ -1415,6 +1417,7 @@
|
||||
"block.cobblemon.deepslate_water_stone_ore": "Deepslate Water Stone Ore",
|
||||
"block.cobblemon.dripstone_moon_stone_ore": "Dripstone Moon Stone Ore",
|
||||
"block.cobblemon.nether_fire_stone_ore": "Nether Fire Stone Ore",
|
||||
"block.cobblemon.dynite_ore": "Dynite Ore",
|
||||
"block.cobblemon.pasture": "Pasture Block",
|
||||
|
||||
"gamerule.doPokemonSpawning": "Spawn Pokémon",
|
||||
@@ -3306,6 +3309,7 @@
|
||||
|
||||
"cobblemon.entity.pokemon": "Pokémon",
|
||||
"entity.cobblemon.empty_pokeball": "Empty Poké Ball",
|
||||
"entity.cobblemon.falling_star": "Falling Star",
|
||||
|
||||
"cobblemon.species.bulbasaur.name": "Bulbasaur",
|
||||
"cobblemon.species.bulbasaur.desc": "While it is young, it uses the nutrients that are stored in the seed on its back in order to grow.",
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "cobblemon:block/dynite_ore"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"parent": "item/handheld_rod",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/fishing/pokerod"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"predicate": {
|
||||
"cast": 1
|
||||
},
|
||||
"model": "cobblemon:item/pokerod_cast"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/pokerod",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/fishing/pokerod_cast"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 156 B |
@@ -96,6 +96,8 @@ transitive-accessible field net/minecraft/client/model/ModelPart$Cuboid sides [L
|
||||
transitive-accessible class net/minecraft/client/model/ModelPart$Quad
|
||||
|
||||
transitive-accessible method net/minecraft/entity/ai/brain/Activity <init> (Ljava/lang/String;)V
|
||||
#accessible method net/minecraft/client/render/RenderLayer$MultiPhase (Ljava/lang/String;Lnet/minecraft/client/render/VertexFormat;Lnet/minecraft/client/render/VertexFormat$DrawMode;IZZLnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase;
|
||||
accessible method net/minecraft/client/item/ModelPredicateProviderRegistry register (Lnet/minecraft/util/Identifier;Lnet/minecraft/client/item/ClampedModelPredicateProvider;)V
|
||||
accessible method net/minecraft/client/item/ModelPredicateProviderRegistry register (Lnet/minecraft/item/Item;Lnet/minecraft/util/Identifier;Lnet/minecraft/client/item/ClampedModelPredicateProvider;)V
|
||||
|
||||
#accessible method net/minecraft/client/render/RenderLayer$MultiPhase (Ljava/lang/String;Lnet/minecraft/client/render/VertexFormat;Lnet/minecraft/client/render/VertexFormat$DrawMode;IZZLnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase;
|
||||
#String name, VertexFormat vertexFormat, VertexFormat.DrawMode drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent, MultiPhaseParameters phases
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"type": "minecraft:generic",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "cobblemon:poke_ball"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "minecraft:fishing_rod"
|
||||
},
|
||||
"X": {
|
||||
"item": "cobblemon:poke_ball"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"# ",
|
||||
" X"
|
||||
],
|
||||
"result": {
|
||||
"item": "cobblemon:pokerod"
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,15 @@
|
||||
"#cobblemon:is_ocean"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "magikarp-fishing-1",
|
||||
"pokemon": "magikarp",
|
||||
"type": "pokemon",
|
||||
"context": "fishing",
|
||||
"bucket": "common",
|
||||
"level": "1-20",
|
||||
"weight": 1.98
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"neededInstalledMods": [],
|
||||
"neededUninstalledMods": [],
|
||||
"spawns": [
|
||||
{
|
||||
"id": "minior-fallingstar-1",
|
||||
"pokemon": "minior",
|
||||
"type": "pokemon",
|
||||
"context": "fallingstar",
|
||||
"bucket": "common",
|
||||
"level": "1-20",
|
||||
"weight": 1.98
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.CobblemonClient.reloadCodedAssets
|
||||
import com.cobblemon.mod.common.client.keybind.CobblemonKeyBinds
|
||||
import com.cobblemon.mod.common.client.render.atlas.CobblemonAtlases
|
||||
import com.cobblemon.mod.common.client.render.item.CobblemonModelPredicateRegistry
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
|
||||
import com.cobblemon.mod.common.particle.CobblemonParticles
|
||||
import com.cobblemon.mod.common.particle.SnowstormParticleType
|
||||
import com.cobblemon.mod.common.platform.events.ClientPlayerEvent
|
||||
@@ -41,6 +43,7 @@ import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.client.color.block.BlockColorProvider
|
||||
import net.minecraft.client.color.item.ItemColorProvider
|
||||
import net.minecraft.client.item.ModelPredicateProviderRegistry
|
||||
import net.minecraft.client.model.TexturedModelData
|
||||
import net.minecraft.client.particle.ParticleFactory
|
||||
import net.minecraft.client.particle.SpriteProvider
|
||||
@@ -96,6 +99,8 @@ class CobblemonFabricClient: ClientModInitializer, CobblemonClientImplementation
|
||||
ClientPlayConnectionEvents.JOIN.register { _, _, client -> client.player?.let { PlatformEvents.CLIENT_PLAYER_LOGIN.post(ClientPlayerEvent.Login(it)) } }
|
||||
ClientPlayConnectionEvents.DISCONNECT.register { _, client -> client.player?.let { PlatformEvents.CLIENT_PLAYER_LOGOUT.post(ClientPlayerEvent.Logout(it)) } }
|
||||
ItemTooltipCallback.EVENT.register { stack, context, lines -> PlatformEvents.CLIENT_ITEM_TOOLTIP.post(ItemTooltipEvent(stack, context, lines)) }
|
||||
|
||||
CobblemonModelPredicateRegistry.registerPredicates()
|
||||
}
|
||||
|
||||
override fun registerLayer(modelLayer: EntityModelLayer, supplier: Supplier<TexturedModelData>) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.client.CobblemonClient.reloadCodedAssets
|
||||
import com.cobblemon.mod.common.client.keybind.CobblemonKeyBinds
|
||||
import com.cobblemon.mod.common.compat.LambDynamicLightsCompat
|
||||
import com.cobblemon.mod.common.client.render.shader.CobblemonShaders
|
||||
import com.cobblemon.mod.common.client.render.item.CobblemonModelPredicateRegistry
|
||||
import com.cobblemon.mod.common.item.group.CobblemonItemGroups
|
||||
import com.cobblemon.mod.common.particle.CobblemonParticles
|
||||
import com.cobblemon.mod.common.particle.SnowstormParticleType
|
||||
@@ -84,6 +85,7 @@ object CobblemonForgeClient : CobblemonClientImplementation {
|
||||
private fun onClientSetup(event: FMLClientSetupEvent) {
|
||||
event.enqueueWork {
|
||||
CobblemonClient.initialize(this)
|
||||
CobblemonModelPredicateRegistry.registerPredicates()
|
||||
this.attemptModCompat()
|
||||
}
|
||||
ForgeClientPlatformEventHandler.register()
|
||||
|
||||
Reference in New Issue
Block a user