mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-11-04 15:28:52 -05:00
Compare commits
54
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da76b2fb94 | ||
|
|
87d8197dd0 | ||
|
|
2ed6f89d09 | ||
|
|
5947468cd9 | ||
|
|
7ba1507ac8 | ||
|
|
9fdffdc392 | ||
|
|
6a01fe3863 | ||
|
|
9b5a153e3f | ||
|
|
def975c03f | ||
|
|
e67567e8dc | ||
|
|
23a42a29b3 | ||
|
|
2e88d971f7 | ||
|
|
bfc1c66097 | ||
|
|
13d9f84d8d | ||
|
|
148eb130d9 | ||
|
|
eb07b0e03f | ||
|
|
1b8d416962 | ||
|
|
3030b544b5 | ||
|
|
b890d662f6 | ||
|
|
2a9bbc1d68 | ||
|
|
735817869a | ||
|
|
488e6dcf7a | ||
|
|
a0f32ea444 | ||
|
|
182e06205d | ||
|
|
4c391645fe | ||
|
|
79bf50004a | ||
|
|
396ab13164 | ||
|
|
c10c91d86a | ||
|
|
d5fd2e9a07 | ||
|
|
45cc0ba579 | ||
|
|
1880a0a24e | ||
|
|
5f3a0b96cc | ||
|
|
7ab1610700 | ||
|
|
daad9f6c00 | ||
|
|
2b234b740e | ||
|
|
39e3983020 | ||
|
|
9d58cdb21c | ||
|
|
f05e35e792 | ||
|
|
a333e68620 | ||
|
|
2c2791ec69 | ||
|
|
635b09d82f | ||
|
|
46c3ff9db4 | ||
|
|
8bfc95c23a | ||
|
|
99d05b6ef7 | ||
|
|
1c0a14c819 | ||
|
|
fe5cd58801 | ||
|
|
c3bd007f5a | ||
|
|
dba24e104e | ||
|
|
35815e371b | ||
|
|
d0f8ae0565 | ||
|
|
b2e21969ca | ||
|
|
ea57c233a3 | ||
|
|
0d39b47f22 | ||
|
|
9f3a279b03 |
No files matched your search
+21
-13
@@ -1,27 +1,35 @@
|
||||
# Changelog
|
||||
## [1.8.5 (MONTH xth, 2026)](#1-8-5)
|
||||
## [1.9.0 (MONTH xth, 2026)](#1-9-0)
|
||||
|
||||
### Additions
|
||||
- Added the `healersSetSpawn` gamerule. When enabled, using a healing machine will set your spawnpoint.
|
||||
- A Pokémon holding a Power item now gains 1 point in the corresponding riding stat every two minutes while being ridden. The interval is configurable, and can be disabled with `-1`.
|
||||
- Added sounds to Gigaton Hammer and Pyro Ball
|
||||
- Added stepsounds to Venusaur, Blastoise, Dewgong, Rhydon, Rhyhorn, Parasect and Mr. Mime.
|
||||
- Trainer bags and packs got added
|
||||
- You can craft and equip those to store additional items
|
||||
|
||||
### Changes
|
||||
- Amethyst now grows from Typegem core blocks like typegems do
|
||||
- Updated the recipe category for the Create compatibility EXP Candy recipe
|
||||
- Added No Man's Lands' Honeyed Apple to the Leaves Leftovers tag
|
||||
- Trading has been overhauled to allow offering multiple Pokémon, up to the entire party, in a single trade
|
||||
- Selected Pokémon are now highlighted in both parties with new party slot assets
|
||||
- Hovering an offered Pokémon now shows its summary, and clicking the active Pokémon no longer exits the summary view
|
||||
- The trade animation now moves the offered Pokémon towards the Poké Ball
|
||||
- Parties are compacted after a trade so no empty slots are left between Pokémon
|
||||
|
||||
### Fixes
|
||||
- Fixed Ponigiri food values for AppleSkin integration
|
||||
- Fixed errors emitted by typos in Parched Peat bog structure files
|
||||
|
||||
### Developer
|
||||
- Trade network packets (`TradeUpdatedPacket`, `UpdateTradeOfferPacket`, and `TradeCompletedPacket`) now receive an array of Pokémon instead of a single Pokémon to execute trades
|
||||
- `TradeEvent.Pre` and `TradeEvent.Post` now expose every Pokémon each participant receives (`tradeParticipant1Pokemon` and `tradeParticipant2Pokemon` are now lists), and their Molang context includes `trade_participant_1_pokemon_list` and `trade_participant_2_pokemon_list`
|
||||
|
||||
### Molang & Datapacks
|
||||
- `q.is_standing_on_blocks` now properly checks for non-full blocks like slabs, Mud or Soul Sand
|
||||
- Added Molang functions to play footstep sounds based on the corresponding surface. These are intended to be used by Pokémon animations.
|
||||
- Pokémon can now have their Minecraft footstep sounds silenced in their poser. This doesn't affect emitting game events.
|
||||
- `bag_categories` got added which control what kind of tabs and capabilities the Trainerbags have
|
||||
```json
|
||||
{
|
||||
"order": 1,
|
||||
"icon": "cobblemon:textures/item/medicine/potion.png",
|
||||
"whiteListTag": "cobblemon:bag/whitelist_consumables",
|
||||
"blackListTag": "cobblemon:bag/blacklist_consumables",
|
||||
"maxCount": 512
|
||||
}
|
||||
```
|
||||
- Bunch of default tags as white/blacklist got added to control what can be inserted the corresponding bag categories
|
||||
|
||||
### Particles
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Spec Doc: https://docs.google.com/document/d/1hEKKrT4JEagJBykx-k9K2BoeNxiMGahUWXnf8YQ85xo/edit?tab=t.0
|
||||
Marshal: dhi_holo
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.bag;
|
||||
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagContainer;
|
||||
|
||||
public interface BagEntity {
|
||||
CobblemonBagContainer cobblemon$getBagContainer();
|
||||
void cobblemon$setBagContainer(CobblemonBagContainer bagContainer);
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
|
||||
import com.cobblemon.mod.common.duck.PlayerDuck;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.bag.BagEntity;
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagContainer;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.ScannableEntity;
|
||||
import com.cobblemon.mod.common.pokemon.FormData;
|
||||
@@ -56,6 +58,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -73,7 +76,7 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mixin(Player.class)
|
||||
public abstract class PlayerMixin extends LivingEntity implements ScannableEntity, OrientationControllable, PlayerDuck, RidePassenger {
|
||||
public abstract class PlayerMixin extends LivingEntity implements ScannableEntity, OrientationControllable, PlayerDuck, RidePassenger, BagEntity {
|
||||
|
||||
@Unique
|
||||
private Vector3f cobblemon$driverInput;
|
||||
@@ -107,6 +110,8 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
|
||||
@Unique private Vec3 cobblemon$rideEyePos = Vec3.ZERO;
|
||||
|
||||
@Unique private CobblemonBagContainer cobblemon$cobblemonBagContainer = new CobblemonBagContainer();
|
||||
|
||||
protected PlayerMixin(EntityType<? extends LivingEntity> p_20966_, Level p_20967_) {
|
||||
super(p_20966_, p_20967_);
|
||||
}
|
||||
@@ -404,4 +409,37 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
original.call(target, strength, x, z);
|
||||
}
|
||||
|
||||
@Override @NotNull
|
||||
public CobblemonBagContainer cobblemon$getBagContainer() { return cobblemon$cobblemonBagContainer; }
|
||||
|
||||
@Override
|
||||
public void cobblemon$setBagContainer(CobblemonBagContainer bagContainer) { cobblemon$cobblemonBagContainer = bagContainer; }
|
||||
|
||||
@Inject(
|
||||
method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void cobblemon$readAdditionalSaveData(CompoundTag compound, CallbackInfo ci) {
|
||||
if (compound.contains("CobblemonBagData", 9)) {
|
||||
this.cobblemon$cobblemonBagContainer.fromTag(compound.getList("CobblemonBagData", 10), this.registryAccess());
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void cobblemon$addAdditionalSaveData(CompoundTag compound, CallbackInfo ci) {
|
||||
compound.put("CobblemonBagData", this.cobblemon$cobblemonBagContainer.createTag(this.registryAccess()));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "dropEquipment()V",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void cobblemon$dropCobblemonBag(CallbackInfo ci) {
|
||||
if (level().getGameRules().getBoolean(CobblemonGameRules.BAG_DROP_ITEMS)) {
|
||||
this.cobblemon$cobblemonBagContainer.dropAll((Player)(Object)this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.cobblemon.mod.common.api.stats.CobblemonStats;
|
||||
import com.cobblemon.mod.common.block.HealingMachineBlock;
|
||||
import com.cobblemon.mod.common.duck.ServerLevelDuck;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.bag.BagEntity;
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
@@ -163,4 +164,12 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
||||
cir.setReturnValue(HealingMachineBlock.Companion.findStandUpPosition(EntityType.PLAYER, level, pos).map((vec3) -> ServerPlayer.RespawnPosAngle.of(vec3, pos)));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "restoreFrom",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void cobblemon$restoreCobblemonBag(ServerPlayer that, boolean keepEverything, CallbackInfo ci) {
|
||||
((BagEntity)(Object)this).cobblemon$setBagContainer(((BagEntity)that).cobblemon$getBagContainer());
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.block.appliances.CopperFridgeBlockEntity
|
||||
import com.cobblemon.mod.common.block.appliances.CopperMowerBlockEntity
|
||||
import com.cobblemon.mod.common.block.appliances.CopperWasherBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.*
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
|
||||
@@ -129,49 +126,4 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
CobblemonBlocks.MISTLEAF
|
||||
).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val COPPER_FRIDGE: BlockEntityType<CopperFridgeBlockEntity> = this.create(
|
||||
"copper_fridge",
|
||||
BlockEntityType.Builder.of(::CopperFridgeBlockEntity,
|
||||
CobblemonBlocks.COPPER_FRIDGE,
|
||||
CobblemonBlocks.EXPOSED_COPPER_FRIDGE,
|
||||
CobblemonBlocks.WEATHERED_COPPER_FRIDGE,
|
||||
CobblemonBlocks.OXIDIZED_COPPER_FRIDGE,
|
||||
CobblemonBlocks.WAXED_COPPER_FRIDGE,
|
||||
CobblemonBlocks.WAXED_EXPOSED_COPPER_FRIDGE,
|
||||
CobblemonBlocks.WAXED_WEATHERED_COPPER_FRIDGE,
|
||||
CobblemonBlocks.WAXED_OXIDIZED_COPPER_FRIDGE
|
||||
).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val COPPER_WASHER: BlockEntityType<CopperWasherBlockEntity> = this.create(
|
||||
"copper_washer",
|
||||
BlockEntityType.Builder.of(::CopperWasherBlockEntity,
|
||||
CobblemonBlocks.COPPER_WASHER,
|
||||
CobblemonBlocks.EXPOSED_COPPER_WASHER,
|
||||
CobblemonBlocks.WEATHERED_COPPER_WASHER,
|
||||
CobblemonBlocks.OXIDIZED_COPPER_WASHER,
|
||||
CobblemonBlocks.WAXED_COPPER_WASHER,
|
||||
CobblemonBlocks.WAXED_EXPOSED_COPPER_WASHER,
|
||||
CobblemonBlocks.WAXED_WEATHERED_COPPER_WASHER,
|
||||
CobblemonBlocks.WAXED_OXIDIZED_COPPER_WASHER
|
||||
).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val COPPER_MOWER: BlockEntityType<CopperMowerBlockEntity> = this.create(
|
||||
"copper_mower",
|
||||
BlockEntityType.Builder.of(::CopperMowerBlockEntity,
|
||||
CobblemonBlocks.COPPER_MOWER,
|
||||
CobblemonBlocks.EXPOSED_COPPER_MOWER,
|
||||
CobblemonBlocks.WEATHERED_COPPER_MOWER,
|
||||
CobblemonBlocks.OXIDIZED_COPPER_MOWER,
|
||||
CobblemonBlocks.WAXED_COPPER_MOWER,
|
||||
CobblemonBlocks.WAXED_EXPOSED_COPPER_MOWER,
|
||||
CobblemonBlocks.WAXED_WEATHERED_COPPER_MOWER,
|
||||
CobblemonBlocks.WAXED_OXIDIZED_COPPER_MOWER
|
||||
).build(null)
|
||||
)
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.block.*
|
||||
import com.cobblemon.mod.common.block.LecternBlock
|
||||
import com.cobblemon.mod.common.block.appliances.*
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
|
||||
@@ -29,7 +28,12 @@ import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
|
||||
import com.cobblemon.mod.common.block.tmmachine.TMMachineBlock
|
||||
import com.cobblemon.mod.common.block.general.MintLitterBlock
|
||||
import com.cobblemon.mod.common.mixin.invoker.*
|
||||
import com.cobblemon.mod.common.mixin.invoker.BlocksInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.DoorBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.FireBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.PressurePlateBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.StairsBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.TrapdoorBlockInvoker
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.BlockPos
|
||||
@@ -817,93 +821,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F).requiresCorrectToolForDrops()))
|
||||
|
||||
//Rotom Blocks
|
||||
//Oven
|
||||
@JvmField
|
||||
val COPPER_OVEN = create("copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.BLOCK)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_OVEN = create("exposed_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_OVEN = create("weathered_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_OVEN = create("oxidized_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_OVEN = create("waxed_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_OVEN = create("waxed_exposed_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_OVEN)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_OVEN = create("waxed_weathered_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_OVEN)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_OVEN = create("waxed_oxidized_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_OVEN)))
|
||||
//Washer
|
||||
@JvmField
|
||||
val COPPER_WASHER = create("copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.BLOCK)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_WASHER = create("exposed_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_WASHER = create("weathered_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_WASHER = create("oxidized_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_WASHER = create("waxed_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_WASHER = create("waxed_exposed_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_WASHER)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_WASHER = create("waxed_weathered_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_WASHER)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_WASHER = create("waxed_oxidized_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_WASHER)))
|
||||
//Fan
|
||||
@JvmField
|
||||
val COPPER_FAN = create("copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.DESTROY)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FAN = create("exposed_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FAN = create("weathered_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FAN = create("oxidized_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FAN = create("waxed_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_FAN)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FAN = create("waxed_exposed_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_FAN)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FAN = create("waxed_weathered_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_FAN)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FAN = create("waxed_oxidized_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_FAN)))
|
||||
//Mower
|
||||
@JvmField
|
||||
val COPPER_MOWER = create("copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.NORMAL)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_MOWER = create("exposed_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_MOWER = create("weathered_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_MOWER = create("oxidized_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_MOWER = create("waxed_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_MOWER = create("waxed_exposed_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_MOWER)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_MOWER = create("waxed_weathered_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_MOWER)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_MOWER = create("waxed_oxidized_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_MOWER)))
|
||||
//Fridge
|
||||
@JvmField
|
||||
val COPPER_FRIDGE = create("copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.BLOCK)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FRIDGE = create("exposed_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FRIDGE = create("weathered_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FRIDGE = create("oxidized_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FRIDGE = create("waxed_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FRIDGE = create("waxed_exposed_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_FRIDGE)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FRIDGE = create("waxed_weathered_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_FRIDGE)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FRIDGE = create("waxed_oxidized_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_FRIDGE)))
|
||||
|
||||
// TODO after 1.7
|
||||
// @JvmField
|
||||
// val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F)))
|
||||
@@ -932,6 +849,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val GALARICA_NUT_BUSH = this.create("galarica_nut_bush", NutBushBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().sound(SoundType.SWEET_BERRY_BUSH).pushReaction(PushReaction.DESTROY)))
|
||||
|
||||
|
||||
@JvmField
|
||||
val RED_MINT_LEAF_LITTER = this.mintLitter("red_mint_leaf_litter", MapColor.COLOR_RED)
|
||||
@JvmField
|
||||
@@ -1009,57 +927,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
|
||||
SACCHARINE_LOG_SLATHERED to STRIPPED_SACCHARINE_LOG
|
||||
)
|
||||
/**Same idea as above, but for Copper Oxidation over time (or when inverted, scraping with an axe)*/
|
||||
fun oxidizingBlocks(): Map<Block, Block> = mapOf(
|
||||
//Ovens
|
||||
COPPER_OVEN to EXPOSED_COPPER_OVEN,
|
||||
EXPOSED_COPPER_OVEN to WEATHERED_COPPER_OVEN,
|
||||
WEATHERED_COPPER_OVEN to OXIDIZED_COPPER_OVEN,
|
||||
//Washers
|
||||
COPPER_WASHER to EXPOSED_COPPER_WASHER,
|
||||
EXPOSED_COPPER_WASHER to WEATHERED_COPPER_WASHER,
|
||||
WEATHERED_COPPER_WASHER to OXIDIZED_COPPER_WASHER,
|
||||
//Fans
|
||||
COPPER_FAN to EXPOSED_COPPER_FAN,
|
||||
EXPOSED_COPPER_FAN to WEATHERED_COPPER_FAN,
|
||||
WEATHERED_COPPER_FAN to OXIDIZED_COPPER_FAN,
|
||||
//Fridges
|
||||
COPPER_FRIDGE to EXPOSED_COPPER_FRIDGE,
|
||||
EXPOSED_COPPER_FRIDGE to WEATHERED_COPPER_FRIDGE,
|
||||
WEATHERED_COPPER_FRIDGE to OXIDIZED_COPPER_FRIDGE,
|
||||
//Mowers
|
||||
COPPER_MOWER to EXPOSED_COPPER_MOWER,
|
||||
EXPOSED_COPPER_MOWER to WEATHERED_COPPER_MOWER,
|
||||
WEATHERED_COPPER_MOWER to OXIDIZED_COPPER_MOWER
|
||||
)
|
||||
/**Same idea as above, but for waxing blocks with Honeycomb (or unwaxing them with an axe)*/
|
||||
fun waxingBlocks(): Map<Block, Block> = mapOf(
|
||||
//Ovens
|
||||
COPPER_OVEN to WAXED_COPPER_OVEN,
|
||||
EXPOSED_COPPER_OVEN to WAXED_EXPOSED_COPPER_OVEN,
|
||||
WEATHERED_COPPER_OVEN to WAXED_WEATHERED_COPPER_OVEN,
|
||||
OXIDIZED_COPPER_OVEN to WAXED_OXIDIZED_COPPER_OVEN,
|
||||
//Washers
|
||||
COPPER_WASHER to WAXED_COPPER_WASHER,
|
||||
EXPOSED_COPPER_WASHER to WAXED_EXPOSED_COPPER_WASHER,
|
||||
WEATHERED_COPPER_WASHER to WAXED_WEATHERED_COPPER_WASHER,
|
||||
OXIDIZED_COPPER_WASHER to WAXED_OXIDIZED_COPPER_WASHER,
|
||||
//Fans
|
||||
COPPER_FAN to WAXED_COPPER_FAN,
|
||||
EXPOSED_COPPER_FAN to WAXED_EXPOSED_COPPER_FAN,
|
||||
WEATHERED_COPPER_FAN to WAXED_WEATHERED_COPPER_FAN,
|
||||
OXIDIZED_COPPER_FAN to WAXED_OXIDIZED_COPPER_FAN,
|
||||
//Fridges
|
||||
COPPER_FRIDGE to WAXED_COPPER_FRIDGE,
|
||||
EXPOSED_COPPER_FRIDGE to WAXED_EXPOSED_COPPER_FRIDGE,
|
||||
WEATHERED_COPPER_FRIDGE to WAXED_WEATHERED_COPPER_FRIDGE,
|
||||
OXIDIZED_COPPER_FRIDGE to WAXED_OXIDIZED_COPPER_FRIDGE,
|
||||
//Mowers
|
||||
COPPER_MOWER to WAXED_COPPER_MOWER,
|
||||
EXPOSED_COPPER_MOWER to WAXED_EXPOSED_COPPER_MOWER,
|
||||
WEATHERED_COPPER_MOWER to WAXED_WEATHERED_COPPER_MOWER,
|
||||
OXIDIZED_COPPER_MOWER to WAXED_OXIDIZED_COPPER_MOWER
|
||||
)
|
||||
|
||||
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(BlockBehaviour.Properties.of().mapColor(apricorn.mapColor()).randomTicks().strength(Blocks.OAK_LOG.defaultDestroyTime(), Blocks.OAK_LOG.explosionResistance).sound(SoundType.WOOD).noOcclusion(), apricorn))
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.cobblemon.mod.common.client.pokedex.PokedexType
|
||||
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
|
||||
import com.cobblemon.mod.common.item.*
|
||||
import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagItem
|
||||
import com.cobblemon.mod.common.item.battle.DireHitItem
|
||||
import com.cobblemon.mod.common.item.battle.GuardSpecItem
|
||||
import com.cobblemon.mod.common.item.battle.XStatItem
|
||||
@@ -1517,87 +1518,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val BLANK_TM = this.create("blank_tm", CobblemonItem(Item.Properties()))
|
||||
|
||||
@JvmField
|
||||
val COPPER_OVEN = this.create("copper_oven", BlockItem(CobblemonBlocks.COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_OVEN = this.create("exposed_copper_oven", BlockItem(CobblemonBlocks.EXPOSED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_OVEN = this.create("weathered_copper_oven", BlockItem(CobblemonBlocks.WEATHERED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_OVEN = this.create("oxidized_copper_oven", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_OVEN = this.create("waxed_copper_oven", BlockItem(CobblemonBlocks.WAXED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_OVEN = this.create("waxed_exposed_copper_oven", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_OVEN = this.create("waxed_weathered_copper_oven", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_OVEN = this.create("waxed_oxidized_copper_oven", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_WASHER = this.create("copper_washer", BlockItem(CobblemonBlocks.COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_WASHER = this.create("exposed_copper_washer", BlockItem(CobblemonBlocks.EXPOSED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_WASHER = this.create("weathered_copper_washer", BlockItem(CobblemonBlocks.WEATHERED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_WASHER = this.create("oxidized_copper_washer", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_WASHER = this.create("waxed_copper_washer", BlockItem(CobblemonBlocks.WAXED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_WASHER = this.create("waxed_exposed_copper_washer", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_WASHER = this.create("waxed_weathered_copper_washer", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_WASHER = this.create("waxed_oxidized_copper_washer", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_FAN = this.create("copper_fan", BlockItem(CobblemonBlocks.COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FAN = this.create("exposed_copper_fan", BlockItem(CobblemonBlocks.EXPOSED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FAN = this.create("weathered_copper_fan", BlockItem(CobblemonBlocks.WEATHERED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FAN = this.create("oxidized_copper_fan", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FAN = this.create("waxed_copper_fan", BlockItem(CobblemonBlocks.WAXED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FAN = this.create("waxed_exposed_copper_fan", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FAN = this.create("waxed_weathered_copper_fan", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FAN = this.create("waxed_oxidized_copper_fan", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_MOWER = this.create("copper_mower", BlockItem(CobblemonBlocks.COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_MOWER = this.create("exposed_copper_mower", BlockItem(CobblemonBlocks.EXPOSED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_MOWER = this.create("weathered_copper_mower", BlockItem(CobblemonBlocks.WEATHERED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_MOWER = this.create("oxidized_copper_mower", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_MOWER = this.create("waxed_copper_mower", BlockItem(CobblemonBlocks.WAXED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_MOWER = this.create("waxed_exposed_copper_mower", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_MOWER = this.create("waxed_weathered_copper_mower", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_MOWER = this.create("waxed_oxidized_copper_mower", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_FRIDGE = this.create("copper_fridge", BlockItem(CobblemonBlocks.COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FRIDGE = this.create("exposed_copper_fridge", BlockItem(CobblemonBlocks.EXPOSED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FRIDGE = this.create("weathered_copper_fridge", BlockItem(CobblemonBlocks.WEATHERED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FRIDGE = this.create("oxidized_copper_fridge", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FRIDGE = this.create("waxed_copper_fridge", BlockItem(CobblemonBlocks.WAXED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FRIDGE = this.create("waxed_exposed_copper_fridge", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FRIDGE = this.create("waxed_weathered_copper_fridge", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FRIDGE = this.create("waxed_oxidized_copper_fridge", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_FRIDGE, Item.Properties()))
|
||||
|
||||
// Type Gems
|
||||
@JvmField
|
||||
val NORMAL_GEM = this.create("normal_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_NORMAL))
|
||||
@@ -1658,6 +1578,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val LUCIBELL = compostableBlockItem("lucibell", CobblemonBlocks.LUCIBELL, 0.85f)
|
||||
|
||||
//Bags
|
||||
@JvmField
|
||||
val TRAINER_BAG = this.create("trainer_bag", CobblemonBagItem())
|
||||
@JvmField
|
||||
val TRAINER_PACK = this.create("trainer_pack", CobblemonBagItem())
|
||||
|
||||
private fun blockItem(name: String, block: Block, rarity: Rarity = Rarity.COMMON): BlockItem = this.create(name, BlockItem(block, Item.Properties().rarity(rarity)))
|
||||
|
||||
private fun itemNameBlockItem(name: String, block: Block, rarity: Rarity = Rarity.COMMON): ItemNameBlockItem = this.create(name, ItemNameBlockItem(block, Item.Properties().rarity(rarity)))
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagMenu
|
||||
import com.cobblemon.mod.common.block.tmmachine.TMMachineMenu
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
@@ -20,8 +21,9 @@ import net.minecraft.world.inventory.MenuType
|
||||
|
||||
object CobblemonMenuType : PlatformRegistry<Registry<MenuType<*>>, ResourceKey<Registry<MenuType<*>>>, MenuType<*>>() {
|
||||
|
||||
val COOKING_POT = MenuType.register("cooking_pot_menu", ::CookingPotMenu)
|
||||
val COOKING_POT = MenuType.register("cooking_pot", ::CookingPotMenu)
|
||||
val TM_MACHINE = MenuType.register("tm_machine_menu", ::TMMachineMenu)
|
||||
val COBBLEMON_BAG = MenuType.register("cobblemon_bag", ::CobblemonBagMenu)
|
||||
|
||||
override val registry: Registry<MenuType<*>>
|
||||
get() = BuiltInRegistries.MENU
|
||||
|
||||
@@ -13,6 +13,8 @@ import com.cobblemon.mod.common.client.net.OpenBehaviourEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
|
||||
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
|
||||
import com.cobblemon.mod.common.client.net.animation.PlayPosableAnimationHandler
|
||||
import com.cobblemon.mod.common.client.net.bag.UpdateBagMenuDataHandler
|
||||
import com.cobblemon.mod.common.client.net.bag.UseItemOnPokemonFromBagHandler
|
||||
import com.cobblemon.mod.common.client.net.battle.*
|
||||
import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
|
||||
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
|
||||
@@ -76,6 +78,8 @@ import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.SetClientPlayerDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.bag.UpdateBagMenuDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.bag.UseItemOnPokemonFromBagPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.*
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
|
||||
@@ -444,6 +448,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideSettingsSyncPacket.ID, RideSettingsSyncPacket::decode, RideSettingsSyncHandler))
|
||||
list.add(PacketRegisterInfo(BagCategoriesSyncPacket.ID, BagCategoriesSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(TechnicalMachineRegistrySyncPacket.ID, TechnicalMachineRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
// Effects
|
||||
@@ -640,6 +645,10 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(SetActiveTMPacket.ID, SetActiveTMPacket::decode, SetActiveTMPacketHandler))
|
||||
list.add(PacketRegisterInfo(SetTMMachineContainerDataPacket.ID, SetTMMachineContainerDataPacket::decode, SetTMMachineContainerDataPacketHandler))
|
||||
|
||||
// Bag
|
||||
list.add(PacketRegisterInfo(UpdateBagMenuDataPacket.ID, UpdateBagMenuDataPacket::decode, UpdateBagMenuDataHandler))
|
||||
list.add(PacketRegisterInfo(UseItemOnPokemonFromBagPacket.ID, UseItemOnPokemonFromBagPacket::decode, UseItemOnPokemonFromBagHandler))
|
||||
|
||||
// Behaviour Packets
|
||||
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
|
||||
list.add(PacketRegisterInfo(DamageOnCollisionPacket.ID, DamageOnCollisionPacket::decode, DamageOnCollisionPacketHandler))
|
||||
@@ -647,7 +656,7 @@ object CobblemonNetwork {
|
||||
// Habitat blocks
|
||||
list.add(PacketRegisterInfo(SaveHabitatBlockSettingsPacket.ID, SaveHabitatBlockSettingsPacket::decode, SaveHabitatBlockSettingsHandler))
|
||||
|
||||
// Debug / cheats
|
||||
// Debug
|
||||
list.add(PacketRegisterInfo(RequestOpenRidingStatsDebugGUIPacket.ID, RequestOpenRidingStatsDebugGUIPacket::decode, RequestOpenRidingStatsDebugGUIHandler))
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ package com.cobblemon.mod.common
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.washer.WasherRecipe
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
@@ -27,9 +26,7 @@ object CobblemonRecipeSerializers : PlatformRegistry<Registry<RecipeSerializer<*
|
||||
val COOKING_POT_SHAPELESS: RecipeSerializer<*> = register("cobblemon:cooking_pot_shapeless", CookingPotShapelessRecipe.Serializer())
|
||||
|
||||
val BREWING_STAND: RecipeSerializer<*> = register("cobblemon:brewing_stand", BrewingStandRecipe.Serializer())
|
||||
|
||||
val WASHER: RecipeSerializer<*> = register("cobblemon:washer", WasherRecipe.Serializer())
|
||||
|
||||
|
||||
override val registry: Registry<RecipeSerializer<*>>
|
||||
get() = BuiltInRegistries.RECIPE_SERIALIZER
|
||||
override val resourceKey: ResourceKey<Registry<RecipeSerializer<*>>>
|
||||
|
||||
@@ -12,7 +12,6 @@ package com.cobblemon.mod.common
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.washer.WasherRecipe
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
@@ -27,9 +26,7 @@ object CobblemonRecipeTypes : PlatformRegistry<Registry<RecipeType<*>>, Resource
|
||||
val COOKING_POT_SHAPELESS: RecipeType<CookingPotShapelessRecipe> = register("cobblemon:cooking_pot_shapeless")
|
||||
|
||||
val BREWING_STAND: RecipeType<BrewingStandRecipe> = register("cobblemon:brewing_stand")
|
||||
|
||||
val WASHER: RecipeType<WasherRecipe> = register("cobblemon:washer")
|
||||
|
||||
|
||||
override val registry: Registry<RecipeType<*>>
|
||||
get() = BuiltInRegistries.RECIPE_TYPE
|
||||
override val resourceKey: ResourceKey<Registry<RecipeType<*>>>
|
||||
|
||||
@@ -321,6 +321,19 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK_PLACE = this.create("block.medicinal_leek.plant")
|
||||
|
||||
@JvmField
|
||||
val ITEM_BAG_OPEN = this.create("item.bag.open")
|
||||
@JvmField
|
||||
val ITEM_BAG_CLOSE = this.create("item.bag.close")
|
||||
@JvmField
|
||||
val ITEM_BAG_CLICK = this.create("item.bag.click")
|
||||
@JvmField
|
||||
val ITEM_BAG_ITEM_IN = this.create("item.bag.item_in")
|
||||
@JvmField
|
||||
val ITEM_BAG_ITEM_OUT = this.create("item.bag.item_out")
|
||||
@JvmField
|
||||
val ITEM_BAG_EQUIP = this.create("item.bag.equip")
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST_OPEN = this.create("block.gilded_chest.open")
|
||||
@JvmField
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.bag
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.BagCategoriesSyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.TagKeyAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
|
||||
object BagCategories: JsonDataRegistry<BagCategory> {
|
||||
|
||||
override val id: ResourceLocation = cobblemonResource("bag_categories")
|
||||
override val type: PackType = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<BagCategories>()
|
||||
|
||||
override val gson = GsonBuilder()
|
||||
.disableHtmlEscaping()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(TagKey::class.java, Item::class.java).type, TagKeyAdapter(Registries.ITEM))
|
||||
.create()
|
||||
|
||||
override val typeToken: TypeToken<BagCategory> = TypeToken.get(BagCategory::class.java)
|
||||
override val resourcePath = "bag_categories"
|
||||
|
||||
private val bagCategories = hashMapOf<ResourceLocation, BagCategory>()
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, BagCategory>) {
|
||||
bagCategories.clear()
|
||||
data.forEach { identifier, category ->
|
||||
try {
|
||||
category.identifier = identifier
|
||||
bagCategories[identifier] = category
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.error("Skipped loading the {} category", identifier, e)
|
||||
}
|
||||
}
|
||||
Cobblemon.LOGGER.info("Loaded {} bag categories", bagCategories.size)
|
||||
this.observable.emit(this)
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
BagCategoriesSyncPacket(bagCategories.values.toList())
|
||||
}
|
||||
|
||||
fun getOrderedCategoriesList(): List<BagCategory> {
|
||||
return bagCategories.values.toList().sortedBy { it.order }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.bag
|
||||
|
||||
import com.cobblemon.mod.common.util.readIdentifier
|
||||
import com.cobblemon.mod.common.util.writeIdentifier
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
class BagCategory(
|
||||
identifier: ResourceLocation,
|
||||
val order: Int,
|
||||
val icon: ResourceLocation,
|
||||
val whiteListTag: TagKey<Item>,
|
||||
val blackListTag: TagKey<Item>,
|
||||
val maxCount: Int
|
||||
): StringRepresentable {
|
||||
@Transient
|
||||
var identifier: ResourceLocation = identifier
|
||||
internal set
|
||||
|
||||
override fun getSerializedName(): String = identifier.toString()
|
||||
|
||||
fun getName(): MutableComponent = Component.translatable("${identifier.namespace}.bag_category.${identifier.path}")
|
||||
|
||||
fun itemIsValid(itemStack: ItemStack): Boolean {
|
||||
if (itemStack.`is`(blackListTag)) return false
|
||||
if (itemStack.`is`(whiteListTag)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeIdentifier(identifier)
|
||||
buffer.writeInt(order)
|
||||
buffer.writeIdentifier(icon)
|
||||
buffer.writeIdentifier(whiteListTag.location)
|
||||
buffer.writeIdentifier(blackListTag.location)
|
||||
buffer.writeInt(maxCount)
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal fun decode(buffer: RegistryFriendlyByteBuf): BagCategory {
|
||||
return BagCategory(
|
||||
buffer.readIdentifier(),
|
||||
buffer.readInt(),
|
||||
buffer.readIdentifier(),
|
||||
TagKey.create(Registries.ITEM, buffer.readIdentifier()),
|
||||
TagKey.create(Registries.ITEM, buffer.readIdentifier()),
|
||||
buffer.readInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,14 @@
|
||||
package com.cobblemon.mod.common.api.events.pokemon
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.trade.TradeParticipant
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
|
||||
/**
|
||||
@@ -31,9 +33,9 @@ interface TradeEvent {
|
||||
val tradeParticipant1: TradeParticipant
|
||||
|
||||
/**
|
||||
* The [Pokemon] being traded by the first participant.
|
||||
* All the [Pokemon] the first participant receives in the trade.
|
||||
*/
|
||||
val tradeParticipant1Pokemon: Pokemon
|
||||
val tradeParticipant1Pokemon: List<Pokemon>
|
||||
|
||||
/**
|
||||
* The second [TradeParticipant].
|
||||
@@ -41,9 +43,19 @@ interface TradeEvent {
|
||||
val tradeParticipant2: TradeParticipant
|
||||
|
||||
/**
|
||||
* The [Pokemon] being traded by the second participant.
|
||||
* All the [Pokemon] the second participant receives in the trade.
|
||||
*/
|
||||
val tradeParticipant2Pokemon: Pokemon
|
||||
val tradeParticipant2Pokemon: List<Pokemon>
|
||||
|
||||
fun createContext(): MutableMap<String, MoValue> = mutableMapOf(
|
||||
"trade_participant_1" to (tradeParticipant1.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_2" to (tradeParticipant2.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
// Kept for backwards compatibility, this is the first Pokémon of each side.
|
||||
"trade_participant_1_pokemon" to tradeParticipant1Pokemon.first().struct,
|
||||
"trade_participant_2_pokemon" to tradeParticipant2Pokemon.first().struct,
|
||||
"trade_participant_1_pokemon_list" to tradeParticipant1Pokemon.asArrayValue { it.struct },
|
||||
"trade_participant_2_pokemon_list" to tradeParticipant2Pokemon.asArrayValue { it.struct }
|
||||
)
|
||||
|
||||
/**
|
||||
* Event fired when a trade is about to happen. Cancelling this event prevents the trade from occurring.
|
||||
@@ -53,16 +65,11 @@ interface TradeEvent {
|
||||
*/
|
||||
data class Pre(
|
||||
override val tradeParticipant1: TradeParticipant,
|
||||
override val tradeParticipant1Pokemon: Pokemon,
|
||||
override val tradeParticipant1Pokemon: List<Pokemon>,
|
||||
override val tradeParticipant2: TradeParticipant,
|
||||
override val tradeParticipant2Pokemon: Pokemon
|
||||
override val tradeParticipant2Pokemon: List<Pokemon>
|
||||
) : TradeEvent, Cancelable() {
|
||||
val context = mutableMapOf(
|
||||
"trade_participant_1" to (tradeParticipant1.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_2" to (tradeParticipant2.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_1_pokemon" to tradeParticipant1Pokemon.struct,
|
||||
"trade_participant_2_pokemon" to tradeParticipant2Pokemon.struct
|
||||
)
|
||||
val context = createContext()
|
||||
|
||||
val functions = moLangFunctionMap(
|
||||
cancelFunc
|
||||
@@ -77,15 +84,10 @@ interface TradeEvent {
|
||||
*/
|
||||
data class Post(
|
||||
override val tradeParticipant1: TradeParticipant,
|
||||
override val tradeParticipant1Pokemon: Pokemon,
|
||||
override val tradeParticipant1Pokemon: List<Pokemon>,
|
||||
override val tradeParticipant2: TradeParticipant,
|
||||
override val tradeParticipant2Pokemon: Pokemon
|
||||
override val tradeParticipant2Pokemon: List<Pokemon>
|
||||
) : TradeEvent {
|
||||
val context = mutableMapOf(
|
||||
"trade_participant_1" to (tradeParticipant1.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_2" to (tradeParticipant2.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_1_pokemon" to tradeParticipant1Pokemon.struct,
|
||||
"trade_participant_2_pokemon" to tradeParticipant2Pokemon.struct
|
||||
)
|
||||
val context = createContext()
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,9 @@
|
||||
package com.cobblemon.mod.common.api.riding.stats
|
||||
|
||||
import com.cobblemon.mod.common.api.cooking.Flavour
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
|
||||
/**
|
||||
* A stat that is used for riding Pokémon. The exact implementation of each of these depends on the [com.cobblemon.mod.common.api.riding.controller.RideController].
|
||||
@@ -23,14 +20,13 @@ import net.minecraft.world.item.Item
|
||||
* @since February 17th, 2025
|
||||
*/
|
||||
enum class RidingStat(
|
||||
val flavour: Flavour,
|
||||
val powerItem: TagKey<Item>
|
||||
val flavour: Flavour
|
||||
) {
|
||||
ACCELERATION(Flavour.SPICY, CobblemonItemTags.POWER_BRACER),
|
||||
SKILL(Flavour.DRY, CobblemonItemTags.POWER_BELT),
|
||||
SPEED(Flavour.SWEET, CobblemonItemTags.POWER_ANKLET),
|
||||
STAMINA(Flavour.SOUR, CobblemonItemTags.POWER_WEIGHT),
|
||||
JUMP(Flavour.BITTER, CobblemonItemTags.POWER_BAND);
|
||||
ACCELERATION(Flavour.SPICY),
|
||||
SKILL(Flavour.DRY),
|
||||
SPEED(Flavour.SWEET),
|
||||
STAMINA(Flavour.SOUR),
|
||||
JUMP(Flavour.BITTER);
|
||||
|
||||
companion object {
|
||||
fun getByName(name: String) = RidingStat.entries.firstOrNull { it.name.equals(name, ignoreCase = true) }
|
||||
|
||||
@@ -140,6 +140,20 @@ object CobblemonItemTags {
|
||||
@JvmField val WEARABLE_HAT_ITEMS = create("held/visibility/hat")
|
||||
@JvmField val HIDDEN_ITEMS = create("held/visibility/hidden")
|
||||
|
||||
//Bag Categories Tags
|
||||
@JvmField val BAG_WHITELIST_POKE_BALLS = create("bag/whitelist_poke_balls")
|
||||
@JvmField val BAG_BLACKLIST_POKE_BALLS = create("bag/blacklist_poke_balls")
|
||||
@JvmField val BAG_WHITELIST_CONSUMABLES = create("bag/whitelist_consumables")
|
||||
@JvmField val BAG_BLACKLIST_CONSUMABLES = create("bag/blacklist_consumables")
|
||||
@JvmField val BAG_WHITELIST_BERRIES = create("bag/whitelist_berries")
|
||||
@JvmField val BAG_BLACKLIST_BERRIES = create("bag/blacklist_berries")
|
||||
@JvmField val BAG_WHITELIST_HELD_EVO = create("bag/whitelist_held_evo")
|
||||
@JvmField val BAG_BLACKLIST_HELD_EVO = create("bag/blacklist_held_evo")
|
||||
@JvmField val BAG_WHITELIST_CURRENCY = create("bag/whitelist_currency")
|
||||
@JvmField val BAG_BLACKLIST_CURRENCY = create("bag/blacklist_currency")
|
||||
@JvmField val BAG_WHITELIST_TMS = create("bag/whitelist_tms")
|
||||
@JvmField val BAG_BLACKLIST_TMS = create("bag/blacklist_tms")
|
||||
|
||||
//Empty Tag
|
||||
@JvmField val EMPTY = create("empty")
|
||||
|
||||
|
||||
@@ -1,87 +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.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: All the Fan appliance stuff
|
||||
//TODO: Able to place the Fan on Walls, models and hitbox are there (blockstate would need edits to support it)
|
||||
open class CopperFanBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperFanBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperFanBlock) }
|
||||
//val FACE = //TODO: Floor/Wall
|
||||
val POWER = BlockStateProperties.POWER;
|
||||
val PUSH = BooleanProperty.create("push")
|
||||
|
||||
val FLOOR_HITBOX = Shapes.or(
|
||||
Shapes.box(0.0625, 0.125, 0.4375, 0.9375, 1.0, 0.5625),
|
||||
Shapes.box(0.375, 0.0, 0.375, 0.625, 0.125, 0.625))
|
||||
val WALL_HITBOX = Shapes.box(0.0625, 0.0625, 0.875, 0.9375, 0.9375, 1.0)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
//.setValue(FACE, AttachFace.FLOOR)
|
||||
.setValue(POWER, 0)
|
||||
.setValue(PUSH, true) //If True, fan pushes entities, If False, fan is cosmetic only
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperFanBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, /*FACE,*/ POWER, PUSH)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, FLOOR_HITBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
return getCollisionShape(state, level, pos, context)
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
}
|
||||
-275
@@ -1,275 +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.appliances
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.util.isServerSide
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.ItemInteractionResult
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.LevelReader
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: Oxidation/Waxing/Scraping not breaking the blocks
|
||||
//TODO: All the Fridge appliance stuff
|
||||
open class CopperFridgeBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
fun getBlockEntity(level: ServerLevel, pos: BlockPos) = level.getBlockEntity(getBottomPos(level, pos)) as CopperFridgeBlockEntity
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperFridgeBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperFridgeBlock) }
|
||||
val HALF: EnumProperty<DoubleBlockHalf> = BlockStateProperties.DOUBLE_BLOCK_HALF
|
||||
val POWERED = BooleanProperty.create("powered")
|
||||
val FACING = HorizontalDirectionalBlock.FACING
|
||||
|
||||
val LOWER_HITBOX = Shapes.or(
|
||||
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.0625, 0.9375),
|
||||
Shapes.box(0.0, 0.0625, 0.0625, 1.0, 1.0, 1.0))
|
||||
val UPPER_HITBOX = Shapes.or(
|
||||
Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0),
|
||||
Shapes.box(0.25, 0.125, 0.0, 0.375, 0.3125, 0.0625),
|
||||
Shapes.box(0.625, 0.125, 0.0, 0.75, 0.3125, 0.0625))
|
||||
val UPPER_COLLISSIONBOX = Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0)
|
||||
//The handles get ignored by entity collission, because it feels nicer, but still count as part of the hitbox
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(HALF, DoubleBlockHalf.LOWER)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(POWERED, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperFridgeBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, HALF, WATERLOGGED, POWERED)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
|
||||
val isFridge = neighborState.`is`(this)
|
||||
val half = state.getValue(HALF)
|
||||
if (!isFridge && half == DoubleBlockHalf.UPPER && neighborPos == pos.below()) {
|
||||
return Blocks.AIR.defaultBlockState()
|
||||
} else if (!isFridge && half == DoubleBlockHalf.LOWER && neighborPos == pos.above()) {
|
||||
return Blocks.AIR.defaultBlockState()
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
|
||||
rotateShape(Direction.NORTH, direction, LOWER_HITBOX)
|
||||
} else {
|
||||
rotateShape(Direction.NORTH, direction, UPPER_COLLISSIONBOX)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
|
||||
rotateShape(Direction.NORTH, direction, LOWER_HITBOX)
|
||||
} else {
|
||||
rotateShape(Direction.NORTH, direction, UPPER_HITBOX)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setPlacedBy(world: Level, pos: BlockPos, state: BlockState, placer: LivingEntity?, itemStack: ItemStack) {
|
||||
world.setBlock(pos.above(),
|
||||
state
|
||||
.setValue(HALF, DoubleBlockHalf.UPPER)
|
||||
.setValue(WATERLOGGED, world.getFluidState((pos.above())).type == Fluids.WATER)
|
||||
, 3)
|
||||
world.blockUpdated(pos, Blocks.AIR)
|
||||
state.updateNeighbourShapes(world, pos, 3)
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState? {
|
||||
val abovePosition = blockPlaceContext.clickedPos.above()
|
||||
val world = blockPlaceContext.level
|
||||
if (world.getBlockState(abovePosition).canBeReplaced(blockPlaceContext) && !world.isOutsideBuildHeight(abovePosition)) {
|
||||
return defaultBlockState()
|
||||
.setValue(FACING, blockPlaceContext.horizontalDirection.opposite)
|
||||
.setValue(HALF, DoubleBlockHalf.LOWER)
|
||||
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getRenderShape(state: BlockState) = RenderShape.MODEL
|
||||
|
||||
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
|
||||
val blockPos = pos.below()
|
||||
val blockState = world.getBlockState(blockPos)
|
||||
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) blockState.isFaceSturdy(world, blockPos, Direction.UP) else blockState.`is`(this)
|
||||
}
|
||||
|
||||
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
|
||||
if (!world.isClientSide && player.isCreative) {
|
||||
var blockPos: BlockPos = BlockPos.ZERO
|
||||
var blockState: BlockState = state
|
||||
val half = state.getValue(HALF)
|
||||
if (half == DoubleBlockHalf.UPPER && world.getBlockState(pos.below().also { blockPos = it }).also { blockState = it }.`is`(state.block) && blockState.getValue(
|
||||
HALF
|
||||
) == DoubleBlockHalf.LOWER) {
|
||||
val blockState2 = if (blockState.fluidState.`is`(Fluids.WATER)) Blocks.WATER.defaultBlockState() else Blocks.AIR.defaultBlockState()
|
||||
world.setBlock(blockPos, blockState2, UPDATE_ALL or UPDATE_SUPPRESS_DROPS)
|
||||
world.levelEvent(player, LevelEvent.PARTICLES_DESTROY_BLOCK, blockPos, getId(blockState))
|
||||
}
|
||||
}
|
||||
return super.playerWillDestroy(world, pos, state, player)
|
||||
}
|
||||
|
||||
override fun useItemOn(
|
||||
stack: ItemStack,
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
player: Player,
|
||||
hand: InteractionHand,
|
||||
hitResult: BlockHitResult
|
||||
): ItemInteractionResult {
|
||||
if (level.isServerSide()) {
|
||||
val handStack = player.getItemInHand(hand)
|
||||
val stack = getBlockEntity(level as ServerLevel, pos).theItem
|
||||
|
||||
when (stack.item) {
|
||||
Items.AIR -> {
|
||||
if (handStack.`is`(Items.WATER_BUCKET)) {
|
||||
if (!player.isCreative) player.setItemInHand(hand, Items.BUCKET.defaultInstance)
|
||||
getBlockEntity(level, pos).timer = 100
|
||||
getBlockEntity(level, pos).theItem = Items.WATER_BUCKET.defaultInstance
|
||||
return ItemInteractionResult.SUCCESS
|
||||
} else {
|
||||
return ItemInteractionResult.FAIL
|
||||
}
|
||||
}
|
||||
|
||||
Items.WATER_BUCKET -> {
|
||||
if (handStack.`is`(Items.BUCKET)) {
|
||||
player.setItemInHand(hand, Items.WATER_BUCKET.defaultInstance)
|
||||
getBlockEntity(level, pos).theItem = Items.AIR.defaultInstance
|
||||
getBlockEntity(level, pos).timer = 0
|
||||
return ItemInteractionResult.SUCCESS
|
||||
} else {
|
||||
return ItemInteractionResult.FAIL
|
||||
}
|
||||
}
|
||||
|
||||
Items.ICE -> {
|
||||
val facing = state.getValue(HORIZONTAL_FACING)
|
||||
val spawnPos = getBottomPos(level, pos)
|
||||
val itemEntity =
|
||||
ItemEntity(level, spawnPos.x + 0.5, spawnPos.y + 0.5, spawnPos.z + 0.5, Items.ICE.defaultInstance)
|
||||
itemEntity.deltaMovement = Vec3(facing.stepX.toDouble(), 0.0, facing.stepZ.toDouble()).scale(0.2)
|
||||
level.addFreshEntity(itemEntity)
|
||||
getBlockEntity(level, pos).theItem = Items.AIR.defaultInstance
|
||||
return ItemInteractionResult.SUCCESS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ItemInteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun getAnalogOutputSignal(state: BlockState, level: Level, pos: BlockPos): Int {
|
||||
if (level.isClientSide) return super.getAnalogOutputSignal(state, level, pos)
|
||||
return when (getBlockEntity(level as ServerLevel, pos).theItem.item) {
|
||||
Items.WATER_BUCKET -> 1
|
||||
Items.ICE -> 2
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun tick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
|
||||
(level.getBlockEntity(pos) as CopperFridgeBlockEntity).processTick()
|
||||
super.tick(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun newBlockEntity(pos: BlockPos, state: BlockState) = if (state.getValue(HALF) == DoubleBlockHalf.LOWER) CopperFridgeBlockEntity(pos, state) else null
|
||||
|
||||
override fun neighborChanged(
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
neighborBlock: Block,
|
||||
neighborPos: BlockPos,
|
||||
movedByPiston: Boolean
|
||||
) {
|
||||
if (!level.isClientSide) {
|
||||
val otherPos = if (state.getValue(HALF) == DoubleBlockHalf.LOWER) pos.above() else pos.below()
|
||||
val powered = level.hasNeighborSignal(pos) || level.hasNeighborSignal(otherPos)
|
||||
|
||||
if (state.getValue(POWERED) != powered) {
|
||||
level.setBlock(pos, state.setValue(POWERED, powered), 3)
|
||||
}
|
||||
|
||||
val otherState = level.getBlockState(otherPos)
|
||||
if (otherState.`is`(this) && otherState.getValue(POWERED) != powered) {
|
||||
level.setBlock(otherPos, otherState.setValue(POWERED, powered), 3)
|
||||
}
|
||||
}
|
||||
super.neighborChanged(state, level, pos, neighborBlock, neighborPos, movedByPiston)
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity> getTicker(
|
||||
level: Level,
|
||||
state: BlockState,
|
||||
blockEntityType: BlockEntityType<T>
|
||||
): BlockEntityTicker<T>? {
|
||||
return if (level.isClientSide)
|
||||
null
|
||||
else
|
||||
createTickerHelper(blockEntityType, CobblemonBlockEntities.COPPER_FRIDGE, CopperFridgeBlockEntity.TICKER::tick)
|
||||
}
|
||||
|
||||
fun getBottomPos(level: Level, pos: BlockPos) = if (level.getBlockState(pos).getValue(HALF) == DoubleBlockHalf.UPPER) pos.below() else pos
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.ticks.ContainerSingleItem
|
||||
|
||||
class CopperFridgeBlockEntity(val pos: BlockPos, val state: BlockState) : BlockEntity(
|
||||
CobblemonBlockEntities.COPPER_FRIDGE, pos, state
|
||||
), ContainerSingleItem.BlockContainerSingleItem {
|
||||
|
||||
private var item: ItemStack = Items.AIR.defaultInstance
|
||||
var timer: Int = -1
|
||||
|
||||
fun processTick() {
|
||||
if (level == null) return
|
||||
if (!level!!.getBlockState(pos).getValue(CopperFridgeBlock.POWERED)) return
|
||||
if (timer > 0) timer--
|
||||
if (timer == 0 && item.item == Items.WATER_BUCKET) {
|
||||
item = Items.ICE.defaultInstance
|
||||
timer = -1
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContainerBlockEntity() = this
|
||||
override fun getTheItem() = item
|
||||
|
||||
override fun setTheItem(item: ItemStack) {
|
||||
this.item = item
|
||||
}
|
||||
|
||||
override fun canTakeItem(target: Container, slot: Int, stack: ItemStack): Boolean {
|
||||
return stack.item == Items.ICE
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val TICKER = BlockEntityTicker<CopperFridgeBlockEntity> { level, pos, state, entity ->
|
||||
if (!level.isClientSide) {
|
||||
entity.processTick()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +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.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: All the Mower appliance stuff
|
||||
open class CopperMowerBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperMowerBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperMowerBlock) }
|
||||
val TRIGGERED = BooleanProperty.create("triggered")
|
||||
|
||||
val COLLISIONBOX = Shapes.or(
|
||||
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
|
||||
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
|
||||
Shapes.box(0.125, 0.0, 0.1875, 0.875, 0.3125, 0.5),
|
||||
//The next three lines are just so the handle does have collision, it feels awkward without it but it looks bad as hitbox
|
||||
Shapes.box(0.375, 0.375, 0.375, 0.625, 0.625, 0.5625),
|
||||
Shapes.box(0.4375, 0.5625, 0.5, 0.5625, 0.875, 0.625),
|
||||
Shapes.box(0.25, 0.875, 0.5625, 0.75, 1.0, 0.6875)
|
||||
)
|
||||
val HITBOX = Shapes.or(
|
||||
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
|
||||
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
|
||||
Shapes.box(0.125, 0.0, 0.1875, 0.875, 0.3125, 0.5)
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(TRIGGERED, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperMowerBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, TRIGGERED)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, COLLISIONBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, HITBOX)
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
|
||||
override fun newBlockEntity(
|
||||
pos: BlockPos,
|
||||
state: BlockState
|
||||
) = CopperMowerBlockEntity(pos, state)
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class CopperMowerBlockEntity(val pos: BlockPos, val state: BlockState) : BlockEntity(
|
||||
CobblemonBlockEntities.COPPER_MOWER,
|
||||
pos, state
|
||||
) {
|
||||
}
|
||||
@@ -1,88 +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.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: All the Oven appliance stuff - Good Luck Coders
|
||||
open class CopperOvenBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperOvenBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperOvenBlock) }
|
||||
val EJECTING = BooleanProperty.create("ejecting")
|
||||
val COOKING = EnumProperty.create("cooking", CookingState::class.java)
|
||||
|
||||
val HITBOX = Shapes.box(0.0625, 0.0, 0.3125, 0.9375, 0.625, 0.9375)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(COOKING, CookingState.CLOSED)
|
||||
.setValue(EJECTING, false)
|
||||
)
|
||||
}
|
||||
enum class CookingState : StringRepresentable {
|
||||
CLOSED, //Door is closed
|
||||
OPEN, //Door is open
|
||||
COOKING; //Door is locked closed and the light level is cranked up, as long as the block is powered by redstone. Acts as closed lid in the original Campfire Pot
|
||||
override fun getSerializedName(): String = this.name.lowercase()
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperOvenBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, COOKING, EJECTING)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, HITBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
return getCollisionShape(state, level, pos, context).singleEncompassing()
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
}
|
||||
-124
@@ -1,124 +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.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.isServerSide
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.ItemInteractionResult
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
|
||||
open class CopperWasherBlock(settings: Properties) : BaseEntityBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperWasherBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperWasherBlock) }
|
||||
val POWERED = BooleanProperty.create("powered")
|
||||
|
||||
val HITBOX = Shapes.box(0.0625, 0.0, 0.125, 0.9375, 1.0, 1.0)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(POWERED, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperWasherBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, POWERED)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, HITBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
return getCollisionShape(state, level, pos, context).singleEncompassing()
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
|
||||
override fun newBlockEntity(pos: BlockPos, state: BlockState) = CopperWasherBlockEntity(pos, state)
|
||||
|
||||
override fun getRenderShape(state: BlockState) = RenderShape.MODEL
|
||||
|
||||
override fun useItemOn(
|
||||
stack: ItemStack,
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
player: Player,
|
||||
hand: InteractionHand,
|
||||
hitResult: BlockHitResult
|
||||
): ItemInteractionResult {
|
||||
val entity = level.getBlockEntity(pos) as CopperWasherBlockEntity
|
||||
val item = entity.theItem
|
||||
if (item == ItemStack.EMPTY) {
|
||||
if (level.isServerSide()) {
|
||||
entity.theItem = stack.copyWithCount(1)
|
||||
if (!player.isCreative) stack.shrink(1)
|
||||
entity.craft()
|
||||
}
|
||||
return ItemInteractionResult.SUCCESS
|
||||
} else {
|
||||
if (level.isServerSide()) {
|
||||
val facing = state.getValue(HORIZONTAL_FACING)
|
||||
val itemEntity =
|
||||
ItemEntity(level, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, entity.theItem)
|
||||
itemEntity.deltaMovement = Vec3(facing.stepX.toDouble(), 0.0, facing.stepZ.toDouble()).scale(0.2)
|
||||
level.addFreshEntity(itemEntity)
|
||||
entity.theItem = ItemStack.EMPTY
|
||||
}
|
||||
return ItemInteractionResult.SUCCESS
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.CobblemonRecipeTypes
|
||||
import com.cobblemon.mod.common.item.crafting.washer.WasherInput
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.ticks.ContainerSingleItem
|
||||
|
||||
class CopperWasherBlockEntity(val pos: BlockPos, val state: BlockState): BlockEntity(
|
||||
CobblemonBlockEntities.COPPER_WASHER,
|
||||
pos, state
|
||||
), ContainerSingleItem.BlockContainerSingleItem {
|
||||
|
||||
private var item: ItemStack = ItemStack.EMPTY
|
||||
|
||||
override fun getContainerBlockEntity() = this
|
||||
override fun getTheItem() = item
|
||||
override fun setTheItem(item: ItemStack) { this.item = item }
|
||||
|
||||
fun craft() {
|
||||
val level = level ?: return
|
||||
if (level.isClientSide || theItem.isEmpty) return
|
||||
|
||||
val input = WasherInput(theItem.copyWithCount(1))
|
||||
val recipe = level.recipeManager
|
||||
.getRecipeFor(CobblemonRecipeTypes.WASHER, input, level)
|
||||
.orElse(null) ?: return
|
||||
|
||||
theItem = recipe.value().assemble(input, level.registryAccess())
|
||||
setChanged()
|
||||
level.sendBlockUpdated(worldPosition, blockState, blockState, 3)
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperFanBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperFanBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +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.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties
|
||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
|
||||
|
||||
class WeatheringCopperFridgeBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperFridgeBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
|
||||
if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
}
|
||||
|
||||
override fun changeOverTime(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) {
|
||||
val upperPos = pos.above()
|
||||
val upperState = level.getBlockState(upperPos)
|
||||
if (upperState.block != this || upperState.getValue(HALF) != DoubleBlockHalf.UPPER) {
|
||||
return
|
||||
}
|
||||
|
||||
if (random.nextFloat() < 0.05688889F) {
|
||||
getNextState(state, level, pos, random).ifPresent { nextState ->
|
||||
val nextLowerState = nextState.setValue(HALF, DoubleBlockHalf.LOWER)
|
||||
val nextUpperState = nextState
|
||||
.setValue(HALF, DoubleBlockHalf.UPPER)
|
||||
.setValue(FACING, upperState.getValue(FACING))
|
||||
.setValue(BlockStateProperties.WATERLOGGED, upperState.getValue(BlockStateProperties.WATERLOGGED))
|
||||
.setValue(POWERED, upperState.getValue(POWERED))
|
||||
|
||||
level.setBlock(pos, nextLowerState, Block.UPDATE_CLIENTS)
|
||||
level.setBlock(upperPos, nextUpperState, Block.UPDATE_ALL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.block).isPresent
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperMowerBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperMowerBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperOvenBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperOvenBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperWasherBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperWasherBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,13 @@
|
||||
package com.cobblemon.mod.common.client
|
||||
|
||||
import com.cobblemon.mod.common.BakingOverride
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagItem
|
||||
import com.cobblemon.mod.common.util.cobblemonModel
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.Item
|
||||
|
||||
/**
|
||||
* The purpose of this class is to hold models that we want baked, but aren't associated with
|
||||
@@ -103,9 +106,33 @@ object CobblemonBakingOverrides {
|
||||
cobblemonModel("surprise_mulch", "none")
|
||||
)
|
||||
|
||||
// Bag
|
||||
val bagModels = mutableMapOf<CobblemonBagItem, BakingOverride>()
|
||||
val TRAINER_PACK = registerBagOverride(
|
||||
CobblemonItems.TRAINER_PACK,
|
||||
cobblemonResource("item/bag/trainer_pack"),
|
||||
cobblemonModel("trainer_pack", "none")
|
||||
)
|
||||
val TRAINER_BAG = registerBagOverride(
|
||||
CobblemonItems.TRAINER_BAG,
|
||||
cobblemonResource("item/bag/trainer_bag"),
|
||||
cobblemonModel("trainer_bag", "none")
|
||||
)
|
||||
/*val BAG_PENNY = registerBagOverride(
|
||||
CobblemonItems.TRAINER_PACK,
|
||||
cobblemonResource("item/bag/bag_penny"),
|
||||
cobblemonModel("bag_penny", "penny")
|
||||
)*/
|
||||
|
||||
fun registerOverride(modelLocation: ResourceLocation, modelIdentifier: ModelResourceLocation): BakingOverride {
|
||||
val result = BakingOverride(modelLocation, modelIdentifier)
|
||||
models.add(result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun registerBagOverride(associatedItem: CobblemonBagItem, modelLocation: ResourceLocation, modelIdentifier: ModelResourceLocation): BakingOverride {
|
||||
val result = registerOverride(modelLocation, modelIdentifier)
|
||||
bagModels[associatedItem] = result
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.cobblemon.mod.common.client.battle.ClientBattle
|
||||
import com.cobblemon.mod.common.client.gui.PartyOverlay
|
||||
import com.cobblemon.mod.common.client.gui.PartyOverlayDataControl
|
||||
import com.cobblemon.mod.common.client.gui.RideControlsOverlay
|
||||
import com.cobblemon.mod.common.client.gui.bag.CobblemonBagScreen
|
||||
import com.cobblemon.mod.common.client.gui.battle.BattleOverlay
|
||||
import com.cobblemon.mod.common.client.gui.cookingpot.CookingPotScreen
|
||||
import com.cobblemon.mod.common.client.gui.party.PartyTutorialToasts
|
||||
@@ -46,6 +47,7 @@ import com.cobblemon.mod.common.client.render.generic.GenericBedrockRenderer
|
||||
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
|
||||
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
|
||||
import com.cobblemon.mod.common.client.render.layer.PlayerRecallBallRenderer
|
||||
import com.cobblemon.mod.common.client.render.layer.CobblemonBagRenderer
|
||||
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
|
||||
@@ -516,17 +518,7 @@ object CobblemonClient {
|
||||
CobblemonBlocks.POTTED_WATMEL_BERRY,
|
||||
CobblemonBlocks.POTTED_WEPEAR_BERRY,
|
||||
CobblemonBlocks.POTTED_WIKI_BERRY,
|
||||
CobblemonBlocks.POTTED_YACHE_BERRY,
|
||||
CobblemonBlocks.SCOPE_LENS,
|
||||
|
||||
CobblemonBlocks.COPPER_FAN,
|
||||
CobblemonBlocks.EXPOSED_COPPER_FAN,
|
||||
CobblemonBlocks.WEATHERED_COPPER_FAN,
|
||||
CobblemonBlocks.OXIDIZED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_EXPOSED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_WEATHERED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_OXIDIZED_COPPER_FAN
|
||||
CobblemonBlocks.POTTED_YACHE_BERRY
|
||||
)
|
||||
|
||||
this.createBoatModelLayers()
|
||||
@@ -549,14 +541,17 @@ object CobblemonClient {
|
||||
skinMap?.get(PlayerSkin.Model.WIDE) as LivingEntityRenderer<Player, PlayerModel<Player>>
|
||||
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
|
||||
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
|
||||
renderer?.addLayer(CobblemonBagRenderer(renderer))
|
||||
renderer = skinMap[PlayerSkin.Model.SLIM] as LivingEntityRenderer<Player, PlayerModel<Player>>?
|
||||
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
|
||||
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
|
||||
renderer?.addLayer(CobblemonBagRenderer(renderer))
|
||||
}
|
||||
|
||||
private fun registerMenuScreens() {
|
||||
MenuScreens.register(CobblemonMenuType.COOKING_POT, ::CookingPotScreen)
|
||||
MenuScreens.register(CobblemonMenuType.TM_MACHINE, ::TMMachineScreen)
|
||||
MenuScreens.register(CobblemonMenuType.COBBLEMON_BAG, ::CobblemonBagScreen)
|
||||
}
|
||||
|
||||
private fun registerBlockEntityRenderers() {
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.bag
|
||||
|
||||
import com.cobblemon.mod.common.api.bag.BagCategories
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import com.cobblemon.mod.common.client.render.getDepletableRedGreen
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.sounds.SoundManager
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class BagCategoryButton(
|
||||
x: Int,
|
||||
y: Int,
|
||||
val parent: CobblemonBagScreen,
|
||||
val category: Int,
|
||||
val action: OnPress
|
||||
): Button(x, y, WIDTH, HEIGHT, Component.empty(), action, DEFAULT_NARRATION), CobblemonRenderable {
|
||||
companion object {
|
||||
private const val WIDTH = 32
|
||||
private const val HEIGHT = 31
|
||||
|
||||
private val CATEGORY_SLOT = cobblemonResource("textures/gui/bag/bag_tab.png")
|
||||
private val VOLUME_BAR = cobblemonResource("textures/gui/bag/bag_tab_volume_bar.png")
|
||||
}
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) {
|
||||
val orderedCategories = BagCategories.getOrderedCategoriesList()
|
||||
|
||||
blitk(
|
||||
matrixStack = context.pose(),
|
||||
texture = CATEGORY_SLOT,
|
||||
x = x, y = y,
|
||||
width = WIDTH, height = HEIGHT,
|
||||
textureHeight = 64,
|
||||
vOffset = if (parent.menu.currentlySelectedCategory == category) 32 else 0
|
||||
)
|
||||
|
||||
blitk(
|
||||
matrixStack = context.pose(),
|
||||
texture = if (category == -1) ResourceLocation("minecraft", "textures/item/bundle.png") else orderedCategories[category].icon,
|
||||
x = x + 8, y = y + 9,
|
||||
width = 16, height = 16
|
||||
)
|
||||
|
||||
//The Bar
|
||||
if (category != -1) {
|
||||
blitk(
|
||||
matrixStack = context.pose(),
|
||||
texture = VOLUME_BAR,
|
||||
x = x + 8, y = y + 25,
|
||||
width = 16, height = 3
|
||||
)
|
||||
|
||||
val itemRatio = (parent.menu.categoryItemCounts[category].toFloat() / orderedCategories[category].maxCount).coerceIn(0F, 1F)
|
||||
val barWidth = itemRatio * 14
|
||||
val (red, green) = getDepletableRedGreen(1 - itemRatio)
|
||||
|
||||
blitk(
|
||||
matrixStack = context.pose(),
|
||||
texture = CobblemonResources.WHITE,
|
||||
x = x + 9, y = y + 26,
|
||||
width = barWidth, height = 1,
|
||||
red = red * 0.8F, green = green * 0.8F, blue = 0.27F
|
||||
)
|
||||
}
|
||||
|
||||
if (isHovered) {
|
||||
context.renderTooltip(Minecraft.getInstance().font, if (category == -1) lang("bag_categories.all_items") else orderedCategories[category].getName(), mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
|
||||
override fun playDownSound(handler: SoundManager) {}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.bag
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.sounds.SoundManager
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
class BagCategoryPageButton(
|
||||
x: Int,
|
||||
y: Int,
|
||||
val parent: CobblemonBagScreen,
|
||||
val leftButton: Boolean,
|
||||
val action: OnPress
|
||||
): Button(x, y, WIDTH, HEIGHT, Component.empty(), action, DEFAULT_NARRATION), CobblemonRenderable {
|
||||
companion object {
|
||||
private const val WIDTH = 12
|
||||
private const val HEIGHT = 10
|
||||
|
||||
private val LEFT_BUTTON = cobblemonResource("textures/gui/bag/button_left.png")
|
||||
private val RIGHT_BUTTON = cobblemonResource("textures/gui/bag/button_right.png")
|
||||
}
|
||||
|
||||
var enabled = true
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) {
|
||||
blitk(
|
||||
matrixStack = context.pose(),
|
||||
texture = if (leftButton) LEFT_BUTTON else RIGHT_BUTTON,
|
||||
x = x / 0.5F, y = y / 0.5F,
|
||||
width = WIDTH * 2, height = HEIGHT * 2,
|
||||
textureHeight = 40,
|
||||
vOffset = if (enabled) 20 else 0,
|
||||
scale = 0.5f
|
||||
)
|
||||
}
|
||||
|
||||
override fun playDownSound(handler: SoundManager) {}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.bag
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendToServer
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.bag.BagCategories
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.drawScaledTextJustifiedRight
|
||||
import com.cobblemon.mod.common.client.render.getDepletableRedGreen
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagMenu
|
||||
import com.cobblemon.mod.common.item.battle.BagItem
|
||||
import com.cobblemon.mod.common.net.messages.client.bag.UpdateBagMenuDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.bag.UseItemOnPokemonFromBagPacket
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
|
||||
import juuxel.adorn.util.Colors
|
||||
import net.fabricmc.api.EnvType
|
||||
import net.fabricmc.api.Environment
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.inventory.ClickType
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
class CobblemonBagScreen(
|
||||
menu: CobblemonBagMenu,
|
||||
playerInventory: Inventory,
|
||||
title: Component
|
||||
): AbstractContainerScreen<CobblemonBagMenu>(
|
||||
menu,
|
||||
playerInventory,
|
||||
Component.translatable("cobblemon.container.bag")
|
||||
) {
|
||||
companion object {
|
||||
private const val BACKGROUND_HEIGHT = 197
|
||||
private const val BACKGROUND_WIDTH = 184
|
||||
|
||||
private val BACKGROUND = cobblemonResource("textures/gui/bag/bag_base.png")
|
||||
private val SCROLL_TRACK = cobblemonResource("textures/gui/bag/scrollbar_track.png")
|
||||
private val SCROLL_SLIDE = cobblemonResource("textures/gui/bag/scrollbar_slide.png")
|
||||
private val PARTY_SLOT_BASE = cobblemonResource("textures/gui/bag/party_slot_base.png")
|
||||
private val PARTY_SLOT_COLLAPSED = cobblemonResource("textures/gui/bag/party_slot_collapsed.png")
|
||||
private val PARTY_SLOT = cobblemonResource("textures/gui/bag/party_slot.png")
|
||||
private val PARTY_SLOT_FAINTED = cobblemonResource("textures/gui/bag/party_slot_fainted.png")
|
||||
private val GENDER_ICON_MALE = cobblemonResource("textures/gui/party/party_gender_male.png")
|
||||
private val GENDER_ICON_FEMALE = cobblemonResource("textures/gui/party/party_gender_female.png")
|
||||
}
|
||||
|
||||
val categoriesWidgets = mutableListOf<BagCategoryButton>()
|
||||
lateinit var allItemsCategoryWidget: BagCategoryButton
|
||||
lateinit var leftCategoryPageButton: BagCategoryPageButton
|
||||
lateinit var rightCategoryPageButton: BagCategoryPageButton
|
||||
var currentCategoryPage = 0
|
||||
var lastCategory = menu.currentlySelectedCategory
|
||||
var lastScroll = menu.scroll
|
||||
var scrolling = false
|
||||
|
||||
init {
|
||||
this.imageWidth = BACKGROUND_WIDTH + 69
|
||||
this.imageHeight = BACKGROUND_HEIGHT + 27
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
this.leftPos -= 34
|
||||
|
||||
for (i in 0..3) {
|
||||
if (i < BagCategories.getOrderedCategoriesList().size) {
|
||||
categoriesWidgets.add(
|
||||
BagCategoryButton(leftPos + 76 + i * 33, topPos, this, i) {
|
||||
if (menu.currentlySelectedCategory != i) {
|
||||
menu.changeCategory(i)
|
||||
playSound(CobblemonSounds.ITEM_BAG_CLICK)
|
||||
}
|
||||
}.also { addRenderableWidget(it) }
|
||||
)
|
||||
} else break
|
||||
}
|
||||
|
||||
allItemsCategoryWidget = BagCategoryButton(leftPos + 214, topPos, this, -1) {
|
||||
if (menu.currentlySelectedCategory != -1) {
|
||||
menu.changeCategory(-1)
|
||||
playSound(CobblemonSounds.ITEM_BAG_CLICK)
|
||||
}
|
||||
}.also { addRenderableWidget(it) }
|
||||
|
||||
leftCategoryPageButton = BagCategoryPageButton(leftPos + 218, topPos + 32, this, true) {
|
||||
if (leftCategoryPageButton.enabled) {
|
||||
cycleCategoryPage(false)
|
||||
playSound(CobblemonSounds.ITEM_BAG_CLICK)
|
||||
}
|
||||
}.also { addRenderableWidget(it) }
|
||||
rightCategoryPageButton = BagCategoryPageButton(leftPos + 229, topPos + 32, this, false) {
|
||||
if (rightCategoryPageButton.enabled) {
|
||||
cycleCategoryPage(true)
|
||||
playSound(CobblemonSounds.ITEM_BAG_CLICK)
|
||||
}
|
||||
}.also { addRenderableWidget(it) }
|
||||
|
||||
playSound(CobblemonSounds.ITEM_BAG_OPEN)
|
||||
}
|
||||
|
||||
override fun renderBg(context: GuiGraphics, partialTick: Float, mouseX: Int, mouseY: Int) {}
|
||||
override fun renderBackground(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) {}
|
||||
|
||||
override fun renderLabels(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int) {}
|
||||
|
||||
override fun render(context: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) {
|
||||
renderTransparentBackground(context)
|
||||
|
||||
val matrices = context.pose()
|
||||
|
||||
// Background
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = BACKGROUND,
|
||||
x = leftPos + 69, y = topPos + 27,
|
||||
width = BACKGROUND_WIDTH, height = BACKGROUND_HEIGHT
|
||||
)
|
||||
|
||||
//Scroll
|
||||
val scrollYOffset = if (menu.maxScroll == 0) {
|
||||
if (menu.scroll == 0) 0 else 53
|
||||
} else ((min(menu.scroll, menu.maxScroll).toFloat() / menu.maxScroll) * 53).toInt()
|
||||
val trackHeight = 71 - scrollYOffset - 13
|
||||
|
||||
if (trackHeight > 0) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = SCROLL_TRACK,
|
||||
x = leftPos + 230, y = topPos + 49 + (71 - trackHeight),
|
||||
width = 9, height = trackHeight,
|
||||
textureHeight = 71,
|
||||
vOffset = 71 - trackHeight
|
||||
)
|
||||
}
|
||||
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = SCROLL_SLIDE,
|
||||
x = leftPos + 230, y = topPos + 49 + scrollYOffset,
|
||||
width = 9, height = 17
|
||||
)
|
||||
|
||||
// Pokemon
|
||||
val party = CobblemonClient.storage.party
|
||||
for (i in 0..5) {
|
||||
val pokemon = party.get(i)
|
||||
val slotYPosition = topPos + i * 33 + 27
|
||||
|
||||
if (pokemon != null) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = PARTY_SLOT_BASE,
|
||||
x = leftPos, y = slotYPosition,
|
||||
width = 67, height = 31
|
||||
)
|
||||
|
||||
val slotWidth = 32
|
||||
val slotLeft = leftPos + 11
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = if (pokemon.isFainted()) PARTY_SLOT_FAINTED else PARTY_SLOT,
|
||||
x = slotLeft, y = slotYPosition,
|
||||
width = slotWidth, height = 26,
|
||||
textureHeight = 52,
|
||||
vOffset = if (!menu.carried.isEmpty && menu.carried.item is BagItem && partySlotHovered(i, mouseX, mouseY)) 26 else 0
|
||||
)
|
||||
|
||||
val expForThisLevel = pokemon.experience - pokemon.experienceGroup.getExperience(pokemon.level)
|
||||
val expToNextLevel = pokemon.experienceGroup.getExperience(pokemon.level + 1) - pokemon.experienceGroup.getExperience(pokemon.level)
|
||||
val expRatio = expForThisLevel.toFloat() / expToNextLevel
|
||||
|
||||
val expBarHeight = expRatio * 20
|
||||
|
||||
if (expBarHeight > 0) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = CobblemonResources.WHITE,
|
||||
x = leftPos + 6, y = slotYPosition + 24 - expBarHeight,
|
||||
width = 1, height = expBarHeight,
|
||||
red = 0.2, green = 0.65, blue = 0.84
|
||||
)
|
||||
}
|
||||
|
||||
val hpRatio = pokemon.currentHealth.toFloat() / pokemon.maxHealth
|
||||
val hpBarHeight = hpRatio * 20
|
||||
val (red, green) = getDepletableRedGreen(hpRatio)
|
||||
|
||||
if (hpBarHeight > 0) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = CobblemonResources.WHITE,
|
||||
x = leftPos + 8, y = slotYPosition + 24 - hpBarHeight,
|
||||
width = 2, height = hpBarHeight,
|
||||
red = red * 0.8F, green = green * 0.8F, blue = 0.27F
|
||||
)
|
||||
}
|
||||
|
||||
// Ball Icon
|
||||
val ballIcon = cobblemonResource("textures/gui/ball/" + pokemon.caughtBall.name.path + ".png")
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = ballIcon,
|
||||
x = (leftPos + 3.5F) / 0.5F, y = (slotYPosition + 23) / 0.5F,
|
||||
width = 18, height = 22,
|
||||
textureHeight = 44,
|
||||
scale = 0.5F
|
||||
)
|
||||
|
||||
//Gender
|
||||
if (pokemon.gender != Gender.GENDERLESS) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = if (pokemon.gender == Gender.MALE) GENDER_ICON_MALE else GENDER_ICON_FEMALE,
|
||||
x = (leftPos + 62) / 0.5F, y = (slotYPosition + 26) / 0.5F,
|
||||
width = 5, height = 7,
|
||||
scale = 0.5F
|
||||
)
|
||||
}
|
||||
|
||||
//Status
|
||||
val status = pokemon.status?.status
|
||||
if (!pokemon.isFainted() && status != null) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = cobblemonResource("textures/gui/bag/status_${status.showdownName}.png"),
|
||||
x = leftPos + 1, y = slotYPosition + 9,
|
||||
width = 4, height = 14
|
||||
)
|
||||
}
|
||||
|
||||
matrices.pushPose()
|
||||
matrices.translate(slotLeft + ((slotWidth - 8) / 2.0), slotYPosition.toDouble() - 6, 0.0)
|
||||
matrices.scale(3.5F, 3.5F, 1F)
|
||||
|
||||
val state = FloatingState()
|
||||
state.currentAspects = pokemon.aspects
|
||||
drawProfilePokemon(
|
||||
species = pokemon.species.resourceIdentifier,
|
||||
matrixStack = matrices,
|
||||
rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(13F, 35F, 0F)),
|
||||
state = state,
|
||||
scale = 4.5F,
|
||||
partialTicks = 0F
|
||||
)
|
||||
matrices.popPose()
|
||||
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 100.0)
|
||||
// Level and Name and Gender
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = pokemon.getDisplayName(),
|
||||
x = leftPos + 14, y = slotYPosition + 26,
|
||||
scale = 0.5F
|
||||
)
|
||||
|
||||
drawScaledTextJustifiedRight(
|
||||
context = context,
|
||||
text = lang("ui.lv"),
|
||||
x = leftPos + 40, y = slotYPosition + 14,
|
||||
shadow = true,
|
||||
scale = 0.5F
|
||||
)
|
||||
|
||||
drawScaledTextJustifiedRight(
|
||||
context = context,
|
||||
text = pokemon.level.toString().text(),
|
||||
x = leftPos + 40, y = slotYPosition + 19,
|
||||
shadow = true,
|
||||
scale = 0.5F
|
||||
)
|
||||
matrices.popPose()
|
||||
} else {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = PARTY_SLOT_COLLAPSED,
|
||||
x = leftPos + 64, y = slotYPosition,
|
||||
width = 5, height = 31
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//Titles
|
||||
context.drawString(font, title, leftPos + 80, topPos + 33, Colors.WHITE, false)
|
||||
context.drawString(font, playerInventoryTitle, leftPos + 80, topPos + 129, 4210752, false)
|
||||
|
||||
super.render(context, mouseX, mouseY, partialTick)
|
||||
renderTooltip(context, mouseX, mouseY)
|
||||
}
|
||||
|
||||
fun partySlotHovered(index: Int, mouseX: Int, mouseY: Int): Boolean {
|
||||
val left = leftPos + 11
|
||||
val top = topPos + index * 33 + 27
|
||||
return mouseX in left..(left + 32) && mouseY in top..(top + 26)
|
||||
}
|
||||
|
||||
fun cycleCategoryPage(next: Boolean) {
|
||||
val orderedCategories = BagCategories.getOrderedCategoriesList()
|
||||
currentCategoryPage = (currentCategoryPage + if (next) 1 else -1).coerceIn(0, (orderedCategories.size - 1) / 4)
|
||||
categoriesWidgets.forEach {
|
||||
removeWidget(it)
|
||||
}
|
||||
categoriesWidgets.clear()
|
||||
for (i in 0..3) {
|
||||
val adjustedIndex = i + 4 * currentCategoryPage
|
||||
if (adjustedIndex < orderedCategories.size) {
|
||||
categoriesWidgets.add(
|
||||
BagCategoryButton(leftPos + 76 + i * 33, topPos, this, adjustedIndex) {
|
||||
playSound(CobblemonSounds.ITEM_BAG_CLICK)
|
||||
menu.changeCategory(adjustedIndex)
|
||||
}.also { addRenderableWidget(it) }
|
||||
)
|
||||
} else break
|
||||
}
|
||||
leftCategoryPageButton.enabled = currentCategoryPage > 0
|
||||
rightCategoryPageButton.enabled = currentCategoryPage < (orderedCategories.size - 1) / 4
|
||||
}
|
||||
|
||||
fun updateScrollValue(mouseY: Double) {
|
||||
val adjustedMouseY = mouseY - topPos - 49.0
|
||||
if (adjustedMouseY < 0) {
|
||||
menu.scroll = 0
|
||||
} else if (adjustedMouseY > 71) {
|
||||
menu.scroll = menu.maxScroll
|
||||
} else {
|
||||
menu.scroll = ((adjustedMouseY / 71.0) * (menu.maxScroll)).roundToInt()
|
||||
}
|
||||
menu.setupSlotsBasedOnContent()
|
||||
}
|
||||
|
||||
override fun slotClicked(slot: Slot?, slotId: Int, mouseButton: Int, type: ClickType) {
|
||||
if (slotId in CobblemonBagMenu.BAG_SLOTS && (lastCategory != menu.currentlySelectedCategory || lastScroll != menu.scroll)) {
|
||||
lastCategory = menu.currentlySelectedCategory
|
||||
lastScroll = menu.scroll
|
||||
sendToServer(UpdateBagMenuDataPacket(menu.currentlySelectedCategory, menu.scroll)) // Synchronize this data
|
||||
}
|
||||
super.slotClicked(slot, slotId, mouseButton, type)
|
||||
}
|
||||
|
||||
override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean {
|
||||
if (scrollY < 0 && menu.scroll < menu.maxScroll) {
|
||||
menu.scroll += 1
|
||||
} else if (scrollY > 0 && menu.scroll > 0) {
|
||||
menu.scroll -= 1
|
||||
}
|
||||
menu.setupSlotsBasedOnContent()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
if (mouseX in (leftPos + 229.0)..(leftPos + 240.0) && mouseY in (topPos + 49.0)..(topPos + 120.0)) {
|
||||
scrolling = true
|
||||
updateScrollValue(mouseY)
|
||||
return true
|
||||
}
|
||||
val party = CobblemonClient.storage.party
|
||||
if (!menu.carried.isEmpty && menu.carried.item is BagItem) {
|
||||
for (i in 0..5) {
|
||||
if (party.get(i) != null && partySlotHovered(i, mouseX.toInt(), mouseY.toInt())) {
|
||||
playSound(CobblemonSounds.GUI_CLICK)
|
||||
sendToServer(UseItemOnPokemonFromBagPacket(i))
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.mouseClicked(mouseX, mouseY, button)
|
||||
}
|
||||
|
||||
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
scrolling = false
|
||||
return super.mouseReleased(mouseX, mouseY, button)
|
||||
}
|
||||
|
||||
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, dragX: Double, dragY: Double): Boolean {
|
||||
if (scrolling) {
|
||||
updateScrollValue(mouseY)
|
||||
return true
|
||||
}
|
||||
return super.mouseDragged(mouseX, mouseY, button, dragX, dragY)
|
||||
}
|
||||
|
||||
fun playSound(soundEvent: SoundEvent) {
|
||||
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(soundEvent, 1.0F))
|
||||
}
|
||||
|
||||
override fun onClose() {
|
||||
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(CobblemonSounds.ITEM_BAG_CLOSE, 1.0F))
|
||||
super.onClose()
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,9 @@ import org.joml.Vector3f
|
||||
|
||||
open class PartySlot(
|
||||
x: Int, y: Int,
|
||||
private val pokemon: TradeStartedPacket.TradeablePokemon?,
|
||||
val pokemon: TradeStartedPacket.TradeablePokemon?,
|
||||
private val parent: TradeGUI,
|
||||
private val isOpposing: Boolean = false,
|
||||
val isOpposing: Boolean = false,
|
||||
onPress: OnPress
|
||||
) : Button(x, y, SIZE, SIZE, Component.literal("PartySlot"), onPress, DEFAULT_NARRATION), CobblemonRenderable {
|
||||
val state = FloatingState()
|
||||
@@ -42,6 +42,8 @@ open class PartySlot(
|
||||
private val genderIconFemale = cobblemonResource("textures/gui/pc/gender_icon_female.png")
|
||||
private val selectPointerResource = cobblemonResource("textures/gui/pc/pc_pointer.png")
|
||||
private val untradeableResource = cobblemonResource("textures/gui/trade/trade_slot_icon_locked.png")
|
||||
private val tradePartySlotSelectedResource = cobblemonResource("textures/gui/trade/trade_party_slot_selected.png")
|
||||
private val tradePartySlotSelectedOpposingResource = cobblemonResource("textures/gui/trade/trade_party_slot_selected_opposing.png")
|
||||
}
|
||||
|
||||
override fun playDownSound(soundManager: SoundManager) {
|
||||
@@ -60,6 +62,17 @@ open class PartySlot(
|
||||
)
|
||||
}
|
||||
|
||||
if (hasSelected()) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = if (isOpposing) tradePartySlotSelectedOpposingResource else tradePartySlotSelectedResource,
|
||||
x = x - 2,
|
||||
y = y - 2,
|
||||
width = 29,
|
||||
height = 29
|
||||
)
|
||||
}
|
||||
|
||||
if (pokemon != null) {
|
||||
// context.enableScissor(x - 2, y + 2, x + SIZE + 4, y + SIZE + 4)
|
||||
// Render Pokémon
|
||||
@@ -118,7 +131,16 @@ open class PartySlot(
|
||||
}
|
||||
|
||||
matrices.popPose()
|
||||
if (hasSelected()) {
|
||||
|
||||
val isViewed = if (isOpposing) {
|
||||
parent.opposingOfferedPokemon?.uuid == pokemon.pokemonId
|
||||
} else {
|
||||
parent.offeredPokemon?.uuid == pokemon.pokemonId
|
||||
}
|
||||
|
||||
if (isViewed && pokemon.tradeable) {
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 200.0)
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = selectPointerResource,
|
||||
@@ -128,6 +150,7 @@ open class PartySlot(
|
||||
height = 8,
|
||||
scale = TradeGUI.SCALE
|
||||
)
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
// Held Item
|
||||
@@ -145,8 +168,9 @@ open class PartySlot(
|
||||
}
|
||||
|
||||
open fun hasSelected(): Boolean {
|
||||
val offeredPokemon = if (isOpposing) parent.trade.oppositeOffer.get() else parent.trade.myOffer.get()
|
||||
return pokemon?.pokemonId == offeredPokemon?.uuid && pokemon != null
|
||||
if (pokemon == null) return false
|
||||
val offeredPokemons = if (isOpposing) parent.trade.oppositeOffer.get() else parent.trade.myOffer.get()
|
||||
return offeredPokemons.any { it.uuid == pokemon.pokemonId }
|
||||
}
|
||||
|
||||
fun isHovered(mouseX: Int, mouseY: Int) = pokemon?.tradeable != false && mouseX.toFloat() in (x.toFloat()..(x.toFloat() + SIZE)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + SIZE))
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.cobblemon.mod.common.client.gui.summary.widgets.common.reformatNature
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.drawScaledTextJustifiedRight
|
||||
import com.cobblemon.mod.common.client.trade.ClientTrade
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket.TradeablePokemon
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.*
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
@@ -98,15 +99,23 @@ class TradeGUI(
|
||||
private val tradeAnimationArrowsResource = cobblemonResource("textures/gui/trade/trade_animation_arrows.png")
|
||||
}
|
||||
|
||||
private var offeredPokemonModel: ModelWidget? = null
|
||||
private var opposingOfferedPokemonModel: ModelWidget? = null
|
||||
private var offeredPokemonModels: MutableList<ModelWidget> = mutableListOf()
|
||||
private var opposingOfferedPokemonModels: MutableList<ModelWidget> = mutableListOf()
|
||||
|
||||
private lateinit var offeredPokemonMarkings: MarkingsWidget
|
||||
private lateinit var opposingOfferedPokemonMarkings: MarkingsWidget
|
||||
|
||||
var selectedPartyIndices = mutableListOf<Int>()
|
||||
var offeredPokemons: MutableList<Pokemon> = mutableListOf()
|
||||
var opposingPokemons: MutableList<Pokemon> = mutableListOf()
|
||||
|
||||
// For backwards compatibility where single is referenced in rendering text info
|
||||
var offeredPokemon: Pokemon? = null
|
||||
var opposingOfferedPokemon: Pokemon? = null
|
||||
|
||||
var myGridMode = true
|
||||
var opposingGridMode = true
|
||||
|
||||
var ticksElapsed = 0
|
||||
var protectiveTicks = 0
|
||||
var selectPointerOffsetY = 0
|
||||
@@ -125,30 +134,67 @@ class TradeGUI(
|
||||
}
|
||||
|
||||
trade.completedEmitter.subscribe {
|
||||
val (pokemonId1, pokemonId2) = it
|
||||
val myTradedPokemon = party.find { it?.pokemonId == pokemonId1 }
|
||||
val theirTradedPokemon = traderParty.find { it?.pokemonId == pokemonId2 }
|
||||
if (myTradedPokemon == null || theirTradedPokemon == null) {
|
||||
val (pokemonIds1, pokemonIds2) = it
|
||||
val myTradedPokemons = pokemonIds1.mapNotNull { id -> party.find { it?.pokemonId == id } }
|
||||
val theirTradedPokemons = pokemonIds2.mapNotNull { id -> traderParty.find { it?.pokemonId == id } }
|
||||
if (myTradedPokemons.isEmpty() || theirTradedPokemons.isEmpty()) {
|
||||
CobblemonNetwork.sendToServer(CancelTradePacket())
|
||||
return@subscribe onClose()
|
||||
}
|
||||
val tradedSlot = party.indexOf(myTradedPokemon)
|
||||
val opposingTradedSlot = traderParty.indexOf(theirTradedPokemon)
|
||||
party[tradedSlot] = theirTradedPokemon
|
||||
traderParty[opposingTradedSlot] = myTradedPokemon
|
||||
|
||||
myTradedPokemons.forEach { pk ->
|
||||
val idx = party.indexOf(pk)
|
||||
if (idx != -1) party[idx] = null
|
||||
}
|
||||
theirTradedPokemons.forEach { pk ->
|
||||
val idx = traderParty.indexOf(pk)
|
||||
if (idx != -1) traderParty[idx] = null
|
||||
}
|
||||
|
||||
val newSelectedIndices = mutableListOf<Int>()
|
||||
theirTradedPokemons.forEach { pk ->
|
||||
val emptyIdx = party.indexOf(null)
|
||||
if (emptyIdx != -1) {
|
||||
party[emptyIdx] = pk
|
||||
}
|
||||
}
|
||||
myTradedPokemons.forEach { pk ->
|
||||
val emptyIdx = traderParty.indexOf(null)
|
||||
if (emptyIdx != -1) traderParty[emptyIdx] = pk
|
||||
}
|
||||
|
||||
val compactUI = { list: MutableList<TradeStartedPacket.TradeablePokemon?> ->
|
||||
val nonNulls = list.filterNotNull()
|
||||
list.clear()
|
||||
list.addAll(nonNulls)
|
||||
while (list.size < 6) list.add(null)
|
||||
}
|
||||
compactUI(party)
|
||||
compactUI(traderParty)
|
||||
|
||||
theirTradedPokemons.forEach { pk ->
|
||||
val idx = party.indexOf(pk)
|
||||
if (idx != -1) newSelectedIndices.add(idx)
|
||||
}
|
||||
|
||||
trade.oppositeAcceptedMyOffer.set(false)
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(Pair(theirTradedPokemon.pokemonId, PartyPosition(tradedSlot))))
|
||||
selectedPartyIndices.clear()
|
||||
selectedPartyIndices.addAll(newSelectedIndices)
|
||||
|
||||
val newOffers = selectedPartyIndices.mapNotNull { idx ->
|
||||
party[idx]?.let { it.pokemonId to PartyPosition(idx) }
|
||||
}
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(newOffers))
|
||||
|
||||
rebuildWidgets()
|
||||
}
|
||||
|
||||
trade.oppositeOffer.subscribe { newOffer: Pokemon? ->
|
||||
setOfferedPokemon(pokemon = newOffer, isOpposing = true)
|
||||
trade.oppositeOffer.subscribe { newOffer: List<Pokemon> ->
|
||||
setOfferedPokemon(pokemonList = newOffer, isOpposing = true)
|
||||
}
|
||||
|
||||
trade.myOffer.subscribe { myOffer: Pokemon? ->
|
||||
setOfferedPokemon(pokemon = myOffer)
|
||||
trade.myOffer.subscribe { myOffer: List<Pokemon> ->
|
||||
setOfferedPokemon(pokemonList = myOffer)
|
||||
}
|
||||
|
||||
trade.oppositeAcceptedMyOffer.subscribe {
|
||||
@@ -216,9 +262,16 @@ class TradeGUI(
|
||||
pokemon = pokemon,
|
||||
parent = this,
|
||||
onPress = {
|
||||
if (!trade.acceptedOppositeOffer && !tradeProcessing) {
|
||||
val pk = if (offeredPokemon?.uuid == pokemon?.pokemonId) null else pokemon
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(pk?.let { it.pokemonId to PartyPosition(partyIndex) }))
|
||||
if (!trade.acceptedOppositeOffer && !tradeProcessing && pokemon != null) {
|
||||
if (selectedPartyIndices.contains(partyIndex)) {
|
||||
selectedPartyIndices.remove(partyIndex)
|
||||
} else if (selectedPartyIndices.size < 6) {
|
||||
selectedPartyIndices.add(partyIndex)
|
||||
}
|
||||
val newOffers = selectedPartyIndices.mapNotNull { idx ->
|
||||
party[idx]?.let { it.pokemonId to PartyPosition(idx) }
|
||||
}
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(newOffers))
|
||||
playSound(CobblemonSounds.GUI_CLICK)
|
||||
}
|
||||
}
|
||||
@@ -250,8 +303,8 @@ class TradeGUI(
|
||||
).also { widget -> addRenderableWidget(widget) }
|
||||
}
|
||||
|
||||
setOfferedPokemon(pokemon = offeredPokemon, isOpposing = false)
|
||||
setOfferedPokemon(pokemon = opposingOfferedPokemon, isOpposing = true)
|
||||
setOfferedPokemon(pokemonList = offeredPokemons.toList(), isOpposing = false)
|
||||
setOfferedPokemon(pokemonList = opposingPokemons.toList(), isOpposing = true)
|
||||
|
||||
offeredPokemonMarkings = MarkingsWidget(x + 74.5, y + 21, offeredPokemon, false)
|
||||
opposingOfferedPokemonMarkings = MarkingsWidget(x + 177.5, y + 21, opposingOfferedPokemon, false)
|
||||
@@ -284,7 +337,7 @@ class TradeGUI(
|
||||
if (tradeAnimationProgress > REVERSE_ANIMATION_TICK)
|
||||
(REVERSE_ANIMATION_TICK + TRADE_ANIMATION_FRAMES - tradeAnimationProgress)
|
||||
else (tradeAnimationProgress - MODEL_SCALE_BUFFER_FRAMES)
|
||||
) * TRADE_ANIMATION_HEIGHT
|
||||
) * TRADE_ANIMATION_HEIGHT
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = tradeAnimationResource,
|
||||
@@ -313,20 +366,56 @@ class TradeGUI(
|
||||
// Render Model Portraits
|
||||
var scale = PORTRAIT_SCALE
|
||||
var scaleOffsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
var isShrinking = false
|
||||
if (tradeProcessing) {
|
||||
val scaleInterval = if (tradeAnimationProgress > REVERSE_ANIMATION_TICK) (MAX_TRADE_PROGRESS - tradeAnimationProgress) else tradeAnimationProgress
|
||||
scale = (PORTRAIT_SCALE - (scaleInterval * PORTRAIT_SCALE_MULTIPLIER)).coerceIn(0F, PORTRAIT_SCALE)
|
||||
scaleOffsetY = (45.0 - (45.0 / PORTRAIT_SCALE) * scale) + PORTRAIT_MODEL_OFFSET_Y
|
||||
isShrinking = true
|
||||
}
|
||||
val shrinkPercentage = if (isShrinking) 1.0F - (scale / PORTRAIT_SCALE) else 0.0F
|
||||
val myCenterXDest = x + 70 + (PORTRAIT_SIZE / 2.0)
|
||||
val myCenterYDest = y + 30 + (PORTRAIT_SIZE / 2.0)
|
||||
val opCenterXDest = x + 145 + (PORTRAIT_SIZE / 2.0)
|
||||
val opCenterYDest = y + 30 + (PORTRAIT_SIZE / 2.0)
|
||||
|
||||
if (scale > 0F) {
|
||||
context.enableScissor(backgroundX, backgroundY, backgroundX + BASE_BACKGROUND_WIDTH, backgroundY + BASE_BACKGROUND_HEIGHT)
|
||||
offeredPokemonModel?.baseScale = scale
|
||||
offeredPokemonModel?.offsetY = scaleOffsetY
|
||||
offeredPokemonModel?.render(context, mouseX, mouseY, delta)
|
||||
|
||||
opposingOfferedPokemonModel?.baseScale = scale
|
||||
opposingOfferedPokemonModel?.offsetY = scaleOffsetY
|
||||
opposingOfferedPokemonModel?.render(context, mouseX, mouseY, delta)
|
||||
offeredPokemonModels.forEachIndexed { i, model ->
|
||||
val posAndScale = getModelPositionAndScale(i, offeredPokemons.size, x + 70, y + 30)
|
||||
val originalScale = posAndScale.second
|
||||
model.baseScale = if (isShrinking) (originalScale / PORTRAIT_SCALE) * scale else originalScale
|
||||
model.offsetY = if (isShrinking) scaleOffsetY else PORTRAIT_MODEL_OFFSET_Y
|
||||
|
||||
val startCenterX = posAndScale.first.first + (PORTRAIT_SIZE / 2.0)
|
||||
val startCenterY = posAndScale.first.second + (PORTRAIT_SIZE / 2.0)
|
||||
|
||||
context.pose().pushPose()
|
||||
context.pose().translate((myCenterXDest - startCenterX) * shrinkPercentage, (myCenterYDest - startCenterY) * shrinkPercentage, 0.0)
|
||||
|
||||
model.render(context, mouseX, mouseY, delta)
|
||||
|
||||
context.pose().popPose()
|
||||
}
|
||||
|
||||
opposingOfferedPokemonModels.forEachIndexed { i, model ->
|
||||
val posAndScale = getModelPositionAndScale(i, opposingPokemons.size, x + 145, y + 30)
|
||||
val originalScale = posAndScale.second
|
||||
model.baseScale = if (isShrinking) (originalScale / PORTRAIT_SCALE) * scale else originalScale
|
||||
model.offsetY = if (isShrinking) scaleOffsetY else PORTRAIT_MODEL_OFFSET_Y
|
||||
|
||||
val startCenterX = posAndScale.first.first + (PORTRAIT_SIZE / 2.0)
|
||||
val startCenterY = posAndScale.first.second + (PORTRAIT_SIZE / 2.0)
|
||||
|
||||
context.pose().pushPose()
|
||||
context.pose().translate((opCenterXDest - startCenterX) * shrinkPercentage, (opCenterYDest - startCenterY) * shrinkPercentage, 0.0)
|
||||
|
||||
model.render(context, mouseX, mouseY, delta)
|
||||
|
||||
context.pose().popPose()
|
||||
}
|
||||
|
||||
context.disableScissor()
|
||||
}
|
||||
|
||||
@@ -341,8 +430,46 @@ class TradeGUI(
|
||||
|
||||
renderInfoLabels(context, x, y)
|
||||
|
||||
renderPokemonInfo(offeredPokemon, false, context, x, y, mouseX, mouseY)
|
||||
renderPokemonInfo(opposingOfferedPokemon, true, context, x, y, mouseX, mouseY)
|
||||
children().filterIsInstance<PartySlot>().forEach { slot ->
|
||||
if (slot.isHovered(mouseX, mouseY)) {
|
||||
val hoveredId = slot.pokemon?.pokemonId
|
||||
if (slot.isOpposing && slot.hasSelected()) {
|
||||
opposingPokemons.find { it.uuid == hoveredId }?.let { opposingOfferedPokemon = it }
|
||||
} else if (!slot.isOpposing) {
|
||||
val matchingModel = offeredPokemons.find { it.uuid == hoveredId }
|
||||
if (matchingModel != null) {
|
||||
offeredPokemon = matchingModel
|
||||
} else {
|
||||
val realPokemon = com.cobblemon.mod.common.client.CobblemonClient.storage.party.find { it?.uuid == hoveredId }
|
||||
if (realPokemon != null) {
|
||||
offeredPokemon = realPokemon
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val currentOffered = offeredPokemon
|
||||
if (currentOffered != null) {
|
||||
renderPokemonInfo(currentOffered, false, context, x, y, mouseX, mouseY)
|
||||
if (::offeredPokemonMarkings.isInitialized) {
|
||||
offeredPokemonMarkings.visible = true
|
||||
if (offeredPokemonMarkings.pokemon != currentOffered) offeredPokemonMarkings.setActivePokemon(currentOffered)
|
||||
}
|
||||
} else {
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.visible = false
|
||||
}
|
||||
|
||||
val currentOpposing = opposingOfferedPokemon
|
||||
if (currentOpposing != null) {
|
||||
renderPokemonInfo(currentOpposing, true, context, x, y, mouseX, mouseY)
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) {
|
||||
opposingOfferedPokemonMarkings.visible = true
|
||||
if (opposingOfferedPokemonMarkings.pokemon != currentOpposing) opposingOfferedPokemonMarkings.setActivePokemon(currentOpposing)
|
||||
}
|
||||
} else {
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.visible = false
|
||||
}
|
||||
|
||||
if (trade.acceptedOppositeOffer) {
|
||||
blitk(
|
||||
@@ -431,19 +558,25 @@ class TradeGUI(
|
||||
|
||||
super.render(context, mouseX, mouseY, delta)
|
||||
|
||||
// Item Tooltip
|
||||
if (offeredPokemon != null && !offeredPokemon!!.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 50
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, offeredPokemon!!.heldItemNoCopy(), mouseX, mouseY)
|
||||
val ttOffered = offeredPokemon
|
||||
if (ttOffered != null) {
|
||||
// Item Tooltip
|
||||
if (!ttOffered.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 50
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, ttOffered.heldItemNoCopy(), mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
|
||||
if (opposingOfferedPokemon != null && !opposingOfferedPokemon!!.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 227
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, opposingOfferedPokemon!!.heldItemNoCopy(), mouseX, mouseY)
|
||||
val ttOpposing = opposingOfferedPokemon
|
||||
if (ttOpposing != null) {
|
||||
if (!ttOpposing.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 227
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, ttOpposing.heldItemNoCopy(), mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,11 +613,13 @@ class TradeGUI(
|
||||
}
|
||||
|
||||
if (tradeAnimationProgress == (MAX_TRADE_PROGRESS + CRY_BUFFER)) {
|
||||
if (offeredPokemonModel !== null && opposingOfferedPokemonModel !== null) {
|
||||
offeredPokemonModel!!.state.activeAnimations.clear()
|
||||
offeredPokemonModel!!.state.addFirstAnimation(setOf("cry"))
|
||||
opposingOfferedPokemonModel!!.state.activeAnimations.clear()
|
||||
opposingOfferedPokemonModel!!.state.addFirstAnimation(setOf("cry"))
|
||||
offeredPokemonModels.forEach {
|
||||
it.state.activeAnimations.clear()
|
||||
it.state.addFirstAnimation(setOf("cry"))
|
||||
}
|
||||
opposingOfferedPokemonModels.forEach {
|
||||
it.state.activeAnimations.clear()
|
||||
it.state.addFirstAnimation(setOf("cry"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,41 +650,140 @@ class TradeGUI(
|
||||
|
||||
override fun renderMenuBackground(context: GuiGraphics) {}
|
||||
|
||||
private fun setOfferedPokemon(pokemon: Pokemon?, isOpposing: Boolean = false) {
|
||||
private fun setOfferedPokemon(pokemonList: List<Pokemon>, isOpposing: Boolean = false) {
|
||||
protectiveTicks = 20
|
||||
if (isOpposing) {
|
||||
val wasEmpty = opposingPokemons.isEmpty()
|
||||
val currentViewedUuid = if (opposingGridMode) null else opposingOfferedPokemon?.uuid
|
||||
opposingPokemons.clear()
|
||||
opposingPokemons.addAll(pokemonList)
|
||||
|
||||
val matchingPokemon = opposingPokemons.find { it.uuid == currentViewedUuid }
|
||||
|
||||
if (matchingPokemon != null) {
|
||||
opposingOfferedPokemon = matchingPokemon
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.setActivePokemon(opposingOfferedPokemon)
|
||||
} else {
|
||||
opposingOfferedPokemon = opposingPokemons.lastOrNull()
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.setActivePokemon(opposingOfferedPokemon)
|
||||
if (wasEmpty && opposingOfferedPokemon != null) {
|
||||
opposingGridMode = false
|
||||
} else if (!opposingGridMode) {
|
||||
opposingGridMode = true
|
||||
}
|
||||
}
|
||||
trade.acceptedOppositeOffer = false
|
||||
} else {
|
||||
val wasEmpty = offeredPokemons.isEmpty()
|
||||
val currentViewedUuid = if (myGridMode) null else offeredPokemon?.uuid
|
||||
offeredPokemons.clear()
|
||||
offeredPokemons.addAll(pokemonList)
|
||||
|
||||
val matchingPokemon = offeredPokemons.find { it.uuid == currentViewedUuid }
|
||||
|
||||
if (matchingPokemon != null) {
|
||||
offeredPokemon = matchingPokemon
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.setActivePokemon(offeredPokemon)
|
||||
} else {
|
||||
offeredPokemon = offeredPokemons.lastOrNull()
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.setActivePokemon(offeredPokemon)
|
||||
if (wasEmpty && offeredPokemon != null) {
|
||||
myGridMode = false
|
||||
} else if (!myGridMode) {
|
||||
myGridMode = true
|
||||
}
|
||||
}
|
||||
}
|
||||
rebuildSelectedModels(isOpposing)
|
||||
}
|
||||
|
||||
private fun rebuildSelectedModels(isOpposing: Boolean) {
|
||||
val x = (width - BASE_WIDTH) / 2
|
||||
val y = (height - BASE_HEIGHT) / 2
|
||||
|
||||
if (isOpposing) {
|
||||
opposingOfferedPokemon = pokemon
|
||||
opposingOfferedPokemonModel = if (pokemon != null) ModelWidget(
|
||||
pX = x + 145,
|
||||
pY = y + 30,
|
||||
pWidth = PORTRAIT_SIZE,
|
||||
pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pokemon.asRenderablePokemon(),
|
||||
baseScale = PORTRAIT_SCALE,
|
||||
rotationY = 35F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
) else null
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.setActivePokemon(opposingOfferedPokemon)
|
||||
trade.acceptedOppositeOffer = false
|
||||
opposingOfferedPokemonModels.clear()
|
||||
val total = opposingPokemons.size
|
||||
opposingPokemons.forEachIndexed { i, pk ->
|
||||
val (pos, currentScale) = getModelPositionAndScale(i, total, x + 145, y + 30)
|
||||
opposingOfferedPokemonModels.add(ModelWidget(
|
||||
pX = pos.first, pY = pos.second,
|
||||
pWidth = PORTRAIT_SIZE, pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pk.asRenderablePokemon(),
|
||||
baseScale = currentScale,
|
||||
rotationY = 35F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
))
|
||||
}
|
||||
} else {
|
||||
offeredPokemon = pokemon
|
||||
offeredPokemonModel = if (pokemon != null) ModelWidget(
|
||||
pX = x + 70,
|
||||
pY = y + 30,
|
||||
pWidth = PORTRAIT_SIZE,
|
||||
pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pokemon.asRenderablePokemon(),
|
||||
baseScale = PORTRAIT_SCALE,
|
||||
rotationY = 325F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
) else null
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.setActivePokemon(offeredPokemon)
|
||||
offeredPokemonModels.clear()
|
||||
val total = offeredPokemons.size
|
||||
offeredPokemons.forEachIndexed { i, pk ->
|
||||
val (pos, currentScale) = getModelPositionAndScale(i, total, x + 70, y + 30)
|
||||
offeredPokemonModels.add(ModelWidget(
|
||||
pX = pos.first, pY = pos.second,
|
||||
pWidth = PORTRAIT_SIZE, pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pk.asRenderablePokemon(),
|
||||
baseScale = currentScale,
|
||||
rotationY = 325F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getModelPositionAndScale(index: Int, total: Int, baseX: Int, baseY: Int): Pair<Pair<Int, Int>, Float> {
|
||||
val scale = when (total) {
|
||||
1 -> PORTRAIT_SCALE
|
||||
2 -> PORTRAIT_SCALE * 0.75f
|
||||
3 -> PORTRAIT_SCALE * 0.65f
|
||||
4 -> PORTRAIT_SCALE * 0.55f
|
||||
else -> PORTRAIT_SCALE * 0.5f
|
||||
}
|
||||
|
||||
if (total <= 1) {
|
||||
return Pair(Pair(baseX, baseY), scale)
|
||||
}
|
||||
|
||||
val rowLength1 = when (total) {
|
||||
2, 3, 4 -> 2
|
||||
else -> 3
|
||||
}
|
||||
val rowLength2 = total - rowLength1
|
||||
|
||||
val isBottomRow = index >= rowLength1
|
||||
val row = if (isBottomRow) 1 else 0
|
||||
val col = if (isBottomRow) index - rowLength1 else index
|
||||
val currentRowLength = if (isBottomRow) rowLength2 else rowLength1
|
||||
|
||||
val colSpacing = when (total) {
|
||||
2 -> 35
|
||||
3 -> 30
|
||||
4 -> 25
|
||||
else -> 23
|
||||
}
|
||||
val rowSpacing = when (total) {
|
||||
2, 3 -> 30
|
||||
4 -> 28
|
||||
else -> 25
|
||||
}
|
||||
|
||||
val totalWidth = (currentRowLength - 1) * colSpacing
|
||||
val startX = baseX - (totalWidth / 2)
|
||||
|
||||
val totalHeight = if (rowLength2 > 0) rowSpacing else 0
|
||||
var startY = baseY + 12 - (totalHeight / 2)
|
||||
|
||||
if (total >= 4) {
|
||||
startY += 8
|
||||
}
|
||||
|
||||
val posX = startX + (col * colSpacing)
|
||||
val posY = startY + (row * rowSpacing)
|
||||
|
||||
return Pair(Pair(posX, posY), scale)
|
||||
}
|
||||
|
||||
private fun playSound(soundEvent: SoundEvent): SoundInstance {
|
||||
val soundInstance = SimpleSoundInstance.forUI(soundEvent, 1.0F)
|
||||
Minecraft.getInstance().soundManager.play(soundInstance)
|
||||
@@ -557,10 +791,10 @@ class TradeGUI(
|
||||
}
|
||||
|
||||
private fun cancelTradeSound() {
|
||||
if (tradeSoundInstance !== null) Minecraft.getInstance().soundManager.stop(tradeSoundInstance)
|
||||
if (tradeSoundInstance != null) Minecraft.getInstance().soundManager.stop(tradeSoundInstance!!)
|
||||
}
|
||||
|
||||
private fun renderPokemonInfo(pokemon: Pokemon?, isOpposing: Boolean, context: GuiGraphics, x: Int, y: Int, mouseX: Int, mouseY: Int) {
|
||||
public fun renderPokemonInfo(pokemon: Pokemon?, isOpposing: Boolean, context: GuiGraphics, x: Int, y: Int, mouseX: Int, mouseY: Int) {
|
||||
if (pokemon != null) {
|
||||
val matrices = context.pose()
|
||||
// Level
|
||||
@@ -1047,4 +1281,4 @@ class TradeGUI(
|
||||
scale = SCALE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.net.bag
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagMenu
|
||||
import com.cobblemon.mod.common.net.messages.client.bag.UpdateBagMenuDataPacket
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
object UpdateBagMenuDataHandler : ServerNetworkPacketHandler<UpdateBagMenuDataPacket> {
|
||||
override fun handle(packet: UpdateBagMenuDataPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
if (player.containerMenu !is CobblemonBagMenu) {
|
||||
Cobblemon.LOGGER.debug("Player {} interacted with invalid menu {}", player, player.containerMenu)
|
||||
return
|
||||
}
|
||||
|
||||
val menu = player.containerMenu as? CobblemonBagMenu ?: return
|
||||
menu.currentlySelectedCategory = packet.categoryId
|
||||
menu.scroll = packet.scroll
|
||||
menu.setupSlotsBasedOnContent()
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.net.bag
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagMenu
|
||||
import com.cobblemon.mod.common.net.messages.client.bag.UseItemOnPokemonFromBagPacket
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
object UseItemOnPokemonFromBagHandler: ServerNetworkPacketHandler<UseItemOnPokemonFromBagPacket> {
|
||||
override fun handle(packet: UseItemOnPokemonFromBagPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
if (player.containerMenu !is CobblemonBagMenu) {
|
||||
Cobblemon.LOGGER.debug("Player {} interacted with invalid menu {}", player, player.containerMenu)
|
||||
return
|
||||
}
|
||||
|
||||
val menu = player.containerMenu as? CobblemonBagMenu ?: return
|
||||
menu.useHeldItemOnPokemon(packet.partySlot)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -15,9 +15,9 @@ import net.minecraft.client.Minecraft
|
||||
|
||||
object TradeAcceptanceChangedHandler : ClientNetworkPacketHandler<TradeAcceptanceChangedPacket> {
|
||||
override fun handle(packet: TradeAcceptanceChangedPacket, client: Minecraft) {
|
||||
if (CobblemonClient.trade?.myOffer?.get()?.uuid == packet.pokemonId) {
|
||||
if (CobblemonClient.trade?.myOffer?.get()?.any { it.uuid == packet.pokemonId } == true) {
|
||||
CobblemonClient.trade!!.oppositeAcceptedMyOffer.set(packet.accepted)
|
||||
} else if (CobblemonClient.trade?.oppositeOffer?.get()?.uuid == packet.pokemonId) {
|
||||
} else if (CobblemonClient.trade?.oppositeOffer?.get()?.any { it.uuid == packet.pokemonId } == true) {
|
||||
CobblemonClient.trade!!.acceptedOppositeOffer = packet.accepted
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,6 +16,6 @@ import net.minecraft.client.Minecraft
|
||||
object TradeCompletedHandler : ClientNetworkPacketHandler<TradeCompletedPacket> {
|
||||
override fun handle(packet: TradeCompletedPacket, client: Minecraft) {
|
||||
val trade = CobblemonClient.trade ?: return
|
||||
trade.completedEmitter.emit(packet.pokemonId1 to packet.pokemonId2)
|
||||
trade.completedEmitter.emit(packet.pokemonIds1 to packet.pokemonIds2)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@ import net.minecraft.client.Minecraft
|
||||
|
||||
object TradeStartedHandler : ClientNetworkPacketHandler<TradeStartedPacket> {
|
||||
override fun handle(packet: TradeStartedPacket, client: Minecraft) {
|
||||
Cobblemon.LOGGER.error("handle trade start from: " + packet.traderId)
|
||||
Cobblemon.LOGGER.info("Trade started with {}", packet.traderId)
|
||||
val trade = ClientTrade()
|
||||
CobblemonClient.trade = trade
|
||||
Minecraft.getInstance().setScreen(
|
||||
|
||||
+2
-2
@@ -18,9 +18,9 @@ object TradeUpdatedHandler : ClientNetworkPacketHandler<TradeUpdatedPacket> {
|
||||
val trade = CobblemonClient.trade ?: return
|
||||
|
||||
if (packet.playerId == Minecraft.getInstance().player?.uuid) {
|
||||
trade.myOffer.set(packet.pokemon)
|
||||
trade.myOffer.set(packet.pokemons)
|
||||
} else {
|
||||
trade.oppositeOffer.set(packet.pokemon)
|
||||
trade.oppositeOffer.set(packet.pokemons)
|
||||
}
|
||||
trade.oppositeAcceptedMyOffer.set(false)
|
||||
trade.acceptedOppositeOffer = false
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.layer
|
||||
|
||||
import com.cobblemon.mod.common.client.CobblemonBakingOverrides
|
||||
import com.cobblemon.mod.common.item.bag.CobblemonBagItem
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.model.PlayerModel
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.entity.RenderLayerParent
|
||||
import net.minecraft.client.renderer.entity.layers.RenderLayer
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
|
||||
class CobblemonBagRenderer<T : Player>(renderLayerParent: RenderLayerParent<T, PlayerModel<T>>): RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
|
||||
override fun render(
|
||||
poseStack: PoseStack,
|
||||
bufferSource: MultiBufferSource,
|
||||
packedLight: Int,
|
||||
player: T,
|
||||
limbSwing: Float,
|
||||
limbSwingAmount: Float,
|
||||
partialTick: Float,
|
||||
ageInTicks: Float,
|
||||
netHeadYaw: Float,
|
||||
headPitch: Float
|
||||
) {
|
||||
val bagItem = player.getItemBySlot(EquipmentSlot.CHEST)
|
||||
if (bagItem.item !is CobblemonBagItem) return
|
||||
val model = CobblemonBakingOverrides.bagModels[bagItem.item]?.getModel() ?: return
|
||||
|
||||
player.level().profiler.push("cobblemon_bag_render")
|
||||
poseStack.pushPose()
|
||||
|
||||
parentModel.body.translateAndRotate(poseStack)
|
||||
|
||||
poseStack.rotateAround(Axis.ZP.rotationDegrees(180F), 0F, 1F, 0F)
|
||||
poseStack.translate(0.0, 1.0, 0.0)
|
||||
|
||||
Minecraft.getInstance().itemRenderer.render(
|
||||
bagItem,
|
||||
ItemDisplayContext.FIXED,
|
||||
false,
|
||||
poseStack,
|
||||
bufferSource,
|
||||
packedLight,
|
||||
OverlayTexture.NO_OVERLAY,
|
||||
model
|
||||
)
|
||||
|
||||
poseStack.popPose()
|
||||
player.level().profiler.pop()
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,12 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import java.util.UUID
|
||||
|
||||
class ClientTrade {
|
||||
var myOffer = SettableObservable<Pokemon?>(null)
|
||||
var oppositeOffer = SettableObservable<Pokemon?>(null)
|
||||
var myOffer = SettableObservable<List<Pokemon>>(emptyList())
|
||||
var oppositeOffer = SettableObservable<List<Pokemon>>(emptyList())
|
||||
var tradeProcessing = SettableObservable(Pair(false, false))
|
||||
var oppositeAcceptedMyOffer = SettableObservable(false)
|
||||
var acceptedOppositeOffer = false
|
||||
|
||||
var completedEmitter = SimpleObservable<Pair<UUID, UUID>>()
|
||||
var completedEmitter = SimpleObservable<Pair<List<UUID>, List<UUID>>>()
|
||||
var cancelEmitter = SimpleObservable<Unit>()
|
||||
}
|
||||
@@ -47,10 +47,6 @@ class CobblemonConfig {
|
||||
@IntConstraint(min = 0, max = 1000)
|
||||
var maxPokemonFriendship = 255
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "power_item_ride_stat_gain_interval_seconds", SERVER)
|
||||
@IntConstraint(min = -1, max = Int.MAX_VALUE)
|
||||
var powerItemRideStatGainIntervalSeconds = 120
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "announce_drop_items", SERVER)
|
||||
var announceDropItems = true
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "default_drop_item_method", SERVER)
|
||||
|
||||
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.data
|
||||
import com.cobblemon.mod.common.*
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.abilities.Abilities
|
||||
import com.cobblemon.mod.common.api.bag.BagCategories
|
||||
import com.cobblemon.mod.common.api.berry.Berries
|
||||
import com.cobblemon.mod.common.api.cooking.Seasonings
|
||||
import com.cobblemon.mod.common.api.data.DataProvider
|
||||
@@ -120,6 +121,7 @@ object CobblemonDataProvider : DataProvider {
|
||||
this.register(SpawnBaitEffects, reloadable = false)
|
||||
this.register(CobblemonRideSettings, reloadable = true)
|
||||
this.register(TechnicalMachines, reloadable = false)
|
||||
this.register(BagCategories, reloadable = false)
|
||||
SpawnBait.Effects.setupEffects()
|
||||
|
||||
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe {
|
||||
|
||||
-1
@@ -160,5 +160,4 @@ class CobblemonChestBoatEntity(entityType: EntityType<CobblemonChestBoatEntity>,
|
||||
private const val INVENTORY_SLOTS = 27
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-27
@@ -22,7 +22,6 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.TickingSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawnCause.Companion.DROPS_REROLL_ASPECT
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
@@ -47,15 +46,10 @@ import kotlin.math.*
|
||||
|
||||
/** Handles purely server logic for a Pokémon */
|
||||
class PokemonServerDelegate : PokemonSideDelegate {
|
||||
companion object {
|
||||
private const val RIDE_STAT_GAIN_AMOUNT = 1F
|
||||
}
|
||||
|
||||
lateinit var entity: PokemonEntity
|
||||
var acknowledgedHPValue = -1
|
||||
var acknowledgedLevel = -1
|
||||
val passengerOffsets = mutableMapOf<Int, Vec3>()
|
||||
private var rideStatGainAnchor: Vec3? = null
|
||||
|
||||
/** Mocked properties exposed to the client [PokemonEntity]. */
|
||||
private val mock: PokemonProperties?
|
||||
@@ -361,30 +355,9 @@ class PokemonServerDelegate : PokemonSideDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
val rideStatGainIntervalSeconds = Cobblemon.config.powerItemRideStatGainIntervalSeconds
|
||||
if (rideStatGainIntervalSeconds > 0) {
|
||||
val rideStatGainIntervalTicks = rideStatGainIntervalSeconds * 20L
|
||||
if (entity.level().gameTime % rideStatGainIntervalTicks == 0L) {
|
||||
trainRideStats()
|
||||
}
|
||||
}
|
||||
|
||||
updateTrackedValues()
|
||||
}
|
||||
|
||||
private fun trainRideStats() {
|
||||
val position = entity.position()
|
||||
val anchor = rideStatGainAnchor
|
||||
rideStatGainAnchor = position
|
||||
if (anchor == null || anchor == position || entity.passengers.isEmpty()) return
|
||||
|
||||
val heldItem = entity.pokemon.heldItemNoCopy()
|
||||
if (heldItem.isEmpty) return
|
||||
|
||||
val stat = RidingStat.entries.firstOrNull { heldItem.`is`(it.powerItem) } ?: return
|
||||
entity.pokemon.addRideBoost(stat, RIDE_STAT_GAIN_AMOUNT)
|
||||
}
|
||||
|
||||
fun updateShownItem() {
|
||||
val trackedShownItem = when {
|
||||
// Show Hand Item if Held item is hidden
|
||||
|
||||
@@ -31,6 +31,7 @@ import net.minecraft.world.item.BlockItem
|
||||
import com.cobblemon.mod.common.platform.events.ServerPlayerEvent
|
||||
import com.cobblemon.mod.common.api.storage.player.PlayerInstancedDataStoreTypes
|
||||
import com.cobblemon.mod.common.item.GemItem
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
||||
import com.cobblemon.mod.common.util.effectiveName
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
@@ -164,26 +165,21 @@ object AdvancementHandler : EventHandler {
|
||||
}
|
||||
|
||||
fun onTradeCompleted(event : TradeEvent.Post) {
|
||||
val player1 = event.tradeParticipant1Pokemon.getOwnerPlayer()
|
||||
val player2 = event.tradeParticipant2Pokemon.getOwnerPlayer()
|
||||
if (player1 != null) {
|
||||
CobblemonCriteria.TRADE_POKEMON.trigger(player1, TradePokemonContext(event.tradeParticipant1Pokemon, event.tradeParticipant2Pokemon))
|
||||
val playerData = Cobblemon.playerDataManager.getGenericData(player1)
|
||||
val advancementData = playerData.advancementData
|
||||
advancementData.updateTotalTradedCount()
|
||||
advancementData.updateAspectsCollected(player1, event.tradeParticipant2Pokemon)
|
||||
CobblemonCriteria.COLLECT_ASPECT.trigger(player1, advancementData.aspectsCollected)
|
||||
Cobblemon.playerDataManager.saveSingle(playerData, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
}
|
||||
if (player2 != null) {
|
||||
CobblemonCriteria.TRADE_POKEMON.trigger(player2, TradePokemonContext(event.tradeParticipant2Pokemon, event.tradeParticipant1Pokemon))
|
||||
val playerData = Cobblemon.playerDataManager.getGenericData(player2)
|
||||
val advancementData = playerData.advancementData
|
||||
advancementData.updateTotalTradedCount()
|
||||
advancementData.updateAspectsCollected(player2, event.tradeParticipant1Pokemon)
|
||||
CobblemonCriteria.COLLECT_ASPECT.trigger(player2, advancementData.aspectsCollected)
|
||||
Cobblemon.playerDataManager.saveSingle(playerData, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
onTradeCompleted(event.tradeParticipant1Pokemon, event.tradeParticipant2Pokemon)
|
||||
onTradeCompleted(event.tradeParticipant2Pokemon, event.tradeParticipant1Pokemon)
|
||||
}
|
||||
|
||||
private fun onTradeCompleted(received: List<Pokemon>, traded: List<Pokemon>) {
|
||||
val player = received.firstOrNull()?.getOwnerPlayer() ?: return
|
||||
received.forEach { receivedPokemon ->
|
||||
traded.forEach { tradedPokemon -> CobblemonCriteria.TRADE_POKEMON.trigger(player, TradePokemonContext(tradedPokemon, receivedPokemon)) }
|
||||
}
|
||||
val playerData = Cobblemon.playerDataManager.getGenericData(player)
|
||||
val advancementData = playerData.advancementData
|
||||
advancementData.updateTotalTradedCount()
|
||||
received.forEach { advancementData.updateAspectsCollected(player, it) }
|
||||
CobblemonCriteria.COLLECT_ASPECT.trigger(player, advancementData.aspectsCollected)
|
||||
Cobblemon.playerDataManager.saveSingle(playerData, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,8 +110,8 @@ object StatHandler : EventHandler {
|
||||
}
|
||||
|
||||
fun onTradeCompleted(event : TradeEvent.Post) {
|
||||
event.tradeParticipant1Pokemon.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
event.tradeParticipant2Pokemon.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
event.tradeParticipant1Pokemon.firstOrNull()?.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
event.tradeParticipant2Pokemon.firstOrNull()?.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
}
|
||||
|
||||
fun onFossilRevived(event : FossilRevivedEvent) {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.item.bag
|
||||
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.ContainerHelper
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.min
|
||||
|
||||
class CobblemonBagContainer: Container {
|
||||
val items: MutableList<ItemStack> = mutableListOf()
|
||||
|
||||
override fun getContainerSize(): Int {
|
||||
return items.size
|
||||
}
|
||||
|
||||
override fun getItem(slot: Int): ItemStack {
|
||||
if (slot >= items.size) return ItemStack.EMPTY
|
||||
return items[slot]
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return items.isEmpty()
|
||||
}
|
||||
|
||||
override fun removeItem(slot: Int, amount: Int): ItemStack {
|
||||
if (slot >= items.size) return ItemStack.EMPTY
|
||||
val itemStack = items[slot].split(amount)
|
||||
if (items[slot].isEmpty) {
|
||||
items.removeAt(slot)
|
||||
}
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun removeItemNoUpdate(slot: Int): ItemStack { return ItemStack.EMPTY }
|
||||
|
||||
override fun clearContent() {
|
||||
items.clear()
|
||||
setChanged()
|
||||
}
|
||||
|
||||
override fun setChanged() {
|
||||
}
|
||||
|
||||
override fun setItem(slot: Int, stack: ItemStack) {} // Obsolete
|
||||
|
||||
override fun stillValid(player: Player): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getMaxStackSize(): Int {
|
||||
return 99999
|
||||
}
|
||||
|
||||
fun fromTag(tag: ListTag, levelRegistry: HolderLookup.Provider) {
|
||||
items.clear()
|
||||
|
||||
tag.forEach {
|
||||
val compoundTag = it as CompoundTag
|
||||
val count = compoundTag.getInt("count")
|
||||
compoundTag.putInt("count", 1)
|
||||
val item = ItemStack.parse(levelRegistry, it)
|
||||
item.ifPresent { theItem ->
|
||||
theItem.count = count
|
||||
items.add(theItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createTag(levelRegistry: HolderLookup.Provider): ListTag {
|
||||
val tag = ListTag()
|
||||
|
||||
items.forEach {
|
||||
val fakeItem = it.copyWithCount(1)
|
||||
val compoundTag = fakeItem.save(levelRegistry) as CompoundTag
|
||||
compoundTag.putInt("count", it.count) // ItemStack does not save count above 99 for some reason, so we save it ourselves
|
||||
tag.add(compoundTag)
|
||||
}
|
||||
|
||||
return tag
|
||||
}
|
||||
|
||||
fun dropAll(player: Player) {
|
||||
items.forEach {
|
||||
player.drop(it, true, false)
|
||||
}
|
||||
items.clear()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.item.bag
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.item.CobblemonItem
|
||||
import com.cobblemon.mod.common.bag.BagEntity
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.InteractionResultHolder
|
||||
import net.minecraft.world.MenuProvider
|
||||
import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.Equipable
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
|
||||
class CobblemonBagItem: CobblemonItem(Properties().stacksTo(1)), MenuProvider, Equipable {
|
||||
override fun use(level: Level, player: Player, usedHand: InteractionHand): InteractionResultHolder<ItemStack?> {
|
||||
val itemStack = player.getItemInHand(usedHand)
|
||||
player.openMenu(this)
|
||||
return InteractionResultHolder.success(itemStack)
|
||||
}
|
||||
|
||||
override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu {
|
||||
val bagEntity = (player as? BagEntity)
|
||||
val container = bagEntity?.`cobblemon$getBagContainer`() ?: CobblemonBagContainer()
|
||||
|
||||
return CobblemonBagMenu(i, inventory, container)
|
||||
}
|
||||
|
||||
override fun getDisplayName(): Component? {
|
||||
return Component.translatable("cobblemon.container.bag")
|
||||
}
|
||||
|
||||
override fun getEquipmentSlot(): EquipmentSlot = EquipmentSlot.CHEST
|
||||
|
||||
override fun getEquipSound(): Holder<SoundEvent?>? {
|
||||
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(CobblemonSounds.ITEM_BAG_EQUIP, 1.0F))
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.item.bag
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonMenuType
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.advancement.CobblemonCriteria
|
||||
import com.cobblemon.mod.common.advancement.criterion.PokemonInteractContext
|
||||
import com.cobblemon.mod.common.api.bag.BagCategories
|
||||
import com.cobblemon.mod.common.api.item.PokemonSelectingItem
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.util.isInBattle
|
||||
import net.minecraft.CrashReport
|
||||
import net.minecraft.ReportedException
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.inventory.ClickAction
|
||||
import net.minecraft.world.inventory.ClickType
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class CobblemonBagMenu: AbstractContainerMenu {
|
||||
companion object {
|
||||
val BAG_SLOTS = 0..31
|
||||
private val PARTY_SLOTS = 32..37
|
||||
private val INVENTORY_SLOTS = 38..64
|
||||
private val HOTBAR_SLOTS = 65..73
|
||||
}
|
||||
|
||||
private val playerInventory: Inventory
|
||||
private val bagContainer: CobblemonBagContainer
|
||||
private val partyContainer: SimpleContainer
|
||||
|
||||
private var serverParty: PartyStore? = null
|
||||
var currentlySelectedCategory = -1
|
||||
var scroll = 0
|
||||
var maxScroll = 0
|
||||
var categoryItemCounts = mutableListOf<Int>()
|
||||
|
||||
constructor(containerId: Int, playerInventory: Inventory): super(CobblemonMenuType.COBBLEMON_BAG, containerId) {
|
||||
this.playerInventory = playerInventory
|
||||
this.bagContainer = CobblemonBagContainer()
|
||||
this.partyContainer = SimpleContainer(6)
|
||||
for (i in 0..<BagCategories.getOrderedCategoriesList().size) { //Pre-init so Screen does not crash
|
||||
categoryItemCounts.add(0)
|
||||
}
|
||||
initializeSlots(playerInventory)
|
||||
}
|
||||
|
||||
constructor(containerId: Int, playerInventory: Inventory, bagContainer: CobblemonBagContainer): super(CobblemonMenuType.COBBLEMON_BAG, containerId) {
|
||||
this.playerInventory = playerInventory
|
||||
this.bagContainer = bagContainer
|
||||
this.partyContainer = SimpleContainer(6)
|
||||
this.serverParty = Cobblemon.storage.getParty(playerInventory.player as ServerPlayer)
|
||||
initializeSlots(playerInventory)
|
||||
setupSlotsBasedOnContent()
|
||||
calculateCategoriesItemCounts()
|
||||
}
|
||||
|
||||
private fun initializeSlots(playerInventory: Inventory) {
|
||||
for ((index, _) in BAG_SLOTS.withIndex()) {
|
||||
val i = index / 8
|
||||
val j = index % 8
|
||||
addSlot(CobblemonBagSlot(bagContainer, -1, 81 + j * 18, 50 + i * 18))
|
||||
}
|
||||
|
||||
for ((index, _) in PARTY_SLOTS.withIndex()) {
|
||||
val xPos = 46
|
||||
val yPos = 32 + 33 * index
|
||||
if (serverParty != null) {
|
||||
addSlot(CobblemonBagPartySlot(partyContainer, index,
|
||||
{ serverParty?.get(index) != null },
|
||||
{ serverParty?.get(index)?.heldItem() ?: ItemStack.EMPTY },
|
||||
xPos, yPos))
|
||||
} else {
|
||||
addSlot(CobblemonBagPartySlot(partyContainer, index,
|
||||
{ CobblemonClient.storage.party.get(index) != null },
|
||||
{ CobblemonClient.storage.party.get(index)?.heldItem() ?: ItemStack.EMPTY },
|
||||
xPos, yPos))
|
||||
}
|
||||
}
|
||||
|
||||
for ((index, _) in INVENTORY_SLOTS.withIndex()) {
|
||||
val i = index / 9
|
||||
val j = index % 9
|
||||
addSlot(Slot(playerInventory, 9 + index, 81 + j * 18, 142 + i * 18))
|
||||
}
|
||||
|
||||
for ((index, _) in HOTBAR_SLOTS.withIndex()) {
|
||||
addSlot(Slot(playerInventory, index, 81 + index * 18, 200))
|
||||
}
|
||||
}
|
||||
|
||||
fun setupSlotsBasedOnContent() {
|
||||
BAG_SLOTS.forEach {
|
||||
(getSlot(it) as CobblemonBagSlot).let {
|
||||
it.simulatedSlot = -1
|
||||
it.slotOverflowValue = 0
|
||||
}
|
||||
}
|
||||
|
||||
var slotId = BAG_SLOTS.first - 8 * scroll
|
||||
bagContainer.items.forEachIndexed { index, itemStack ->
|
||||
if (currentlySelectedCategory == -1 || BagCategories.getOrderedCategoriesList()[currentlySelectedCategory].itemIsValid(itemStack)) {
|
||||
val stackCount = ceil(itemStack.count.toFloat() / itemStack.maxStackSize).toInt()
|
||||
for (i in 0..<stackCount) {
|
||||
if (slotId in BAG_SLOTS) {
|
||||
val slot = getSlot(slotId) as CobblemonBagSlot
|
||||
slot.simulatedSlot = index
|
||||
slot.slotOverflowValue = i
|
||||
}
|
||||
slotId += 1
|
||||
if (slotId > BAG_SLOTS.last) return@forEachIndexed
|
||||
}
|
||||
}
|
||||
}
|
||||
updateMaxScroll()
|
||||
}
|
||||
|
||||
fun calculateCategoriesItemCounts() {
|
||||
val orderedCategories = BagCategories.getOrderedCategoriesList()
|
||||
categoryItemCounts.clear()
|
||||
for (i in 0..<orderedCategories.size) {
|
||||
categoryItemCounts.add(0)
|
||||
}
|
||||
|
||||
bagContainer.items.forEach { itemStack ->
|
||||
for (i in 0..<orderedCategories.size) {
|
||||
val category = orderedCategories[i]
|
||||
if (category.itemIsValid(itemStack)) {
|
||||
categoryItemCounts[i] += itemStack.count
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun changeCategory(categoryId: Int) {
|
||||
currentlySelectedCategory = categoryId
|
||||
scroll = 0
|
||||
setupSlotsBasedOnContent()
|
||||
}
|
||||
|
||||
fun updateMaxScroll() {
|
||||
var itemCount = 0
|
||||
bagContainer.items.forEach { itemStack ->
|
||||
if (currentlySelectedCategory == -1 || BagCategories.getOrderedCategoriesList()[currentlySelectedCategory].itemIsValid(itemStack)) {
|
||||
itemCount += ceil(itemStack.count.toFloat() / itemStack.maxStackSize).toInt()
|
||||
}
|
||||
}
|
||||
val rowsWithItems = (itemCount - 1) / 8 + 1
|
||||
maxScroll = max(rowsWithItems - 3, 0)
|
||||
}
|
||||
|
||||
override fun stillValid(player: Player): Boolean {
|
||||
return true //Add some extra logic like checking for maybe bag item existance
|
||||
}
|
||||
|
||||
override fun sendAllDataToRemote() { //We want to send more info than just the slots
|
||||
val items = NonNullList.create<ItemStack>()
|
||||
for (i in PARTY_SLOTS.first..HOTBAR_SLOTS.last) {
|
||||
this.remoteSlots[i] = this.slots[i].item.copy()
|
||||
items.add(this.remoteSlots[i].copy())
|
||||
}
|
||||
|
||||
this.remoteCarried = this.carried.copy()
|
||||
|
||||
bagContainer.items.forEach {
|
||||
items.add(it.copy())
|
||||
}
|
||||
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer!!.sendInitialData(this, items, this.remoteCarried, this.remoteDataSlots.toIntArray())
|
||||
}
|
||||
}
|
||||
|
||||
override fun initializeContents(stateId: Int, items: List<ItemStack>, carried: ItemStack) {
|
||||
bagContainer.items.clear()
|
||||
items.forEachIndexed { index, stack ->
|
||||
val adjustedIndex = index + PARTY_SLOTS.first
|
||||
if (adjustedIndex in PARTY_SLOTS.first..HOTBAR_SLOTS.last) {
|
||||
this.slots[adjustedIndex].set(stack)
|
||||
} else {
|
||||
bagContainer.items.add(stack)
|
||||
}
|
||||
}
|
||||
|
||||
this.carried = carried
|
||||
this.stateId = stateId
|
||||
setupSlotsBasedOnContent()
|
||||
calculateCategoriesItemCounts()
|
||||
}
|
||||
|
||||
override fun clicked(slotId: Int, button: Int, clickType: ClickType, player: Player) {
|
||||
if (slotId in BAG_SLOTS) {
|
||||
try {
|
||||
doBagClick(slotId, button, clickType, player)
|
||||
} catch (exception: Exception) {
|
||||
val crashReport = CrashReport.forThrowable(exception, "Container click")
|
||||
val crashReportCategory = crashReport.addCategory("Click info")
|
||||
crashReportCategory.setDetail("Menu Type") {
|
||||
if (this.menuType != null) BuiltInRegistries.MENU.getKey(this.menuType!!)
|
||||
.toString() else "<no type>"
|
||||
}
|
||||
crashReportCategory.setDetail("Menu Class") { this.javaClass.getCanonicalName() }
|
||||
crashReportCategory.setDetail("Slot Count", this.slots.size)
|
||||
crashReportCategory.setDetail("Slot", slotId)
|
||||
crashReportCategory.setDetail("Button", button)
|
||||
crashReportCategory.setDetail("Type", clickType)
|
||||
throw ReportedException(crashReport)
|
||||
}
|
||||
return
|
||||
} else if (slotId in PARTY_SLOTS) {
|
||||
onPartySlotClick(slotId, button, clickType, player)
|
||||
}
|
||||
super.clicked(slotId, button, clickType, player)
|
||||
}
|
||||
|
||||
// We handle the bag slots completely differently than normal slots, but a lot of default logic is cut
|
||||
private fun doBagClick(slotId: Int, button: Int, clickType: ClickType, player: Player) {
|
||||
val slot = (getSlot(slotId) as? CobblemonBagSlot) ?: return
|
||||
val slotItem = slot.item
|
||||
|
||||
if (clickType == ClickType.PICKUP && (button == 0 || button == 1)) {
|
||||
val primaryButton = if (button == 0) ClickAction.PRIMARY else ClickAction.SECONDARY
|
||||
val carriedStack = carried
|
||||
|
||||
if (carriedStack.isEmpty) {
|
||||
if (!slotItem.isEmpty) {
|
||||
val pickupCount = if (primaryButton == ClickAction.PRIMARY) slotItem.count else (slotItem.count + 1) / 2
|
||||
|
||||
val removedItemStack = slot.remove(pickupCount)
|
||||
if (!removedItemStack.isEmpty) {
|
||||
carried = removedItemStack
|
||||
slot.onTake(player, removedItemStack)
|
||||
getAndReduceCategoryCount(removedItemStack)
|
||||
}
|
||||
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_OUT)
|
||||
setupSlotsBasedOnContent()
|
||||
}
|
||||
} else {
|
||||
val (categoryId, allowedTransfer) = calculateInsertCount(carriedStack)
|
||||
if (allowedTransfer <= 0) return
|
||||
|
||||
val transferCount = if (primaryButton == ClickAction.PRIMARY) min(carriedStack.count, allowedTransfer) else 1
|
||||
|
||||
bagContainer.items.forEachIndexed { index, slotStack ->
|
||||
if (ItemStack.isSameItemSameComponents(carriedStack, slotStack) && !tryItemClickBehaviourOverride(player, primaryButton, CobblemonBagSlot(bagContainer, index, 0, 0), slotStack, carriedStack)
|
||||
) { // Provide a slot with index equal to the item, as there is not really any 'real' slots
|
||||
slotStack.grow(transferCount)
|
||||
carriedStack.shrink(transferCount)
|
||||
categoryItemCounts[categoryId] += transferCount
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_IN)
|
||||
setupSlotsBasedOnContent()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val transferItem = carriedStack.split(transferCount)
|
||||
bagContainer.items.add(transferItem)
|
||||
categoryItemCounts[categoryId] += transferCount
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_IN)
|
||||
setupSlotsBasedOnContent()
|
||||
}
|
||||
} else if (clickType == ClickType.QUICK_MOVE && (button == 0 || button == 1)) {
|
||||
quickMoveStackFromBag(player, slot)
|
||||
} else if (clickType == ClickType.CLONE && player.hasInfiniteMaterials() && carried.isEmpty && !slotItem.isEmpty) {
|
||||
carried = slotItem.copyWithCount(slotItem.maxStackSize)
|
||||
} else if (clickType == ClickType.THROW && carried.isEmpty && !slotItem.isEmpty) {
|
||||
val throwCount = if (button == 0) 1 else min(slotItem.count, slotItem.maxStackSize)
|
||||
val bagSize = bagContainer.items.size
|
||||
val removedItemStack = slot.remove(throwCount)
|
||||
player.drop(removedItemStack, true)
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_OUT)
|
||||
getAndReduceCategoryCount(removedItemStack)
|
||||
|
||||
if (bagSize != bagContainer.items.size) {
|
||||
setupSlotsBasedOnContent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Handle party slot clicked
|
||||
private fun onPartySlotClick(slotId: Int, button: Int, clickType: ClickType, player: Player) {
|
||||
val slotItem = getSlot(slotId).item
|
||||
if (clickType == ClickType.CLONE && player.hasInfiniteMaterials() && carried.isEmpty && !slotItem.isEmpty) {
|
||||
carried = slotItem.copyWithCount(slotItem.maxStackSize)
|
||||
} else if (clickType != ClickType.PICKUP) return
|
||||
|
||||
if (serverParty == null) return // Client does nothing
|
||||
|
||||
if (!carried.isEmpty && (isBlacklisted(carried) || !isWhitelisted(carried))) return //Blacklisted and Whitelisted checks
|
||||
|
||||
val index = slotId - PARTY_SLOTS.first
|
||||
val pokemon = serverParty?.get(index) ?: return
|
||||
|
||||
val heldItem = pokemon.heldItem()
|
||||
|
||||
if (carried.isEmpty || carried.count <= 1) { // Can Swap/Pickup
|
||||
val returned = pokemon.swapHeldItem(carried, aiCanDrop = false)
|
||||
carried = returned
|
||||
broadcastChanges()
|
||||
} else if (heldItem.isEmpty) { // Can Placedown
|
||||
pokemon.swapHeldItem(carried, aiCanDrop = false)
|
||||
broadcastChanges()
|
||||
}
|
||||
}
|
||||
|
||||
//Handled only by server
|
||||
fun useHeldItemOnPokemon(partySlot: Int) {
|
||||
if (carried.isEmpty) return
|
||||
|
||||
val pokemon = serverParty?.get(partySlot) ?: return
|
||||
val item = carried.item as? PokemonSelectingItem ?: return
|
||||
val player = playerInventory.player as? ServerPlayer ?: return
|
||||
|
||||
if (player.isInBattle()) return
|
||||
|
||||
val interaction = item.applyToPokemon(player, carried, pokemon)
|
||||
if (interaction?.result == InteractionResult.SUCCESS) {
|
||||
CobblemonCriteria.POKEMON_INTERACT.trigger(player, PokemonInteractContext(pokemon.species.resourceIdentifier, BuiltInRegistries.ITEM.getKey(carried.item)))
|
||||
broadcastChanges()
|
||||
}
|
||||
}
|
||||
|
||||
private fun isBlacklisted(stack: ItemStack): Boolean =
|
||||
BuiltInRegistries.ITEM.getTagOrEmpty(CobblemonItemTags.BLACKLISTED_ITEMS_TO_HOLD).any()
|
||||
&& stack.`is`(CobblemonItemTags.BLACKLISTED_ITEMS_TO_HOLD)
|
||||
|
||||
private fun isWhitelisted(stack: ItemStack): Boolean =
|
||||
BuiltInRegistries.ITEM.getTagOrEmpty(CobblemonItemTags.WHITELISTED_ITEMS_TO_HOLD).none()
|
||||
|| stack.`is`(CobblemonItemTags.WHITELISTED_ITEMS_TO_HOLD)
|
||||
|
||||
override fun quickMoveStack(player: Player, index: Int): ItemStack { // This will only be called by base inventory
|
||||
if (index < 0 || index >= slots.size) return ItemStack.EMPTY
|
||||
val slot = slots[index]
|
||||
val itemStack = slot.item
|
||||
|
||||
val (categoryId, allowedTransfer) = calculateInsertCount(itemStack)
|
||||
if (allowedTransfer <= 0) return ItemStack.EMPTY
|
||||
|
||||
val transferCount = min(itemStack.count, allowedTransfer)
|
||||
|
||||
if (slot.hasItem()) {
|
||||
bagContainer.items.forEach { slotStack ->
|
||||
if (ItemStack.isSameItemSameComponents(slotStack, itemStack)) {
|
||||
slotStack.grow(transferCount)
|
||||
itemStack.shrink(transferCount)
|
||||
categoryItemCounts[categoryId] += transferCount
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_IN)
|
||||
setupSlotsBasedOnContent()
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
bagContainer.items.add(itemStack.split(transferCount))
|
||||
categoryItemCounts[categoryId] += transferCount
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_IN)
|
||||
setupSlotsBasedOnContent()
|
||||
}
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
|
||||
fun quickMoveStackFromBag(player: Player, slot: CobblemonBagSlot) { //Called by bag items
|
||||
val transferStack = slot.item
|
||||
val startingCount = transferStack.count
|
||||
|
||||
if (moveItemStackTo(transferStack, INVENTORY_SLOTS.first, HOTBAR_SLOTS.last + 1, false)) {
|
||||
val itemsMoved = startingCount - transferStack.count
|
||||
getAndReduceCategoryCount(slot.remove(itemsMoved))
|
||||
playSound(CobblemonSounds.ITEM_BAG_ITEM_OUT)
|
||||
setupSlotsBasedOnContent()
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateInsertCount(stack: ItemStack): Pair<Int, Int> {
|
||||
if (stack.isEmpty) return -1 to 0
|
||||
|
||||
BagCategories.getOrderedCategoriesList().forEachIndexed { index, category ->
|
||||
if (category.itemIsValid(stack)) {
|
||||
val maxAllowed = max(category.maxCount - categoryItemCounts[index], 0)
|
||||
return index to min(stack.count, maxAllowed)
|
||||
}
|
||||
}
|
||||
return -1 to 0
|
||||
}
|
||||
|
||||
fun getAndReduceCategoryCount(stack: ItemStack) {
|
||||
if (stack.isEmpty) return
|
||||
|
||||
BagCategories.getOrderedCategoriesList().forEachIndexed { index, category ->
|
||||
if (category.itemIsValid(stack)) {
|
||||
categoryItemCounts[index] -= stack.count
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun canTakeItemForPickAll(stack: ItemStack, slot: Slot): Boolean {
|
||||
return slot.index !in BAG_SLOTS
|
||||
}
|
||||
|
||||
fun playSound(soundEvent: SoundEvent) {
|
||||
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(soundEvent, 1.0F))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.item.bag
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
class CobblemonBagPartySlot(
|
||||
container: SimpleContainer,
|
||||
index: Int,
|
||||
val activeGetter: () -> Boolean,
|
||||
val itemGetter: () -> ItemStack,
|
||||
x: Int,
|
||||
y: Int
|
||||
): Slot(container, index, x, y) {
|
||||
override fun getMaxStackSize(): Int = 1
|
||||
|
||||
override fun mayPlace(stack: ItemStack): Boolean = false
|
||||
override fun mayPickup(player: Player): Boolean = false
|
||||
|
||||
override fun getItem(): ItemStack {
|
||||
return itemGetter.invoke()
|
||||
}
|
||||
|
||||
override fun isActive(): Boolean {
|
||||
return activeGetter.invoke()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.item.bag
|
||||
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import java.util.Optional
|
||||
import kotlin.math.min
|
||||
|
||||
class CobblemonBagSlot(
|
||||
container: CobblemonBagContainer,
|
||||
var simulatedSlot: Int, //Cant override base slot variable so it is forever -1
|
||||
x: Int,
|
||||
y: Int
|
||||
): Slot(container, 0, x, y) {
|
||||
var slotOverflowValue = 0
|
||||
|
||||
override fun set(stack: ItemStack) {}
|
||||
|
||||
override fun getItem(): ItemStack {
|
||||
if (simulatedSlot == -1) return ItemStack.EMPTY
|
||||
val itemStack = container.getItem(simulatedSlot)
|
||||
val count = min(itemStack.count - itemStack.maxStackSize * slotOverflowValue, itemStack.maxStackSize)
|
||||
return itemStack.copyWithCount(count)
|
||||
}
|
||||
|
||||
override fun remove(amount: Int): ItemStack {
|
||||
if (simulatedSlot == -1) return ItemStack.EMPTY
|
||||
return container.removeItem(simulatedSlot, amount)
|
||||
}
|
||||
|
||||
override fun mayPlace(stack: ItemStack): Boolean = false
|
||||
override fun mayPickup(player: Player): Boolean = false
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.cobblemon.mod.common.item.crafting.washer
|
||||
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
import net.minecraft.world.item.crafting.RecipeInput
|
||||
|
||||
class WasherInput(
|
||||
val item: ItemStack = ItemStack.EMPTY
|
||||
) : RecipeInput {
|
||||
|
||||
override fun getItem(index: Int): ItemStack? {
|
||||
return if (index == 0) item else null
|
||||
}
|
||||
|
||||
override fun size() = 1
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.cobblemon.mod.common.item.crafting.washer
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeSerializers
|
||||
import com.cobblemon.mod.common.CobblemonRecipeTypes
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.component.DataComponents
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
import net.minecraft.world.item.crafting.Recipe
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||
import net.minecraft.world.level.Level
|
||||
|
||||
class WasherRecipe(
|
||||
val input: Ingredient,
|
||||
val result: ItemStack,
|
||||
val preserveInputComponents: Boolean = false,
|
||||
val removeDyedColor: Boolean = false
|
||||
) : Recipe<WasherInput> {
|
||||
|
||||
override fun getType() = CobblemonRecipeTypes.WASHER
|
||||
override fun canCraftInDimensions(width: Int, height: Int) = true
|
||||
override fun assemble(input: WasherInput, registries: HolderLookup.Provider): ItemStack {
|
||||
val output = if (preserveInputComponents) {
|
||||
input.item.transmuteCopy(result.item, result.count)
|
||||
} else {
|
||||
result.copy()
|
||||
}
|
||||
if (removeDyedColor) {
|
||||
output.remove(DataComponents.DYED_COLOR)
|
||||
}
|
||||
return output
|
||||
}
|
||||
override fun getSerializer() = CobblemonRecipeSerializers.WASHER
|
||||
override fun getResultItem(registries: HolderLookup.Provider): ItemStack = result.copy()
|
||||
override fun matches(input: WasherInput, level: Level) =
|
||||
this.input.test(input.item) && (!removeDyedColor || input.item.has(DataComponents.DYED_COLOR))
|
||||
|
||||
class Serializer : RecipeSerializer<WasherRecipe> {
|
||||
companion object {
|
||||
val CODEC: MapCodec<WasherRecipe> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
Ingredient.CODEC.fieldOf("input").forGetter { recipe -> recipe.input },
|
||||
ItemStack.STRICT_CODEC.fieldOf("result").forGetter { recipe -> recipe.result },
|
||||
Codec.BOOL.optionalFieldOf("preserve_input_components", false)
|
||||
.forGetter { recipe -> recipe.preserveInputComponents },
|
||||
Codec.BOOL.optionalFieldOf("remove_dyed_color", false)
|
||||
.forGetter { recipe -> recipe.removeDyedColor }
|
||||
).apply(instance, ::WasherRecipe)
|
||||
}
|
||||
}
|
||||
|
||||
val STREAM_CODEC: StreamCodec<RegistryFriendlyByteBuf, WasherRecipe> =
|
||||
StreamCodec.of(::toNetwork, ::fromNetwork)
|
||||
|
||||
private fun fromNetwork(buffer: RegistryFriendlyByteBuf): WasherRecipe {
|
||||
val input = Ingredient.CONTENTS_STREAM_CODEC.decode(buffer)
|
||||
val result = ItemStack.STREAM_CODEC.decode(buffer)
|
||||
val preserveInputComponents = buffer.readBoolean()
|
||||
val removeDyedColor = buffer.readBoolean()
|
||||
return WasherRecipe(input, result, preserveInputComponents, removeDyedColor)
|
||||
}
|
||||
|
||||
private fun toNetwork(buffer: RegistryFriendlyByteBuf, recipe: WasherRecipe) {
|
||||
Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, recipe.input)
|
||||
ItemStack.STREAM_CODEC.encode(buffer, recipe.result)
|
||||
buffer.writeBoolean(recipe.preserveInputComponents)
|
||||
buffer.writeBoolean(recipe.removeDyedColor)
|
||||
}
|
||||
|
||||
override fun codec() = CODEC
|
||||
override fun streamCodec() = STREAM_CODEC
|
||||
}
|
||||
|
||||
}
|
||||
@@ -570,47 +570,6 @@ object CobblemonItemGroups {
|
||||
entries.accept(CobblemonItems.PINK_PLAQUE)
|
||||
|
||||
CobblemonItems.campfire_pots.forEach(entries::accept)
|
||||
|
||||
entries.accept(CobblemonItems.COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.COPPER_FAN)
|
||||
entries.accept(CobblemonItems.COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_FRIDGE)
|
||||
}
|
||||
|
||||
private fun consumableEntries(displayContext: ItemDisplayParameters, entries: Output) {
|
||||
@@ -986,6 +945,8 @@ object CobblemonItemGroups {
|
||||
CobblemonItems.pokeBalls.forEach(entries::accept)
|
||||
CobblemonItems.pokeRods.forEach(entries::accept)
|
||||
CobblemonItems.pokedexes.forEach(entries::accept)
|
||||
entries.accept(CobblemonItems.TRAINER_PACK)
|
||||
entries.accept(CobblemonItems.TRAINER_BAG)
|
||||
}
|
||||
|
||||
private fun blocksInjections(injector: Injector) {
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.client.bag
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class UpdateBagMenuDataPacket(val categoryId: Int, val scroll: Int): NetworkPacket<UpdateBagMenuDataPacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("update_bag_menu_data")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): UpdateBagMenuDataPacket {
|
||||
return UpdateBagMenuDataPacket(buffer.readInt(), buffer.readInt())
|
||||
}
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeInt(categoryId)
|
||||
buffer.writeInt(scroll)
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.client.bag
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class UseItemOnPokemonFromBagPacket(val partySlot: Int): NetworkPacket<UseItemOnPokemonFromBagPacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("use_item_on_pokemon_from_bag")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): UseItemOnPokemonFromBagPacket {
|
||||
return UseItemOnPokemonFromBagPacket(buffer.readInt())
|
||||
}
|
||||
}
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeInt(partySlot)
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.bag.BagCategories
|
||||
import com.cobblemon.mod.common.api.bag.BagCategory
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class BagCategoriesSyncPacket(categories: List<BagCategory>): DataRegistrySyncPacket<BagCategory, BagCategoriesSyncPacket>(categories) {
|
||||
companion object {
|
||||
val ID = cobblemonResource("bag_categories")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = BagCategoriesSyncPacket(emptyList()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encodeEntry(buffer: RegistryFriendlyByteBuf, entry: BagCategory) {
|
||||
entry.encode(buffer)
|
||||
}
|
||||
|
||||
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): BagCategory = BagCategory.decode(buffer)
|
||||
|
||||
override fun synchronizeDecoded(entries: Collection<BagCategory>) {
|
||||
BagCategories.reload(entries.associateBy { it.identifier })
|
||||
}
|
||||
}
|
||||
+7
-4
@@ -23,16 +23,19 @@ import java.util.UUID
|
||||
* @author Hiroku
|
||||
* @since March 5th, 2023
|
||||
*/
|
||||
class TradeCompletedPacket(val pokemonId1: UUID, val pokemonId2: UUID) : NetworkPacket<TradeCompletedPacket> {
|
||||
class TradeCompletedPacket(val pokemonIds1: List<UUID>, val pokemonIds2: List<UUID>) : NetworkPacket<TradeCompletedPacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("trade_completed")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeCompletedPacket(buffer.readUUID(), buffer.readUUID())
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeCompletedPacket(
|
||||
buffer.readList { it.readUUID() },
|
||||
buffer.readList { it.readUUID() }
|
||||
)
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeUUID(pokemonId1)
|
||||
buffer.writeUUID(pokemonId2)
|
||||
buffer.writeCollection(pokemonIds1) { buf, id -> buf.writeUUID(id) }
|
||||
buffer.writeCollection(pokemonIds2) { buf, id -> buf.writeUUID(id) }
|
||||
}
|
||||
}
|
||||
+6
-7
@@ -12,10 +12,6 @@ import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.net.UnsplittablePacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readNullable
|
||||
import com.cobblemon.mod.common.util.readUUID
|
||||
import com.cobblemon.mod.common.util.writeNullable
|
||||
import com.cobblemon.mod.common.util.writeUUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import java.util.UUID
|
||||
|
||||
@@ -27,15 +23,18 @@ import java.util.UUID
|
||||
* @author Hiroku
|
||||
* @since March 5th, 2023
|
||||
*/
|
||||
class TradeUpdatedPacket(val playerId: UUID, val pokemon: Pokemon?) : NetworkPacket<TradeUpdatedPacket>, UnsplittablePacket {
|
||||
class TradeUpdatedPacket(val playerId: UUID, val pokemons: List<Pokemon>) : NetworkPacket<TradeUpdatedPacket>, UnsplittablePacket {
|
||||
companion object {
|
||||
val ID = cobblemonResource("trade_updated")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeUpdatedPacket(buffer.readUUID(), buffer.readNullable { Pokemon.S2C_CODEC.decode(buffer) })
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeUpdatedPacket(
|
||||
buffer.readUUID(),
|
||||
buffer.readList { Pokemon.S2C_CODEC.decode(it as RegistryFriendlyByteBuf) }
|
||||
)
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeUUID(playerId)
|
||||
buffer.writeNullable(pokemon) { _, pokemon -> Pokemon.S2C_CODEC.encode(buffer, pokemon) }
|
||||
buffer.writeCollection(pokemons) { buf, pokemon -> Pokemon.S2C_CODEC.encode(buf as RegistryFriendlyByteBuf, pokemon) }
|
||||
}
|
||||
}
|
||||
+9
-5
@@ -11,26 +11,30 @@ package com.cobblemon.mod.common.net.messages.server.trade
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyPosition
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readList
|
||||
import com.cobblemon.mod.common.util.readNullable
|
||||
import com.cobblemon.mod.common.util.readPartyPosition
|
||||
import com.cobblemon.mod.common.util.readUUID
|
||||
import com.cobblemon.mod.common.util.writeCollection
|
||||
import com.cobblemon.mod.common.util.writeNullable
|
||||
import com.cobblemon.mod.common.util.writePartyPosition
|
||||
import com.cobblemon.mod.common.util.writeUUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import java.util.UUID
|
||||
|
||||
class UpdateTradeOfferPacket(val newOffer: Pair<UUID, PartyPosition>?): NetworkPacket<UpdateTradeOfferPacket> {
|
||||
class UpdateTradeOfferPacket(val newOffers: List<Pair<UUID, PartyPosition>>): NetworkPacket<UpdateTradeOfferPacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("update_trade_offer")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = UpdateTradeOfferPacket(buffer.readNullable { buffer.readUUID() to buffer.readPartyPosition() })
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = UpdateTradeOfferPacket(
|
||||
buffer.readList { it.readUUID() to it.readPartyPosition() }
|
||||
)
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeNullable(newOffer) { buffer, (pokemonId, partyPosition) ->
|
||||
buffer.writeUUID(pokemonId)
|
||||
buffer.writePartyPosition(partyPosition)
|
||||
buffer.writeCollection(newOffers) { buf, (pokemonId, partyPosition) ->
|
||||
buf.writeUUID(pokemonId)
|
||||
buf.writePartyPosition(partyPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@ object ChangeTradeAcceptanceHandler : ServerNetworkPacketHandler<ChangeTradeAcce
|
||||
override fun handle(packet: ChangeTradeAcceptancePacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val trade = TradeManager.getActiveTrade(player.uuid) ?: return player.sendPacket(TradeCancelledPacket())
|
||||
val tradeParticipant = trade.getTradeParticipant(player.uuid)
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon?.uuid == packet.pokemonOfferId) {
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon.any { it.uuid == packet.pokemonOfferId }) {
|
||||
trade.updateAcceptance(tradeParticipant, packet.newAcceptance)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ object PerformTradeHandler : ServerNetworkPacketHandler<PerformTradePacket> {
|
||||
override fun handle(packet: PerformTradePacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val trade = TradeManager.getActiveTrade(player.uuid) ?: return player.sendPacket(TradeCancelledPacket())
|
||||
val tradeParticipant = trade.getTradeParticipant(player.uuid)
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon?.uuid == packet.pokemonOfferId) {
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon.any { it.uuid == packet.pokemonOfferId }) {
|
||||
trade.performTrade(tradeParticipant)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-12
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.trade.TradeManager
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import net.minecraft.server.MinecraftServer
|
||||
@@ -21,20 +22,16 @@ object UpdateTradeOfferHandler : ServerNetworkPacketHandler<UpdateTradeOfferPack
|
||||
override fun handle(packet: UpdateTradeOfferPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val trade = TradeManager.getActiveTrade(player.uuid) ?: return player.sendPacket(CancelTradePacket())
|
||||
val tradeParticipant = trade.getTradeParticipant(player.uuid)
|
||||
val newOffer = packet.newOffer
|
||||
if (newOffer == null) {
|
||||
trade.updateOffer(tradeParticipant, null)
|
||||
} else {
|
||||
val (pokemonId, partyPosition) = newOffer
|
||||
val party = player.party()
|
||||
val newOffers = packet.newOffers
|
||||
|
||||
val validPokemons = mutableListOf<Pokemon>()
|
||||
val party = player.party()
|
||||
for ((pokemonId, partyPosition) in newOffers) {
|
||||
val pokemon = party[partyPosition]
|
||||
if (pokemon == null || pokemon.uuid != pokemonId) {
|
||||
return
|
||||
} else if (!pokemon.tradeable) {
|
||||
return
|
||||
} else {
|
||||
trade.updateOffer(tradeParticipant, pokemon)
|
||||
if (pokemon != null && pokemon.uuid == pokemonId && pokemon.tradeable) {
|
||||
validPokemons.add(pokemon)
|
||||
}
|
||||
}
|
||||
trade.updateOffer(tradeParticipant, validPokemons)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
fun getOffer(tradeParticipant: TradeParticipant) = if (tradeParticipant == player1) player1Offer else player2Offer
|
||||
fun getOpposingOffer(tradeParticipant: TradeParticipant) = if (tradeParticipant == player1) player2Offer else player1Offer
|
||||
|
||||
fun updateOffer(tradeParticipant: TradeParticipant, pokemon: Pokemon?) {
|
||||
fun updateOffer(tradeParticipant: TradeParticipant, pokemon: List<Pokemon>) {
|
||||
getOffer(tradeParticipant).updateOffer(pokemon)
|
||||
getOffer(getOppositePlayer(tradeParticipant)).accepted = false
|
||||
player1.updateOffer(this, tradeParticipant, pokemon)
|
||||
@@ -30,8 +30,9 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
val offer = getOpposingOffer(tradeParticipant)
|
||||
if (offer.accepted != acceptance) {
|
||||
offer.accepted = acceptance
|
||||
getOppositePlayer(tradeParticipant).changeTradeAcceptance(this, offer.pokemon!!.uuid, acceptance)
|
||||
tradeParticipant.changeTradeAcceptance(this, offer.pokemon!!.uuid, acceptance)
|
||||
val firstId = offer.pokemon.firstOrNull()?.uuid ?: java.util.UUID.randomUUID()
|
||||
getOppositePlayer(tradeParticipant).changeTradeAcceptance(this, firstId, acceptance)
|
||||
tradeParticipant.changeTradeAcceptance(this, firstId, acceptance)
|
||||
}
|
||||
|
||||
if (offer.accepted && getOffer(tradeParticipant).accepted) {
|
||||
@@ -51,8 +52,8 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
activeTrade = this,
|
||||
player1 = player1,
|
||||
player2 = player2,
|
||||
pokemon1 = player1Offer.pokemon!!,
|
||||
pokemon2 = player2Offer.pokemon!!
|
||||
pokemon1 = player1Offer.pokemon,
|
||||
pokemon2 = player2Offer.pokemon
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -64,12 +65,14 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
}
|
||||
|
||||
fun completeTrade() {
|
||||
player1.completeTrade(this, player1Offer.pokemon!!.uuid, player2Offer.pokemon!!.uuid)
|
||||
player2.completeTrade(this, player2Offer.pokemon!!.uuid, player1Offer.pokemon!!.uuid)
|
||||
val uuids1 = player1Offer.pokemon.map { it.uuid }
|
||||
val uuids2 = player2Offer.pokemon.map { it.uuid }
|
||||
player1.completeTrade(this, uuids1, uuids2)
|
||||
player2.completeTrade(this, uuids2, uuids1)
|
||||
|
||||
player1Offer.pokemon = null
|
||||
player1Offer.pokemon = emptyList()
|
||||
player1Offer.accepted = false
|
||||
player2Offer.pokemon = null
|
||||
player2Offer.pokemon = emptyList()
|
||||
player2Offer.accepted = false
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.pokemon.TradeEvent
|
||||
import com.cobblemon.mod.common.api.interaction.ServerPlayerActionRequest
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||
import com.cobblemon.mod.common.api.text.aqua
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
|
||||
@@ -101,71 +102,98 @@ object TradeManager : RequestManager<TradeManager.TradeRequest>() {
|
||||
fun performTrade(
|
||||
activeTrade: ActiveTrade,
|
||||
player1: TradeParticipant,
|
||||
pokemon1: Pokemon,
|
||||
pokemon1: List<Pokemon>,
|
||||
player2: TradeParticipant,
|
||||
pokemon2: Pokemon
|
||||
pokemon2: List<Pokemon>
|
||||
) {
|
||||
val party1 = player1.party
|
||||
val party2 = player2.party
|
||||
|
||||
if (pokemon1 !in party1 || pokemon2 !in party2) {
|
||||
if (pokemon1.any { it !in party1 } || pokemon2.any { it !in party2 }) {
|
||||
Cobblemon.LOGGER.warn("Attempted to perform a trade with Pokémon that aren't in the party anymore. Could be attempted duping between ${player1.name} and ${player2.name}")
|
||||
activeTrade.cancelTrade()
|
||||
return
|
||||
}
|
||||
|
||||
CobblemonEvents.TRADE_EVENT_PRE.postThen(TradeEvent.Pre(player1, pokemon2, player2, pokemon1)) {
|
||||
val party1 = player1.party
|
||||
val party2 = player2.party
|
||||
if (pokemon1.isEmpty() || pokemon2.isEmpty()) {
|
||||
Cobblemon.LOGGER.warn("Attempted to perform a trade where one side offered no Pokémon between ${player1.name} and ${player2.name}. This should never happen.")
|
||||
activeTrade.cancelTrade()
|
||||
return
|
||||
}
|
||||
|
||||
val player1Removed = party1.remove(pokemon1)
|
||||
val player2Removed = party2.remove(pokemon2)
|
||||
CobblemonEvents.TRADE_EVENT_PRE.postThen(
|
||||
TradeEvent.Pre(player1, pokemon2, player2, pokemon1)
|
||||
) {
|
||||
val player1Removed = pokemon1.filter { party1.remove(it) }
|
||||
val player2Removed = pokemon2.filter { party2.remove(it) }
|
||||
|
||||
if (!player1Removed || !player2Removed) {
|
||||
if (!player1Removed) {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${pokemon1.species.resourceIdentifier} from ${player1.name.string}(${player1.uuid}). Aborting trade with ${player2.name.string}(${player2.uuid}), potential exploit abused.")
|
||||
if (player1Removed.size != pokemon1.size || player2Removed.size != pokemon2.size) {
|
||||
(pokemon1 - player1Removed.toSet()).forEach {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${it.species.resourceIdentifier} from ${player1.name.string}(${player1.uuid}). Aborting trade with ${player2.name.string}(${player2.uuid}), potential exploit abused.")
|
||||
}
|
||||
|
||||
if (!player2Removed) {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${pokemon2.species.resourceIdentifier} from ${player2.name.string}(${player2.uuid}). Aborting trade with ${player1.name.string}(${player1.uuid}), potential exploit abused.")
|
||||
(pokemon2 - player2Removed.toSet()).forEach {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${it.species.resourceIdentifier} from ${player2.name.string}(${player2.uuid}). Aborting trade with ${player1.name.string}(${player1.uuid}), potential exploit abused.")
|
||||
}
|
||||
|
||||
// Revert any changes if one of the removals failed
|
||||
if (player1Removed) party1.add(pokemon1)
|
||||
if (player2Removed) party2.add(pokemon2)
|
||||
player1Removed.forEach { party1.add(it) }
|
||||
player2Removed.forEach { party2.add(it) }
|
||||
return@postThen
|
||||
}
|
||||
|
||||
// If player1 is the OT, keep track of the friendship
|
||||
pokemon1.cacheFriendship(player1.uuid)
|
||||
pokemon1.forEach { it.cacheFriendship(player1.uuid) }
|
||||
// If player2 is the OT, keep track of the friendship
|
||||
pokemon2.cacheFriendship(player2.uuid)
|
||||
pokemon2.forEach { it.cacheFriendship(player2.uuid) }
|
||||
|
||||
// If pokemon2 was originally player1's, set the friendship back to what it was at point of trading
|
||||
if ( !pokemon2.restoreFriendship(player1.uuid) ) {
|
||||
// Otherwise, reset the friendship
|
||||
pokemon2.setFriendship(pokemon2.form.baseFriendship)
|
||||
// If a Pokémon received by player1 was originally theirs, set the friendship back to what it was at point of trading
|
||||
pokemon2.forEach {
|
||||
if (!it.restoreFriendship(player1.uuid)) {
|
||||
// Otherwise, reset the friendship
|
||||
it.setFriendship(it.form.baseFriendship)
|
||||
}
|
||||
}
|
||||
// If pokemon1 was originally player2's, set the friendship back to what it was at point of trading
|
||||
if ( !pokemon1.restoreFriendship(player2.uuid) ) {
|
||||
// Otherwise, reset the friendship
|
||||
pokemon1.setFriendship(pokemon1.form.baseFriendship)
|
||||
// If a Pokémon received by player2 was originally theirs, set the friendship back to what it was at point of trading
|
||||
pokemon1.forEach {
|
||||
if (!it.restoreFriendship(player2.uuid)) {
|
||||
// Otherwise, reset the friendship
|
||||
it.setFriendship(it.form.baseFriendship)
|
||||
}
|
||||
}
|
||||
|
||||
party2.add(pokemon1)
|
||||
party1.add(pokemon2)
|
||||
pokemon1.forEach { party2.add(it) }
|
||||
pokemon2.forEach { party1.add(it) }
|
||||
|
||||
pokemon1.lockedEvolutions.filterIsInstance<TradeEvolution>().firstOrNull {
|
||||
it.attemptEvolution(pokemon1, pokemon2)
|
||||
}
|
||||
// Each traded Pokémon may evolve if any of the Pokémon it was traded for satisfies its context.
|
||||
// Evolutions are resolved before any are applied so one evolving can't invalidate another's context.
|
||||
(pokemon1.map { it to pokemon2 } + pokemon2.map { it to pokemon1 })
|
||||
.mapNotNull { (pokemon, tradedFor) ->
|
||||
pokemon.lockedEvolutions.filterIsInstance<TradeEvolution>()
|
||||
.firstOrNull { evolution -> tradedFor.any { evolution.testContext(pokemon, it) } && evolution.test(pokemon) }
|
||||
?.let { pokemon to it }
|
||||
}
|
||||
.forEach { (pokemon, evolution) -> evolution.evolve(pokemon) }
|
||||
|
||||
pokemon2.lockedEvolutions.filterIsInstance<TradeEvolution>().firstOrNull {
|
||||
it.attemptEvolution(pokemon2, pokemon1)
|
||||
val compactParty = { party: PartyStore ->
|
||||
var writeIdx = 0
|
||||
for (readIdx in 0 until party.size()) {
|
||||
if (party.get(readIdx) != null) {
|
||||
if (readIdx != writeIdx) {
|
||||
party.swap(readIdx, writeIdx)
|
||||
}
|
||||
writeIdx++
|
||||
}
|
||||
}
|
||||
}
|
||||
compactParty(party1)
|
||||
compactParty(party2)
|
||||
|
||||
activeTrade.completeTrade()
|
||||
|
||||
CobblemonEvents.TRADE_EVENT_POST.post(TradeEvent.Post(player1, pokemon2, player2, pokemon1))
|
||||
CobblemonEvents.TRADE_EVENT_POST.post(
|
||||
TradeEvent.Post(player1, pokemon2, player2, pokemon1)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,10 @@ package com.cobblemon.mod.common.trade
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
class TradeOffer {
|
||||
var pokemon: Pokemon? = null
|
||||
var pokemon: List<Pokemon> = emptyList()
|
||||
var accepted = false
|
||||
|
||||
fun updateOffer(pokemon: Pokemon?) {
|
||||
fun updateOffer(pokemon: List<Pokemon>) {
|
||||
this.pokemon = pokemon
|
||||
accepted = false
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ interface TradeParticipant {
|
||||
*
|
||||
* If it's null, it means they're no longer offering a Pokémon (so they're redeciding).
|
||||
*/
|
||||
fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: Pokemon?)
|
||||
fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: List<Pokemon>)
|
||||
|
||||
/**
|
||||
* Notifies the participant that the acceptance state for trading with the opponent [Pokemon] with UUID [pokemonId]
|
||||
@@ -59,7 +59,7 @@ interface TradeParticipant {
|
||||
fun cancelTrade(trade: ActiveTrade)
|
||||
|
||||
/** Notifies the participant that the trade has been completed. The actual Pokémon have already been exchanged. */
|
||||
fun completeTrade(trade: ActiveTrade, pokemonId1: UUID, pokemonId2: UUID)
|
||||
fun completeTrade(trade: ActiveTrade, pokemonIds1: List<UUID>, pokemonIds2: List<UUID>)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ class PlayerTradeParticipant(val player: ServerPlayer): TradeParticipant {
|
||||
override val uuid = player.uuid
|
||||
override val party = player.party()
|
||||
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: Pokemon?) {
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: List<Pokemon>) {
|
||||
player.sendPacket(TradeUpdatedPacket(tradeParticipant.uuid, pokemon))
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ class PlayerTradeParticipant(val player: ServerPlayer): TradeParticipant {
|
||||
player.sendPacket(TradeCancelledPacket())
|
||||
}
|
||||
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonId1: UUID, pokemonId2: UUID) {
|
||||
player.sendPacket(TradeCompletedPacket(pokemonId1, pokemonId2))
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonIds1: List<UUID>, pokemonIds2: List<UUID>) {
|
||||
player.sendPacket(TradeCompletedPacket(pokemonIds1, pokemonIds2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class DummyTradeParticipant(val pokemonList: MutableList<Pokemon>) : TradePartic
|
||||
// Don't need to do any notifying.
|
||||
}
|
||||
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonId1: UUID, pokemonId2: UUID) {
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonIds1: List<UUID>, pokemonIds2: List<UUID>) {
|
||||
// Don't need to do any notifying.
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ class DummyTradeParticipant(val pokemonList: MutableList<Pokemon>) : TradePartic
|
||||
// React, maybe. Change code and hotswap.
|
||||
}
|
||||
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: Pokemon?) {
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: List<Pokemon>) {
|
||||
// React, maybe. Change code and hotswap.
|
||||
}
|
||||
}
|
||||
@@ -30,4 +30,6 @@ object CobblemonGameRules {
|
||||
val HEALER_SET_SPAWN: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersSetSpawn", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
|
||||
@JvmField
|
||||
val DO_POKEMON_PREDATION: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doPokemonPredation", GameRules.Category.MOBS, BooleanRuleInvoker.`cobblemon$create`(true))
|
||||
@JvmField
|
||||
val BAG_DROP_ITEMS: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("bagDropItems", GameRules.Category.PLAYER, BooleanRuleInvoker.`cobblemon$create`(false))
|
||||
}
|
||||
+649
-837
File diff suppressed because it is too large.
Load diff
-6
@@ -456,12 +456,6 @@
|
||||
"cannon_left": {
|
||||
"position": [0, 0, 3]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.25": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.25": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"2.25": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"3.25": "q.run_molang('cobblemon:stepsound_standard_large');"
|
||||
}
|
||||
},
|
||||
"animation.blastoise.ground_run": {
|
||||
|
||||
-11
@@ -83,7 +83,6 @@
|
||||
},
|
||||
"animation.parasect.ground_walk": {
|
||||
"loop": true,
|
||||
"animation_length": 1,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": [0, 0, 0],
|
||||
@@ -135,12 +134,6 @@
|
||||
"locator_seat_1": {
|
||||
"rotation": [7.5, 0, 0]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_minecraft');",
|
||||
"0.25": "q.run_molang('cobblemon:stepsound_minecraft');",
|
||||
"0.5": "q.run_molang('cobblemon:stepsound_minecraft');",
|
||||
"0.75": "q.run_molang('cobblemon:stepsound_minecraft');"
|
||||
}
|
||||
},
|
||||
"animation.parasect.ground_run": {
|
||||
@@ -265,10 +258,6 @@
|
||||
"rotation": ["5+Math.cos((query.anim_time) * 90 * 16 - 90) * 2", 0, 0],
|
||||
"position": [0, "0+Math.cos((query.anim_time) * 90 * 32) * -0.2", -0.25]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_minecraft');",
|
||||
"0.125": "q.run_molang('cobblemon:stepsound_minecraft');"
|
||||
}
|
||||
},
|
||||
"animation.parasect.ride_ground_run": {
|
||||
|
||||
-4
@@ -391,10 +391,6 @@
|
||||
"0.7083": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0833": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"0.2917": "q.run_molang('cobblemon:stepsound_standard_medium');"
|
||||
}
|
||||
},
|
||||
"animation.dewgong.water_idle": {
|
||||
|
||||
-20
@@ -1071,16 +1071,6 @@
|
||||
"head": {
|
||||
"rotation": ["-0.8*math.cos(q.anim_time*90*8-120)", 0, "3*math.sin(q.anim_time*90*4+70)"]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"0.5": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.5": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"2.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"2.5": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"3.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"3.5": "q.run_molang('cobblemon:stepsound_standard_large');"
|
||||
}
|
||||
},
|
||||
"animation.rhyhorn.ride_ground_walk": {
|
||||
@@ -1927,16 +1917,6 @@
|
||||
],
|
||||
"position": [0, "0.4+0.6*math.cos(q.anim_time*90*8-120)", 0]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"0.375": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"0.5": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"0.875": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"1.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.375": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"1.5": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.875": "q.run_molang('cobblemon:stepsound_standard_medium');"
|
||||
}
|
||||
},
|
||||
"animation.rhyhorn.ride_ground_run": {
|
||||
|
||||
-12
@@ -329,12 +329,6 @@
|
||||
"locator_seat_1": {
|
||||
"rotation": [-15, 0, 0]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"2.0": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"3.0": "q.run_molang('cobblemon:stepsound_standard_large');"
|
||||
}
|
||||
},
|
||||
"animation.rhydon.ride_ground_walk": {
|
||||
@@ -813,12 +807,6 @@
|
||||
"locator_seat_1": {
|
||||
"rotation": [-15, 0, 0]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.3333": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"0.8333": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.3333": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"1.8333": "q.run_molang('cobblemon:stepsound_standard_large');"
|
||||
}
|
||||
},
|
||||
"animation.rhydon.ride_ground_run": {
|
||||
|
||||
-4
@@ -391,10 +391,6 @@
|
||||
"1.0": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0833": "q.run_molang('cobblemon:stepsound_minecraft');",
|
||||
"0.5833": "q.run_molang('cobblemon:stepsound_minecraft');"
|
||||
}
|
||||
},
|
||||
"animation.mr_mime.ground_run": {
|
||||
|
||||
@@ -1,469 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered"
|
||||
},
|
||||
"facing=south,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom"
|
||||
},
|
||||
"facing=south,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top"
|
||||
},
|
||||
"facing=south,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/copper_mower",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/copper_mower"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/copper_mower",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/copper_mower",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open"
|
||||
},
|
||||
"facing=south,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open"
|
||||
},
|
||||
"facing=south,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/copper_washer",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/copper_washer"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/copper_washer",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/copper_washer",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,469 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,power=0": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_unpowered",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=0": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_unpowered"
|
||||
},
|
||||
"facing=south,power=0": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_unpowered",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=0": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_unpowered",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=1,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=1,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=2,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=2,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=3,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=3,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=4,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=4,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=5,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=5,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=6,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=6,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=7,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=7,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=8,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=8,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=9,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=9,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=10,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=10,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=11,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=11,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=12,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=12,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=13,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=13,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=14,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=14,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=15,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=false": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=15,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=true": {
|
||||
"model": "cobblemon:block/exposed_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,half=lower": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_bottom",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=lower": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_bottom"
|
||||
},
|
||||
"facing=south,half=lower": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_bottom",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=lower": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_bottom",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=upper": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_top",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=upper": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_top"
|
||||
},
|
||||
"facing=south,half=upper": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_top",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=upper": {
|
||||
"model": "cobblemon:block/exposed_copper_fridge_top",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/exposed_copper_mower",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/exposed_copper_mower"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/exposed_copper_mower",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/exposed_copper_mower",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open"
|
||||
},
|
||||
"facing=south,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,ejecting=true": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,ejecting=true": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open"
|
||||
},
|
||||
"facing=south,ejecting=true": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,ejecting=true": {
|
||||
"model": "cobblemon:block/exposed_copper_oven_open",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/exposed_copper_washer",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/exposed_copper_washer"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/exposed_copper_washer",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/exposed_copper_washer",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,469 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,power=0": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_unpowered",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=0": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_unpowered"
|
||||
},
|
||||
"facing=south,power=0": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_unpowered",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=0": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_unpowered",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=1,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=1,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=2,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=2,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=3,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=3,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=4,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=4,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=5,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=5,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=6,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=6,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=7,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=7,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=8,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=8,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=9,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=9,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=10,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=10,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=11,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=11,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=12,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=12,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=13,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=13,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=14,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=14,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=15,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=15,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,half=lower": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_bottom",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=lower": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_bottom"
|
||||
},
|
||||
"facing=south,half=lower": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_bottom",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=lower": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_bottom",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=upper": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_top",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=upper": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_top"
|
||||
},
|
||||
"facing=south,half=upper": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_top",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=upper": {
|
||||
"model": "cobblemon:block/oxidized_copper_fridge_top",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/oxidized_copper_mower",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/oxidized_copper_mower"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/oxidized_copper_mower",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/oxidized_copper_mower",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open"
|
||||
},
|
||||
"facing=south,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,ejecting=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,ejecting=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open"
|
||||
},
|
||||
"facing=south,ejecting=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,ejecting=true": {
|
||||
"model": "cobblemon:block/oxidized_copper_oven_open",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/oxidized_copper_washer",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/oxidized_copper_washer"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/oxidized_copper_washer",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/oxidized_copper_washer",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,469 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered"
|
||||
},
|
||||
"facing=south,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=0": {
|
||||
"model": "cobblemon:block/copper_fan_unpowered",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=1,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=2,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=3,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=4,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=5,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=6,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative"
|
||||
},
|
||||
"facing=south,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing"
|
||||
},
|
||||
"facing=south,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=7,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=8,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=9,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=10,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=11,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=12,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=13,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=14,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong"
|
||||
},
|
||||
"facing=south,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=false": {
|
||||
"model": "cobblemon:block/copper_fan_decorative_strong",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong"
|
||||
},
|
||||
"facing=south,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,power=15,push=true": {
|
||||
"model": "cobblemon:block/copper_fan_pushing_strong",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom"
|
||||
},
|
||||
"facing=south,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=lower": {
|
||||
"model": "cobblemon:block/copper_fridge_bottom",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top"
|
||||
},
|
||||
"facing=south,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=upper": {
|
||||
"model": "cobblemon:block/copper_fridge_top",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "cobblemon:block/copper_mower",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "cobblemon:block/copper_mower"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "cobblemon:block/copper_mower",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "cobblemon:block/copper_mower",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=closed,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open"
|
||||
},
|
||||
"facing=south,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=open,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed"
|
||||
},
|
||||
"facing=south,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,cooking=cooking,ejecting=false": {
|
||||
"model": "cobblemon:block/copper_oven_closed",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open"
|
||||
},
|
||||
"facing=south,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,ejecting=true": {
|
||||
"model": "cobblemon:block/copper_oven_open",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 425 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user