Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c74f01bd6d | ||
|
|
199a8ba675 | ||
|
|
556f92e4b0 | ||
|
|
4f395ca47f | ||
|
|
2a5a292386 | ||
|
|
e8a09f5c48 | ||
|
|
e82193cdfd | ||
|
|
87e7cdebf6 | ||
|
|
9ca84d852f | ||
|
|
635f29e1ac | ||
|
|
db2001b60a | ||
|
|
b5098a2ad0 | ||
|
|
8c939ee276 | ||
|
|
645b8993c8 | ||
|
|
d96799cac7 | ||
|
|
b822b626c4 | ||
|
|
4d9b182fb3 | ||
|
|
88d155eaf4 | ||
|
|
af96469b7a | ||
|
|
65f1e7a3be | ||
|
|
16cd2de02f | ||
|
|
22a44bd7e9 | ||
|
|
d37bd4ef03 | ||
|
|
a3d9a10f2e | ||
|
|
7801e3feee | ||
|
|
4a54cb4674 | ||
|
|
24fe1c125c | ||
|
|
023160f87a | ||
|
|
17fbf7c6f0 | ||
|
|
ec86b7d4bf | ||
|
|
7561eb116f | ||
|
|
6467b97a23 | ||
|
|
6d5909a1e3 | ||
|
|
2bb0d43ca8 | ||
|
|
1fb3f0ebdc | ||
|
|
fb2154e2c3 | ||
|
|
3b14d19fdb | ||
|
|
6840c2fdef | ||
|
|
8fc2031806 | ||
|
|
4795e2e1bc | ||
|
|
c563627b05 | ||
|
|
73ebf7a789 | ||
|
|
a1b3d3d2ca | ||
|
|
8baacbcf90 | ||
|
|
f2e357b749 | ||
|
|
b95900b29a | ||
|
|
03585fafb0 | ||
|
|
e3d0252d75 | ||
|
|
dbe8e57341 | ||
|
|
6f37fd69cd | ||
|
|
b191f4e9fb | ||
|
|
a5a7cc20ba | ||
|
|
02b6c46082 | ||
|
|
881a30cca4 | ||
|
|
d01011f4d0 | ||
|
|
309ed379c7 | ||
|
|
edbf667f45 | ||
|
|
b6bc766adf | ||
|
|
1ecf556cf2 | ||
|
|
6d32073604 | ||
|
|
aa0f5d8a05 | ||
|
|
6202c14215 | ||
|
|
b0790341c7 | ||
|
|
4f0fa6af4a | ||
|
|
4e24e09924 | ||
|
|
48676067b7 | ||
|
|
6432db9f7d | ||
|
|
2cb28fb384 | ||
|
|
3b59148151 | ||
|
|
d6198631ba | ||
|
|
47daea6195 | ||
|
|
aca66a4bb0 | ||
|
|
e9fe1774c0 | ||
|
|
bb8b8a77c9 | ||
|
|
c692b6b5c1 | ||
|
|
68c6d5d9b2 | ||
|
|
221547aabf | ||
|
|
f6b3591d80 | ||
|
|
f9878d6137 | ||
|
|
94da3b8d21 |
@@ -17,6 +17,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.ai.memory.MemoryStatus;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BeehiveBlock;
|
||||
@@ -52,7 +53,9 @@ public abstract class BeeOccupantMixin {
|
||||
var facing = state.getValue(HorizontalDirectionalBlock.FACING);
|
||||
newPos = pos.relative(facing).getCenter();
|
||||
newYaw = facing.toYRot();
|
||||
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
|
||||
}
|
||||
} else {
|
||||
// Block has likely been destroyed
|
||||
var center = pos.getCenter();
|
||||
@@ -62,25 +65,31 @@ public abstract class BeeOccupantMixin {
|
||||
center.z + level.random.nextFloat() * 0.6 - 0.3
|
||||
);
|
||||
newYaw = level.random.nextFloat() * 360F;
|
||||
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
|
||||
}
|
||||
}
|
||||
entity.yRotO = newYaw;
|
||||
entity.setPos(newPos);
|
||||
// Do honey logic
|
||||
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
if (hasNectar) {
|
||||
// Remove nectar and reset got to hive cooldown
|
||||
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
|
||||
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
|
||||
// Increment honey level of the hive
|
||||
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
|
||||
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
|
||||
if (i < 5) {
|
||||
int j = level.random.nextInt(100) == 0 ? 2 : 1;
|
||||
if (i + j > 5) {
|
||||
--j;
|
||||
if (brain.checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)) {
|
||||
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
if (hasNectar) {
|
||||
// Remove nectar and reset got to hive cooldown
|
||||
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
|
||||
}
|
||||
// Increment honey level of the hive
|
||||
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
|
||||
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
|
||||
if (i < 5) {
|
||||
int j = level.random.nextInt(100) == 0 ? 2 : 1;
|
||||
if (i + j > 5) {
|
||||
--j;
|
||||
}
|
||||
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
|
||||
}
|
||||
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,12 +101,13 @@ public abstract class BeeOccupantMixin {
|
||||
@Inject(method = "of", at = @At("HEAD"), cancellable = true)
|
||||
private static void cobblemon$of(Entity entity, CallbackInfoReturnable<BeehiveBlockEntity.Occupant> cir) {
|
||||
if (entity instanceof PokemonEntity pokemonEntity) {
|
||||
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "Brain", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
|
||||
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
entity.save(compoundTag);
|
||||
Objects.requireNonNull(compoundTag);
|
||||
IGNORED_BEE_TAGS.forEach(compoundTag::remove);
|
||||
Boolean hasNectar = pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
boolean hasNectar = pokemonEntity.getBrain().checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)
|
||||
&& pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
cir.setReturnValue(new BeehiveBlockEntity.Occupant(CustomData.of(compoundTag), 0, hasNectar ? 2400 : 600));
|
||||
cir.cancel();
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.PreEmptsExplosion;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = Explosion.class)
|
||||
public class ExplosionMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "finalizeExplosion",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
public BlockState cobblemon$whenExploded(Level world, BlockPos pos) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if(blockState.getBlock() instanceof PreEmptsExplosion preExplosionBlock) {
|
||||
preExplosionBlock.whenExploded(world, blockState, pos);
|
||||
}
|
||||
return blockState;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import net.minecraft.stats.RecipeBookSettings;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(RecipeBookSettings.class)
|
||||
public class RecipeBookSettingsMixin {
|
||||
|
||||
|
||||
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void cobblemon$init(CallbackInfo ci) {
|
||||
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.client.CobblemonClient;
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.RidingFreelookBinding;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
|
||||
@@ -156,7 +157,7 @@ public abstract class MouseHandlerMixin {
|
||||
}
|
||||
|
||||
var vehicleController = controllableVehicle.getOrientationController();
|
||||
var lookaroundButtonPressed = Minecraft.getInstance().mouseHandler.isMiddlePressed();
|
||||
var freeLooking = RidingFreelookBinding.INSTANCE.isDown();
|
||||
Pair<Boolean, Boolean> mouseShouldModifyDriver = ((PokemonEntity) vehicle).ifRidingAvailableSupply(new Pair(false, false), (behaviour, settings, state) -> {
|
||||
return behaviour.mouseModifiesDriverRotation(
|
||||
settings,
|
||||
@@ -170,7 +171,7 @@ public abstract class MouseHandlerMixin {
|
||||
// affect the vehicle orientation when looking around.
|
||||
// If the client is a passenger it will modify these rotations and return
|
||||
//-------------------------------------------------------------------------
|
||||
if (lookaroundButtonPressed || player.getControlledVehicle() == null) {
|
||||
if (freeLooking || player.getControlledVehicle() == null) {
|
||||
// Modify driver rotations
|
||||
cobblemon$setDriverRotations(player, cursorDeltaX, cursorDeltaY);
|
||||
|
||||
@@ -192,10 +193,10 @@ public abstract class MouseHandlerMixin {
|
||||
// Smoothly return driver rotations to zero when needed
|
||||
//-------------------------------------------------------------------------
|
||||
var playerRotater = (RidePassenger)player;
|
||||
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getFirst()){
|
||||
if( !freeLooking && !mouseShouldModifyDriver.getFirst()){
|
||||
playerRotater.cobblemon$setRideYRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideYRot()), 0.0f));
|
||||
}
|
||||
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getSecond()) {
|
||||
if( !freeLooking && !mouseShouldModifyDriver.getSecond()) {
|
||||
playerRotater.cobblemon$setRideXRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideXRot()), 0.0f));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.mixin.entity;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
@@ -23,6 +24,7 @@ import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -68,18 +70,7 @@ public abstract class EntityMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$modifyEyePosition_partial(float partialTicks, CallbackInfoReturnable<Vec3> cir) {
|
||||
var entity = (Entity)(Object)this;
|
||||
if (entity.level().isClientSide) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
if (!(player instanceof RidePassenger ridePassenger)) return;
|
||||
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
|
||||
var vehicleController = vehicle.getOrientationController();
|
||||
if (vehicleController == null) return;
|
||||
|
||||
|
||||
// TODO: Determine if it needs partialtick involved.
|
||||
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
|
||||
cir.setReturnValue(customEyePos);
|
||||
cobblemon$getCustomEyePos(cir);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -88,15 +79,20 @@ public abstract class EntityMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$modifyEyePosition_noPartial(CallbackInfoReturnable<Vec3> cir) {
|
||||
cobblemon$getCustomEyePos(cir);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void cobblemon$getCustomEyePos(CallbackInfoReturnable<Vec3> cir) {
|
||||
var entity = (Entity)(Object)this;
|
||||
if (entity.level().isClientSide) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
if (!(player instanceof RidePassenger ridePassenger)) return;
|
||||
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
|
||||
if (!(vehicle instanceof PokemonEntity)) return;
|
||||
var vehicleController = vehicle.getOrientationController();
|
||||
if (vehicleController == null) return;
|
||||
|
||||
// TODO: Determine if it needs partialtick involved.
|
||||
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
|
||||
cir.setReturnValue(customEyePos);
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.cobblemon.mod.common.block.MintBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.client.pokedex.PokedexType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotColor
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
|
||||
import com.cobblemon.mod.common.item.*
|
||||
import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
|
||||
@@ -42,6 +43,7 @@ import com.cobblemon.mod.common.item.interactive.ability.AbilityChangeItem
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.IVs
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.Registry
|
||||
@@ -50,6 +52,7 @@ import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.effect.MobEffectInstance
|
||||
import net.minecraft.world.effect.MobEffects
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -66,6 +69,7 @@ import net.minecraft.world.item.SignItem
|
||||
import net.minecraft.world.item.SmithingTemplateItem
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import kotlin.math.ceil
|
||||
|
||||
@Suppress("unused", "SameParameterValue")
|
||||
object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<Item>>, Item>() {
|
||||
@@ -614,7 +618,11 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
|
||||
// Medicine
|
||||
@JvmField
|
||||
val RARE_CANDY = candyItem("rare_candy", Rarity.RARE) { _, pokemon -> pokemon.getExperienceToNextLevel() }
|
||||
val RARE_CANDY = candyItem("rare_candy", Rarity.RARE) { player, pokemon ->
|
||||
if (pokemon != null) return@candyItem pokemon.getExperienceToNextLevel()
|
||||
return@candyItem -1
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDY_XS = candyItem("exp_candy_xs") { _, _ -> CandyItem.DEFAULT_XS_CANDY_YIELD }
|
||||
@JvmField
|
||||
@@ -1476,7 +1484,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
return item
|
||||
}
|
||||
|
||||
private fun candyItem(name: String, rarity: Rarity = Rarity.COMMON, calculator: CandyItem.Calculator): CandyItem = this.create(name, CandyItem(rarity, calculator))
|
||||
private fun candyItem(name: String, rarity: Rarity = Rarity.COMMON, calculator: (ServerPlayer, Pokemon?) -> Int): CandyItem = this.create(name, CandyItem(rarity, calculator))
|
||||
|
||||
private fun pokerodItem(pokeRodId: ResourceLocation, rarity: Rarity = Rarity.COMMON): PokerodItem {
|
||||
val settings = Item.Properties().stacksTo(1).durability(256).rarity(rarity)
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import net.minecraft.client.RecipeBookCategories
|
||||
import net.minecraft.world.inventory.RecipeBookType
|
||||
|
||||
enum class CobblemonRecipeCategories {
|
||||
|
||||
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COOKING_POT_MISC");
|
||||
COOKING_POT_SEARCH("COBBLEMON_COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COBBLEMON_COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COBBLEMON_COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COBBLEMON_COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COBBLEMON_COOKING_POT_MISC");
|
||||
|
||||
companion object {
|
||||
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
|
||||
@@ -35,6 +36,9 @@ enum class CobblemonRecipeCategories {
|
||||
fun toVanillaCategory(): RecipeBookCategories {
|
||||
return RecipeBookCategories.valueOf(this.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object CobblemonRecipeBookTypes {
|
||||
const val COOKING_POT_NAME = "COBBLEMON_COOKING_POT"
|
||||
val COOKING_POT: RecipeBookType = RecipeBookType.valueOf(COOKING_POT_NAME)
|
||||
}
|
||||
@@ -89,7 +89,14 @@ object CobblemonTradeOffers {
|
||||
* @return The resulting list.
|
||||
*/
|
||||
fun resolveWanderingTradeOffers(): List<WandererTradeOffer> = listOf(
|
||||
WandererTradeOffer(false, listOf(VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6)))
|
||||
WandererTradeOffer(false, listOf(
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 6, 1, 1, 6),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.SACCHARINE_SAPLING, 5, 1, 4, 1),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.HEARTY_GRAINS, 1, 1, 12, 1),
|
||||
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.CHIPPED_POT, 5, 1, 1, 2),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.MASTERPIECE_TEACUP, 5, 1, 1, 2)
|
||||
))
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -109,7 +109,7 @@ class PollinateFlowerTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
|
||||
override fun stop(level: ServerLevel, entity: LivingEntity, gameTime: Long) {
|
||||
|
||||
hoverPos = null
|
||||
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
|
||||
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
|
||||
}
|
||||
|
||||
@@ -9,13 +9,8 @@
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.util.math.geometry.toDegrees
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import net.minecraft.util.FastColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
private val colourMap = mapOf(
|
||||
Flavour.SPICY to 0xFEB37D,
|
||||
@@ -34,27 +29,30 @@ private val bubbleColourMap = mapOf(
|
||||
)
|
||||
|
||||
fun getColourMixFromSeasonings(seasonings: List<ItemStack>, forBubbles: Boolean = false): Int? {
|
||||
val flavors = seasonings
|
||||
.mapNotNull { Seasonings.getFlavoursFromItemStack(it) }
|
||||
.flatMap { it.entries }
|
||||
.groupingBy { it.key }
|
||||
.fold(0) { acc, entry -> acc + entry.value }
|
||||
val flavourValues = mutableMapOf<Flavour, Int>()
|
||||
for (seasoning in seasonings) {
|
||||
val flavours = Seasonings.getFlavoursFromItemStack(seasoning) ?: continue
|
||||
for ((flavour, value) in flavours.entries) {
|
||||
flavourValues[flavour] = (flavourValues[flavour] ?: 0) + value
|
||||
}
|
||||
}
|
||||
|
||||
if (flavors.isEmpty()) return null
|
||||
if (flavourValues.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val maxFlavorValue = flavors.values.maxOrNull()
|
||||
val dominantFlavors = flavors.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
val maxFlavorValue = flavourValues.values.maxOrNull()
|
||||
val dominantFlavours = flavourValues.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
|
||||
return getColourMixFromFlavours(dominantFlavors, forBubbles)
|
||||
return getColourMixFromFlavours(dominantFlavours, forBubbles)
|
||||
}
|
||||
|
||||
fun getColourMixFromFlavours(dominantFlavours: List<Flavour>, forBubbles: Boolean = false): Int? {
|
||||
val colors =
|
||||
dominantFlavours.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
dominantFlavours
|
||||
.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
.map { FastColor.ARGB32.opaque(it) }
|
||||
|
||||
if (colors.isEmpty()) return null
|
||||
|
||||
return getColourMixFromColors(colors)
|
||||
}
|
||||
|
||||
@@ -62,104 +60,33 @@ fun getColourMixFromRideStatBoosts(dominantBoosts: Iterable<RidingStat>, forBubb
|
||||
return getColourMixFromFlavours(dominantBoosts.map { it.flavour }, forBubbles)
|
||||
}
|
||||
|
||||
// Mixing RGB colors directly often gives poor results
|
||||
// Converting them to HSL and averaging hues circularly produces more natural blends
|
||||
fun getColourMixFromColors(colors: List<Int>): Int? {
|
||||
if (colors.isEmpty()) return null
|
||||
if (colors.size == 1) return colors[0]
|
||||
|
||||
val hslColors = colors.map {
|
||||
val red = FastColor.ARGB32.red(it)
|
||||
val green = FastColor.ARGB32.green(it)
|
||||
val blue = FastColor.ARGB32.blue(it)
|
||||
val firstWeight = 0.7f
|
||||
val otherWeightTotal = 1f - firstWeight
|
||||
val otherWeight = otherWeightTotal / (colors.size - 1)
|
||||
|
||||
rgbToHsl(red, green, blue)
|
||||
var alphaSum = 0f
|
||||
var redSum = 0f
|
||||
var greenSum = 0f
|
||||
var blueSum = 0f
|
||||
|
||||
for (i in colors.indices) {
|
||||
val weight = if (i == 0) firstWeight else otherWeight
|
||||
val color = colors[i]
|
||||
|
||||
alphaSum += FastColor.ARGB32.alpha(color) * weight
|
||||
redSum += FastColor.ARGB32.red(color) * weight
|
||||
greenSum += FastColor.ARGB32.green(color) * weight
|
||||
blueSum += FastColor.ARGB32.blue(color) * weight
|
||||
}
|
||||
|
||||
val hues = hslColors.map { it.h.toDouble() }
|
||||
val huesAverage = hueAverage(hues).toFloat()
|
||||
val saturations = hslColors.map { it.s }
|
||||
val saturationsAverage = average(saturations)
|
||||
val lightness = hslColors.map { it.l }
|
||||
val lightnessAverage = average(lightness)
|
||||
|
||||
val rgbColor = hslToRgb(huesAverage, saturationsAverage, lightnessAverage)
|
||||
|
||||
return FastColor.ARGB32.color(rgbColor.r, rgbColor.g, rgbColor.b)
|
||||
}
|
||||
|
||||
// Based on https://iter.ca/post/hue-avg
|
||||
fun hueAverage(hues: List<Double>): Float {
|
||||
val points = hues.map { hue ->
|
||||
val rad = hue.toRadians()
|
||||
Pair(cos(rad), sin(rad))
|
||||
}
|
||||
|
||||
val avgX = points.sumOf { it.first.toDouble() } / points.size
|
||||
val avgY = points.sumOf { it.second.toDouble() } / points.size
|
||||
|
||||
var degrees = atan2(avgY, avgX).toDegrees()
|
||||
if (degrees < 0) {
|
||||
degrees += 360f
|
||||
} else if (degrees > 360) {
|
||||
degrees -= 360f
|
||||
}
|
||||
|
||||
return degrees
|
||||
}
|
||||
|
||||
fun average(values: List<Float>): Float {
|
||||
if (values.isEmpty()) return 0f
|
||||
return values.sum() / values.size
|
||||
}
|
||||
|
||||
data class HSL(val h: Float, val s: Float, val l: Float)
|
||||
|
||||
fun rgbToHsl(r: Int, g: Int, b: Int): HSL {
|
||||
val rf = r / 255f
|
||||
val gf = g / 255f
|
||||
val bf = b / 255f
|
||||
|
||||
val max = maxOf(rf, gf, bf)
|
||||
val min = minOf(rf, gf, bf)
|
||||
val delta = max - min
|
||||
|
||||
var h = 0f
|
||||
val l = (max + min) / 2f
|
||||
val s = if (delta == 0f) 0f else delta / (1f - kotlin.math.abs(2f * l - 1f))
|
||||
|
||||
if (delta != 0f) {
|
||||
h = when (max) {
|
||||
rf -> ((gf - bf) / delta) % 6f
|
||||
gf -> ((bf - rf) / delta) + 2f
|
||||
else -> ((rf - gf) / delta) + 4f
|
||||
}
|
||||
h *= 60f
|
||||
if (h < 0) h += 360f
|
||||
}
|
||||
|
||||
return HSL(h, s, l)
|
||||
}
|
||||
|
||||
data class RGB(val r: Int, val g: Int, val b: Int)
|
||||
|
||||
fun hslToRgb(h: Float, s: Float, l: Float): RGB {
|
||||
val c = (1f - kotlin.math.abs(2f * l - 1f)) * s
|
||||
val x = c * (1f - kotlin.math.abs((h / 60f) % 2f - 1f))
|
||||
val m = l - c / 2f
|
||||
|
||||
val (rf, gf, bf) = when {
|
||||
h < 60f -> Triple(c, x, 0f)
|
||||
h < 120f -> Triple(x, c, 0f)
|
||||
h < 180f -> Triple(0f, c, x)
|
||||
h < 240f -> Triple(0f, x, c)
|
||||
h < 300f -> Triple(x, 0f, c)
|
||||
else -> Triple(c, 0f, x)
|
||||
}
|
||||
|
||||
return RGB(
|
||||
((rf + m) * 255).toInt().coerceIn(0, 255),
|
||||
((gf + m) * 255).toInt().coerceIn(0, 255),
|
||||
((bf + m) * 255).toInt().coerceIn(0, 255)
|
||||
return FastColor.ARGB32.color(
|
||||
alphaSum.toInt(),
|
||||
redSum.toInt(),
|
||||
greenSum.toInt(),
|
||||
blueSum.toInt()
|
||||
)
|
||||
}
|
||||
@@ -37,8 +37,6 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import org.joml.Matrix4f
|
||||
import org.joml.Vector3f
|
||||
import org.lwjgl.opengl.GL30
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
@JvmOverloads
|
||||
fun blitk(
|
||||
@@ -357,10 +355,10 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
|
||||
val matrix: PoseStack.Pose = matrixStack.last()
|
||||
matrix.pose().translate(-1f, 0f, 0f)
|
||||
|
||||
RenderSystem.setShaderTexture(0, sprite);
|
||||
RenderSystem.setShaderTexture(0, sprite)
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader)
|
||||
|
||||
var buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
|
||||
val buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
|
||||
|
||||
buffer.addVertex(matrix, 2f, 0f, 0.0f).setUv(1f, 0f)
|
||||
buffer.addVertex(matrix, 0f, 0f, 0.0f).setUv(0f, 0f)
|
||||
@@ -369,25 +367,3 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
|
||||
|
||||
BufferUploader.drawWithShader(buffer.buildOrThrow())
|
||||
}
|
||||
|
||||
fun getPixelRGB(x: Int, y: Int): Triple<Int, Int, Int> {
|
||||
val window = Minecraft.getInstance().window
|
||||
val scale = window.guiScale
|
||||
val buffer = ByteBuffer.allocateDirect(4)
|
||||
|
||||
RenderSystem.readPixels(
|
||||
(x * scale).toInt(),
|
||||
(window.height - y * scale - scale).toInt(),
|
||||
1,
|
||||
1,
|
||||
GL30.GL_RGBA,
|
||||
GL30.GL_UNSIGNED_BYTE,
|
||||
buffer
|
||||
)
|
||||
|
||||
return Triple(
|
||||
buffer[0].toInt() and 0xFF,
|
||||
buffer[1].toInt() and 0xFF,
|
||||
buffer[2].toInt() and 0xFF
|
||||
)
|
||||
}
|
||||
|
||||
@@ -409,13 +409,7 @@ open class PokemonProperties {
|
||||
shiny?.let { pokemon.shiny = it }
|
||||
gender?.let { pokemon.gender = it }
|
||||
level?.let { pokemon.level = it }
|
||||
friendship.also {
|
||||
if (it != null) {
|
||||
pokemon.setFriendship(it)
|
||||
} else {
|
||||
pokemon.setFriendship(pokemon.form.baseFriendship)
|
||||
}
|
||||
}
|
||||
friendship?.also { pokemon.setFriendship(it) }
|
||||
fullness?.let { pokemon.currentFullness = it }
|
||||
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemon.caughtBall = pokeball } }
|
||||
nature?.let { Natures.getNature(it.asIdentifierDefaultingNamespace())?.let { nature -> pokemon.nature = nature } }
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import net.minecraft.commands.CommandSourceStack
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
/**
|
||||
@@ -25,8 +26,13 @@ interface ExperienceSource {
|
||||
fun isInteraction() = this is CandyExperienceSource
|
||||
fun isCommand() = this is CommandExperienceSource
|
||||
fun isSidemod() = this is SidemodExperienceSource
|
||||
fun isMob() = this is MobExperienceSource
|
||||
}
|
||||
|
||||
open class MobExperienceSource(
|
||||
mob: LivingEntity,
|
||||
) : ExperienceSource
|
||||
|
||||
open class SidemodExperienceSource(
|
||||
val sidemodId: String
|
||||
) : ExperienceSource
|
||||
|
||||
@@ -40,9 +40,12 @@ class PokemonSpawnAction(
|
||||
override fun createEntity(): PokemonEntity {
|
||||
val props = props.copy()
|
||||
props.level = levelRange.random()
|
||||
|
||||
val sourcePlayer = spawnablePosition.cause.entity as? ServerPlayer
|
||||
val entity = props.createEntity(spawnablePosition.world, sourcePlayer)
|
||||
entity.spawnCause = spawnablePosition.cause
|
||||
entity.pokemon.setFriendship(entity.pokemon.form.baseFriendship)
|
||||
|
||||
SeasonFeatureHandler.updateSeason(entity.pokemon, Cobblemon.seasonResolver(spawnablePosition.world, spawnablePosition.position))
|
||||
val heldItem = heldItem
|
||||
if (heldItem != ItemStack.EMPTY && heldItem != null) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.tags.FluidTags
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.*
|
||||
import net.minecraft.world.level.block.Block
|
||||
@@ -175,7 +174,7 @@ class HeartyGrainsBlock(settings: Properties) : CropBlock(settings), SimpleWater
|
||||
UPDATE_CLIENTS
|
||||
)
|
||||
}
|
||||
else if (stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
|
||||
else if (stateAbove.hasProperty(HALF) && stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
|
||||
world.setBlock(
|
||||
abovePos,
|
||||
stateAbove.setValue(AGE, newAge),
|
||||
|
||||
@@ -34,6 +34,7 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Explosion
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.LevelReader
|
||||
@@ -55,9 +56,10 @@ import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import java.util.*
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.gameevent.GameEvent
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION", "DEPRECATION")
|
||||
class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWaterloggedBlock, PreEmptsExplosion {
|
||||
class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWaterloggedBlock {
|
||||
companion object {
|
||||
val CODEC = simpleCodec(::PastureBlock)
|
||||
|
||||
@@ -213,9 +215,19 @@ class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWater
|
||||
return super.playerWillDestroy(world, pos, state, player)
|
||||
}
|
||||
|
||||
override fun whenExploded(world: Level, state: BlockState, pos: BlockPos) {
|
||||
val blockEntity = world.getBlockEntity(pos) as? PokemonPastureBlockEntity ?: return
|
||||
blockEntity.onBroken()
|
||||
override fun onExplosionHit(
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
explosion: Explosion,
|
||||
dropConsumer: BiConsumer<ItemStack?, BlockPos?>
|
||||
) {
|
||||
val interaction = explosion.blockInteraction
|
||||
if (interaction == Explosion.BlockInteraction.DESTROY || interaction == Explosion.BlockInteraction.DESTROY_WITH_DECAY) {
|
||||
val blockEntity = level.getBlockEntity(pos) as? PokemonPastureBlockEntity ?: return
|
||||
blockEntity.onBroken()
|
||||
}
|
||||
super.onExplosionHit(state, level, pos, explosion, dropConsumer)
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity?> getTicker(world: Level, state: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.block
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.Level
|
||||
|
||||
interface PreEmptsExplosion {
|
||||
fun whenExploded(world: Level, state: BlockState, pos: BlockPos)
|
||||
}
|
||||
@@ -271,15 +271,16 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings) {
|
||||
player.addItem(Items.HONEY_BOTTLE.defaultInstance)
|
||||
|
||||
level.playSound(null, pos, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS)
|
||||
level.setBlock(pos, state.setValue(AGE, 0), 2)
|
||||
level.setBlock(pos, state.setValue(AGE, 0), UPDATE_CLIENTS)
|
||||
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
|
||||
return ItemInteractionResult.SUCCESS
|
||||
} else if (isHoneyBottle && !isAtMaxAge(state)) {
|
||||
// Decrement stack if not in creative mode
|
||||
itemStack.consume(1, player)
|
||||
player.addItem(Items.GLASS_BOTTLE.defaultInstance)
|
||||
|
||||
level.playSound(null, pos, SoundEvents.HONEY_BLOCK_PLACE, SoundSource.BLOCKS)
|
||||
level.setBlock(pos, state.setValue(AGE, 2), 2)
|
||||
level.setBlock(pos, state.setValue(AGE, 2), UPDATE_CLIENTS)
|
||||
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
|
||||
return ItemInteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.block.campfirepot
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMenuType
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes.COOKING_POT
|
||||
import com.cobblemon.mod.common.CobblemonRecipeTypes
|
||||
import com.cobblemon.mod.common.api.cooking.Seasonings
|
||||
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity
|
||||
@@ -211,7 +212,7 @@ class CookingPotMenu : RecipeBookMenu<CraftingInput, CookingPotRecipeBase>, Cont
|
||||
}
|
||||
|
||||
override fun getRecipeBookType(): RecipeBookType {
|
||||
return RecipeBookType.valueOf("COOKING_POT")
|
||||
return COOKING_POT
|
||||
}
|
||||
|
||||
override fun shouldMoveToInventory(slotIndex: Int): Boolean {
|
||||
|
||||
@@ -111,13 +111,18 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
|
||||
BlockEntitySoundTracker.stop(pos, campfireBlockEntity.ambientSound.location)
|
||||
}
|
||||
|
||||
campfireBlockEntity.brothColor =
|
||||
getColourMixFromSeasonings(campfireBlockEntity.getSeasonings())
|
||||
?: BASE_BROTH_COLOR
|
||||
val seasonings = campfireBlockEntity.getSeasonings()
|
||||
if (seasonings.size != campfireBlockEntity.lastSeasoningStacks.size || seasonings.any { it !in campfireBlockEntity.lastSeasoningStacks }) {
|
||||
campfireBlockEntity.lastSeasoningStacks = seasonings
|
||||
|
||||
campfireBlockEntity.bubbleColor =
|
||||
getColourMixFromSeasonings(campfireBlockEntity.getSeasonings(), true)
|
||||
?: BASE_BROTH_BUBBLE_COLOR
|
||||
campfireBlockEntity.brothColor =
|
||||
getColourMixFromSeasonings(seasonings)
|
||||
?: BASE_BROTH_COLOR
|
||||
|
||||
campfireBlockEntity.bubbleColor =
|
||||
getColourMixFromSeasonings(seasonings, true)
|
||||
?: BASE_BROTH_BUBBLE_COLOR
|
||||
}
|
||||
|
||||
if (campfireBlockEntity.particleCooldown > 0) {
|
||||
campfireBlockEntity.particleCooldown--
|
||||
@@ -241,6 +246,9 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
|
||||
var bubbleColor: Int = BASE_BROTH_BUBBLE_COLOR
|
||||
var time: Int = 0
|
||||
|
||||
/** Used to know if we should be changing the colour of the broth or if we can go with the previous colour. */
|
||||
var lastSeasoningStacks = listOf<ItemStack>()
|
||||
|
||||
var dataAccess: ContainerData = object : ContainerData {
|
||||
override fun get(index: Int): Int {
|
||||
return when (index) {
|
||||
|
||||
@@ -49,7 +49,6 @@ import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import java.util.*
|
||||
|
||||
open class PokeSnackBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
TintBlockEntity(CobblemonBlockEntities.POKE_SNACK, pos, state),
|
||||
@@ -120,7 +119,7 @@ open class PokeSnackBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
level.dimension(),
|
||||
)
|
||||
|
||||
block.eat(level, blockPos, blockState, action.spawnablePosition.cause.entity as? Player)
|
||||
block.eat(level, blockPos, blockState, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ object CobblemonClient {
|
||||
) { it is PokemonEntity }
|
||||
|
||||
nearbyPokemon?.forEach { entity ->
|
||||
if (entity is PokemonEntity && !entity.isSilent) {
|
||||
if (entity is PokemonEntity && !entity.isSilent && !entity.passengers.contains(player)) {
|
||||
if (player.isLookingAt(entity) && !player.isSpectator && entity.pokemon.shiny) entity.delegate.spawnShinyParticle(player)
|
||||
entity.delegate.spawnAspectParticle()
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import kotlin.math.max
|
||||
class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
companion object {
|
||||
private const val FADE_FRAMES = 20F
|
||||
private const val CONTROLS_FADE_FRAMES = 20F
|
||||
private const val BASELINE_FPS = 60F
|
||||
|
||||
private const val HALF_SCALE = 0.5F
|
||||
@@ -63,9 +63,9 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
private val screenExemptions: List<Class<out Screen>> = listOf(ChatScreen::class.java)
|
||||
|
||||
private var maxDurationFrames = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
private var durationFrames = maxDurationFrames
|
||||
private var fadeFrames = FADE_FRAMES
|
||||
private var controlsMaxDurationFrames = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
private var controlsDurationFrames = controlsMaxDurationFrames
|
||||
private var controlsFadeFrames = CONTROLS_FADE_FRAMES
|
||||
|
||||
private var lastMouseX = 0
|
||||
private var lastMouseY = 0
|
||||
@@ -88,123 +88,132 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
if (minecraft.options.hideGui || minecraft.debugOverlay.showDebugScreen()) return
|
||||
|
||||
val riddenEntity = minecraft.player?.vehicle
|
||||
if (riddenEntity != null && riddenEntity is PokemonEntity) {
|
||||
// Update max duration if user has changed config
|
||||
val configDuration = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
if (maxDurationFrames != configDuration) {
|
||||
maxDurationFrames = configDuration
|
||||
resetOverlayState()
|
||||
}
|
||||
|
||||
// Don't render if duration config set to 0 or less
|
||||
if (maxDurationFrames <= 0F) return
|
||||
|
||||
val rideBehaviourSettings = riddenEntity.ridingController?.context?.settings ?: return
|
||||
val ridingBehaviourState = riddenEntity.ridingController?.context?.state ?: return
|
||||
val rideBehaviourKey = rideBehaviourSettings.key
|
||||
|
||||
// Update current ride behaviour if changed
|
||||
// If composite, get active behaviour instead
|
||||
if (rideBehaviourKey == CompositeBehaviour.KEY) {
|
||||
val activeBehaviour = (ridingBehaviourState as CompositeState).activeBehaviour.get()
|
||||
if (currentBehaviourKey != activeBehaviour) {
|
||||
currentBehaviourKey = activeBehaviour
|
||||
resetOverlayState()
|
||||
minecraft.player?.let { player ->
|
||||
val riddenEntity = player.vehicle
|
||||
if (riddenEntity != null && riddenEntity is PokemonEntity) {
|
||||
// Only show controls to driver
|
||||
if (riddenEntity === player.controlledVehicle) {
|
||||
renderControls(minecraft, context, tickCounter, riddenEntity)
|
||||
}
|
||||
} else if (currentBehaviourKey != rideBehaviourKey) {
|
||||
currentBehaviourKey = rideBehaviourKey
|
||||
resetOverlayState()
|
||||
} else {
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
|
||||
// Render elements if entity has ride behaviour and if display duration has not ended yet
|
||||
if (rideBehaviourSettings != null && fadeFrames > 0) {
|
||||
val tickDelta = tickCounter.realtimeDeltaTicks.takeIf { !minecraft.isPaused } ?: 0F
|
||||
val updateInterval = (tickDelta / 20F) * BASELINE_FPS
|
||||
|
||||
durationFrames = max(durationFrames - updateInterval, 0F)
|
||||
if (durationFrames == 0F && fadeFrames > 0) fadeFrames = max(fadeFrames - updateInterval, 0F)
|
||||
|
||||
var showVerticalMouse = true // Show moving mouse up and down with arrows
|
||||
var showHorizontalMouse = true // Show moving mouse left and right with arrows
|
||||
var showSneakKey = true
|
||||
var showJumpKey = true
|
||||
var showMovementKeys = true
|
||||
var disableHorizontalMovementKeys = false // Disable left and right movement keys
|
||||
|
||||
// Configure what controls to show for each behaviour
|
||||
when (currentBehaviourKey) {
|
||||
BirdBehaviour.KEY -> {}
|
||||
BoatBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
BurstBehaviour.KEY -> {}
|
||||
DolphinBehaviour.KEY -> {
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
GliderBehaviour.KEY -> {}
|
||||
HelicopterBehaviour.KEY -> {}
|
||||
HorseBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
}
|
||||
HoverBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
}
|
||||
JetBehaviour.KEY -> {
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
MinekartBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
RocketBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
}
|
||||
VehicleBehaviour.KEY -> {}
|
||||
}
|
||||
|
||||
val centerX = minecraft.window.guiScaledWidth / 2
|
||||
val centerY = minecraft.window.guiScaledHeight / 2
|
||||
|
||||
renderMouseControls(
|
||||
context,
|
||||
!showMovementKeys && !showJumpKey && !showSneakKey,
|
||||
showHorizontalMouse,
|
||||
showVerticalMouse,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
fadeFrames / FADE_FRAMES
|
||||
)
|
||||
renderKeyControls(
|
||||
context,
|
||||
!showHorizontalMouse && !showVerticalMouse,
|
||||
showMovementKeys,
|
||||
disableHorizontalMovementKeys,
|
||||
showJumpKey,
|
||||
showSneakKey,
|
||||
minecraft.player?.input,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
fadeFrames / FADE_FRAMES
|
||||
)
|
||||
}
|
||||
} else {
|
||||
resetOverlayState()
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetOverlayState() {
|
||||
if (durationFrames != maxDurationFrames) durationFrames = maxDurationFrames
|
||||
if (fadeFrames != FADE_FRAMES) fadeFrames = FADE_FRAMES
|
||||
private fun renderControls(minecraft: Minecraft, context: GuiGraphics, tickCounter: DeltaTracker, riddenEntity: PokemonEntity) {
|
||||
// Update max duration if user has changed config
|
||||
val configDuration = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
if (controlsMaxDurationFrames != configDuration) {
|
||||
controlsMaxDurationFrames = configDuration
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
|
||||
// Don't render if duration config set to 0 or less
|
||||
if (controlsMaxDurationFrames <= 0F) return
|
||||
|
||||
val rideBehaviourSettings = riddenEntity.ridingController?.context?.settings ?: return
|
||||
val ridingBehaviourState = riddenEntity.ridingController?.context?.state ?: return
|
||||
val rideBehaviourKey = rideBehaviourSettings.key
|
||||
|
||||
// Update current ride behaviour if changed
|
||||
// If composite, get active behaviour instead
|
||||
if (rideBehaviourKey == CompositeBehaviour.KEY) {
|
||||
val activeBehaviour = (ridingBehaviourState as CompositeState).activeBehaviour.get()
|
||||
if (currentBehaviourKey != activeBehaviour) {
|
||||
currentBehaviourKey = activeBehaviour
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
} else if (currentBehaviourKey != rideBehaviourKey) {
|
||||
currentBehaviourKey = rideBehaviourKey
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
|
||||
// Render elements if entity has ride behaviour and if display duration has not ended yet
|
||||
if (rideBehaviourSettings != null && controlsFadeFrames > 0) {
|
||||
val tickDelta = tickCounter.realtimeDeltaTicks.takeIf { !minecraft.isPaused } ?: 0F
|
||||
val updateInterval = (tickDelta / 20F) * BASELINE_FPS
|
||||
|
||||
controlsDurationFrames = max(controlsDurationFrames - updateInterval, 0F)
|
||||
if (controlsDurationFrames == 0F && controlsFadeFrames > 0) controlsFadeFrames = max(controlsFadeFrames - updateInterval, 0F)
|
||||
|
||||
var showVerticalMouse = true // Show moving mouse up and down with arrows
|
||||
var showHorizontalMouse = true // Show moving mouse left and right with arrows
|
||||
var showSneakKey = true
|
||||
var showJumpKey = true
|
||||
var showMovementKeys = true
|
||||
var disableHorizontalMovementKeys = false // Disable left and right movement keys
|
||||
|
||||
// Configure what controls to show for each behaviour
|
||||
when (currentBehaviourKey) {
|
||||
BirdBehaviour.KEY -> {}
|
||||
BoatBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
BurstBehaviour.KEY -> {}
|
||||
DolphinBehaviour.KEY -> {
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
GliderBehaviour.KEY -> {}
|
||||
HelicopterBehaviour.KEY -> {}
|
||||
HorseBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
}
|
||||
HoverBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
}
|
||||
JetBehaviour.KEY -> {
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
MinekartBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
RocketBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
}
|
||||
VehicleBehaviour.KEY -> {}
|
||||
}
|
||||
|
||||
val centerX = minecraft.window.guiScaledWidth / 2
|
||||
val centerY = minecraft.window.guiScaledHeight / 2
|
||||
|
||||
renderMouseControls(
|
||||
context,
|
||||
!showMovementKeys && !showJumpKey && !showSneakKey,
|
||||
showHorizontalMouse,
|
||||
showVerticalMouse,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
controlsFadeFrames / CONTROLS_FADE_FRAMES
|
||||
)
|
||||
renderKeyControls(
|
||||
context,
|
||||
!showHorizontalMouse && !showVerticalMouse,
|
||||
showMovementKeys,
|
||||
disableHorizontalMovementKeys,
|
||||
showJumpKey,
|
||||
showSneakKey,
|
||||
minecraft.player?.input,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
controlsFadeFrames / CONTROLS_FADE_FRAMES
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetControlsOverlayState() {
|
||||
if (controlsDurationFrames != controlsMaxDurationFrames) controlsDurationFrames = controlsMaxDurationFrames
|
||||
if (controlsFadeFrames != CONTROLS_FADE_FRAMES) controlsFadeFrames = CONTROLS_FADE_FRAMES
|
||||
if (mouseMovedUp != null) {
|
||||
mouseMovedUp = null
|
||||
lastMouseY = 0
|
||||
@@ -413,7 +422,7 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
if (showJump || showSneak) {
|
||||
val offsetY = if (showMovement) 0 else -14
|
||||
var label: MutableComponent? = null
|
||||
var label: MutableComponent?
|
||||
|
||||
if (showJump && showSneak) {
|
||||
label = "key.sneak".asTranslated().append("/").append("key.jump".asTranslated())
|
||||
|
||||
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.gui.pc
|
||||
import com.cobblemon.mod.common.CobblemonNetwork
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.gui.getPixelRGB
|
||||
import com.cobblemon.mod.common.api.storage.StorePosition
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyPosition
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCPosition
|
||||
@@ -284,20 +283,6 @@ class StorageWidget(
|
||||
height = 189,
|
||||
alpha = if (screenLoaded) 1F else ((pcGui.ticksElapsed).toFloat() / 10F).coerceIn(0F, 1F)
|
||||
)
|
||||
} else {
|
||||
val rgb = getPixelRGB(x + (SCREEN_WIDTH / 2), y + (SCREEN_HEIGHT / 2))
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = screenGlowResource,
|
||||
x = x - 17,
|
||||
y = y - 17,
|
||||
width = 208,
|
||||
height = 189,
|
||||
red = rgb.first / 255F,
|
||||
green = rgb.second / 255F,
|
||||
blue = rgb.third / 255F,
|
||||
alpha = if (screenLoaded) 1F else ((pcGui.ticksElapsed).toFloat() / 10F).coerceIn(0F, 1F)
|
||||
)
|
||||
}
|
||||
|
||||
blitk(
|
||||
|
||||
@@ -38,6 +38,7 @@ object CobblemonKeyBinds {
|
||||
val PARTY_OVERLAY_DOWN = this.queue(DownShiftPartyBinding)
|
||||
val PARTY_OVERLAY_UP = this.queue(UpShiftPartyBinding)
|
||||
val SEND_OUT_POKEMON = this.queue(PartySendBinding)
|
||||
val RIDING_FREELOOK = this.queue(RidingFreelookBinding)
|
||||
|
||||
fun register(registrar: (KeyMapping) -> Unit) {
|
||||
this.keyBinds.forEach(registrar::invoke)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.keybind.keybinds
|
||||
|
||||
import com.cobblemon.mod.common.client.keybind.CobblemonBlockingKeyBinding
|
||||
import com.cobblemon.mod.common.client.keybind.KeybindCategories
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
|
||||
|
||||
object RidingFreelookBinding : CobblemonBlockingKeyBinding(
|
||||
"key.cobblemon.ridingfreelook",
|
||||
InputConstants.Type.MOUSE,
|
||||
InputConstants.MOUSE_BUTTON_MIDDLE,
|
||||
KeybindCategories.COBBLEMON_CATEGORY
|
||||
) {
|
||||
override fun onTick() {
|
||||
}
|
||||
override fun onRelease() {
|
||||
}
|
||||
override fun onPress() {
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import com.cobblemon.mod.common.duck.CameraDuck
|
||||
import com.cobblemon.mod.common.duck.RidePassenger
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.util.toVec3d
|
||||
import com.mojang.blaze3d.Blaze3D
|
||||
import net.minecraft.client.Camera
|
||||
import net.minecraft.client.CameraType
|
||||
@@ -35,6 +34,7 @@ import net.minecraft.world.phys.HitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.Matrix3f
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3d
|
||||
import org.joml.Vector3f
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sign
|
||||
@@ -81,7 +81,6 @@ object MountedCameraRenderer {
|
||||
val currEyeHeight: Double = Mth.lerp(instance.partialTickTime.toDouble(), eyeHeight, eyeHeightOld)
|
||||
var offset = Vec3(0.0, currEyeHeight - (driver.bbHeight / 2), 0.0)
|
||||
var eyeOffset = Vec3(0.0, currEyeHeight - (driver.bbHeight / 2), 0.0)
|
||||
val locatorOffset = Vec3(locator.matrix.getTranslation(Vector3f()))
|
||||
|
||||
val shouldFlip = !(vehicleController.active && vehicleController.orientation != null) // Do not flip the offset for 3rd person reverse unless we are using normal mc camera rotation.
|
||||
val isFirstPerson = Minecraft.getInstance().options.cameraType == CameraType.FIRST_PERSON
|
||||
@@ -103,15 +102,17 @@ object MountedCameraRenderer {
|
||||
else Quaternionf()
|
||||
.rotateY((Math.PI.toFloat() - Mth.lerp(instance.partialTickTime, vehicle.yRotO, vehicle.yRot).toRadians()))
|
||||
|
||||
offset = rotation.transform(offset.toVector3f()).toVec3d()
|
||||
eyeOffset = rotation.transform(eyeOffset.toVector3f()).toVec3d()
|
||||
offset = rotation.transform(Vector3d(offset.x, offset.y, offset.z)).let { Vec3(it.x, it.y, it.z) }
|
||||
eyeOffset = rotation.transform(Vector3d(eyeOffset.x, eyeOffset.y, eyeOffset.z)).let { Vec3(it.x, it.y, it.z) }
|
||||
|
||||
val eyePos = locatorOffset.add(entityPos)
|
||||
val eyeLocatorOffset = Vec3(locator.matrix.getTranslation(Vector3f()))
|
||||
val eyePos = eyeLocatorOffset.add(entityPos)
|
||||
|
||||
// Get the camera position before offsets are applied (which are done with maxZoom to account for clipping). If 3rd person viewbobbing is enabled or the player is
|
||||
// in first person then base the camera position off the seat locator offset
|
||||
val pos = /* if (isFirstPerson || Cobblemon.config.thirdPersonViewBobbing) { */
|
||||
locatorOffset.add(entityPos)
|
||||
Vec3(locator.matrix.getTranslation(Vector3f()))
|
||||
.add(entityPos)
|
||||
/* } else {
|
||||
val pokemonCenter = Vector3f(0f, driver.bbHeight/2, 0f)
|
||||
|
||||
@@ -326,7 +327,7 @@ object MountedCameraRenderer {
|
||||
locatorName: String,
|
||||
shouldFlip: Boolean = true
|
||||
): Vec3 {
|
||||
var offset = if (thirdPersonReverse && cameraOffsets.containsKey(locatorName + "_reverse")) {
|
||||
val offset = if (thirdPersonReverse && cameraOffsets.containsKey(locatorName + "_reverse")) {
|
||||
cameraOffsets[locatorName + "_reverse"]!!
|
||||
} else if (cameraOffsets.containsKey(locatorName)) {
|
||||
cameraOffsets[locatorName]!!
|
||||
@@ -336,8 +337,7 @@ object MountedCameraRenderer {
|
||||
|
||||
// Don't need to account for this since orientation is derived from camera rotation and that z is already flipped.
|
||||
// Flip only when not on a rollable.
|
||||
if (thirdPersonReverse && shouldFlip) offset = offset.multiply(1.0, 1.0, -1.0)
|
||||
return offset
|
||||
return if (thirdPersonReverse && shouldFlip) offset.multiply(1.0, 1.0, -1.0) else offset
|
||||
}
|
||||
|
||||
private fun getFirstPersonOffset(model: PosableModel, locatorName: String): Vec3 {
|
||||
|
||||
@@ -344,6 +344,9 @@ class CobblemonConfig {
|
||||
@CobblemonConfigField(Category.Spawning, lang = "despawner_max_age_ticks", SERVER)
|
||||
var despawnerMaxAgeTicks = 3600
|
||||
|
||||
@CobblemonConfigField(Category.World, lang = "mob_experience_conversion_rate", SERVER)
|
||||
var mobExperienceConversionRate = 50.0
|
||||
|
||||
fun clone(): CobblemonConfig {
|
||||
val newConfig = CobblemonConfig()
|
||||
CobblemonConfig::class.memberProperties.forEach { property ->
|
||||
|
||||
@@ -186,7 +186,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
|
||||
|
||||
val blockState = this.world.getBlockState(target)
|
||||
val path = if (!blockState.isSolid
|
||||
|| (blockState.`is`(BlockTags.LEAVES) && blockState.block == CobblemonBlocks.SACCHARINE_LEAVES && (this.entity as PokemonEntity).canPathThroughSaccLeaves())) {
|
||||
|| (blockState.`is`(BlockTags.LEAVES) && blockState.block == CobblemonBlocks.SACCHARINE_LEAVES && pather.canPathThroughSaccLeaves())) {
|
||||
findPath(target, distance)
|
||||
} else {
|
||||
blockPos = target.above()
|
||||
@@ -269,7 +269,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
|
||||
// If we can fly and we're airborne, return the current Y position
|
||||
return vec.y
|
||||
}
|
||||
if (world.getBlockState(blockPos).block == CobblemonBlocks.SACCHARINE_LEAVES && (this.entity as PokemonEntity).canPathThroughSaccLeaves()) {
|
||||
if (world.getBlockState(blockPos).block == CobblemonBlocks.SACCHARINE_LEAVES && pather.canPathThroughSaccLeaves()) {
|
||||
return vec.y + 0.5
|
||||
}
|
||||
return if ((canFloat()) && blockGetter.getFluidState(blockPos).`is`(FluidTags.WATER)) vec.y + 0.5 else super.getGroundY(vec)
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.cobblemon.mod.common.api.net.serializers.PoseTypeDataSerializer
|
||||
import com.cobblemon.mod.common.api.net.serializers.RideBoostsDataSerializer
|
||||
import com.cobblemon.mod.common.api.net.serializers.StringSetDataSerializer
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.pokemon.experience.MobExperienceSource
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.ChoiceSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.FlagSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
@@ -1259,7 +1260,18 @@ open class PokemonEntity(
|
||||
|
||||
override fun doHurtTarget(target: Entity): Boolean {
|
||||
if (beamMode != 0) return false
|
||||
return super.doHurtTarget(target)
|
||||
val result = super.doHurtTarget(target)
|
||||
if (result && !target.isAlive && target is LivingEntity && !level().isClientSide) {
|
||||
val experience = target.getExperienceReward(level() as ServerLevel, this)
|
||||
val source = MobExperienceSource(mob = target)
|
||||
if (this.owner is ServerPlayer) {
|
||||
pokemon.addExperienceWithPlayer(this.owner as ServerPlayer, source, (experience * Cobblemon.config.mobExperienceConversionRate).toInt())
|
||||
}
|
||||
else {
|
||||
pokemon.addExperience(source, (experience * Cobblemon.config.mobExperienceConversionRate).toInt())
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun hurt(source: DamageSource, amount: Float): Boolean {
|
||||
|
||||
@@ -52,8 +52,9 @@ object PlaceHoneyInHiveTask {
|
||||
if (blockEntity.isFull) {
|
||||
// Erase Hive memory and give the bee a moment to locate a new hive
|
||||
entity.brain.eraseMemory(CobblemonMemories.HIVE_LOCATION)
|
||||
} else {
|
||||
blockEntity.addOccupant(entity)
|
||||
}
|
||||
blockEntity.addOccupant(entity)
|
||||
}
|
||||
|
||||
return@Trigger true
|
||||
|
||||
@@ -8,17 +8,24 @@
|
||||
|
||||
package com.cobblemon.mod.common.item.interactive
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
|
||||
import com.cobblemon.mod.common.api.item.PokemonSelectingItem
|
||||
import com.cobblemon.mod.common.api.pokemon.experience.CandyExperienceSource
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.item.CobblemonItem
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.InteractionResultHolder
|
||||
import net.minecraft.world.entity.ExperienceOrb
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.food.FoodProperties
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Rarity
|
||||
import net.minecraft.world.level.Level
|
||||
@@ -34,22 +41,59 @@ import net.minecraft.world.level.Level
|
||||
*/
|
||||
class CandyItem(
|
||||
val item_rarity: Rarity,
|
||||
val calculator: Calculator
|
||||
val expYield: (ServerPlayer, Pokemon?) -> Int
|
||||
) : CobblemonItem(Properties().apply {
|
||||
rarity(item_rarity)
|
||||
}), PokemonSelectingItem {
|
||||
food(FoodProperties.Builder()
|
||||
.alwaysEdible()
|
||||
.nutrition(0)
|
||||
.saturationModifier(0.0f)
|
||||
.build())
|
||||
}) {
|
||||
|
||||
override val bagItem = null
|
||||
override fun finishUsingItem(stack: ItemStack, level: Level, livingEntity: LivingEntity): ItemStack? {
|
||||
if (livingEntity !is Player) return super.finishUsingItem(stack, level, livingEntity)
|
||||
|
||||
override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
if (user is ServerPlayer) {
|
||||
return use(user, user.getItemInHand(hand))
|
||||
/* Didn't find a good way to determine the XP needed until the beginning of the next level.
|
||||
* This works but is a little jank. Feel free to investigate a better solution.
|
||||
*/
|
||||
if (level.isClientSide && this == CobblemonItems.RARE_CANDY) {
|
||||
val volume = if (livingEntity.experienceLevel > 30) 1.0f else livingEntity.experienceLevel.toFloat() / 30.0f
|
||||
livingEntity.playSound(SoundEvents.PLAYER_LEVELUP, volume * 0.75f, 1.0f)
|
||||
}
|
||||
return InteractionResultHolder.success(user.getItemInHand(hand))
|
||||
|
||||
if (livingEntity !is ServerPlayer) return super.finishUsingItem(stack, level, livingEntity)
|
||||
if (this == CobblemonItems.RARE_CANDY) {
|
||||
livingEntity.setExperienceLevels(livingEntity.experienceLevel + 1)
|
||||
livingEntity.setExperiencePoints(0)
|
||||
}
|
||||
else {
|
||||
val expYield = expYield(livingEntity, null)
|
||||
val playerExperience = (expYield / Cobblemon.config.mobExperienceConversionRate).toInt().coerceAtLeast(1)
|
||||
ExperienceOrb.award(livingEntity.serverLevel(), livingEntity.position(), playerExperience)
|
||||
}
|
||||
return super.finishUsingItem(stack, level, livingEntity)
|
||||
}
|
||||
|
||||
override fun applyToPokemon(player: ServerPlayer, stack: ItemStack, pokemon: Pokemon): InteractionResultHolder<ItemStack>? {
|
||||
val experience = this.calculator.calculate(player, pokemon)
|
||||
override fun interactLivingEntity(
|
||||
stack: ItemStack,
|
||||
player: Player,
|
||||
interactionTarget: LivingEntity,
|
||||
usedHand: InteractionHand
|
||||
): InteractionResult {
|
||||
if (player.level().isClientSide) return InteractionResult.FAIL
|
||||
if (player.isCrouching) return InteractionResult.FAIL
|
||||
if (interactionTarget !is PokemonEntity) return InteractionResult.PASS
|
||||
if (interactionTarget.pokemon.getOwnerPlayer() != player) return InteractionResult.PASS
|
||||
return applyToPokemon(player as ServerPlayer, stack, interactionTarget.pokemon)?.result ?: InteractionResult.FAIL
|
||||
}
|
||||
|
||||
fun applyToPokemon(player: ServerPlayer, stack: ItemStack, pokemon: Pokemon): InteractionResultHolder<ItemStack>? {
|
||||
if (!pokemon.canLevelUpFurther()) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
val experience = expYield(player, pokemon)
|
||||
CobblemonEvents.EXPERIENCE_CANDY_USE_PRE.postThen(
|
||||
event = ExperienceCandyUseEvent.Pre(player, pokemon, this, experience, experience),
|
||||
ifSucceeded = { preEvent ->
|
||||
@@ -74,29 +118,6 @@ class CandyItem(
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
override fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean {
|
||||
return pokemon.isPlayerOwned()
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface responsible for resolving the experience a candy will yield.
|
||||
*
|
||||
* @author Licious
|
||||
* @since March 5th, 2022
|
||||
*/
|
||||
fun interface Calculator {
|
||||
|
||||
/**
|
||||
* Resolves the experience the [CandyItem] will give.
|
||||
*
|
||||
* @param player The [ServerPlayer] using the candy.
|
||||
* @param pokemon The [Pokemon] receiving experience.
|
||||
* @return The experience that will be received
|
||||
*/
|
||||
fun calculate(player: ServerPlayer, pokemon: Pokemon): Int
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_XS_CANDY_YIELD = 100
|
||||
const val DEFAULT_S_CANDY_YIELD = 800
|
||||
|
||||
@@ -23,7 +23,6 @@ import net.minecraft.world.level.Level
|
||||
class PonigiriItem : Item(
|
||||
Properties().stacksTo(64)
|
||||
.food(FoodProperties.Builder()
|
||||
.alwaysEdible()
|
||||
.nutrition(2)
|
||||
.saturationModifier(0.55f)
|
||||
.build())
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacketToPlayers
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
@@ -148,6 +149,7 @@ import net.minecraft.util.Mth.ceil
|
||||
import net.minecraft.util.Mth.clamp
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.entity.ExperienceOrb
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.MobSpawnType
|
||||
import net.minecraft.world.entity.player.Player
|
||||
@@ -2016,6 +2018,12 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
}
|
||||
)
|
||||
|
||||
val player = getOwnerPlayer()
|
||||
if (player != null && player.inventory.getArmor(3).item == CobblemonItems.EXP_SHARE) {
|
||||
val playerExperience = (appliedXP / Cobblemon.config.mobExperienceConversionRate * Cobblemon.config.experienceShareMultiplier).toInt().coerceAtLeast(1)
|
||||
ExperienceOrb.award(player.serverLevel(), player.position(), playerExperience)
|
||||
}
|
||||
|
||||
experience += appliedXP
|
||||
// Bound is needed here as we can still be allowed to level up but go over the current cap
|
||||
var newLevel = experienceGroup.getLevel(experience).coerceAtMost(Cobblemon.config.maxPokemonLevel)
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
{
|
||||
"aspects": ["female"],
|
||||
"model": "cobblemon:combee_female.geo"
|
||||
},
|
||||
{
|
||||
"aspects": ["shiny", "female"],
|
||||
"texture": "cobblemon:textures/pokemon/0415_combee/combee_shiny.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2041,6 +2041,7 @@
|
||||
"key.cobblemon.pokenavigator": "Open PokéNav",
|
||||
"key.cobblemon.summary": "Open Summary",
|
||||
"key.cobblemon.pokedex": "Open Pokédex",
|
||||
"key.cobblemon.ridingfreelook": "Riding Freelook",
|
||||
"key.cobblemon.categories.cobblemon": "Cobblemon",
|
||||
|
||||
"key.cobblemon.scaleportraitup": "Scale Portrait Up",
|
||||
@@ -2620,6 +2621,8 @@
|
||||
"cobblemon.config.ui.infinite_ride_stamina.tooltip": "Whether rideable Pokémon have infinite stamina.",
|
||||
"cobblemon.config.ui.remember_riding_camera": "Remember Riding Camera",
|
||||
"cobblemon.config.ui.remember_riding_camera.tooltip": "Whether the camera mode will automatically switch to the last used camera mode when mounting a rideable Pokémon.",
|
||||
"cobblemon.config.ui.mob_experience_conversion_rate": "Mob Experience Conversion Rate",
|
||||
"cobblemon.config.ui.mob_experience_conversion_rate.tooltip": "The conversion rate for mob experience to pokemon experience when a Pokemon kills a mob.",
|
||||
|
||||
"cobblemon.config.ui.allow_starter_on_join": "Allow Starter on Join",
|
||||
"cobblemon.config.ui.prompt_starter_once_only": "Prompt Starter Once Only",
|
||||
@@ -3589,7 +3592,8 @@
|
||||
"tag.item.cobblemon.small_flowers": "Small Flowers",
|
||||
"tag.item.cobblemon.held.blacklisted_items_to_hold": "Blacklisted Held Items",
|
||||
"tag.item.cobblemon.held.whitelisted_items_to_hold": "Whitelisted Held Items",
|
||||
"tag.item.cobblemon.recipe_filters.poke_puff_seasoner": "Poké Puff Berries",
|
||||
"tag.item.cobblemon.recipe_filters.poke_puff_seasoning": "Poké Puff Seasoning Items",
|
||||
"tag.item.cobblemon.recipe_filters.tea_seasoning": "Tea Seasoning Items",
|
||||
"tag.item.cobblemon.recipe_filters.bait_seasoning": "Baits",
|
||||
"tag.item.cobblemon.recipe_filters.effect_seasoning": "Effect Seasoning Items",
|
||||
"tag.item.cobblemon.recipe_filters.nutrition_seasoning": "Nutrition Seasoning Items",
|
||||
|
||||
@@ -6165,7 +6165,7 @@
|
||||
"cobblemon.command.freezepokemon.non_pokemon": "Vous ne pointez pas un Pokémon.",
|
||||
"advancements.cobblemon.craft_rod": "Équipé pour pécho !",
|
||||
"advancements.cobblemon.use_bait.description": "Utiliser une baie avec la Poké Rod",
|
||||
"advancements.cobblemon.craft_master_rod": "Dévouement magistral",
|
||||
"advancements.cobblemon.craft_master_rod": "Cela affectera la population de Barbicha",
|
||||
"cobblemon.battle.resisted_spread": "Ça n'est pas très efficace sur %1$s.",
|
||||
"cobblemon.battle.superEffective_spread": "C'est super efficace sur %1$s !",
|
||||
"cobblemon.battle.crit_spread": "Coup critique infligé à %1$s !",
|
||||
@@ -8773,7 +8773,7 @@
|
||||
"cobblemon.config.ui.despawner_max_age_ticks": "Âge maximum (Ticks)",
|
||||
"cobblemon.config.ui.despawner_max_age_ticks.tooltip": "L'âge (en ticks de jeu) qu'un Pokémon doit atteindre avant de pouvoir disparaître à petite distance.",
|
||||
"advancements.cobblemon.resurrect_galar_fossil": "N'arrêtez jamais d'apprendre",
|
||||
"advancements.cobblemon.resurrect_galar_fossil.description": "Ressuscitez un Pokémon fossile créé à partir d'un Fossile Oiseau ou Fossile Poisson et d'un Fossile Dragon ou Fossile Aileron",
|
||||
"advancements.cobblemon.resurrect_galar_fossil.description": "Ressuscitez un Pokémon fossile créé à partir d’un Fossile Oiseau ou Poisson et d’un Fossile Dragon ou Aileron",
|
||||
"advancements.cobblemon.ride_pokemon": "Monteur de Pokémon !",
|
||||
"advancements.cobblemon.ride_pokemon.description": "Montez sur un Pokémon pour la première fois",
|
||||
"cobblemon.battle.sidestart.ally.auroraveil": "Voile Aurore augmente la résistance des Pokémon de l'équipe aux capacités physiques et spéciales !",
|
||||
@@ -9088,7 +9088,7 @@
|
||||
"cobblemon.config.ui.summary_profile_animations.animate_selected.tooltip": "Animer le Pokémon sélectionné à moins d'être K.O.",
|
||||
"tag.item.cobblemon.berries.status_recovery": "Baies de récupération de statut",
|
||||
"cobblemon.behaviour.configurable_resource_identifier.desc": "Permet de modifier l'identifiant de ressource qui contrôle l'apparence du PNJ.",
|
||||
"item.cobblemon.moomoo_milk.tooltip": "Efface tous les changements de stats du Pokémon cible lorsqu'il est utilisé au combat.",
|
||||
"item.cobblemon.moomoo_milk.tooltip": "Efface tous les changements de stats du Pokémon cible lorsqu'il est utilisé au combat",
|
||||
"cobblemon.config.ui.poke_snack_pokemon_per_chunk": "Poké Snack Pokémon par tronçon",
|
||||
"cobblemon.config.ui.animate_battle_tiles": "Animer les tuiles de combat",
|
||||
"cobblemon.config.ui.pc_profile_animations.never_animate": "Ne jamais animer",
|
||||
@@ -9104,5 +9104,35 @@
|
||||
"cobblemon.entity.variable.display_name_tag.name": "Afficher l'étiquette",
|
||||
"cobblemon.entity.variable.display_name_tag.desc": "Permet d'afficher ou masquer l'étiquette de l'entité.",
|
||||
"cobblemon.behaviour.dialogue_selection.name": "Sélection du dialogue",
|
||||
"cobblemon.behaviour.dialogue_selection.desc": "Permet de configurer l'interaction avec le PNJ afin d'ouvrir un dialogue spécifique."
|
||||
"cobblemon.behaviour.dialogue_selection.desc": "Permet de configurer l'interaction avec le PNJ afin d'ouvrir un dialogue spécifique.",
|
||||
"cobblemon.fishing_bait_effects.drops_reroll.tooltip": "%1$s%% - %3$s× Relance Des Butins",
|
||||
"cobblemon.requires_debug_keys": "Les touches de débogage doivent être activées sur le serveur pour utiliser cette fonctionnalité.",
|
||||
"cobblemon.requires_permission": "Vous n’avez pas l’autorisation requise pour effectuer cette action.",
|
||||
"cobblemon.ui.stats.blocks_traveled": "Pas",
|
||||
"item.cobblemon.eggant_berry.tooltip": "Le porteur est soigné s’il est amoureux",
|
||||
"cobblemon.config.ui.default_key_items.tooltip": "Les objets rares que les joueurs obtiennent par défaut au début.",
|
||||
"cobblemon.config.ui.default_key_items": "Objets Rares Par Défaut",
|
||||
"advancements.cobblemon.cook_all_regional_delicacies": "Paul Bocuse",
|
||||
"advancements.cobblemon.cook_all_regional_delicacies.description": "Cuisinez chaque Spécialité Régionale",
|
||||
"advancements.cobblemon.cook_all_ev_mochi": "Mochi Mochi !",
|
||||
"advancements.cobblemon.cook_all_ev_mochi.description": "Cuisinez chaque parfum de mochi, une délicieuse friandise capable de modifier les Points d’Effort d’un Pokémon",
|
||||
"advancements.cobblemon.cook_snack": "Sentez-Moi Ça !",
|
||||
"advancements.cobblemon.cook_snack.description": "Préparez un Poké Snack, un délicieux gâteau capable d’attirer certains Pokémon selon les Baies utilisées",
|
||||
"advancements.cobblemon.use_poke_bait": "Souvenirs D'Enfance",
|
||||
"advancements.cobblemon.use_poke_bait.description": "Préparez un Poké Appât personnalisé dans une Marmite de Feu de Camp et utilisez-le pour ferrer un Pokémon",
|
||||
"advancements.cobblemon.max_ride_stats": "Poké-Athlète, Médaille D'Or",
|
||||
"advancements.cobblemon.max_ride_stats.description": "Maximisez les cinq statistiques de monture d’un Pokémon en lui donnant du Jus d’Abriko aromatisé\nDifférents profils de saveurs augmentent différentes statistiques",
|
||||
"advancements.cobblemon.interact_with_pokemon": "Le Bonheur À Portée De Main",
|
||||
"advancements.cobblemon.interact_with_pokemon.description": "Utilisez l’un de vos nombreux outils pour obtenir des ressources de votre Pokémon",
|
||||
"advancements.cobblemon.slather_saccharine": "Juste Une Lichette",
|
||||
"advancements.cobblemon.slather_saccharine.description": "Étalez un pot de miel sur le tronc d’un arbre Saccharine pour attirer l’apparition de certains Pokémon",
|
||||
"gamerule.healersHealPC": "Soigne les Pokémon du PC lors de l’utilisation d’une Machine de Soin",
|
||||
"tag.item.cobblemon.berries.colour.white": "Baies Blanches",
|
||||
"tag.item.cobblemon.berries.colour.brown": "Baies Marrons",
|
||||
"tag.item.cobblemon.berries.colour.red": "Baies Rouges",
|
||||
"tag.item.cobblemon.berries.colour.orange": "Baies Oranges",
|
||||
"tag.item.cobblemon.berries.colour.yellow": "Baies Jaunes",
|
||||
"tag.item.cobblemon.berries.colour.lime": "Baies Vert Clair",
|
||||
"tag.item.cobblemon.berries.colour.green": "Baies Vertes",
|
||||
"tag.item.cobblemon.berries.colour.cyan": "Baies Cyan"
|
||||
}
|
||||
|
||||
@@ -6270,7 +6270,7 @@
|
||||
"cobblemon.ui.pc.search": "検索",
|
||||
"cobblemon.ui.wallpapers": "壁紙",
|
||||
"cobblemon.ui.interact.ride": "騎乗",
|
||||
"cobblemon.ui.interact.give.cosmetic_item": "コスメティックアイテムの変更",
|
||||
"cobblemon.ui.interact.give.cosmetic_item": "衣装アイテムの変更",
|
||||
"item.cobblemon.syrupy_apple.tooltip": "とにかく 蜜入りの 不思議なりんご。カジッチュに使うと カミッチュに進化する。",
|
||||
"cobblemon.fishing.no_bite": "釣れないなぁ……",
|
||||
"cobblemon.ui.interact.request_already_expired": "そのリクエストはすでに期限切れです!",
|
||||
@@ -7778,7 +7778,7 @@
|
||||
"cobblemon.move.gmaxtartness.desc": "キョダイマックスした アップリューが 繰りだす くさタイプの 攻撃。 相手の 回避率を 下げる。",
|
||||
"cobblemon.species.basculin-white.desc": "極寒の 海で 群れを 作り エサを 分け合って 暮らす。 時が 来ると 生まれた 川に 帰る。",
|
||||
"cobblemon.species.landorus-therian.desc": "霊獣の姿にて 天翔けしとき 大地に 豊穣もたらす。 衆人 これを 敬う。 一刻あれば ヒスイの地を 縦断す。",
|
||||
"cobblemon.ui.pokedex.info.form.greninja-bond": " ",
|
||||
"cobblemon.ui.pokedex.info.form.greninja-bond": "きずなへんげ",
|
||||
"cobblemon.species.vivillon-polar.desc": "生まれた 土地の 気候や 風土の 影響により 模様が 変わる。 降雪の 多い 土地の 姿。",
|
||||
"cobblemon.species.vivillon-archipelago.desc": "生まれた 土地の 気候や 風土の 影響により 模様が 変わる。 島が 群れ成す 土地の 姿。",
|
||||
"cobblemon.species.furfrou-diamond.desc": "ボサボサの 体毛を 刈りこむと 姿が 美しくなる だけでなく 身体の キレが 良くなるのだ。",
|
||||
@@ -7921,7 +7921,7 @@
|
||||
"cobblemon.species.arceus-ice.desc": "アルセウスの持つ つららのプレートには 文字が 刻まれている。 「そのもの じかん くうかんの 2ひき ぶんしんとして よに はなつ」",
|
||||
"cobblemon.ui.pokedex.info.form.arceus-dragon": "アルセウスのすがた",
|
||||
"cobblemon.ui.pokedex.info.form.arceus-dark": "アルセウスのすがた",
|
||||
"cobblemon.species.arceus-dark.desc": "アルセウスの持つ りゅうのプレートには 文字が 刻まれている。 「そのもの じかん くうかんを つなぐ 3びきの ポケモンをも うみだす」",
|
||||
"cobblemon.species.arceus-dark.desc": "アルセウスの持つ こわもてプレートには 文字が 刻まれている。 「2ひきに もの 3びきに こころ いのり うませ せかい かたちづくる」",
|
||||
"cobblemon.ui.pokedex.info.form.arceus-fairy": "アルセウスのすがた",
|
||||
"cobblemon.ui.pokedex.info.form.oshawott": " ",
|
||||
"cobblemon.ui.pokedex.info.form.dewott": " ",
|
||||
@@ -8068,8 +8068,8 @@
|
||||
"cobblemon.ui.pokedex.info.form.zygarde": "50%フォルム",
|
||||
"cobblemon.ui.pokedex.info.form.zygarde-10": "10%フォルム",
|
||||
"cobblemon.species.zygarde-10.desc": "鋭い キバで 敵を 仕留める。 ずっと この身体を 維持 できず 一定時間で バラバラになる。",
|
||||
"cobblemon.ui.pokedex.info.form.zygarde-10c": "10%フォルム",
|
||||
"cobblemon.ui.pokedex.info.form.zygarde-50c": "50%フォルム",
|
||||
"cobblemon.ui.pokedex.info.form.zygarde-10c": "10%(スワームチェンジ)",
|
||||
"cobblemon.ui.pokedex.info.form.zygarde-50c": "50%(スワームチェンジ)",
|
||||
"cobblemon.species.zygarde-50c.desc": "生態系を 脅かす ものと 戦うとき 更に 強力な 姿に 変化すると いわれる。",
|
||||
"cobblemon.ui.pokedex.info.form.zygarde-complete": "パーフェクトフォルム",
|
||||
"cobblemon.species.zygarde-complete.desc": "生態系を 脅かす者を 圧倒的な 力を 以て 制圧する ジガルデの 姿。",
|
||||
@@ -8084,7 +8084,7 @@
|
||||
"cobblemon.species.oricorio-pau.desc": "うすもものミツを 吸った オドリドリ。 踊っている ときは トレーナーの 指示が 聞こえないほど マイペース。",
|
||||
"cobblemon.ui.pokedex.info.form.oricorio-sensu": "まいまいスタイル",
|
||||
"cobblemon.ui.pokedex.info.form.rockruff": " ",
|
||||
"cobblemon.ui.pokedex.info.form.rockruff-dusk": " ",
|
||||
"cobblemon.ui.pokedex.info.form.rockruff-dusk": "マイペース",
|
||||
"cobblemon.ui.pokedex.info.form.lycanroc": "まひるのすがた",
|
||||
"cobblemon.ui.pokedex.info.form.lycanroc-midnight": "まよなかのすがた",
|
||||
"cobblemon.species.lycanroc-midnight.desc": "気に入らない 命令は 平気で 無視。 相手を 仕留めるためなら 傷つくことも まるで 気にしない。",
|
||||
@@ -8959,5 +8959,74 @@
|
||||
"entity.cobblemon.chest_boat": "チェスト付きのボート",
|
||||
"entity.cobblemon.npc": "NPC",
|
||||
"entity.cobblemon.empty_pokeball": "空のモンスターボール",
|
||||
"cobblemon.battle.activate.insomnia": "このポケモンは ふみんのため 眠ることができない!"
|
||||
"cobblemon.battle.activate.insomnia": "このポケモンは ふみんのため 眠ることができない!",
|
||||
"cobblemon.battle.sideend.ally.auroraveil": "味方の オーロラベールが なくなった!",
|
||||
"cobblemon.battle.sideend.ally.toxicspikes": "味方の足元から どくびしが 消えた!",
|
||||
"cobblemon.battle.sideend.opponent.auroraveil": "相手の オーロラベールが なくなった!",
|
||||
"cobblemon.battle.sideend.opponent.lightscreen": "相手の ひかりのかべが なくなった!",
|
||||
"cobblemon.battle.sideend.opponent.mist": "相手の しろいきりが なくなった!",
|
||||
"cobblemon.battle.sideend.opponent.reflect": "相手の リフレクターが なくなった!",
|
||||
"cobblemon.battle.block.aromaveil": "%1$sは アロマベールで 守られている!",
|
||||
"cobblemon.battle.error.incorrect_actor_count": "現在の参加者は %1$s人だが %2%s人の参加者が 必要な ようだ",
|
||||
"cobblemon.battle.error.no_party": "%1$sは バトルに出すための 手持ちのポケモンを 持っていないようだ",
|
||||
"cobblemon.battle.enditem.focusband": "%1$sは きあいのハチマキで 持ちこたえた!",
|
||||
"cobblemon.battle.enditem.focussash": "%1$sは きあいのタスキで 持ちこたえた!",
|
||||
"cobblemon.battle.enditem.ejectpack": "%1$sは だっしゅつパックで 戻っていく!",
|
||||
"cobblemon.battle.enditem.occaberry": "%1$sへの ダメージを オッカのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.passhoberry": "%1$sへの ダメージを イトケのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.chopleberry": "%1$sへの ダメージを ヨプのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.kebiaberry": "%1$sへの ダメージを ビアーのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.shucaberry": "%1$sへの ダメージを シュカのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.cobaberry": "%1$sへの ダメージを バコウのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.payapaberry": "%1$sへの ダメージを ウタンのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.chartiberry": "%1$sへの ダメージを ヨロギのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.kasibberry": "%1$sへの ダメージを カシブのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.habanberry": "%1$sへの ダメージを ハバンのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.babiriberry": "%1$sへの ダメージを リリバのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.chilanberry": "%1$sへの ダメージを ホズのみが 弱めた!",
|
||||
"cobblemon.battle.formechange.default.temporary.ended": "%1$sは 元の姿に 戻った!",
|
||||
"cobblemon.battle.formechange.mega": "%1$sが キーストーンに 共鳴した!",
|
||||
"cobblemon.battle.formechange.ash": "%1$sは サトシゲッコウガに きずなへんげした!",
|
||||
"cobblemon.battle.formechange.school": "%1$sは むれたすがたに なった!",
|
||||
"cobblemon.battle.withdraw.other": "%1$sは %2$sを 引っ込めた!",
|
||||
"cobblemon.battle.sideend.ally.lightscreen": "味方の ひかりのかべが なくなった!",
|
||||
"cobblemon.battle.sideend.ally.reflect": "味方の リフレクターが なくなった!",
|
||||
"cobblemon.battle.sideend.ally.spikes": "味方の足元から まきびしが 消えた!",
|
||||
"cobblemon.battle.sideend.ally.safeguard": "味方の 神秘のベールが なくなった!",
|
||||
"cobblemon.battle.sideend.opponent.stickyweb": "相手の足元から ねばねばネットが なくなった!",
|
||||
"cobblemon.battle.enditem.wacanberry": "%1$sへの ダメージを ソクノのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.rindoberry": "%1$sへの ダメージを リンドのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.yacheberry": "%1$sへの ダメージを ヤチェのみが 弱めた!",
|
||||
"cobblemon.battle.heal.bagitemrevive": "%1$sは ひんしから 回復した!",
|
||||
"cobblemon.battle.heal.bagitemfullrestore": "%1$sの 体力が 回復した!",
|
||||
"cobblemon.battle.formechange.minior": "%1$sの リミットシールド 発動!",
|
||||
"cobblemon.battle.switch.other": "%1$s は %2$sを 繰り出した!",
|
||||
"cobblemon.battle.enditem.tangaberry": "%1$sへの ダメージを タンガのみが 弱めた!",
|
||||
"cobblemon.battle.withdraw.self": "%1$s、戻れ!",
|
||||
"cobblemon.battle.sideend.opponent.luckychant": "相手の おまじないが 切れた!",
|
||||
"cobblemon.battle.block.sweetveil": "%1$sは スイートベールで 眠れない!",
|
||||
"cobblemon.battle.enditem.colburberry": "%1$sへの ダメージを ナモのみが 弱めた!",
|
||||
"cobblemon.battle.enditem.roseliberry": "%1$sへの ダメージを ロゼルのみが 弱めた!",
|
||||
"cobblemon.battle.formechange.wishiwashi": "%1$sの群れは どこかに行ってしまった...",
|
||||
"cobblemon.battle.switch.other.nickname": "%1$s は %2$s (%3$s)を 繰り出した!",
|
||||
"cobblemon.battle.sideend.ally.tailwind": "味方の おいかぜが 切れた!",
|
||||
"cobblemon.battle.sideend.opponent.safeguard": "相手の 神秘のベールが なくなった!",
|
||||
"cobblemon.battle.sideend.ally.stealthrock": "味方の足元から とがった岩が 消えた!",
|
||||
"cobblemon.battle.sideend.ally.stickyweb": "味方の足元から ねばねばネットが なくなった!",
|
||||
"cobblemon.battle.sideend.ally.luckychant": "味方の おまじないが 切れた!",
|
||||
"cobblemon.battle.sideend.ally.mist": "味方の しろいきりが なくなった!",
|
||||
"cobblemon.battle.sideend.opponent.tailwind": "相手の おいかぜが 切れた!",
|
||||
"cobblemon.battle.sideend.opponent.spikes": "相手の足元から まきびしが なくなった!",
|
||||
"cobblemon.battle.sideend.opponent.toxicspikes": "相手の足元から どくびしが なくなった!",
|
||||
"cobblemon.battle.cant.nopp": "%1$sは %2$sを使うための PPが 足りない!",
|
||||
"cobblemon.battle.end.neutralizinggas": "かがくへんかガスが なくなった!",
|
||||
"cobblemon.battle.ability.replace": "%1$sは 特性が %2$sに変わった!",
|
||||
"cobblemon.battle.formechange.default.temporary": "%1$s は %2$sフォルムに なった!",
|
||||
"cobblemon.battle.formechange.default.permanent": "%1$s は %2$sに フォルムチェンジした!",
|
||||
"cobblemon.battle.formechange.meteor": "%1$sの リミットシールド 解除!",
|
||||
"cobblemon.battle.switch.self": "いけ! %1$s!",
|
||||
"cobblemon.fishing_bait_effects.drops_reroll.tooltip": "%1$s%% - %3$s× ドロップ品リロール",
|
||||
"cobblemon.requires_debug_keys": "この機能を使用するには、サーバーでデバッグキーを有効にする必要があります。",
|
||||
"cobblemon.requires_permission": "この操作を行うには必要な権限がありません。",
|
||||
"cobblemon.ui.stats.blocks_traveled": "ステップ"
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@
|
||||
"cobblemon.ui.starter.hasalreadychosen": "%1$s já escolheu um iniciante.",
|
||||
"cobblemon.ui.starter.skippedchoosing": "Você ainda não escolheu um iniciante, mas já recebeu um Pokémon. Para selecionar seu inciante, coloque todos seus Pokémon em um PC e pressione \"%1$s\".",
|
||||
"cobblemon.ui.starter.choose_starter_title": "Escolha o seu inicial!",
|
||||
"cobblemon.ui.starter.choose_starter_description": "Pressiona a tecla \"%1$s\"",
|
||||
"cobblemon.ui.starter.choose_starter_description": "Pressione a tecla \"%1$s\"",
|
||||
"cobblemon.ui.starter.chooseyourstarter": "Pressione %1$s para escolher seu Pokémon e começar sua jornada!",
|
||||
"cobblemon.ui.moves": "Ataques",
|
||||
"cobblemon.ui.moves.switch": "Trocar Ataque",
|
||||
|
||||
@@ -5906,7 +5906,7 @@
|
||||
"advancements.cobblemon.craft_rod.description": "使用宝可梦钓竿锻造模版制作一个宝可梦钓竿",
|
||||
"advancements.cobblemon.use_bait": "非常好树果,使我线轮旋转",
|
||||
"advancements.cobblemon.craft_master_rod.description": "使用大师球制作一个宝可梦钓竿",
|
||||
"advancements.cobblemon.craft_master_rod": "慷慨带不来好运",
|
||||
"advancements.cobblemon.craft_master_rod": "这将影响鲶鱼王的数量",
|
||||
"advancements.cobblemon.craft_rod": "器渔轩昂",
|
||||
"advancements.cobblemon.use_bait.description": "让你的宝可梦钓竿挂上一个树果诱饵",
|
||||
"cobblemon.battle.center": "自动居中!",
|
||||
@@ -8607,7 +8607,7 @@
|
||||
"item.cobblemon.swift_mochi.tooltip": "提升宝可梦的速度基础点数4点",
|
||||
"item.cobblemon.fresh_start_mochi": "净空粘糕",
|
||||
"item.cobblemon.fresh_start_mochi.tooltip": "将宝可梦的全部基础点数清空",
|
||||
"item.cobblemon.poke_bait": "宝可梦诱饵",
|
||||
"item.cobblemon.poke_bait": "宝诱饵",
|
||||
"item.cobblemon.aprijuice_blue": "蓝球果汁",
|
||||
"item.cobblemon.aprijuice_green": "绿球果汁",
|
||||
"item.cobblemon.aprijuice_pink": "粉球果汁",
|
||||
@@ -8751,7 +8751,7 @@
|
||||
"cobblemon.config.ui.maximum_spawning_zone_distance_from_player.tooltip": "宝可梦生成时,距玩家所需的最大方块数。",
|
||||
"cobblemon.config.ui.maximum_spawns_per_pass": "单次生成最大数量",
|
||||
"cobblemon.config.ui.despawner_far_distance.tooltip": "以玩家为中心的最大距离范围。在此范围之外,且存在时间超过最小活动时间的宝可梦会被系统移除。",
|
||||
"advancements.cobblemon.resurrect_galar_fossil.description": "复活一只由化石鸟或化石鱼以及化石海兽或化石龙组成的宝可梦",
|
||||
"advancements.cobblemon.resurrect_galar_fossil.description": "复活一只由化石鸟或化石鱼和化石海兽或化石龙组成的宝可梦",
|
||||
"cobblemon.battle.sidestart.ally.auroraveil": "极光幕使我方的物理和特殊抗性提高了!",
|
||||
"cobblemon.battle.sidestart.ally.safeguard": "我方被神秘之幕包围了!",
|
||||
"cobblemon.battle.sidestart.opponent.auroraveil": "极光幕使对手的物理和特殊抗性提高了!",
|
||||
@@ -9050,7 +9050,7 @@
|
||||
"cobblemon.snapshots.warning.dont_show_again": "不再显示",
|
||||
"cobblemon.snapshots.warning.dont_show_again_tip": "在较新的 方块宝可梦 快照中(例如 1.7.0 与 1.8.0),此设置可能会被忽略",
|
||||
"key.cobblemon.toggleridingstatsgui": "切换骑乘能力界面",
|
||||
"item.cobblemon.moomoo_milk.tooltip": "在战斗中使用时,会清除目标的能力变化。",
|
||||
"item.cobblemon.moomoo_milk.tooltip": "在战斗中使用时,会清除目标的能力变化",
|
||||
"cobblemon.config.ui.poke_snack_pokemon_per_chunk": "每个区块的宝点心宝可梦数量",
|
||||
"cobblemon.config.ui.poke_snack_pokemon_per_chunk.tooltip": "通过宝点心生成时,区块中允许的宝可梦数量。",
|
||||
"cobblemon.config.ui.summary_profile_animations.animate_selected.tooltip": "选中的宝可梦播放动画,除非已昏厥",
|
||||
@@ -9105,5 +9105,25 @@
|
||||
"cobblemon.seasoning_ride_boosts_info_header": "骑乘属性提升:",
|
||||
"item.cobblemon.eggant_berry": "子茄果",
|
||||
"cobblemon.entity.variable.look_at_entity_types.desc": "该实体将看向的实体类型。",
|
||||
"cobblemon.entity.variable.look_at_entity_types.name": "看向实体类型"
|
||||
"cobblemon.entity.variable.look_at_entity_types.name": "看向实体类型",
|
||||
"cobblemon.fishing_bait_effects.drops_reroll.tooltip": "%1$s%% - %3$s× 额外掉落",
|
||||
"cobblemon.requires_debug_keys": "必须在服务器上启用调试键才能使用此功能。",
|
||||
"cobblemon.ui.stats.blocks_traveled": "步数",
|
||||
"cobblemon.requires_permission": "你没有执行此操作的权限。",
|
||||
"cobblemon.config.ui.default_key_items": "默认关键道具",
|
||||
"cobblemon.config.ui.default_key_items.tooltip": "玩家默认拥有的关键道具。",
|
||||
"advancements.cobblemon.cook_all_regional_delicacies": "世界美食之旅",
|
||||
"item.cobblemon.eggant_berry.tooltip": "解除着迷状态",
|
||||
"advancements.cobblemon.cook_all_regional_delicacies.description": "烹饪每种地区美食",
|
||||
"advancements.cobblemon.cook_all_ev_mochi": "咭呗咭呗!",
|
||||
"advancements.cobblemon.use_poke_bait.description": "在营火锅中准备一个自制的宝可梦诱饵,并使用它钓到一只宝可梦",
|
||||
"advancements.cobblemon.max_ride_stats": "明星宝可竞技选手",
|
||||
"advancements.cobblemon.max_ride_stats.description": "通过喂食不同风味的球果汁,将宝可梦宝可梦的五项坐骑能力提升至最高\n不同风味的球果汁会提升不同的能力",
|
||||
"advancements.cobblemon.slather_saccharine": "只是一小口",
|
||||
"advancements.cobblemon.cook_all_ev_mochi.description": "制作每一种口味的粘糕,这种美味点心可以影响宝可梦的基础点数",
|
||||
"advancements.cobblemon.cook_snack": "诱人的香味",
|
||||
"advancements.cobblemon.cook_snack.description": "烘焙一个宝点心,一种美味的蛋糕,可以根据使用的树果吸引特定的宝可梦",
|
||||
"advancements.cobblemon.use_poke_bait": "那是诱饵",
|
||||
"advancements.cobblemon.interact_with_pokemon": "牧场上的家",
|
||||
"advancements.cobblemon.interact_with_pokemon.description": "使用你众多工具的一个,从你的宝可梦那里获取资源"
|
||||
}
|
||||
|
||||
@@ -6433,7 +6433,7 @@
|
||||
"item.cobblemon.smooth_rock.tooltip": "攜帶後,刮起沙暴的話,沙暴的時間就會比平常更長",
|
||||
"item.cobblemon.icy_rock.tooltip": "攜帶後,將天氣變為下雪的話,下雪的時間就會比平常更長",
|
||||
"item.cobblemon.energy_root.tooltip": "使一隻寶可夢回復80HP,同時降低它的親密度",
|
||||
"item.cobblemon.revival_herb.tooltip": "使一隻昏厥的寶可夢回復全部HP,同時降低它的親密度",
|
||||
"item.cobblemon.revival_herb.tooltip": "使一隻昏厥的寶可夢回復最大HP的25%,同時降低它的親密度",
|
||||
"item.cobblemon.remedy.tooltip": "使一隻寶可夢回復20HP,同時小幅降低它的親密度",
|
||||
"item.cobblemon.fine_remedy.tooltip": "使一隻寶可夢回復60HP,同時小幅降低它的親密度",
|
||||
"item.cobblemon.superb_remedy.tooltip": "使一隻寶可夢回復120HP,同時小幅降低它的親密度",
|
||||
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
@@ -1,20 +1,25 @@
|
||||
{
|
||||
"display": {
|
||||
"icon": {
|
||||
"id": "minecraft:shears"
|
||||
},
|
||||
"icon": {
|
||||
"id": "minecraft:shears"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancements.cobblemon.interact_with_pokemon"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancements.cobblemon.interact_with_pokemon.description"
|
||||
},
|
||||
"hidden": false
|
||||
"hidden": false
|
||||
},
|
||||
"parent": "cobblemon:use_pasture",
|
||||
"criteria": {
|
||||
"bucket_interactable_pokemon": {
|
||||
"conditions": {
|
||||
"player": {
|
||||
"flags": {
|
||||
"is_sneaking": false
|
||||
}
|
||||
},
|
||||
"entity": [
|
||||
{
|
||||
"condition": "minecraft:entity_properties",
|
||||
@@ -32,6 +37,11 @@
|
||||
},
|
||||
"shear_interactable_pokemon": {
|
||||
"conditions": {
|
||||
"player": {
|
||||
"flags": {
|
||||
"is_sneaking": false
|
||||
}
|
||||
},
|
||||
"entity": [
|
||||
{
|
||||
"condition": "minecraft:entity_properties",
|
||||
@@ -49,6 +59,11 @@
|
||||
},
|
||||
"bottle_interactable_pokemon": {
|
||||
"conditions": {
|
||||
"player": {
|
||||
"flags": {
|
||||
"is_sneaking": false
|
||||
}
|
||||
},
|
||||
"entity": [
|
||||
{
|
||||
"condition": "minecraft:entity_properties",
|
||||
@@ -66,6 +81,11 @@
|
||||
},
|
||||
"brush_interactable_pokemon": {
|
||||
"conditions": {
|
||||
"player": {
|
||||
"flags": {
|
||||
"is_sneaking": false
|
||||
}
|
||||
},
|
||||
"entity": [
|
||||
{
|
||||
"condition": "minecraft:entity_properties",
|
||||
@@ -83,6 +103,11 @@
|
||||
},
|
||||
"bonemeal_interactable_pokemon": {
|
||||
"conditions": {
|
||||
"player": {
|
||||
"flags": {
|
||||
"is_sneaking": false
|
||||
}
|
||||
},
|
||||
"entity": [
|
||||
{
|
||||
"condition": "minecraft:entity_properties",
|
||||
@@ -100,6 +125,11 @@
|
||||
},
|
||||
"bowl_interactable_pokemon": {
|
||||
"conditions": {
|
||||
"player": {
|
||||
"flags": {
|
||||
"is_sneaking": false
|
||||
}
|
||||
},
|
||||
"entity": [
|
||||
{
|
||||
"condition": "minecraft:entity_properties",
|
||||
@@ -116,6 +146,15 @@
|
||||
"trigger": "minecraft:player_interacted_with_entity"
|
||||
}
|
||||
},
|
||||
"requirements": [[ "bucket_interactable_pokemon", "shear_interactable_pokemon", "bottle_interactable_pokemon", "brush_interactable_pokemon", "bonemeal_interactable_pokemon", "bowl_interactable_pokemon" ]],
|
||||
"requirements": [
|
||||
[
|
||||
"bucket_interactable_pokemon",
|
||||
"shear_interactable_pokemon",
|
||||
"bottle_interactable_pokemon",
|
||||
"brush_interactable_pokemon",
|
||||
"bonemeal_interactable_pokemon",
|
||||
"bowl_interactable_pokemon"
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": false
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
{
|
||||
"type": "cobblemon:activity_change",
|
||||
"activity": "minecraft:idle",
|
||||
"condition": "q.entity.lacks_memory_value('cobblemon:has_nectar', 'cobblemon:nearby_flower') || (q.entity.has_memory_value('cobblemon:has_nectar') && (q.entity.lacks_memory_value('cobblemon:nearby_sacc_leaves', 'cobblemon:hive_location'))) || q.entity.has_memory_value('cobblemon:hive_cooldown')"
|
||||
"condition": "q.entity.lacks_memory_value('cobblemon:has_nectar', 'cobblemon:nearby_flower') || (q.entity.has_memory_value('cobblemon:has_nectar') && (q.entity.lacks_memory_value('cobblemon:nearby_sacc_leaves', 'cobblemon:hive_location'))) || q.entity.has_memory_value('cobblemon:hive_cooldown') || ((q.entity.biome.is_in('#minecraft:is_overworld') && ((q.entity.world.time_of_day >= 13000 && q.entity.world.time_of_day <= 23000) || q.entity.world.is_raining)) && (q.entity.lacks_memory_value('cobblemon:hive_location')))"
|
||||
},
|
||||
{
|
||||
"type": "cobblemon:activity_change",
|
||||
@@ -62,7 +62,7 @@
|
||||
{
|
||||
"type": "cobblemon:activity_change",
|
||||
"activity": "cobblemon:pokemon_pollination",
|
||||
"condition": "(q.entity.has_memory_value('cobblemon:nearby_sacc_leaves') || q.entity.has_memory_value('cobblemon:hive_location')) && !q.entity.has_memory_value('cobblemon:hive_cooldown')"
|
||||
"condition": "((q.entity.has_memory_value('cobblemon:nearby_sacc_leaves') || q.entity.has_memory_value('cobblemon:hive_location')) && !q.entity.has_memory_value('cobblemon:hive_cooldown'))"
|
||||
}
|
||||
],
|
||||
"1": [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"pokemon": ["braixien", "delphox"],
|
||||
"pokemon": ["braixen", "delphox"],
|
||||
"cosmeticItems": [
|
||||
{
|
||||
"consumedItem": "cobblemon:silk_scarf",
|
||||
|
||||
@@ -5,7 +5,7 @@ q.entity.has_memory_value('cobblemon:hive_location') ? {
|
||||
t.wander_control.set_path_cooldown_ticks(50);
|
||||
};
|
||||
q.entity.lacks_memory_value('cobblemon:hive_location') && q.entity.has_memory_value('cobblemon:nearby_sacc_leaves') ? {
|
||||
t.position = q.entity.get_position_memory('cobblemon:hive_location');
|
||||
t.position = q.entity.get_position_memory('cobblemon:nearby_sacc_leaves');
|
||||
t.wander_control = q.entity.get_wander_control_memory();
|
||||
t.wander_control.set_center(t.position.x, t.position.y, t.position.z, 2, 32);
|
||||
t.wander_control.set_path_cooldown_ticks(50);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"type": "cobblemon:brewing_stand",
|
||||
"input": {
|
||||
"item": "cobblemon:petaya_berry"
|
||||
},
|
||||
"bottle": {
|
||||
"item": "cobblemon:potion"
|
||||
},
|
||||
"result": {
|
||||
"id": "cobblemon:throat_spray"
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,14 @@
|
||||
"type": "cobblemon:cooking_pot_shapeless",
|
||||
"category": "medicines",
|
||||
"ingredients": [
|
||||
{
|
||||
[
|
||||
{
|
||||
"item": "minecraft:glass_bottle"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:potion"
|
||||
},
|
||||
}
|
||||
],
|
||||
{
|
||||
"item": "cobblemon:medicinal_leek"
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"type": "cobblemon:cooking_pot_shapeless",
|
||||
"category": "medicines",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:glass_bottle"
|
||||
},
|
||||
{
|
||||
"item": "cobblemon:medicinal_leek"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"id": "cobblemon:medicinal_brew"
|
||||
},
|
||||
"seasoningTag": "cobblemon:empty",
|
||||
"seasoningProcessors": []
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
"item": "cobblemon:green_mint_leaf"
|
||||
},
|
||||
"C": {
|
||||
"tag": "c:concrete"
|
||||
"tag": "c:concretes"
|
||||
},
|
||||
"D": {
|
||||
"tag": "c:gems/diamond"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"item": "cobblemon:pink_mint_leaf"
|
||||
},
|
||||
"C": {
|
||||
"tag": "c:concrete"
|
||||
"tag": "c:concretes"
|
||||
},
|
||||
"D": {
|
||||
"tag": "c:gems/diamond"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"item": "cobblemon:blue_mint_leaf"
|
||||
},
|
||||
"C": {
|
||||
"tag": "c:concrete"
|
||||
"tag": "c:concretes"
|
||||
},
|
||||
"D": {
|
||||
"tag": "c:gems/diamond"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"item": "cobblemon:red_mint_leaf"
|
||||
},
|
||||
"C": {
|
||||
"tag": "c:concrete"
|
||||
"tag": "c:concretes"
|
||||
},
|
||||
"D": {
|
||||
"tag": "c:gems/diamond"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"item": "cobblemon:cyan_mint_leaf"
|
||||
},
|
||||
"C": {
|
||||
"tag": "c:concrete"
|
||||
"tag": "c:concretes"
|
||||
},
|
||||
"D": {
|
||||
"tag": "c:gems/diamond"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"item": "cobblemon:white_mint_leaf"
|
||||
},
|
||||
"C": {
|
||||
"tag": "c:concrete"
|
||||
"tag": "c:concretes"
|
||||
},
|
||||
"D": {
|
||||
"tag": "c:gems/diamond"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"implemented": true,
|
||||
"nationalPokedexNumber": 676,
|
||||
"name": "Furfrou",
|
||||
"primaryType": "normal",
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
"#cobblemon:recipe_filters/effect_seasoning",
|
||||
"#cobblemon:recipe_filters/flavour_seasoning",
|
||||
"#cobblemon:recipe_filters/nutrition_seasoning",
|
||||
"#cobblemon:recipe_filters/poke_puff_seasoner"
|
||||
"#cobblemon:recipe_filters/poke_puff_seasoning"
|
||||
]
|
||||
}
|
||||
@@ -35,7 +35,6 @@
|
||||
"client.MouseHandlerMixin",
|
||||
"client.OptionsMixin",
|
||||
"client.PlayerRendererMixin",
|
||||
"client.RecipeBookCategoriesMixin",
|
||||
"client.RecipeBookComponentMixin",
|
||||
"client.RecipeBookTabButtonMixin",
|
||||
"client.RecipeCollectionMixin",
|
||||
@@ -60,7 +59,6 @@
|
||||
"EntitySkeletonMixin",
|
||||
"EntityStorageMixin",
|
||||
"EntityVillagerMixin",
|
||||
"ExplosionMixin",
|
||||
"ItemStackComponentizationFixMixin",
|
||||
"LecternBlockMixin",
|
||||
"LightningBoltMixin",
|
||||
@@ -74,8 +72,6 @@
|
||||
"PlayerMixin",
|
||||
"PointedDripstoneBlockMixin",
|
||||
"PowderSnowBlockMixin",
|
||||
"RecipeBookSettingsMixin",
|
||||
"RecipeBookTypeMixin",
|
||||
"ServerEntityMixin",
|
||||
"ServerLevelMixin",
|
||||
"ServerPlayerMixin",
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Entity Types Tags
|
||||
|
||||
This file contains tags related to different types of entities in cobblemon.
|
||||
|
||||
## Tags:
|
||||
|
||||
<details>
|
||||
<summary><b>Tag:</b> #cobblemon:boats</summary>
|
||||
|
||||
- cobblemon:boat
|
||||
- cobblemon:chest_boat
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Tag:</b> #cobblemon:cannot_have_name_tag</summary>
|
||||
|
||||
- cobblemon:empty_pokeball
|
||||
- cobblemon:pokemon
|
||||
|
||||
</details>
|
||||
@@ -0,0 +1,180 @@
|
||||
# Spawn Presets
|
||||
|
||||
This file contains all current spawn presets of cobblemon.
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# Spawn Preset List
|
||||
|
||||
## ancient_city
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **maxY** | `62` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:ancient_city_blocks` | |
|
||||
| **structures** | `minecraft:ancient_city` | |
|
||||
## derelict
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **canSeeSky** | `False` | |
|
||||
| **maxLight** | `0` | |
|
||||
| **neededBaseBlocks** | | `#cobblemon:natural` |
|
||||
## desert_pyramid
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `62` | |
|
||||
| **neededBaseBlocks** | | `minecraft:blue_terracotta`; `minecraft:orange_terracotta` |
|
||||
| **neededNearbyBlocks** | `#cobblemon:desert_pyramid_blocks` | |
|
||||
| **structures** | `minecraft:desert_pyramid` | |
|
||||
## end_city
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededBaseBlocks** | `minecraft:end_stone_bricks`; `minecraft:purpur_block`; `minecraft:purpur_pillar` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:end_city_blocks` | |
|
||||
| **structures** | `minecraft:end_city` | |
|
||||
## foliage
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededNearbyBlocks** | `#minecraft:leaves`; `#c:leaves` | |
|
||||
## illager_structures
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `62` | |
|
||||
| **structures** | `minecraft:pillager_outpost`; `minecraft:swamp_hut`; `minecraft:mansion` | |
|
||||
## jungle_pyramid
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `62` | |
|
||||
| **neededBaseBlocks** | `minecraft:cobblestone`; `#minecraft:mossy_cobblestone` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:jungle_pyramid_blocks` | |
|
||||
| **structures** | `minecraft:jungle_pyramid` | |
|
||||
## lava
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **fluid** | `#minecraft:lava` | |
|
||||
## mansion
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `62` | |
|
||||
| **neededBaseBlocks** | `minecraft:birch_planks`; `minecraft:double_smooth_stone_slab`; `minecraft:oak_planks`; `minecraft:polished_andesite`; `#minecraft:wool`; `#minecraft:wool_carpets` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:mansion_blocks` | |
|
||||
| **structures** | `minecraft:mansion` | |
|
||||
## mansion_dining
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `62` | |
|
||||
| **neededBaseBlocks** | `minecraft:birch_planks`; `minecraft:double_smooth_stone_slab`; `minecraft:oak_planks`; `minecraft:polished_andesite`; `#minecraft:wool`; `#minecraft:wool_carpets` | |
|
||||
| **neededNearbyBlocks** | `minecraft:light_grey_carpet`; `minecraft:magenta_carpet`; `minecraft:white_carpet` | |
|
||||
| **structures** | `minecraft:woodland_mansion/1x1_b2`; `minecraft:woodland_mansion/1x2_c1`; `minecraft:woodland_mansion/2x2_b1`; `minecraft:woodland_mansion/2x2_b2` | |
|
||||
## natural
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededBaseBlocks** | `#cobblemon:natural` | `minecraft:farmland` |
|
||||
## nether_fossil
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededNearbyBlocks** | `minecraft:bone_block` | |
|
||||
| **structures** | `minecraft:nether_fossil` | |
|
||||
## nether_structures
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededBaseBlocks** | `minecraft:chiseled_polished_blackstone`; `minecraft:cracked_polished_blackstone_bricks`; `minecraft:gilded_blackstone`; `minecraft:nether_bricks`; `minecraft:polished_basalt`; `minecraft:polished_blackstone_bricks` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:nether_structure_blocks` | |
|
||||
| **structures** | `minecraft:bastion_remnant`; `minecraft:fortress` | |
|
||||
## ocean_monument
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **maxY** | `62` | |
|
||||
| **structures** | `minecraft:monument` | |
|
||||
## ocean_ruins
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **maxY** | `62` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:ocean_ruin_blocks` | |
|
||||
| **structures** | `#minecraft:ocean_ruin` | |
|
||||
## pillager_outpost
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `62` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:pillager_outpost_blocks` | |
|
||||
| **structures** | `minecraft:pillager_outpost` | |
|
||||
## redstone
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededBaseBlocks** | | `#cobblemon:redstone_blocks` |
|
||||
| **neededNearbyBlocks** | `#minecraft:redstone_ores`; `#cobblemon:redstone_blocks`; `#c:redstone_ores` | |
|
||||
## ruined_portal
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededNearbyBlocks** | `ruined_portal_blocks` | |
|
||||
| **structures** | `#minecraft:ruined_portal` | |
|
||||
## saccharine_tree
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededNearbyBlocks** | `cobblemon:saccharine_leaves`; `cobblemon:saccharine_log`; `cobblemon:saccharine_wood`; `cobblemon:stripped_saccharine_log`; `cobblemon:stripped_saccharine_wood` | |
|
||||
## salt
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **biomes** | `biomesoplenty:hot_springs`; `biomesoplenty:wasteland`; `biomesoplenty:wasteland_steppe`; `terralith:amethyst_canyon`; `terralith:amethyst_rainforest`; `terralith:skylands_winter`; `terralith:yellowstone`; `wythers:calcite_caverns`; `wythers:calcite_coast`; `wythers:mediterranean_island_thermal_spring`; `wythers:salt_lakes_pink`; `wythers:salt_lakes_turquoise`; `wythers:salt_lakes_white`; `wythers:thermal_taiga` | |
|
||||
## stronghold
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **maxY** | `62` | |
|
||||
| **neededBaseBlocks** | `#minecraft:stone_bricks` | |
|
||||
| **neededNearbyBlocks** | `minecraft:cracked_stone_bricks`; `minecraft:mossy_stone_bricks` | |
|
||||
| **structures** | `minecraft:stronghold` | |
|
||||
## trail_ruins
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **minY** | `32` | |
|
||||
| **neededBaseBlocks** | `#minecraft:convertable_to_mud`; `#minecraft:sand`; `#minecraft:trail_ruins_replaceable`; `#cobblemon:trail_ruins_blocks`; `minecraft:cobblestone`; `minecraft:stone`; `minecraft:stone_bricks` | |
|
||||
| **neededNearbyBlocks** | `#cobblemon:trail_ruins_blocks` | |
|
||||
| **structures** | `minecraft:trail_ruins` | |
|
||||
## treetop
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededBaseBlocks** | `#cobblemon:trees` | |
|
||||
## urban
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededNearbyBlocks** | `#cobblemon:concrete_blocks` | |
|
||||
| **structures** | | `#minecraft:village`; `minecraft:trail_ruins` |
|
||||
## water
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **fluid** | `#minecraft:water` | |
|
||||
## webs
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **biomes** | `biomesoplenty:spider_nest`; `terralith:cave/infested_caves`; `wythers:forbidden_forest`; `wythers:phantasmal_forest`; `wythers:phantasmal_swamp` | |
|
||||
## wild
|
||||
|
||||
| Key | Conditions | Anticonditions |
|
||||
| --- | ---------- | -------------- |
|
||||
| **neededNearbyBlocks** | | `#cobblemon:concrete_blocks` |
|
||||
| **structures** | | `#minecraft:village` |
|
||||
@@ -6,8 +6,7 @@ PC box wallpapers have two sides, one on client and an optional one on server.
|
||||
This involves adding the texture PNG file to the `assets/cobblemon/textures/gui/pc/wallpaper/` directory. The mod will trawl
|
||||
this directory on asset load and form a base list. The client will send this list to the server to validate
|
||||
the list, with the server returning a list of valid wallpapers. The client will then display the wallpapers in the GUI.
|
||||
The emissive screen glow will be automatically generated using colour of the center pixel of the provided wallpaper.
|
||||
For a custom screen glow, place the file in the `assets/cobblemon/textures/gui/pc/wallpaper/*/glow` directory with the same file name as the wallpaper.
|
||||
The emissive screen glow is an optional asset. To add one, place the file in the `assets/cobblemon/textures/gui/pc/wallpaper/*/glow` directory with the same file name as the wallpaper.
|
||||
An optional, alternate wallpaper can also be provided. This should be similar to the main wallpaper as it will share the custom glow if one is provided. This alternate wallpaper will be shown, replacing the main wallpaper, when holding the Shift key while the wallpaper selection list is open in the PC interface. To add an alternate wallpaper, place the file in the `assets/cobblemon/textures/gui/pc/wallpaper/*/alt` directory with the same file name as the main wallpaper.
|
||||
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
package com.cobblemon.mod.fabric.mixin;
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
@@ -49,17 +50,19 @@ public class RecipeBookCategoriesMixin {
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookCategories> types = new ArrayList<>(List.of($VALUES));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
|
||||
// if you change or add any of these, neoforge uses a separate mechanism
|
||||
// check enumextensions.json and `CobblemonEnumExtensions`
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
|
||||
$VALUES = types.toArray(RecipeBookCategories[]::new);
|
||||
}
|
||||
|
||||
@Inject(method = "getCategories", at = @At("HEAD"), cancellable = true)
|
||||
private static void modifyCategories(RecipeBookType recipeBookType, CallbackInfoReturnable<List<RecipeBookCategories>> cir) {
|
||||
if (recipeBookType == RecipeBookType.valueOf("COOKING_POT")) {
|
||||
if (recipeBookType == CobblemonRecipeBookTypes.INSTANCE.getCOOKING_POT()) {
|
||||
List var10000 = ImmutableList.of(
|
||||
CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory(),
|
||||
@@ -8,25 +8,42 @@
|
||||
|
||||
package com.cobblemon.mod.fabric.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
|
||||
import net.minecraft.stats.RecipeBookSettings;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(RecipeBookSettings.class)
|
||||
public class RecipeBookSettingsMixin {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
|
||||
|
||||
@Inject(method = "<init>(Ljava/util/Map;)V", at = @At("TAIL"))
|
||||
private void cobblemon$init(CallbackInfo ci) {
|
||||
// if you change or add any of these, neoforge uses a separate mechanism
|
||||
// check enumextensions.json and `CobblemonEnumExtensions`
|
||||
states.put(CobblemonRecipeBookTypes.INSTANCE.getCOOKING_POT(), new RecipeBookSettings.TypeSettings(true, true));
|
||||
}
|
||||
|
||||
// this fixes a disconnect issue with vanilla servers where the network sync relies on the enum we modify in a common mixin to be the same on both sides
|
||||
@Redirect( method = "read(Lnet/minecraft/network/FriendlyByteBuf;)Lnet/minecraft/stats/RecipeBookSettings;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookType;values()[Lnet/minecraft/world/inventory/RecipeBookType;"))
|
||||
private static RecipeBookType[] cobblemon$valuesReadRedirect() {
|
||||
return Arrays.stream(RecipeBookType.values()).filter( recipeBookType -> !RecipeBookType.valueOf("COOKING_POT").equals(recipeBookType) ).toArray(RecipeBookType[]::new);
|
||||
return Arrays.stream(RecipeBookType.values()).filter( recipeBookType -> !CobblemonRecipeBookTypes.INSTANCE.getCOOKING_POT().equals(recipeBookType) ).toArray(RecipeBookType[]::new);
|
||||
}
|
||||
|
||||
@Redirect( method = "write(Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookType;values()[Lnet/minecraft/world/inventory/RecipeBookType;"))
|
||||
private RecipeBookType[] cobblemon$valuesWriteRedirect() {
|
||||
return Arrays.stream(RecipeBookType.values()).filter( recipeBookType -> !RecipeBookType.valueOf("COOKING_POT").equals(recipeBookType) ).toArray(RecipeBookType[]::new);
|
||||
return Arrays.stream(RecipeBookType.values()).filter( recipeBookType -> !CobblemonRecipeBookTypes.INSTANCE.getCOOKING_POT().equals(recipeBookType) ).toArray(RecipeBookType[]::new);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
package com.cobblemon.mod.fabric.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -40,7 +41,9 @@ public class RecipeBookTypeMixin {
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookType> types = new ArrayList<>(List.of($VALUES));
|
||||
types.add(cobblemon$createBookType("COOKING_POT", $VALUES.length));
|
||||
// if you change or add any of these, neoforge uses a separate mechanism
|
||||
// check enumextensions.json and `CobblemonEnumExtensions`
|
||||
types.add(cobblemon$createBookType(CobblemonRecipeBookTypes.COOKING_POT_NAME, $VALUES.length));
|
||||
$VALUES = types.toArray(RecipeBookType[]::new);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"FabricCameraMixin",
|
||||
"GameRendererMixin",
|
||||
"GuiMixin",
|
||||
"RecipeBookCategoriesMixin",
|
||||
"pokeball.ModelLoaderMixin"
|
||||
],
|
||||
"mixins": [
|
||||
@@ -15,6 +16,7 @@
|
||||
"FabricBrewingStandMenuMixin",
|
||||
"FabricSoundEngineMixin",
|
||||
"PlayerMixin",
|
||||
"RecipeBookSettingsMixin"
|
||||
"RecipeBookSettingsMixin",
|
||||
"RecipeBookTypeMixin"
|
||||
]
|
||||
}
|
||||
@@ -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.neoforge
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import net.minecraft.client.RecipeBookCategories
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.neoforged.fml.common.asm.enumextension.EnumProxy
|
||||
import java.util.List
|
||||
import java.util.function.Supplier
|
||||
|
||||
|
||||
// to learn more about this, read https://docs.neoforged.net/docs/1.21.1/advanced/extensibleenums/#iextensibleenum
|
||||
// this is the preferred way instead of mixining in ourselves, as it preserves mod compatibility
|
||||
object CobblemonEnumExtensions {
|
||||
@JvmField
|
||||
val COOKING_POT_SEARCH = EnumProxy(RecipeBookCategories::class.java,
|
||||
Supplier<List<ItemStack>> { listOf(ItemStack(Items.COMPASS)) as List<ItemStack> })
|
||||
@JvmField
|
||||
val COOKING_POT_FOODS = EnumProxy(RecipeBookCategories::class.java,
|
||||
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)) as List<ItemStack> })
|
||||
@JvmField
|
||||
val COOKING_POT_MEDICINES = EnumProxy(RecipeBookCategories::class.java,
|
||||
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.POTION)) as List<ItemStack> })
|
||||
@JvmField
|
||||
val COOKING_POT_COMPLEX_DISHES = EnumProxy(RecipeBookCategories::class.java,
|
||||
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.APRIJUICE_RED)) as List<ItemStack> })
|
||||
@JvmField
|
||||
val COOKING_POT_MISC = EnumProxy(RecipeBookCategories::class.java,
|
||||
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.PROTEIN)) as List<ItemStack> })
|
||||
}
|
||||
@@ -9,6 +9,11 @@
|
||||
package com.cobblemon.mod.neoforge
|
||||
|
||||
import com.cobblemon.mod.common.*
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories.COOKING_POT_COMPLEX_DISHES
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories.COOKING_POT_FOODS
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories.COOKING_POT_MEDICINES
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories.COOKING_POT_MISC
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories.COOKING_POT_SEARCH
|
||||
import com.cobblemon.mod.common.advancement.CobblemonCriteria
|
||||
import com.cobblemon.mod.common.advancement.predicate.CobblemonEntitySubPredicates
|
||||
import com.cobblemon.mod.common.api.net.serializers.IdentifierDataSerializer
|
||||
@@ -74,6 +79,7 @@ import net.neoforged.fml.ModList
|
||||
import net.neoforged.fml.common.Mod
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent
|
||||
import net.neoforged.fml.loading.FMLEnvironment
|
||||
import net.neoforged.neoforge.client.event.RegisterRecipeBookCategoriesEvent
|
||||
import net.neoforged.neoforge.common.ItemAbilities
|
||||
import net.neoforged.neoforge.common.NeoForge
|
||||
import net.neoforged.neoforge.common.NeoForgeMod
|
||||
@@ -118,6 +124,7 @@ class CobblemonNeoForge : CobblemonImplementation {
|
||||
addListener(networkManager::registerMessages)
|
||||
addListener(EventPriority.HIGH, ::onBuildContents)
|
||||
addListener(::onAddPackFindersEvent)
|
||||
addListener(::loadRecipeCategory)
|
||||
}
|
||||
with(NeoForge.EVENT_BUS) {
|
||||
addListener(::onDataPackSync)
|
||||
@@ -479,6 +486,19 @@ class CobblemonNeoForge : CobblemonImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadRecipeCategory(e: RegisterRecipeBookCategoriesEvent) {
|
||||
e.registerBookCategories(CobblemonRecipeBookTypes.COOKING_POT, listOf(
|
||||
COOKING_POT_SEARCH.toVanillaCategory(),
|
||||
COOKING_POT_FOODS.toVanillaCategory(),
|
||||
COOKING_POT_MISC.toVanillaCategory(),
|
||||
COOKING_POT_MEDICINES.toVanillaCategory(),
|
||||
COOKING_POT_COMPLEX_DISHES.toVanillaCategory()
|
||||
))
|
||||
CobblemonRecipeCategories.customAggregateCategories.forEach { bookType ->
|
||||
e.registerAggregateCategory(bookType.key, bookType.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onLootTableLoad(e: LootTableLoadEvent) {
|
||||
LootInjector.attemptInjection(e.name) { builder -> e.table.addPool(builder.build()) }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"enum": "net/minecraft/world/inventory/RecipeBookType",
|
||||
"name": "COBBLEMON_COOKING_POT",
|
||||
"constructor": "()V",
|
||||
"parameters": []
|
||||
},
|
||||
{
|
||||
"enum": "net/minecraft/client/RecipeBookCategories",
|
||||
"name": "COBBLEMON_COOKING_POT_SEARCH",
|
||||
"constructor": "(Ljava/util/function/Supplier;)V",
|
||||
"parameters": {
|
||||
"class": "com/cobblemon/mod/neoforge/CobblemonEnumExtensions",
|
||||
"field": "COOKING_POT_SEARCH"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enum": "net/minecraft/client/RecipeBookCategories",
|
||||
"name": "COBBLEMON_COOKING_POT_FOODS",
|
||||
"constructor": "(Ljava/util/function/Supplier;)V",
|
||||
"parameters": {
|
||||
"class": "com/cobblemon/mod/neoforge/CobblemonEnumExtensions",
|
||||
"field": "COOKING_POT_FOODS"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enum": "net/minecraft/client/RecipeBookCategories",
|
||||
"name": "COBBLEMON_COOKING_POT_MEDICINES",
|
||||
"constructor": "(Ljava/util/function/Supplier;)V",
|
||||
"parameters": {
|
||||
"class": "com/cobblemon/mod/neoforge/CobblemonEnumExtensions",
|
||||
"field": "COOKING_POT_MEDICINES"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enum": "net/minecraft/client/RecipeBookCategories",
|
||||
"name": "COBBLEMON_COOKING_POT_COMPLEX_DISHES",
|
||||
"constructor": "(Ljava/util/function/Supplier;)V",
|
||||
"parameters": {
|
||||
"class": "com/cobblemon/mod/neoforge/CobblemonEnumExtensions",
|
||||
"field": "COOKING_POT_COMPLEX_DISHES"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enum": "net/minecraft/client/RecipeBookCategories",
|
||||
"name": "COBBLEMON_COOKING_POT_MISC",
|
||||
"constructor": "(Ljava/util/function/Supplier;)V",
|
||||
"parameters": {
|
||||
"class": "com/cobblemon/mod/neoforge/CobblemonEnumExtensions",
|
||||
"field": "COOKING_POT_MISC"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14,7 +14,7 @@ authors="The Cobblemon Team"
|
||||
description='''
|
||||
Adds Pokémon to the world, letting you find, battle, capture, and evolve them.
|
||||
'''
|
||||
|
||||
enumExtensions="META-INF/enumextensions.json"
|
||||
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
|
||||
# A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
|
||||
|
||||