forked from mirrors/cobblemon
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1817322fa |
@@ -24,7 +24,6 @@ eclipse
|
||||
run
|
||||
runClient
|
||||
runServer
|
||||
utilityscripts/implementation/*.txt
|
||||
|
||||
# Files from Forge MDK
|
||||
forge*changelog.txt
|
||||
@@ -37,11 +36,9 @@ common/src/main/resources/assets/cobblemon/showdown
|
||||
# Generated files
|
||||
*/generated/resources/*
|
||||
/fabric/src/generated/resources/cobblemon-common.accesswidener
|
||||
/fabric/src/main/generated/*
|
||||
/.ignored/
|
||||
common/.fabric
|
||||
.kotlin/
|
||||
|
||||
# MacOS
|
||||
.DS_Store
|
||||
/common/config/*
|
||||
|
||||
+2
-2
@@ -71,8 +71,8 @@ setup_packsquash:
|
||||
- echo "Installing wget & unzip"
|
||||
- yum install -y wget unzip
|
||||
- echo "Downloading PackSquash"
|
||||
- wget https://github.com/ComunidadAylas/PackSquash/releases/download/v0.4.1/packsquash-x86_64-unknown-linux-musl.zip
|
||||
- unzip packsquash-x86_64-unknown-linux-musl.zip -d ./packsquash_bin
|
||||
- wget https://github.com/ComunidadAylas/PackSquash/releases/download/v0.4.0/PackSquash.CLI.executable.x86_64-unknown-linux-musl.zip
|
||||
- unzip PackSquash.CLI.executable.x86_64-unknown-linux-musl.zip -d ./packsquash_bin
|
||||
- echo "Creating PackSquash options.toml"
|
||||
- |
|
||||
cat <<EOF > ./options.toml
|
||||
|
||||
+951
-406
File diff suppressed because it is too large
Load Diff
@@ -1,9 +0,0 @@
|
||||
- Some kind of particle effect for them? they're meant to have glowing eyes, so maybe some red particles on the eye locator
|
||||
--- global posers? stacked posers?
|
||||
--- red texture seems to be what some people wanted.
|
||||
|
||||
/- shoulder mounts part of it
|
||||
- omni boost
|
||||
- roar when player comes within reach, adjust levels
|
||||
|
||||
- Riding settings to control what the min scale is for a pokemon to be ridable.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,61 +0,0 @@
|
||||
# Changelog
|
||||
## [1.7.1 (November 29th, 2025)](#1-7-1)
|
||||
|
||||
### Additions
|
||||
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader.
|
||||
- Added brewing recipe for Throat Spray.
|
||||
- Added vanilla sprinting's field of view change to Pokémon land mounts.
|
||||
- Added a customizable keybind for the riding freelook button.
|
||||
- Added double tap to sprint on land mounts.
|
||||
|
||||
### Changes
|
||||
- Made Jet pitch turning 1.5x faster across all Pokémon.
|
||||
- Party Pokémon now attack only mobs that are attacking their owner, instead of randomly targeting unrelated mobs and getting themselves hurt.
|
||||
- Reduced the cost of the Vivichoke Seed trade with the Wandering Trader.
|
||||
|
||||
### Fixes
|
||||
- Fixed incorrect camera pivot on Bird, Jet, and Dolphin mounts, leading to some disorienting riding.
|
||||
- Fixed players suffocating while on vanilla mounts.
|
||||
- Fixed a graphics crash that could occur on some machines when campfire pots were nearby.
|
||||
- Fixed ride controls overlay being displayed to passengers. The passengers probably don't need to know about those.
|
||||
- Fixed mount jumping so that it doesn't switch back to ground animations.
|
||||
- Fixed ridden Pokémon land collision and some issues around stepping up blocks. Land mounts are smoother overall now.
|
||||
- Fixed Furfrou's pink and magenta trims being swapped. Only a man could make that mistake.
|
||||
- Fixed friendship being reset to the default value when evolving a Pokémon.
|
||||
- Fixed Combees not depositing honey upon leaving a hive if they entered it with nectar.
|
||||
- Fixed pastured Combees not moving during the night or in rain.
|
||||
- Fixed a case in which a Combee might try to path to a flower that no longer exists.
|
||||
- Fixed Combees attempting to enter a full hive.
|
||||
- Fixed a crash involving Combees and hives. 500 bee bugs. Bugged bees? We can be bees. Mark, this is good news.
|
||||
- Fixed a crash related to NPC navigation.
|
||||
- Fixed a crash when opening a PC box with certain wallpapers while using *VulkanMod*.
|
||||
- Fixed a crash when you place a block in the way of hearty grains 2nd block.
|
||||
- Fixed passengers hearing the shiny noise of a ridden shiny Pokémon.
|
||||
- Ponigiri can no longer be eaten at full hunger.
|
||||
- Fixed Poké Snack spawning sounds not coming from the block.
|
||||
- Medicinal Brew's Campfire Pot recipe now correctly displays that it can be made using an empty glass bottle or a filled bottle.
|
||||
- Fixed glass bottle not being returned when slathering honey on a saccharine leaf block.
|
||||
- Fixed saccharine hanging signs sometimes dropping their oak wood counterpart when being broken.
|
||||
- Fixed a bunch of incompatibilities with NeoForge mods.
|
||||
- Fixed a bug where wind charges hitting pasture blocks would recall all Pokémon in it.
|
||||
- Fixed the Home on the Range advancement triggering when opening the Pokémon interaction wheel.
|
||||
- Fixed recipes that use concrete not working on NeoForge.
|
||||
- Fixed Boltund's model.
|
||||
- Fixed Cyclizar's textures.
|
||||
|
||||
### Developer
|
||||
|
||||
### Molang & Datapacks
|
||||
- Removed automatic generation of PC wallpaper screen glow if no asset is provided; it is now optional.
|
||||
- This is because there's no practical way to do this without blowing up things like *VulkanMod*.
|
||||
|
||||
### Particles
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
- French
|
||||
- Japanese
|
||||
- Korean
|
||||
- Brazilian Portuguese
|
||||
- Simplified Chinese
|
||||
- Traditional Chinese
|
||||
@@ -1,137 +0,0 @@
|
||||
# Changelog
|
||||
## [1.7.2 (January 25th, 2026)](#1-7-2)
|
||||
|
||||
### Additions
|
||||
- Added Saccharine wood furniture for Adorn.
|
||||
- Added the Partner Mark, which party Pokémon have a very small chance to earn as the player walks, provided they have enough friendship.
|
||||
- Added decorative block models for existing items: Potion, Super Potion, Hyper Potion, Max Potion, Full Restore, Antidote, Awakening, Burn Heal, Ice Heal, Paralyze Heal, Full Heal, Ether, Elixir, Max Ether, Max Elixir, X Accuracy, X Attack, X Defence, X Special Attack, X Special Defence, X Speed, Dire Hit, Guard Spec, Weakness Policy, Blunder Policy, Cleanse Tag, and Spell Tag.
|
||||
- Added decorative sign blocks called Plaques.
|
||||
- Added ride style labels to ride stats in Pokédex, as well as ride style icons in the summary GUI.
|
||||
- Added more seasonings for sinister tea:
|
||||
- Mental Herb - Mental Restoration I for 10 seconds, which staves off Insomnia.
|
||||
- White Herb - Removes negative effects.
|
||||
- Milk, Moomoo Milk - Removes effects.
|
||||
- Added dispenser support for:
|
||||
- Applying a Honey Bottle to Saccharine Logs.
|
||||
- Washing honey off of Saccharine Slathered Logs.
|
||||
- Applying and removing honey on Saccharine Leaves.
|
||||
- Added riding statistics: `Distance by Pokémon on Land`, `Distance by Pokémon in Air` and `Distance by Pokémon in Liquid`.
|
||||
|
||||
### New rideable Pokémon
|
||||
- Honchkrow
|
||||
- Mantine
|
||||
|
||||
### Pokémon Added
|
||||
|
||||
#### Gen 5
|
||||
- Throh
|
||||
- Sawk
|
||||
|
||||
#### Gen 6
|
||||
- Litleo
|
||||
- Pyroar
|
||||
- Spritzee
|
||||
- Aromatisse
|
||||
- Swirlix
|
||||
- Slurpuff
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
- Falinks
|
||||
- Cottonee
|
||||
- Whimsicott
|
||||
- Ferroseed
|
||||
- Ferrothorn
|
||||
- Chingling
|
||||
- Chimecho
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Mantine (ride animations)
|
||||
- Flygon (ride jump animation)
|
||||
- Honchkrow (ride animations)
|
||||
- Croagunk
|
||||
- Toxicroak
|
||||
|
||||
### Changes
|
||||
- Added a new config option, `Enable In-Flight Dismounting` (default: off), which lets you dismount while riding a Pokémon in the air. This is the textbook definition of caveat emptor.
|
||||
- Ride sounds have been separated into stereo for passengers and mono for other players. Riding will now sound more spacious.
|
||||
- Battle AI now uses a smarter threshold for switching, reducing unnecessary switches.
|
||||
- AI will always use the most damaging move when at low HP and when it is not switching, improving endgame decision-making.
|
||||
- Items given from interacting with Saccharine Leaves are placed in the active hotbar slot if possible.
|
||||
- Added `label` as an alternate key to the `tag` property.
|
||||
|
||||
### Fixes
|
||||
- Fixed crashing when viewing another player in spectator mode. Some said this was reason to release this update a month ago. They were probably right.
|
||||
- Fixed crashing when sending a Pokémon out after editing its form.
|
||||
- Fixed all Pokémon being saved to chunks and never despawning even when they should be.
|
||||
- Fixed Poké Snacks crashing if there was no available spawn.
|
||||
- Fixed Poké Snack / Bait effects so that EV Yield, Type, and Egg Group filters now all apply together when weighting spawns. And you thought you were going crazy.
|
||||
- Fixed Furfrou not being trimmable on NeoForge specifically.
|
||||
- Fixed honey from Saccharine Leaves being harvestable at less than the max age.
|
||||
- Fixed possible error on world generation when Combee are placed in naturally generated bee nests.
|
||||
- Fixed Galarian Weezing crashing the world if it decides to blink the wrong way. The same could happen to you!
|
||||
- Fixed Galarian Mr. Mime incorrectly being rideable. Some would argue that regular Mr. Mime shouldn't be rideable, but that would make them wrong.
|
||||
- Fixed missing apricorn textures for Adorn blocks.
|
||||
- Fixed Apricorn block model rotation for counters/sinks/cupboards/drawers to match that of most recent version of Adorn.
|
||||
- Fixed item interaction sometimes not working properly when playing on servers.
|
||||
- Fixed Mint Leaves not being usable for filling the Resurrection Machine.
|
||||
- Fixed Super Potion recipes incorrectly using Hondew Berry instead of Aguav Berry. They look similar, to be fair.
|
||||
- Fixed Wishiwashi not schooling properly.
|
||||
- Fixed battle item duplication issue. How did it work? Wouldn't you like to know, weather boy.
|
||||
- Fixed the ordering of Aprijuice's riding stat boosts so they always have the same order.
|
||||
- Fixed the movesets of certain Pokémon being incorrectly sanitized upon reload, causing some forms to keep losing moves.
|
||||
- Fixed selected leading Pokémon in battle not being used when levels are set.
|
||||
- Fixed the bottom half of pasture blocks having an incorrect hit-box when facing north or south.
|
||||
- Fixed gimmicks not being usable in double and triple battles.
|
||||
- Fixed gimmick buttons showing when already used in the same turn in double and triple battles.
|
||||
- Fixed mochi items consuming two items at a time.
|
||||
- Fixed Fresh Start Mochi's EV reset not syncing health changes properly.
|
||||
- Fixed Pokémon spawn influences not being specific to regional forms.
|
||||
- Fixed memory leak from battles not being cleaned up after ending.
|
||||
- Fixed orientation not getting reset after crashing while flying and getting back on the Pokémon.
|
||||
- Fixed shiny Pokémon not respecting the `silent` flag on spawn.
|
||||
- Fixed 'Plain' prefix not being applied to all low-quality Aprijuice.
|
||||
- Fixed Pokémon interactions not playing sound effects when the volume was not specified.
|
||||
- Fixed Pokémon interaction cooldowns taking longer than intended when the Pokémon was in the player’s party.
|
||||
- Fixed Pokémon interactions occasionally crashing the game when spamming an interaction with a 0 cooldown.
|
||||
- Fixed Pokémon fullness decreasing more than intended when the Pokémon was pastured.
|
||||
- Fixed Scraggy line, Milcery line, and Morpeko spawning on unnatural blocks.
|
||||
- Fixed invulnerability-bypassed damage being resisted by invulnerable NPC entities.
|
||||
- Fixed Fabric network packets not being handled immediately, fixing incompatibilities with Supplementaries, Prometheus, Sleep Tight, and others.
|
||||
- Fixed killer not being set early enough on a wild Pokémon entity from `WinInstruction`.
|
||||
- Fixed requirements such as `biomeCondition` crashing the game when used to define Pokémon interactions.
|
||||
- Fixed an issue that prevented registering custom dispenser behaviours (no longer overrides vanilla behaviour).
|
||||
- Fixed an issue navigation that prevented Combee from pathing into and out of Saccharine Leaves.
|
||||
- Added Saccharine Boats and Saccharine Boat with Chests to relevant boat tags.
|
||||
- Fixed Soothe Bell not being properly tagged as a held item.
|
||||
- Fixed `/calculateseatpositions` expecting a locator format that even we don't use. It needs an underscore after "seat".
|
||||
- Fixed the `run_script` Molang function to not fail if the environment's context is null.
|
||||
- Fixed the Molang functions `date_local_time`, `date_of`, `date_is_after` to use the correct date format.
|
||||
|
||||
### Developer
|
||||
- Changed the `owner` parameter in the `OwnerQueryRequirement` interface from `ServerPlayer` to `Player`. This method is now also called on the client to verify whether a Pokémon interaction succeeded, so make sure to update your implementations to handle both server and client contexts.
|
||||
- Added the `pnx` to the `BattleFaintedEvent` and `FormeChangeEvent`.
|
||||
- Added register methods for custom instructions to `ShowdownInterpreter`.
|
||||
- Changed callback operations in `BattlePokemon` to allow multiple callbacks and be mutable.
|
||||
- Added `display_name`, `description`, and `max_pp` functions to the `MoveTemplate` struct.
|
||||
- Changed the implementations of `AIBattleActor` to be open classes to allow extension.
|
||||
- Changed the resource location of Poké Ball icons in the GUI to use the balls namespace instead of Cobblemon's, allowing mods to properly use their own namespace for these textures.
|
||||
|
||||
### Molang & Datapacks
|
||||
- Ride sounds can now be set as exclusive to passengers.
|
||||
- Ride sounds no longer play when submerged unless specified with a new setting.
|
||||
- Exception handling has been added to `run_molang`, resolving some crashes caused by malformed MoLang expressions.
|
||||
- Added the `create_itemstack`, `has_inventory_space`, `set_inventory_slot`, and `give_item` MoLang functions for item and inventory utility.
|
||||
- Added the `get_move_from_id` MoLang function for general move info queries without requiring a Moveset object to access.
|
||||
- Added support for optional message variants in battle activate instructions for more context-specific battle text.
|
||||
- Example: `this.add('-activate', pokemon, 'ability: example', '[msg]message1');` will parse to lang key `cobblemon.battle.activate.example.message1`.
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
- French
|
||||
- Canadian French
|
||||
- Simplified Chinese
|
||||
- Ukrainian
|
||||
- Brazilian Portuguese
|
||||
- Spanish
|
||||
- Korean
|
||||
- Japanese
|
||||
@@ -1,22 +0,0 @@
|
||||
# Changelog
|
||||
## [1.7.3 (January 31st, 2026)](#1-7-3)
|
||||
|
||||
### Fixes
|
||||
- Fixed mounted Pokémon not playing sounds.
|
||||
- Fixed players failing to join servers randomly.
|
||||
- Fixed some Pokémon having no stamina for flying.
|
||||
- Fixed `/pctake` not respecting the actual size of the PC.
|
||||
### Developer
|
||||
- Poké Ball GUI textures now respect the ball's namespace, enabling proper texture loading for custom balls from other mods.
|
||||
|
||||
### Molang & Datapacks
|
||||
- Added a `chance` requirement type for Pokémon interactions.
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
- French
|
||||
- Canadian French
|
||||
- Korean
|
||||
- Portuguese
|
||||
- Simplified Chinese
|
||||
- Spanish
|
||||
@@ -55,7 +55,7 @@ dependencies {
|
||||
// modCompileOnly(libs.flywheelFabric)
|
||||
|
||||
// Showdown
|
||||
modCompileOnly(libs.graal.core)
|
||||
modCompileOnly(libs.graal)
|
||||
|
||||
// Data Storage
|
||||
modCompileOnly(libs.bundles.mongo)
|
||||
@@ -72,10 +72,6 @@ tasks.withType<Test> {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
exclude("data/**/README.md")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
blossom {
|
||||
|
||||
@@ -13,6 +13,5 @@ public interface ChannelDuck {
|
||||
void cobblemon$inverseAttenuation(float rolloffFactor);
|
||||
void cobblemon$clearFilters();
|
||||
|
||||
void cobblemon$applyReverb(float decayTime, float gain, float diffusion, float density);
|
||||
void cobblemon$clearReverb();
|
||||
// void cobblemon$exponentialAttenuation(float rolloff, float refDistance, float maxDistance);
|
||||
}
|
||||
|
||||
@@ -11,15 +11,12 @@ package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories;
|
||||
import com.cobblemon.mod.common.api.ai.config.task.PathToBeeHiveTaskConfig;
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.world.feature.SaccharineTreeFeature;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.ai.memory.MemoryStatus;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BeehiveBlock;
|
||||
@@ -44,21 +41,7 @@ public abstract class BeeOccupantMixin {
|
||||
if (cir.getReturnValue() == null) {
|
||||
final BeehiveBlockEntity.Occupant occupant = (BeehiveBlockEntity.Occupant) (Object) this;
|
||||
CompoundTag compoundTag = occupant.entityData().copyTag();
|
||||
String id = compoundTag.getString("id");
|
||||
Entity entity = null;
|
||||
if (id.equals(SaccharineTreeFeature.Companion.getPOKEMON_PLACEHOLD_ID())) {
|
||||
// Special case for Pokemon stuffed into a beenest upon world gen.
|
||||
// For technical reasons we cannot create them as full entities during world gen.
|
||||
// So we look for this special id tag and complete the entity when it attempts to exit a hive.
|
||||
if (compoundTag.contains("pokemonProperties")) {
|
||||
String properties = compoundTag.getString("pokemonProperties");
|
||||
PokemonProperties pokemon = PokemonProperties.Companion.parse(properties);
|
||||
entity = pokemon.createEntity(level);
|
||||
}
|
||||
} else {
|
||||
entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
|
||||
}
|
||||
|
||||
Entity entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
|
||||
if (entity instanceof PokemonEntity pokemonEntity) {
|
||||
var state = level.getBlockState(pos);
|
||||
var newPos = Vec3.ZERO;
|
||||
@@ -69,9 +52,7 @@ public abstract class BeeOccupantMixin {
|
||||
var facing = state.getValue(HorizontalDirectionalBlock.FACING);
|
||||
newPos = pos.relative(facing).getCenter();
|
||||
newYaw = facing.toYRot();
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
|
||||
}
|
||||
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
|
||||
} else {
|
||||
// Block has likely been destroyed
|
||||
var center = pos.getCenter();
|
||||
@@ -81,31 +62,25 @@ public abstract class BeeOccupantMixin {
|
||||
center.z + level.random.nextFloat() * 0.6 - 0.3
|
||||
);
|
||||
newYaw = level.random.nextFloat() * 360F;
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
|
||||
}
|
||||
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
|
||||
}
|
||||
entity.yRotO = newYaw;
|
||||
entity.setPos(newPos);
|
||||
// Do honey logic
|
||||
if (brain.checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)) {
|
||||
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
if (hasNectar) {
|
||||
// Remove nectar and reset got to hive cooldown
|
||||
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
|
||||
}
|
||||
// Increment honey level of the hive
|
||||
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
|
||||
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
|
||||
if (i < 5) {
|
||||
int j = level.random.nextInt(100) == 0 ? 2 : 1;
|
||||
if (i + j > 5) {
|
||||
--j;
|
||||
}
|
||||
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
|
||||
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
if (hasNectar) {
|
||||
// Remove nectar and reset got to hive cooldown
|
||||
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
|
||||
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
|
||||
// Increment honey level of the hive
|
||||
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
|
||||
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
|
||||
if (i < 5) {
|
||||
int j = level.random.nextInt(100) == 0 ? 2 : 1;
|
||||
if (i + j > 5) {
|
||||
--j;
|
||||
}
|
||||
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,13 +92,12 @@ public abstract class BeeOccupantMixin {
|
||||
@Inject(method = "of", at = @At("HEAD"), cancellable = true)
|
||||
private static void cobblemon$of(Entity entity, CallbackInfoReturnable<BeehiveBlockEntity.Occupant> cir) {
|
||||
if (entity instanceof PokemonEntity pokemonEntity) {
|
||||
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
|
||||
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "Brain", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
entity.save(compoundTag);
|
||||
Objects.requireNonNull(compoundTag);
|
||||
IGNORED_BEE_TAGS.forEach(compoundTag::remove);
|
||||
boolean hasNectar = pokemonEntity.getBrain().checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)
|
||||
&& pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
Boolean hasNectar = pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
cir.setReturnValue(new BeehiveBlockEntity.Occupant(CustomData.of(compoundTag), 0, hasNectar ? 2400 : 600));
|
||||
cir.cancel();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.duck.ChannelDuck;
|
||||
import com.mojang.blaze3d.audio.Channel;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.EXTEfx;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(Channel.class)
|
||||
public abstract class ChannelMixin implements ChannelDuck {
|
||||
|
||||
@Shadow
|
||||
private int source;
|
||||
|
||||
// Id of filter applied when sound is obstructed
|
||||
private int cobblemon$lowPassFilterId = 0;
|
||||
|
||||
@Override
|
||||
public void cobblemon$applyLowPassFilter(float gain, float hfGain) {
|
||||
// Delete old filter if it exists
|
||||
if (cobblemon$lowPassFilterId != 0) {
|
||||
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, 0); // Detach filter from source
|
||||
EXTEfx.alDeleteFilters(cobblemon$lowPassFilterId); // Delete old filter
|
||||
cobblemon$lowPassFilterId = 0;
|
||||
}
|
||||
|
||||
// Generate a fresh filter
|
||||
int filterId = EXTEfx.alGenFilters();
|
||||
if (!EXTEfx.alIsFilter(filterId)) {
|
||||
System.err.println("Failed to create OpenAL low-pass filter");
|
||||
return;
|
||||
}
|
||||
|
||||
EXTEfx.alFilteri(filterId, EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS);
|
||||
EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAIN, gain);
|
||||
EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAINHF, hfGain);
|
||||
|
||||
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, filterId);
|
||||
|
||||
// Save the new filter ID
|
||||
cobblemon$lowPassFilterId = filterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cobblemon$inverseAttenuation(float rolloffFactor) {
|
||||
AL10.alSourcei(source, AL10.AL_DISTANCE_MODEL, AL10.AL_INVERSE_DISTANCE);
|
||||
AL10.alSourcef(source, AL10.AL_ROLLOFF_FACTOR, rolloffFactor);
|
||||
AL10.alSourcef(source, AL10.AL_REFERENCE_DISTANCE, 1.0f);
|
||||
AL10.alSourcef(source, AL10.AL_MAX_DISTANCE, 0.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cobblemon$clearFilters() {
|
||||
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, 0);
|
||||
|
||||
if (EXTEfx.alIsFilter(cobblemon$lowPassFilterId)) {
|
||||
EXTEfx.alDeleteFilters(cobblemon$lowPassFilterId);
|
||||
cobblemon$lowPassFilterId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,15 +36,15 @@ public class ClientPacketListenerMixin {
|
||||
for (int passenger : packet.getPassengers()) {
|
||||
passengers.add(this.level.getEntity(passenger));
|
||||
}
|
||||
pokemon.getOccupiedSeats().values().stream()
|
||||
Arrays
|
||||
.stream(pokemon.getOccupiedSeats())
|
||||
.filter(x -> !passengers.contains(x))
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(Entity::stopRiding);
|
||||
|
||||
// Mount passengers not yet in the map
|
||||
var currentPassengers = new ArrayList<>(pokemon.getOccupiedSeats().values());
|
||||
var occupiedSeats = Arrays.asList(pokemon.getOccupiedSeats());
|
||||
passengers.stream()
|
||||
.filter(x -> !currentPassengers.contains(x))
|
||||
.filter(x -> !occupiedSeats.contains(x))
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(x -> x.startRiding(pokemon, true));
|
||||
ci.cancel();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.PreEmptsExplosion;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = Explosion.class)
|
||||
public class ExplosionMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "finalizeExplosion",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
public BlockState cobblemon$whenExploded(Level world, BlockPos pos) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if(blockState.getBlock() instanceof PreEmptsExplosion preExplosionBlock) {
|
||||
preExplosionBlock.whenExploded(world, blockState, pos);
|
||||
}
|
||||
return blockState;
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.mixin.accessor.SinglePoolElementAccessor;
|
||||
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.*;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.alias.PoolAliasLookup;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(JigsawPlacement.class)
|
||||
public class JigsawPlacementMixin {
|
||||
|
||||
@Inject(
|
||||
method = "addPieces(Lnet/minecraft/world/level/levelgen/structure/Structure$GenerationContext;Lnet/minecraft/core/Holder;Ljava/util/Optional;ILnet/minecraft/core/BlockPos;ZLjava/util/Optional;ILnet/minecraft/world/level/levelgen/structure/pools/alias/PoolAliasLookup;Lnet/minecraft/world/level/levelgen/structure/pools/DimensionPadding;Lnet/minecraft/world/level/levelgen/structure/templatesystem/LiquidSettings;)Ljava/util/Optional;",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true
|
||||
)
|
||||
private static void onAddPieces(
|
||||
Structure.GenerationContext context,
|
||||
Holder<StructureTemplatePool> startPool,
|
||||
Optional<ResourceLocation> startJigsawName,
|
||||
int maxDepth,
|
||||
BlockPos pos,
|
||||
boolean useExpansionHack,
|
||||
Optional<Heightmap.Types> projectStartToHeightmap,
|
||||
int maxDistanceFromCenter,
|
||||
PoolAliasLookup aliasLookup,
|
||||
DimensionPadding dimensionPadding,
|
||||
LiquidSettings liquidSettings,
|
||||
CallbackInfoReturnable<Optional<Structure.GenerationStub>> cir
|
||||
) {
|
||||
Optional<Structure.GenerationStub> result = cir.getReturnValue();
|
||||
if (result.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BlockPos spawnPos = result.get().position();
|
||||
boolean canPlace = cobblemon$canAnyStartElementPlace(context, startPool, spawnPos);
|
||||
|
||||
if (canPlace) {
|
||||
return;
|
||||
}
|
||||
|
||||
cir.setReturnValue(Optional.empty());
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static boolean cobblemon$canAnyStartElementPlace(
|
||||
Structure.GenerationContext generationContext,
|
||||
Holder<StructureTemplatePool> startPool,
|
||||
BlockPos startPos
|
||||
) {
|
||||
for (StructurePoolElement element : startPool.value().templates) {
|
||||
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(element);
|
||||
|
||||
if (heightRangeProcessor.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HeightRangeStructureProcessor processor = heightRangeProcessor.get();
|
||||
boolean valid = processor.isValidPlacement(
|
||||
generationContext.chunkGenerator(),
|
||||
generationContext.heightAccessor(),
|
||||
generationContext.randomState(),
|
||||
startPos
|
||||
);
|
||||
|
||||
if (valid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static Optional<HeightRangeStructureProcessor> cobblemon$getHeightRangeProcessor(StructurePoolElement element) {
|
||||
if (!(element instanceof SinglePoolElement)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
StructureProcessorList processorList = ((SinglePoolElementAccessor) element).getProcessors().value();
|
||||
for (StructureProcessor processor : processorList.list()) {
|
||||
if (processor instanceof HeightRangeStructureProcessor heightRangeStructureProcessor) {
|
||||
return Optional.of(heightRangeStructureProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.entity.DiscShelfBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.NoteBlock;
|
||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(NoteBlock.class)
|
||||
public abstract class NoteBlockMixin {
|
||||
@Inject(method = "triggerEvent", at = @At("HEAD"), cancellable = true)
|
||||
private void cobblemon$triggerTMShelfSequencer(BlockState state, Level level, BlockPos pos, int type, int data, CallbackInfoReturnable<Boolean> cir) {
|
||||
final BlockPos shelfPos = pos.below();
|
||||
final BlockEntity blockEntity = level.getBlockEntity(shelfPos);
|
||||
if (!(blockEntity instanceof DiscShelfBlockEntity discShelfBlockEntity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!level.isClientSide) {
|
||||
final BlockPos instrumentPos = shelfPos.below();
|
||||
final SoundEvent soundEvent;
|
||||
if (level.getBlockState(instrumentPos).isAir()) {
|
||||
soundEvent = SoundEvents.NOTE_BLOCK_BIT.value();
|
||||
} else {
|
||||
final NoteBlockInstrument instrument = level.getBlockState(instrumentPos).instrument();
|
||||
final Holder<SoundEvent> holder = instrument.getSoundEvent();
|
||||
soundEvent = holder.value();
|
||||
}
|
||||
discShelfBlockEntity.onNoteBlockPulse(level, pos, soundEvent);
|
||||
}
|
||||
|
||||
// Suppress vanilla note-block playback while it is on top of a TM Shelf.
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,6 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents;
|
||||
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle;
|
||||
import com.cobblemon.mod.common.api.riding.behaviour.types.air.HoverBehaviour;
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore;
|
||||
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
|
||||
@@ -61,7 +59,6 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@@ -172,32 +169,6 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "getDestroySpeed",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/player/Player;onGround()Z"
|
||||
)
|
||||
)
|
||||
private boolean cobblemon$considerHoverOnGround(Player player) {
|
||||
// If riding a Hover Mount, return true to bypass the 5x slowdown
|
||||
if (player.getVehicle() instanceof PokemonEntity vehicle) {
|
||||
|
||||
var ridingController = vehicle.getRidingController();
|
||||
if (ridingController == null) player.onGround();
|
||||
|
||||
var activeContext = ridingController.getContext();
|
||||
if (activeContext == null) player.onGround();
|
||||
|
||||
if (activeContext.getStyle() == RidingStyle.AIR &&
|
||||
activeContext.getBehaviour().equals(HoverBehaviour.Companion.getKEY())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Otherwise, return the actual value
|
||||
return player.onGround();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "eat",
|
||||
at = @At(
|
||||
|
||||
@@ -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.mixin;
|
||||
|
||||
import net.minecraft.stats.RecipeBookSettings;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(RecipeBookSettings.class)
|
||||
public class RecipeBookSettingsMixin {
|
||||
|
||||
|
||||
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void cobblemon$init(CallbackInfo ci) {
|
||||
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
|
||||
}
|
||||
}
|
||||
+2
-5
@@ -6,9 +6,8 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.fabric.mixin;
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -41,9 +40,7 @@ public class RecipeBookTypeMixin {
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookType> types = new ArrayList<>(List.of($VALUES));
|
||||
// if you change or add any of these, neoforge uses a separate mechanism
|
||||
// check enumextensions.json and `CobblemonEnumExtensions`
|
||||
types.add(cobblemon$createBookType(CobblemonRecipeBookTypes.COOKING_POT_NAME, $VALUES.length));
|
||||
types.add(cobblemon$createBookType("COOKING_POT", $VALUES.length));
|
||||
$VALUES = types.toArray(RecipeBookType[]::new);
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,8 @@ import com.cobblemon.mod.common.mixin.accessor.TrackedEntityAccessor;
|
||||
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateDriverInputPacket;
|
||||
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateOrientationPacket;
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.ClientboundUpdateRidingStatePacket;
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClientboundSeatAssignmentPacket;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerEntity;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -39,7 +37,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -56,15 +53,12 @@ public abstract class ServerEntityMixin {
|
||||
private Matrix3f cobblemon$lastSentOrientation;
|
||||
@Unique
|
||||
private boolean cobblemon$lastSentActive;
|
||||
@Unique
|
||||
private List<Entity> cobblemon$lastSeatPassengers = List.of();
|
||||
|
||||
@Inject(method = "sendChanges", at = @At("TAIL"))
|
||||
private void cobblemon$sendChanges(CallbackInfo ci) {
|
||||
cobblemon$sendOrientationChanges();
|
||||
cobblemon$sendRidingStateChanges();
|
||||
cobblemon$sendDriverInput();
|
||||
cobblemon$sendOccupiedSeatsChange();
|
||||
}
|
||||
|
||||
private void cobblemon$sendRidingStateChanges() {
|
||||
@@ -107,24 +101,6 @@ public abstract class ServerEntityMixin {
|
||||
cobblemon$broadcast(new ClientboundUpdateDriverInputPacket(driverInput, entity.getId()));
|
||||
}
|
||||
|
||||
private void cobblemon$sendOccupiedSeatsChange() {
|
||||
if (!(this.entity instanceof PokemonEntity pokemon)) return;
|
||||
|
||||
List<Entity> currentPassengers = pokemon.getPassengers();
|
||||
if (currentPassengers.equals(cobblemon$lastSeatPassengers)) return;
|
||||
cobblemon$lastSeatPassengers = List.copyOf(currentPassengers);
|
||||
|
||||
pokemon.getOccupiedSeats().forEach((seat, passenger) -> {
|
||||
if (seat.getLocator() == null) return;
|
||||
if (passenger == null) return;
|
||||
cobblemon$broadcast(new ClientboundSeatAssignmentPacket(
|
||||
passenger.getId(),
|
||||
pokemon.getId(),
|
||||
seat.getLocator()
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
private void cobblemon$broadcast(NetworkPacket<?> packet) {
|
||||
if (!(entity.level() instanceof ServerLevel level)) return;
|
||||
ChunkMap chunkMap = level.getChunkSource().chunkMap;
|
||||
@@ -139,4 +115,5 @@ public abstract class ServerEntityMixin {
|
||||
CobblemonNetwork.INSTANCE.sendPacketToPlayer(player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,15 +11,11 @@ package com.cobblemon.mod.common.mixin;
|
||||
import com.cobblemon.mod.common.Cobblemon;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.PlayerSpawnerAccessor;
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle;
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
|
||||
import com.cobblemon.mod.common.api.stats.CobblemonStats;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -93,32 +89,4 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
||||
private boolean cobblemon$cancelSavingPokemonMounts(boolean original, @Local(ordinal=0) Entity entity) {
|
||||
return original && !(entity instanceof PokemonEntity);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "checkRidingStatistics", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getVehicle()Lnet/minecraft/world/entity/Entity;"))
|
||||
public Entity cobblemon$checkRidingStatistics(ServerPlayer player, Operation<Entity> original, @Local int distance) {
|
||||
var entity = original.call(player);
|
||||
if (!(entity instanceof PokemonEntity pokemonEntity)) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
var ridingController = pokemonEntity.getRidingController();
|
||||
if (ridingController == null) return entity;
|
||||
|
||||
var activeContext = ridingController.getContext();
|
||||
if (activeContext == null) return entity;
|
||||
|
||||
var ridingStyle = activeContext.getStyle();
|
||||
CobblemonStats.CobblemonStat stat = switch (ridingStyle) {
|
||||
case RidingStyle.LAND -> CobblemonStats.RIDING_LAND;
|
||||
case RidingStyle.AIR -> CobblemonStats.RIDING_AIR;
|
||||
case RidingStyle.LIQUID -> CobblemonStats.RIDING_LIQUID;
|
||||
default -> null;
|
||||
};
|
||||
|
||||
if (stat != null) {
|
||||
player.awardStat(CobblemonStats.getStat(stat), distance);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import net.minecraft.client.sounds.ChannelAccess;
|
||||
import net.minecraft.client.sounds.SoundEngine;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@@ -33,7 +32,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -110,17 +108,6 @@ public abstract class SoundEngineMixin implements SoundEngineDuck {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TM Shelf can intentionally push note-block pitches above vanilla's 2.0f ceiling for octave-up playback.
|
||||
* Keep vanilla clamping for all other sounds.
|
||||
*/
|
||||
@Inject(method = "calculatePitch", at = @At("HEAD"), cancellable = true)
|
||||
private void cobblemon$allowExtendedNoteblockPitch(SoundInstance sound, CallbackInfoReturnable<Float> cir) {
|
||||
if (sound.getLocation().getPath().startsWith("block.note_block.")) {
|
||||
cir.setReturnValue(Mth.clamp(sound.getPitch(), 0.5F, 4.0F));
|
||||
}
|
||||
}
|
||||
|
||||
/** Different behavior for resuming SoundInstances while a BattleMusicInstance is being played. We do not want to resume filtered sounds. */
|
||||
@Inject(method = "resume()V", at = @At("HEAD"), cancellable = true)
|
||||
public void resume(CallbackInfo cb) {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.world.CobblemonStructureIDs;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(Structure.class)
|
||||
public abstract class StructureMixin {
|
||||
// Define a set of structures that should not spawn below Sea Level
|
||||
@Unique
|
||||
private static final Set<ResourceLocation> RESTRICTED_STRUCTURES = new HashSet<>(Arrays.asList(
|
||||
CobblemonStructureIDs.STONJOURNER_HENGE,
|
||||
CobblemonStructureIDs.LUNA_HENGE,
|
||||
CobblemonStructureIDs.SOL_HENGE
|
||||
));
|
||||
|
||||
@Inject(method = "generate", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/StructureStart;isValid()Z"),
|
||||
cancellable = true)
|
||||
public void cobblemon$isValid(RegistryAccess registryAccess, ChunkGenerator chunkGenerator, BiomeSource biomeSource,
|
||||
RandomState randomState, StructureTemplateManager structureTemplateManager, long seed,
|
||||
ChunkPos chunkPos, int references, LevelHeightAccessor heightAccessor,
|
||||
Predicate<Holder<Biome>> validBiome,
|
||||
CallbackInfoReturnable<StructureStart> cir,
|
||||
@Local StructureStart structureStart) {
|
||||
ResourceLocation structureKey = registryAccess.registryOrThrow(Registries.STRUCTURE).getKey((Structure) (Object) this);
|
||||
if(!RESTRICTED_STRUCTURES.contains(structureKey)) {
|
||||
return;
|
||||
}
|
||||
for (StructurePiece piece : structureStart.getPieces()) {
|
||||
if (piece.getBoundingBox().minY() < chunkGenerator.getSeaLevel()) {
|
||||
cir.setReturnValue(StructureStart.INVALID_START);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.accessor;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.core.dispenser.DispenseItemBehavior;
|
||||
import net.minecraft.world.level.block.DispenserBlock;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(DispenserBlock.class)
|
||||
public interface DispenserBlockAccessor {
|
||||
@Accessor("DISPENSER_REGISTRY")
|
||||
static Map<Item, DispenseItemBehavior> getItemBehaviors() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.accessor;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(SinglePoolElement.class)
|
||||
public interface SinglePoolElementAccessor {
|
||||
@Accessor("processors")
|
||||
Holder<StructureProcessorList> getProcessors();
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class AbstractClientPlayerMixin {
|
||||
cir.setReturnValue(usageContext.getFovMultiplier());
|
||||
} else {
|
||||
// Only modify fov through riding if the pokedex is not open
|
||||
AbstractClientPlayer player = (AbstractClientPlayer) (Object) this;
|
||||
LocalPlayer player = (LocalPlayer) (Object) this;
|
||||
// Only modify fov for the driver and not the passengers
|
||||
if (player != null && player.isPassenger() && player.getVehicle() instanceof PokemonEntity && player.getVehicle().getControllingPassenger() == player) {
|
||||
PokemonEntity ride = (PokemonEntity) player.getVehicle();
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.duck.ChannelDuck;
|
||||
import com.mojang.blaze3d.audio.Channel;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.AL11;
|
||||
import org.lwjgl.openal.EXTEfx;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(Channel.class)
|
||||
public abstract class ChannelMixin implements ChannelDuck {
|
||||
|
||||
@Shadow
|
||||
private int source;
|
||||
|
||||
// Ids of effects applied to the channel
|
||||
private int cobblemon$lowPassFilterId = 0;
|
||||
private int cobblemon$reverbEffectId = 0;
|
||||
private int cobblemon$reverbSlotId = 0;
|
||||
|
||||
@Override
|
||||
public void cobblemon$applyLowPassFilter(float gain, float hfGain) {
|
||||
// Delete old filter if it exists
|
||||
if (cobblemon$lowPassFilterId != 0) {
|
||||
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, 0); // Detach filter from source
|
||||
EXTEfx.alDeleteFilters(cobblemon$lowPassFilterId); // Delete old filter
|
||||
cobblemon$lowPassFilterId = 0;
|
||||
}
|
||||
|
||||
// Generate a fresh filter
|
||||
int filterId = EXTEfx.alGenFilters();
|
||||
if (!EXTEfx.alIsFilter(filterId)) {
|
||||
System.err.println("Failed to create OpenAL low-pass filter");
|
||||
return;
|
||||
}
|
||||
|
||||
EXTEfx.alFilteri(filterId, EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS);
|
||||
EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAIN, gain);
|
||||
EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAINHF, hfGain);
|
||||
|
||||
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, filterId);
|
||||
|
||||
// Save the new filter ID
|
||||
cobblemon$lowPassFilterId = filterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cobblemon$inverseAttenuation(float rolloffFactor) {
|
||||
AL10.alSourcei(source, AL10.AL_DISTANCE_MODEL, AL10.AL_INVERSE_DISTANCE);
|
||||
AL10.alSourcef(source, AL10.AL_ROLLOFF_FACTOR, rolloffFactor);
|
||||
AL10.alSourcef(source, AL10.AL_REFERENCE_DISTANCE, 1.0f);
|
||||
AL10.alSourcef(source, AL10.AL_MAX_DISTANCE, 0.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cobblemon$clearFilters() {
|
||||
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, 0);
|
||||
|
||||
if (EXTEfx.alIsFilter(cobblemon$lowPassFilterId)) {
|
||||
EXTEfx.alDeleteFilters(cobblemon$lowPassFilterId);
|
||||
cobblemon$lowPassFilterId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cobblemon$applyReverb(float decayTime, float gain, float diffusion, float density) {
|
||||
// Clean up existing reverb first if it exists
|
||||
cobblemon$clearReverb();
|
||||
|
||||
// Create the effect object
|
||||
int effectId = EXTEfx.alGenEffects();
|
||||
if (!EXTEfx.alIsEffect(effectId)) {
|
||||
System.err.println("Failed to create OpenAL reverb effect");
|
||||
return;
|
||||
}
|
||||
|
||||
EXTEfx.alEffecti(effectId, EXTEfx.AL_EFFECT_TYPE, EXTEfx.AL_EFFECT_REVERB);
|
||||
EXTEfx.alEffectf(effectId, EXTEfx.AL_REVERB_DECAY_TIME, decayTime);
|
||||
EXTEfx.alEffectf(effectId, EXTEfx.AL_REVERB_GAIN, gain);
|
||||
EXTEfx.alEffectf(effectId, EXTEfx.AL_REVERB_DIFFUSION, diffusion);
|
||||
EXTEfx.alEffectf(effectId, EXTEfx.AL_REVERB_DENSITY, density);
|
||||
|
||||
// Create auxiliary effect slot and load effect into it
|
||||
int slotId = EXTEfx.alGenAuxiliaryEffectSlots();
|
||||
if (!EXTEfx.alIsAuxiliaryEffectSlot(slotId)) {
|
||||
System.err.println("Failed to create OpenAL auxiliary effect slot");
|
||||
EXTEfx.alDeleteEffects(effectId);
|
||||
return;
|
||||
}
|
||||
|
||||
EXTEfx.alAuxiliaryEffectSloti(slotId, EXTEfx.AL_EFFECTSLOT_EFFECT, effectId);
|
||||
|
||||
// Route source through the slot — send 0, no direct filter
|
||||
AL11.alSource3i(source, EXTEfx.AL_AUXILIARY_SEND_FILTER, slotId, 0, EXTEfx.AL_FILTER_NULL);
|
||||
|
||||
cobblemon$reverbEffectId = effectId;
|
||||
cobblemon$reverbSlotId = slotId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cobblemon$clearReverb() {
|
||||
if (cobblemon$reverbSlotId != 0) {
|
||||
// Detach source from slot
|
||||
AL11.alSource3i(source, EXTEfx.AL_AUXILIARY_SEND_FILTER,
|
||||
EXTEfx.AL_EFFECTSLOT_NULL, 0, EXTEfx.AL_FILTER_NULL);
|
||||
EXTEfx.alDeleteAuxiliaryEffectSlots(cobblemon$reverbSlotId);
|
||||
cobblemon$reverbSlotId = 0;
|
||||
}
|
||||
if (cobblemon$reverbEffectId != 0) {
|
||||
EXTEfx.alDeleteEffects(cobblemon$reverbEffectId);
|
||||
cobblemon$reverbEffectId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,10 @@
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon;
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents;
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import com.cobblemon.mod.common.ModAPI;
|
||||
import com.cobblemon.mod.common.item.PokeBallItem;
|
||||
import com.cobblemon.mod.common.item.PokedexItem;
|
||||
import com.cobblemon.mod.common.item.WearableItem;
|
||||
import com.cobblemon.mod.common.item.components.TMMoveComponent;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.ItemModelShaper;
|
||||
@@ -57,17 +54,11 @@ public abstract class ItemRendererMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$overrideItemModel(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource multiBufferSource, int light, int overlay, BakedModel model, CallbackInfo ci) {
|
||||
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED || stack.getItem() == CobblemonItems.TECHNICAL_MACHINE;
|
||||
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED;
|
||||
ResourceLocation resourceLocation = null;
|
||||
if (shouldBe2d) {
|
||||
if (stack.getItem() instanceof PokeBallItem pokeBallItem) resourceLocation = pokeBallItem.getPokeBall().getModel2d();
|
||||
else if (stack.getItem() instanceof PokedexItem pokedexItem) resourceLocation = pokedexItem.getType().getItemSpritePath();
|
||||
else if (stack.getItem() == CobblemonItems.TECHNICAL_MACHINE) {
|
||||
TMMoveComponent component = stack.get(CobblemonItemComponents.TM_MOVE);
|
||||
if (component != null) {
|
||||
resourceLocation = new ResourceLocation(Cobblemon.MODID, "tm/" + component.getMove().getElementalType().showdownId() + "_tm");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renderMode != ItemDisplayContext.HEAD && stack.getItem() instanceof WearableItem wearableItem) resourceLocation = wearableItem.getModel2d();
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket;
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket;
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdatePassengerPositionPacket;
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateRiderRotationPacket;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.client.CameraType;
|
||||
@@ -149,22 +148,10 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
|
||||
cobblemon$lastRideYRot = rideYRot;
|
||||
cobblemon$lastRideEyePos = rideEyePos;
|
||||
|
||||
CobblemonNetwork.INSTANCE.sendToServer(
|
||||
new ServerboundUpdateRiderRotationPacket(rideXRot, rideYRot, rideEyePos)
|
||||
);
|
||||
CobblemonNetwork.INSTANCE.sendToServer(new ServerboundUpdateRiderRotationPacket(rideXRot, rideYRot, rideEyePos));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "rideTick", at = @At("TAIL"))
|
||||
private void cobblemon$updatePassengerPosition(CallbackInfo ci) {
|
||||
if (Minecraft.getInstance().player != (Object)this) return;
|
||||
if (!(this.getVehicle() instanceof PokemonEntity pokemonEntity)) return;
|
||||
if (pokemonEntity.getSeatForPassenger(this) == null) return;
|
||||
|
||||
var offset = this.position().subtract(pokemonEntity.position());
|
||||
CobblemonNetwork.INSTANCE.sendToServer(
|
||||
new ServerboundUpdatePassengerPositionPacket(this.getId(), offset)
|
||||
);
|
||||
}
|
||||
|
||||
@Unique
|
||||
@@ -230,10 +217,9 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
|
||||
private void cobblemon$isHandsBusy(CallbackInfoReturnable<Boolean> cir) {
|
||||
Entity vehicle = this.getVehicle();
|
||||
if (vehicle instanceof PokemonEntity pokemonEntity) {
|
||||
Seat seat = pokemonEntity.getSeatForPassenger(this);;
|
||||
if (seat != null) {
|
||||
cir.setReturnValue(seat.getHandsBusy());
|
||||
}
|
||||
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
|
||||
Seat seat = pokemonEntity.getSeats().get(seatIndex);
|
||||
cir.setReturnValue(seat.getHandsBusy());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.client.CobblemonBakingOverrides;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockStateModelLoader;
|
||||
@@ -17,76 +18,29 @@ import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(ModelBakery.class)
|
||||
public abstract class ModelLoaderMixin {
|
||||
|
||||
@Shadow abstract UnbakedModel getModel(ResourceLocation resourceLocation);
|
||||
|
||||
@Shadow protected abstract void registerModel(ModelResourceLocation modelId, UnbakedModel unbakedModel);
|
||||
|
||||
@Shadow protected abstract void loadItemModelAndDependencies(ResourceLocation resourceLocation);
|
||||
|
||||
@Unique
|
||||
List<String> dynamicFolders = Arrays.asList("egg", "tm");
|
||||
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V",
|
||||
ordinal = 1
|
||||
)
|
||||
)
|
||||
public void loadCustomItemModels(BlockColors blockColors,
|
||||
ProfilerFiller profiler,
|
||||
Map<ResourceLocation, BlockModel> jsonUnbakedModels,
|
||||
Map<ResourceLocation, List<BlockStateModelLoader.LoadedJson>> blockStates,
|
||||
CallbackInfo ci
|
||||
) {
|
||||
/*
|
||||
* The models/item/*.json's only get loaded if there's an item in the registry that actually asks for it. It
|
||||
* naively looks for things in the root with an item ID and calls upon it, and some of those JSONs reference
|
||||
* other model JSONs and so it cascades a little bit. Used for block models but more importantly here, sprites.
|
||||
*
|
||||
* The thing about the eggs (and TMs) is, we really want the eggs to be addon-compatible in a way that doesn't restrict
|
||||
* the species that can have eggs, so we can't pre-plan all of them. This mixin looks for the things inside the
|
||||
* egg subfolder (which won't get loaded automagically) and manually inserts them into the unbaked model list so
|
||||
* Minecraft loads them for us. We'll then dynamically call these models from the ItemRendererMixin; so it's
|
||||
* hacky at the init stage and hacky at the render stage. Pretty cool in the gameplay stage though.
|
||||
*
|
||||
* - Hiro
|
||||
*/
|
||||
|
||||
dynamicFolders.forEach(folder -> {
|
||||
Map<ResourceLocation, Resource> map = Minecraft.getInstance().getResourceManager().listResources("models/item/" + folder, (t) -> true);
|
||||
map.forEach((key, value) -> {
|
||||
ResourceLocation resourceLocation = new ResourceLocation(key.getNamespace(), key.getPath().replace("models/item/", "").replace(".json", ""));
|
||||
this.loadItemModelAndDependencies(resourceLocation);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At("TAIL")
|
||||
method = "<init>",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
public void init(BlockColors blockColors,
|
||||
ProfilerFiller profiler,
|
||||
Map<ResourceLocation, BlockModel> jsonUnbakedModels,
|
||||
Map<ResourceLocation, List<BlockStateModelLoader.LoadedJson>> blockStates,
|
||||
CallbackInfo ci) {
|
||||
ProfilerFiller profiler,
|
||||
Map<ResourceLocation, BlockModel> jsonUnbakedModels,
|
||||
Map<ResourceLocation, List<BlockStateModelLoader.LoadedJson>> blockStates,
|
||||
CallbackInfo ci) {
|
||||
CobblemonBakingOverrides.INSTANCE.getModels().forEach(bakingOverride -> {
|
||||
var unbakedModel = this.getModel(bakingOverride.getModelLocation());
|
||||
this.registerModel(bakingOverride.getModelIdentifier(), unbakedModel);
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.client.CobblemonClient;
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.RidingFreelookBinding;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
|
||||
@@ -35,7 +34,6 @@ import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import com.cobblemon.mod.common.client.gui.party.PartyTutorialToasts;
|
||||
|
||||
import static com.google.common.primitives.Floats.min;
|
||||
import static net.minecraft.util.Mth.lerp;
|
||||
@@ -86,13 +84,11 @@ public abstract class MouseHandlerMixin {
|
||||
CobblemonClient.INSTANCE.getStorage().shiftSelected(false);
|
||||
ci.cancel();
|
||||
PartySendBinding.INSTANCE.actioned();
|
||||
PartyTutorialToasts.INSTANCE.onHoldKeyScrollSwitchedSlot();
|
||||
} else if (i < 0) {
|
||||
accumulatedScrollY -= i;
|
||||
CobblemonClient.INSTANCE.getStorage().shiftSelected(true);
|
||||
ci.cancel();
|
||||
PartySendBinding.INSTANCE.actioned();
|
||||
PartyTutorialToasts.INSTANCE.onHoldKeyScrollSwitchedSlot();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,7 +156,7 @@ public abstract class MouseHandlerMixin {
|
||||
}
|
||||
|
||||
var vehicleController = controllableVehicle.getOrientationController();
|
||||
var freeLooking = RidingFreelookBinding.INSTANCE.isDown();
|
||||
var lookaroundButtonPressed = Minecraft.getInstance().mouseHandler.isMiddlePressed();
|
||||
Pair<Boolean, Boolean> mouseShouldModifyDriver = ((PokemonEntity) vehicle).ifRidingAvailableSupply(new Pair(false, false), (behaviour, settings, state) -> {
|
||||
return behaviour.mouseModifiesDriverRotation(
|
||||
settings,
|
||||
@@ -174,7 +170,7 @@ public abstract class MouseHandlerMixin {
|
||||
// affect the vehicle orientation when looking around.
|
||||
// If the client is a passenger it will modify these rotations and return
|
||||
//-------------------------------------------------------------------------
|
||||
if (freeLooking || player.getControlledVehicle() == null) {
|
||||
if (lookaroundButtonPressed || player.getControlledVehicle() == null) {
|
||||
// Modify driver rotations
|
||||
cobblemon$setDriverRotations(player, cursorDeltaX, cursorDeltaY);
|
||||
|
||||
@@ -196,10 +192,10 @@ public abstract class MouseHandlerMixin {
|
||||
// Smoothly return driver rotations to zero when needed
|
||||
//-------------------------------------------------------------------------
|
||||
var playerRotater = (RidePassenger)player;
|
||||
if( !freeLooking && !mouseShouldModifyDriver.getFirst()){
|
||||
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getFirst()){
|
||||
playerRotater.cobblemon$setRideYRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideYRot()), 0.0f));
|
||||
}
|
||||
if( !freeLooking && !mouseShouldModifyDriver.getSecond()) {
|
||||
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getSecond()) {
|
||||
playerRotater.cobblemon$setRideXRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideXRot()), 0.0f));
|
||||
}
|
||||
|
||||
@@ -313,7 +309,7 @@ public abstract class MouseHandlerMixin {
|
||||
var playerRotater = (RidePassenger)player;
|
||||
playerRotater.cobblemon$setRideXRot(playerRotater.cobblemon$getRideXRot() + f);
|
||||
playerRotater.cobblemon$setRideYRot(playerRotater.cobblemon$getRideYRot() + g);
|
||||
playerRotater.cobblemon$setRideXRot(Mth.clamp(playerRotater.cobblemon$getRideXRot(), -89.0F, 89.0F));
|
||||
playerRotater.cobblemon$setRideXRot(Mth.clamp(playerRotater.cobblemon$getRideXRot(), -90.0F, 90.0F));
|
||||
playerRotater.cobblemon$setRideYRot(Mth.clamp(playerRotater.cobblemon$getRideYRot(), -105.0F, 105.0F));
|
||||
if (player.getVehicle() != null) {
|
||||
player.getVehicle().onPassengerTurned(player);
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mixin(RecipeBookCategories.class)
|
||||
public class RecipeBookCategoriesMixin {
|
||||
|
||||
@Final
|
||||
@Mutable
|
||||
@Shadow
|
||||
private static RecipeBookCategories[] $VALUES;
|
||||
|
||||
@Invoker("<init>")
|
||||
private static RecipeBookCategories cobblemon$createCategory(String name, int ordinal, ItemStack... icons) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<clinit>",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookCategories> types = new ArrayList<>(List.of($VALUES));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
|
||||
$VALUES = types.toArray(RecipeBookCategories[]::new);
|
||||
}
|
||||
|
||||
@Inject(method = "getCategories", at = @At("HEAD"), cancellable = true)
|
||||
private static void modifyCategories(RecipeBookType recipeBookType, CallbackInfoReturnable<List<RecipeBookCategories>> cir) {
|
||||
if (recipeBookType == RecipeBookType.valueOf("COOKING_POT")) {
|
||||
List var10000 = ImmutableList.of(
|
||||
CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_MEDICINES.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_COMPLEX_DISHES.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_MISC.toVanillaCategory());
|
||||
cir.setReturnValue(var10000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,17 +11,11 @@ package com.cobblemon.mod.common.mixin.entity;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -29,7 +23,6 @@ import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -55,8 +48,16 @@ public abstract class EntityMixin {
|
||||
)
|
||||
)
|
||||
public boolean cobblemon$forceOnGroundForStepUp(Entity entity, Operation<Boolean> original) {
|
||||
if (entity instanceof PokemonEntity vehicle && entity.hasControllingPassenger()) {
|
||||
return true;
|
||||
if (entity instanceof PokemonEntity && entity.hasControllingPassenger()) {
|
||||
BlockPos below = entity.blockPosition().below();
|
||||
Level level = entity.level();
|
||||
var blockStateBelow = level.getBlockState(below);
|
||||
boolean isAirOrLiquid = blockStateBelow.isAir() || !blockStateBelow.getFluidState().isEmpty();
|
||||
boolean canSupportEntity = blockStateBelow.isFaceSturdy(level, below, Direction.UP);
|
||||
boolean standingOnSolid = canSupportEntity && !isAirOrLiquid;
|
||||
if (standingOnSolid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return original.call(entity);
|
||||
}
|
||||
@@ -67,7 +68,18 @@ public abstract class EntityMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$modifyEyePosition_partial(float partialTicks, CallbackInfoReturnable<Vec3> cir) {
|
||||
cobblemon$getCustomEyePos(cir);
|
||||
var entity = (Entity)(Object)this;
|
||||
if (entity.level().isClientSide) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
if (!(player instanceof RidePassenger ridePassenger)) return;
|
||||
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
|
||||
var vehicleController = vehicle.getOrientationController();
|
||||
if (vehicleController == null) return;
|
||||
|
||||
|
||||
// TODO: Determine if it needs partialtick involved.
|
||||
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
|
||||
cir.setReturnValue(customEyePos);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -76,79 +88,17 @@ public abstract class EntityMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$modifyEyePosition_noPartial(CallbackInfoReturnable<Vec3> cir) {
|
||||
cobblemon$getCustomEyePos(cir);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void cobblemon$getCustomEyePos(CallbackInfoReturnable<Vec3> cir) {
|
||||
var entity = (Entity)(Object)this;
|
||||
if (entity.level().isClientSide) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
if (!(player instanceof RidePassenger ridePassenger)) return;
|
||||
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
|
||||
if (!(vehicle instanceof PokemonEntity)) return;
|
||||
var vehicleController = vehicle.getOrientationController();
|
||||
if (vehicleController == null) return;
|
||||
|
||||
// TODO: Determine if it needs partialtick involved.
|
||||
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
|
||||
cir.setReturnValue(customEyePos);
|
||||
}
|
||||
|
||||
|
||||
@WrapOperation(
|
||||
method = "push(Lnet/minecraft/world/entity/Entity;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(DDD)V", ordinal = 0)
|
||||
)
|
||||
public void cobblemon$customPusherLogic(Entity pusher, double x, double y, double z,
|
||||
Operation<Void> original,
|
||||
@Local(argsOnly = true) Entity pushee,
|
||||
@Local(name = "e") double e, @Local(name = "d") double d,
|
||||
@Share("pusherIsPlayerOrPokemon") LocalBooleanRef pusherIsPlayerOrPokemon,
|
||||
@Share("pusheeIsPlayerOrPokemon") LocalBooleanRef pusheeIsPlayerOrPokemon,
|
||||
@Share("pusheeReceivedForce")LocalFloatRef pusheeReceivedForce) {
|
||||
pusherIsPlayerOrPokemon.set(pusher instanceof PokemonEntity || pusher instanceof Player);
|
||||
pusheeIsPlayerOrPokemon.set(pushee instanceof PokemonEntity || pushee instanceof Player);
|
||||
|
||||
if (!pusheeIsPlayerOrPokemon.get() || !pusherIsPlayerOrPokemon.get()) {
|
||||
original.call(pusher, x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
* Custom portion of the code:
|
||||
* Handle collisions with weight in mind. Use
|
||||
* the weight value of pokemon to determine
|
||||
* which side gets what portion of the total
|
||||
* force.
|
||||
*********************************************/
|
||||
// Weights in hectograms
|
||||
// Check to see if the pusher or pushee is a player. 200ish pounds. Steve's like a 6'6 miner
|
||||
var pusherWeight = pusher instanceof PokemonEntity pusherPokemon ? pusherPokemon.getPokemon().getSpecies().getWeight() : 900F;
|
||||
var pusheeWeight = pushee instanceof PokemonEntity pusheePokemon ? pusheePokemon.getPokemon().getSpecies().getWeight() : 900F;
|
||||
|
||||
// Calculate the portion of force received for both entities. Bigger receives less from the
|
||||
// collision than the smaller one.
|
||||
var totalWeight = pusherWeight + pusheeWeight;
|
||||
var pusherReceivedForce = pusheeWeight / totalWeight * 2F;
|
||||
pusheeReceivedForce.set((pusherWeight / totalWeight) * 2F);
|
||||
|
||||
original.call(pusher, -d * pusherReceivedForce, 0.0, -e * pusherReceivedForce);
|
||||
}
|
||||
|
||||
@WrapOperation(
|
||||
method = "push(Lnet/minecraft/world/entity/Entity;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(DDD)V", ordinal = 1)
|
||||
)
|
||||
public void cobblemon$customPusheeLogic(Entity pusher, double x, double y, double z, Operation<Void> original,
|
||||
@Local(name = "e") double e, @Local(name = "d") double d,
|
||||
@Share("pusherIsPlayerOrPokemon") LocalBooleanRef pusherIsPlayerOrPokemon,
|
||||
@Share("pusheeIsPlayerOrPokemon") LocalBooleanRef pusheeIsPlayerOrPokemon,
|
||||
@Share("pusheeReceivedForce")LocalFloatRef pusheeReceivedForce) {
|
||||
if (!pusheeIsPlayerOrPokemon.get() || !pusherIsPlayerOrPokemon.get()) {
|
||||
original.call(pusher, x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
original.call(pusher, d * pusheeReceivedForce.get(), 0.0, e * pusheeReceivedForce.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import com.cobblemon.mod.common.api.drop.EvolutionItemDropEntry
|
||||
import com.cobblemon.mod.common.api.drop.ItemDropEntry
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
|
||||
import com.cobblemon.mod.common.api.habitats.HabitatPools
|
||||
import com.cobblemon.mod.common.api.interaction.RequestManager
|
||||
import com.cobblemon.mod.common.api.molang.MoLangLoadedFilesCache
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
@@ -34,7 +33,6 @@ import com.cobblemon.mod.common.api.pokemon.feature.ChoiceSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.FlagSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.WeightedChoiceSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.helditem.HeldItemProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.EvCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Generation8EvCalculator
|
||||
@@ -44,8 +42,8 @@ import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePositionResolver
|
||||
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.starter.StarterHandler
|
||||
import com.cobblemon.mod.common.api.stats.CobblemonStats
|
||||
import com.cobblemon.mod.common.api.storage.PokemonStoreManager
|
||||
@@ -64,19 +62,13 @@ import com.cobblemon.mod.common.api.storage.player.adapter.DexDataMongoBackend
|
||||
import com.cobblemon.mod.common.api.storage.player.adapter.DexDataNbtBackend
|
||||
import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataJsonBackend
|
||||
import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataMongoBackend
|
||||
import com.cobblemon.mod.common.api.storage.player.adapter.TMMoveMongoBackend
|
||||
import com.cobblemon.mod.common.api.storage.player.adapter.TMMoveNbtBackend
|
||||
import com.cobblemon.mod.common.api.storage.player.factory.CachedPlayerDataStoreFactory
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.battles.BagItems
|
||||
import com.cobblemon.mod.common.battles.BattleFormat
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.battles.BattleSide
|
||||
import com.cobblemon.mod.common.battles.ShowdownThread
|
||||
import com.cobblemon.mod.common.battles.*
|
||||
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.block.dispenser.DispenserBehaviorRegistry
|
||||
import com.cobblemon.mod.common.block.DispenserBehaviorRegistry
|
||||
import com.cobblemon.mod.common.client.CobblemonPack
|
||||
import com.cobblemon.mod.common.command.argument.*
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
@@ -85,8 +77,8 @@ import com.cobblemon.mod.common.config.constraint.IntConstraint
|
||||
import com.cobblemon.mod.common.config.starter.StarterConfig
|
||||
import com.cobblemon.mod.common.data.CobblemonDataProvider
|
||||
import com.cobblemon.mod.common.events.AdvancementHandler
|
||||
import com.cobblemon.mod.common.events.CallbackHandler
|
||||
import com.cobblemon.mod.common.events.EntityCallbackHandler
|
||||
import com.cobblemon.mod.common.events.CallbackHandler
|
||||
import com.cobblemon.mod.common.events.PokedexHandler
|
||||
import com.cobblemon.mod.common.events.ServerTickHandler
|
||||
import com.cobblemon.mod.common.events.StatHandler
|
||||
@@ -94,25 +86,17 @@ import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacke
|
||||
import com.cobblemon.mod.common.permission.LaxPermissionValidator
|
||||
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.aspects.ALPHA_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.aspects.CHARACTERISTIC_RAINBOW_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.aspects.COSMETIC_SLOT_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.aspects.MARK_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
|
||||
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeature
|
||||
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.BattleCloneProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.LabelProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.*
|
||||
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
|
||||
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
||||
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
||||
import com.cobblemon.mod.common.util.*
|
||||
@@ -123,17 +107,6 @@ import com.mongodb.ConnectionString
|
||||
import com.mongodb.MongoClientSettings
|
||||
import com.mongodb.client.MongoClient
|
||||
import com.mongodb.client.MongoClients
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
import java.io.PrintWriter
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.commands.synchronization.SingletonArgumentInfo
|
||||
import net.minecraft.resources.ResourceKey
|
||||
@@ -146,6 +119,17 @@ import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.storage.LevelResource
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
import java.io.PrintWriter
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
object Cobblemon {
|
||||
const val MODID = CobblemonBuildDetails.MOD_ID
|
||||
@@ -186,7 +170,7 @@ object Cobblemon {
|
||||
val statistics: CobblemonStats = CobblemonStats
|
||||
|
||||
@JvmStatic
|
||||
val builtinPacks = listOf(
|
||||
val builtinPacks = listOf<CobblemonPack>(
|
||||
CobblemonPack(id = "adorncompatibility", name = "Adorn Compatibility", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.ALWAYS_ENABLED, neededMods = setOf("adorn")),
|
||||
CobblemonPack(id = "gyaradosjump", name = "Gyarados Jump Patterns", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.DEFAULT_ENABLED),
|
||||
CobblemonPack(id = "regionbiasforms", name = "Region Bias Forms", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.DEFAULT_ENABLED),
|
||||
@@ -222,7 +206,6 @@ object Cobblemon {
|
||||
implementation.registerEntityDataSerializers()
|
||||
implementation.registerCriteria()
|
||||
implementation.registerEntitySubPredicates()
|
||||
implementation.registerMobEffects()
|
||||
DispenserBehaviorRegistry.registerDispenserBehaviors()
|
||||
|
||||
DropEntry.register("command", CommandDropEntry::class.java)
|
||||
@@ -244,8 +227,6 @@ object Cobblemon {
|
||||
|
||||
DATA_SYNCHRONIZED.subscribe {
|
||||
storage.onPlayerDataSync(it)
|
||||
it.tmList().scheduleFullSyncFromStores(it.party(), it.pc())
|
||||
it.pokedex().scheduleFullSyncFromStores(it.party(), it.pc())
|
||||
playerDataManager.syncAllToPlayer(it)
|
||||
starterHandler.handleJoin(it)
|
||||
it.requestWallpapers()
|
||||
@@ -308,9 +289,6 @@ object Cobblemon {
|
||||
this.config.maxPokemonLevel,
|
||||
this.config.maxPokemonFriendship,
|
||||
this.config.maxDynamaxLevel,
|
||||
this.config.unlockAllMoveDexMovesByDefault,
|
||||
this.config.pokemonIntrinsicSizeMin,
|
||||
this.config.pokemonIntrinsicSizeMax
|
||||
).sendToPlayer(player)
|
||||
}
|
||||
|
||||
@@ -324,11 +302,8 @@ object Cobblemon {
|
||||
GENDER_ASPECT.register()
|
||||
COSMETIC_SLOT_ASPECT.register()
|
||||
CHARACTERISTIC_RAINBOW_ASPECT.register()
|
||||
ALPHA_ASPECT.register()
|
||||
MARK_ASPECT.register()
|
||||
|
||||
SpeciesFeatures.types["choice"] = ChoiceSpeciesFeatureProvider::class.java
|
||||
SpeciesFeatures.types["weighted_choice"] = WeightedChoiceSpeciesFeatureProvider::class.java
|
||||
SpeciesFeatures.types["flag"] = FlagSpeciesFeatureProvider::class.java
|
||||
SpeciesFeatures.types["integer"] = IntSpeciesFeatureProvider::class.java
|
||||
|
||||
@@ -344,7 +319,7 @@ object Cobblemon {
|
||||
|
||||
CustomPokemonProperty.register(UncatchableProperty)
|
||||
CustomPokemonProperty.register(BattleCloneProperty)
|
||||
CustomPokemonProperty.register(LabelProperty)
|
||||
CustomPokemonProperty.register(PokemonFlagProperty)
|
||||
CustomPokemonProperty.register(HiddenAbilityPropertyType)
|
||||
CustomPokemonProperty.register(AspectPropertyType)
|
||||
CustomPokemonProperty.register(UnaspectPropertyType)
|
||||
@@ -371,7 +346,6 @@ object Cobblemon {
|
||||
val server = event.server
|
||||
MoLangLoadedFilesCache.initialize(server)
|
||||
playerDataManager = PlayerInstancedDataStoreManager().also { it.setup(server) }
|
||||
HabitatPools.onServerLoading(server)
|
||||
|
||||
val mongoClient: MongoClient?
|
||||
|
||||
@@ -384,12 +358,8 @@ object Cobblemon {
|
||||
val pokedexNbtFactory = CachedPlayerDataStoreFactory(DexDataNbtBackend())
|
||||
pokedexNbtFactory.setup(server)
|
||||
|
||||
val tmMoveFactory = CachedPlayerDataStoreFactory(TMMoveNbtBackend())
|
||||
tmMoveFactory.setup(server)
|
||||
|
||||
playerDataManager.setFactory(generalJsonFactory, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
playerDataManager.setFactory(pokedexNbtFactory, PlayerInstancedDataStoreTypes.POKEDEX)
|
||||
playerDataManager.setFactory(tmMoveFactory, PlayerInstancedDataStoreTypes.TM_MOVES)
|
||||
|
||||
if (config.storageFormat == "nbt") {
|
||||
NBTStoreAdapter(pokemonStoreRoot.absolutePath, useNestedFolders = true, folderPerClass = true)
|
||||
@@ -416,14 +386,8 @@ object Cobblemon {
|
||||
val pokedexMongoFactory = CachedPlayerDataStoreFactory(DexDataMongoBackend(mongoClient, config.mongoDBDatabaseName, "PokeDexCollection"))
|
||||
pokedexMongoFactory.setup(server)
|
||||
|
||||
val tmMovesMongoFactory = CachedPlayerDataStoreFactory(
|
||||
TMMoveMongoBackend(mongoClient, config.mongoDBDatabaseName, "TMMovesCollection")
|
||||
)
|
||||
tmMovesMongoFactory.setup(server)
|
||||
|
||||
playerDataManager.setFactory(generalMongoFactory, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
playerDataManager.setFactory(pokedexMongoFactory, PlayerInstancedDataStoreTypes.POKEDEX)
|
||||
playerDataManager.setFactory(tmMovesMongoFactory, PlayerInstancedDataStoreTypes.TM_MOVES)
|
||||
MongoDBStoreAdapter(mongoClient, config.mongoDBDatabaseName)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
LOGGER.error("MongoDB driver not found.")
|
||||
@@ -491,7 +455,7 @@ object Cobblemon {
|
||||
server()?.getLevel(dimension)
|
||||
} else {
|
||||
val mc = Minecraft.getInstance()
|
||||
mc.singleplayerServer?.getLevel(dimension) ?: mc.level
|
||||
return mc.singleplayerServer?.getLevel(dimension) ?: mc.level
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,7 +571,6 @@ object Cobblemon {
|
||||
this.implementation.registerCommandArgument(cobblemonResource("mark"), MarkArgumentType::class, SingletonArgumentInfo.contextFree(MarkArgumentType::mark))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("transform_type"), TransformTypeArgumentType::class, SingletonArgumentInfo.contextFree(TransformTypeArgumentType::transformType))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("model_part"), ModelPartArgumentType::class, SingletonArgumentInfo.contextFree(ModelPartArgumentType::modelPart))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("tm"), TmArgumentType::class, SingletonArgumentInfo.contextFree(TmArgumentType::tm))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,15 +8,22 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.block.entity.*
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.PCBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.FossilAnalyzerBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.FossilMultiblockEntity
|
||||
import com.cobblemon.mod.common.block.entity.RestorationTankBlockEntity
|
||||
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockBuilder
|
||||
import com.cobblemon.mod.common.block.entity.*
|
||||
import com.cobblemon.mod.common.block.entity.DisplayCaseBlockEntity
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.resources.ResourceKey
|
||||
|
||||
object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, ResourceKey<Registry<BlockEntityType<*>>>, BlockEntityType<*>>() {
|
||||
|
||||
@@ -32,9 +39,6 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
@JvmField
|
||||
val LECTERN: BlockEntityType<LecternBlockEntity> = this.create("lectern", BlockEntityType.Builder.of(::LecternBlockEntity, CobblemonBlocks.LECTERN).build(null))
|
||||
|
||||
@JvmField
|
||||
val DISC_SHELF: BlockEntityType<DiscShelfBlockEntity> = this.create("disc_shelf", BlockEntityType.Builder.of(::DiscShelfBlockEntity, CobblemonBlocks.DISC_SHELF).build(null))
|
||||
|
||||
@JvmField
|
||||
val BERRY = this.create("berry", BlockEntityType.Builder.of(::BerryBlockEntity, *CobblemonBlocks.berries().values.toTypedArray()).build(null))
|
||||
|
||||
@@ -44,13 +48,6 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.of(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN, CobblemonBlocks.SACCHARINE_SIGN, CobblemonBlocks.SACCHARINE_WALL_SIGN).build(null))
|
||||
@JvmField
|
||||
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.of(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN, CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN).build(null))
|
||||
@JvmField
|
||||
val TM_MACHINE: BlockEntityType<TMMachineBlockEntity> = this.create("tm_machine", BlockEntityType.Builder.of(::TMMachineBlockEntity, CobblemonBlocks.TM_MACHINE).build(null))
|
||||
|
||||
@JvmField
|
||||
val HABITAT_BLOCK: BlockEntityType<HabitatBlockEntity> = this.create("habitat_block",
|
||||
BlockEntityType.Builder.of(::HabitatBlockEntity, CobblemonBlocks.HABITAT_BLOCK).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST: BlockEntityType<GildedChestBlockEntity> = this.create("chest", BlockEntityType.Builder.of(::GildedChestBlockEntity,
|
||||
|
||||
@@ -9,29 +9,21 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
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.campfirepot.CampfireBlock
|
||||
import com.cobblemon.mod.common.block.LecternBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
|
||||
import com.cobblemon.mod.common.block.chest.GildedChestBlock
|
||||
import com.cobblemon.mod.common.block.general.BaleBlock
|
||||
import com.cobblemon.mod.common.block.general.HorizontalRotationCarpetBlock
|
||||
import com.cobblemon.mod.common.block.general.HorizontalRotationalBlock
|
||||
import com.cobblemon.mod.common.block.grower.SaccharineTreeGrower
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
|
||||
import com.cobblemon.mod.common.block.tmmachine.TMMachineBlock
|
||||
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.block.general.HorizontalRotationCarpetBlock
|
||||
import com.cobblemon.mod.common.block.general.HorizontalRotationalBlock
|
||||
import com.cobblemon.mod.common.mixin.invoker.*
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.BlockPos
|
||||
@@ -49,6 +41,7 @@ import net.minecraft.world.level.block.state.BlockBehaviour
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.properties.BlockSetType
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT
|
||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument
|
||||
import net.minecraft.world.level.block.state.properties.WoodType
|
||||
import net.minecraft.world.level.material.MapColor
|
||||
@@ -127,19 +120,19 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
val APRICORN_PLANKS = this.create("apricorn_planks",
|
||||
Block(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.DIRT).instrument(NoteBlockInstrument.BASS)
|
||||
.strength(2.0F, 3.0F).sound(SoundType.WOOD)
|
||||
.strength(2.0f, 3.0f).sound(SoundType.WOOD)
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val APRICORN_LEAVES = leaves("apricorn_leaves")
|
||||
@JvmField
|
||||
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0F, 3.0F).sound(SoundType.WOOD)))
|
||||
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(APRICORN_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).strength(2.0F, 3.0F).sound(SoundType.WOOD).ignitedByLava().forceSolidOn()))
|
||||
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(APRICORN_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).strength(2.0f, 3.0f).sound(SoundType.WOOD).ignitedByLava().forceSolidOn()))
|
||||
@JvmField
|
||||
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(APRICORN_BLOCK_SET_TYPE))
|
||||
@JvmField
|
||||
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(APRICORN_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).noCollission().strength(0.5F).sound(SoundType.WOOD)))
|
||||
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(APRICORN_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).noCollission().strength(0.5f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val APRICORN_SIGN = this.create("apricorn_sign", CobblemonSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), APRICORN_WOOD_TYPE))
|
||||
|
||||
@@ -156,7 +149,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val APRICORN_WALL_HANGING_SIGN = this.create("apricorn_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), APRICORN_WOOD_TYPE))
|
||||
@JvmField
|
||||
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.0F, 3.0F).sound(SoundType.WOOD)))
|
||||
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val APRICORN_STAIRS = this.create("apricorn_stairs", StairsBlockInvoker.`cobblemon$create`(APRICORN_PLANKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(APRICORN_PLANKS)))
|
||||
@JvmField
|
||||
@@ -193,12 +186,12 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val STRIPPED_SACCHARINE_WOOD = this.create("stripped_saccharine_wood", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
|
||||
@JvmField
|
||||
val SACCHARINE_PLANKS = this.create("saccharine_planks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F, 3.0F).sound(SoundType.WOOD)))
|
||||
val SACCHARINE_PLANKS = this.create("saccharine_planks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_LEAVES = this.create("saccharine_leaves", SaccharineLeafBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(
|
||||
MapColor.PLANT
|
||||
).strength(0.2F).randomTicks().sound(SoundType.GRASS).noOcclusion()
|
||||
).strength(0.2f).randomTicks().sound(SoundType.GRASS).noOcclusion()
|
||||
.isValidSpawn { _: BlockState?, _: BlockGetter?, _: BlockPos?, entity: EntityType<*>? ->
|
||||
entity === EntityType.OCELOT || entity === EntityType.PARROT
|
||||
}.isSuffocating { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
|
||||
@@ -210,23 +203,23 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
false
|
||||
}))
|
||||
@JvmField
|
||||
val SACCHARINE_FENCE = this.create("saccharine_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0F, 3.0F).sound(SoundType.WOOD)))
|
||||
val SACCHARINE_FENCE = this.create("saccharine_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_FENCE_GATE = this.create("saccharine_fence_gate", FenceGateBlock(SACCHARINE_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0F, 3.0F).sound(SoundType.WOOD).ignitedByLava().forceSolidOn()))
|
||||
val SACCHARINE_FENCE_GATE = this.create("saccharine_fence_gate", FenceGateBlock(SACCHARINE_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD).ignitedByLava().forceSolidOn()))
|
||||
@JvmField
|
||||
val SACCHARINE_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
|
||||
@JvmField
|
||||
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5F).sound(SoundType.WOOD)))
|
||||
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_SIGN = this.create("saccharine_sign", CobblemonSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_SLAB = this.create("saccharine_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.0F, 3.0F).sound(SoundType.WOOD)))
|
||||
val SACCHARINE_SLAB = this.create("saccharine_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_STAIRS = this.create("saccharine_stairs", StairsBlockInvoker.`cobblemon$create`(SACCHARINE_PLANKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SACCHARINE_PLANKS)))
|
||||
@JvmField
|
||||
@@ -250,36 +243,36 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.PLANT).ignitedByLava().noCollission().instabreak().sound(CobblemonSounds.REVIVAL_HERB_SOUNDS)))
|
||||
|
||||
@JvmField
|
||||
val POKE_CAKE = this.create("poke_cake", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(BlockStateProperties.LIT)) 3 else 0 }, false))
|
||||
val POKE_CAKE = this.create("poke_cake", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(LIT)) 3 else 0 }, false))
|
||||
@JvmField
|
||||
val POKE_SNACK = this.create("poke_snack", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(BlockStateProperties.LIT)) 3 else 0 }, true))
|
||||
val POKE_SNACK = this.create("poke_snack", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(LIT)) 3 else 0 }, true))
|
||||
|
||||
@JvmField
|
||||
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", TumblestoneBlock.STAGE_3, 7, 3, null, MapColor.TERRACOTTA_ORANGE)
|
||||
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
|
||||
@JvmField
|
||||
val LARGE_BUDDING_TUMBLESTONE = tumblestoneBlock("large_budding_tumblestone", TumblestoneBlock.STAGE_2, 5, 3, TUMBLESTONE_CLUSTER, MapColor.TERRACOTTA_ORANGE)
|
||||
val LARGE_BUDDING_TUMBLESTONE = tumblestoneBlock("large_budding_tumblestone", GrowableStoneBlock.STAGE_2, 5, 3, TUMBLESTONE_CLUSTER)
|
||||
@JvmField
|
||||
val MEDIUM_BUDDING_TUMBLESTONE = tumblestoneBlock("medium_budding_tumblestone", TumblestoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_TUMBLESTONE, MapColor.TERRACOTTA_ORANGE)
|
||||
val MEDIUM_BUDDING_TUMBLESTONE = tumblestoneBlock("medium_budding_tumblestone", GrowableStoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_TUMBLESTONE)
|
||||
@JvmField
|
||||
val SMALL_BUDDING_TUMBLESTONE = tumblestoneBlock("small_budding_tumblestone", TumblestoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_TUMBLESTONE, MapColor.TERRACOTTA_ORANGE)
|
||||
val SMALL_BUDDING_TUMBLESTONE = tumblestoneBlock("small_budding_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_TUMBLESTONE)
|
||||
|
||||
@JvmField
|
||||
val SKY_TUMBLESTONE_CLUSTER = tumblestoneBlock("sky_tumblestone_cluster", TumblestoneBlock.STAGE_3, 7, 3, null, MapColor.COLOR_LIGHT_BLUE)
|
||||
val SKY_TUMBLESTONE_CLUSTER = tumblestoneBlock("sky_tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
|
||||
@JvmField
|
||||
val LARGE_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("large_budding_sky_tumblestone", TumblestoneBlock.STAGE_2, 5, 3, SKY_TUMBLESTONE_CLUSTER, MapColor.COLOR_LIGHT_BLUE)
|
||||
val LARGE_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("large_budding_sky_tumblestone", GrowableStoneBlock.STAGE_2, 5, 3, SKY_TUMBLESTONE_CLUSTER)
|
||||
@JvmField
|
||||
val MEDIUM_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("medium_budding_sky_tumblestone", TumblestoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_SKY_TUMBLESTONE, MapColor.COLOR_LIGHT_BLUE)
|
||||
val MEDIUM_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("medium_budding_sky_tumblestone", GrowableStoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_SKY_TUMBLESTONE)
|
||||
@JvmField
|
||||
val SMALL_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("small_budding_sky_tumblestone", TumblestoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_SKY_TUMBLESTONE, MapColor.COLOR_LIGHT_BLUE)
|
||||
val SMALL_BUDDING_SKY_TUMBLESTONE = tumblestoneBlock("small_budding_sky_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_SKY_TUMBLESTONE)
|
||||
|
||||
@JvmField
|
||||
val BLACK_TUMBLESTONE_CLUSTER = tumblestoneBlock("black_tumblestone_cluster", TumblestoneBlock.STAGE_3, 7, 3, null, MapColor.TERRACOTTA_BLACK)
|
||||
val BLACK_TUMBLESTONE_CLUSTER = tumblestoneBlock("black_tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
|
||||
@JvmField
|
||||
val LARGE_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("large_budding_black_tumblestone", TumblestoneBlock.STAGE_2, 5, 3, BLACK_TUMBLESTONE_CLUSTER, MapColor.TERRACOTTA_BLACK)
|
||||
val LARGE_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("large_budding_black_tumblestone", GrowableStoneBlock.STAGE_2, 5, 3, BLACK_TUMBLESTONE_CLUSTER)
|
||||
@JvmField
|
||||
val MEDIUM_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("medium_budding_black_tumblestone", TumblestoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_BLACK_TUMBLESTONE, MapColor.TERRACOTTA_BLACK)
|
||||
val MEDIUM_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("medium_budding_black_tumblestone", GrowableStoneBlock.STAGE_1, 4, 3, LARGE_BUDDING_BLACK_TUMBLESTONE)
|
||||
@JvmField
|
||||
val SMALL_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("small_budding_black_tumblestone", TumblestoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_BLACK_TUMBLESTONE, MapColor.TERRACOTTA_BLACK)
|
||||
val SMALL_BUDDING_BLACK_TUMBLESTONE = tumblestoneBlock("small_budding_black_tumblestone", GrowableStoneBlock.STAGE_0, 3, 4, MEDIUM_BUDDING_BLACK_TUMBLESTONE)
|
||||
|
||||
@JvmField
|
||||
val TUMBLESTONE_BLOCK = this.create("tumblestone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
|
||||
@@ -288,87 +281,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val BLACK_TUMBLESTONE_BLOCK = this.create("black_tumblestone_block", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BLACK).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_CORE = this.create("deepslate_crystal_core", TypeGemCoreBlock(BlockBehaviour.Properties.of().strength(4.0F, 10.0F).requiresCorrectToolForDrops().mapColor(MapColor.DEEPSLATE)))
|
||||
|
||||
private val typeGemBlocks = mutableMapOf<ResourceLocation, Block>()
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_NORMAL = typeGemBlock("normal_gem_block", MapColor.QUARTZ)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FIRE = typeGemBlock("fire_gem_block", MapColor.FIRE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_WATER = typeGemBlock("water_gem_block", MapColor.WATER)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_GRASS = typeGemBlock("grass_gem_block", MapColor.COLOR_LIGHT_GREEN)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_ELECTRIC = typeGemBlock("electric_gem_block", MapColor.GOLD)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_ICE = typeGemBlock("ice_gem_block", MapColor.ICE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FIGHTING = typeGemBlock("fighting_gem_block", MapColor.COLOR_RED)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_POISON = typeGemBlock("poison_gem_block", MapColor.COLOR_PURPLE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_GROUND = typeGemBlock("ground_gem_block", MapColor.PODZOL)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FLYING = typeGemBlock("flying_gem_block", MapColor.COLOR_LIGHT_BLUE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_PSYCHIC = typeGemBlock("psychic_gem_block", MapColor.COLOR_MAGENTA)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_BUG = typeGemBlock("bug_gem_block", MapColor.TERRACOTTA_LIGHT_GREEN)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_ROCK = typeGemBlock("rock_gem_block", MapColor.TERRACOTTA_LIGHT_GRAY)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_GHOST = typeGemBlock("ghost_gem_block", MapColor.TERRACOTTA_MAGENTA)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_DRAGON = typeGemBlock("dragon_gem_block", MapColor.COLOR_BLUE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_DARK = typeGemBlock("dark_gem_block", MapColor.TERRACOTTA_BLACK)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_STEEL = typeGemBlock("steel_gem_block", MapColor.METAL)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FAIRY = typeGemBlock("fairy_gem_block", MapColor.COLOR_PINK)
|
||||
|
||||
private val typeGemClusters = mutableMapOf<ResourceLocation, TypeGemClusterBlock>()
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_NORMAL = typeGemCluster("normal_gem_cluster", TYPE_GEM_BLOCK_NORMAL, cobblemonResource("normal_gem"), MapColor.QUARTZ)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FIRE = typeGemCluster("fire_gem_cluster", TYPE_GEM_BLOCK_FIRE, cobblemonResource("fire_gem"), MapColor.FIRE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_WATER = typeGemCluster("water_gem_cluster", TYPE_GEM_BLOCK_WATER, cobblemonResource("water_gem"), MapColor.WATER)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_GRASS = typeGemCluster("grass_gem_cluster", TYPE_GEM_BLOCK_GRASS, cobblemonResource("grass_gem"), MapColor.COLOR_LIGHT_GREEN)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_ELECTRIC = typeGemCluster("electric_gem_cluster", TYPE_GEM_BLOCK_ELECTRIC, cobblemonResource("electric_gem"), MapColor.GOLD)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_ICE = typeGemCluster("ice_gem_cluster", TYPE_GEM_BLOCK_ICE, cobblemonResource("ice_gem"), MapColor.ICE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FIGHTING = typeGemCluster("fighting_gem_cluster", TYPE_GEM_BLOCK_FIGHTING, cobblemonResource("fighting_gem"), MapColor.COLOR_RED)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_POISON = typeGemCluster("poison_gem_cluster", TYPE_GEM_BLOCK_POISON, cobblemonResource("poison_gem"), MapColor.COLOR_PURPLE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_GROUND = typeGemCluster("ground_gem_cluster", TYPE_GEM_BLOCK_GROUND, cobblemonResource("ground_gem"), MapColor.PODZOL)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FLYING = typeGemCluster("flying_gem_cluster", TYPE_GEM_BLOCK_FLYING, cobblemonResource("flying_gem"), MapColor.COLOR_LIGHT_BLUE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_PSYCHIC = typeGemCluster("psychic_gem_cluster", TYPE_GEM_BLOCK_PSYCHIC, cobblemonResource("psychic_gem"), MapColor.COLOR_MAGENTA)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_BUG = typeGemCluster("bug_gem_cluster", TYPE_GEM_BLOCK_BUG, cobblemonResource("bug_gem"), MapColor.TERRACOTTA_LIGHT_GREEN)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_ROCK = typeGemCluster("rock_gem_cluster", TYPE_GEM_BLOCK_ROCK, cobblemonResource("rock_gem"), MapColor.TERRACOTTA_LIGHT_GRAY)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_GHOST = typeGemCluster("ghost_gem_cluster", TYPE_GEM_BLOCK_GHOST, cobblemonResource("ghost_gem"), MapColor.TERRACOTTA_MAGENTA)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_DRAGON = typeGemCluster("dragon_gem_cluster", TYPE_GEM_BLOCK_DRAGON, cobblemonResource("dragon_gem"), MapColor.COLOR_BLUE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_DARK = typeGemCluster("dark_gem_cluster", TYPE_GEM_BLOCK_DARK, cobblemonResource("dark_gem"), MapColor.TERRACOTTA_BLACK)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_STEEL = typeGemCluster("steel_gem_cluster", TYPE_GEM_BLOCK_STEEL, cobblemonResource("steel_gem"), MapColor.METAL)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FAIRY = typeGemCluster("fairy_gem_cluster", TYPE_GEM_BLOCK_FAIRY, cobblemonResource("fairy_gem"), MapColor.COLOR_PINK)
|
||||
|
||||
@JvmField
|
||||
val POLISHED_TUMBLESTONE = this.create("polished_tumblestone", Block(BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_ORANGE).strength(1.0F).sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS).requiresCorrectToolForDrops().instrument(NoteBlockInstrument.BASEDRUM)))
|
||||
@JvmField
|
||||
@@ -537,18 +449,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val HABITAT_BLOCK = this.create(
|
||||
name = "habitat_block",
|
||||
entry = HabitatBlock(
|
||||
properties = BlockBehaviour.Properties.of()
|
||||
.mapColor(MapColor.STONE)
|
||||
.strength(1.5F, Blocks.OBSIDIAN.explosionResistance)
|
||||
.pushReaction(PushReaction.BLOCK)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@JvmField
|
||||
val CAMPFIRE = create("campfire", CampfireBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.PODZOL).strength(2.0F).lightLevel{14}, false))
|
||||
|
||||
@@ -558,7 +458,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
|
||||
@JvmField
|
||||
val RELIC_COIN_SACK = create("relic_coin_sack", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_SACK_SOUNDS).pushReaction(PushReaction.DESTROY).strength(0.4F).mapColor(MapColor.GOLD), false))
|
||||
val RELIC_COIN_SACK = create("relic_coin_sack", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_SACK_SOUNDS).pushReaction(PushReaction.DESTROY).strength(0.4f), false))
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST = create("gilded_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.RED))
|
||||
@@ -577,139 +477,28 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val GIMMIGHOUL_CHEST = create("gimmighoul_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.FAKE))
|
||||
|
||||
@JvmField
|
||||
val WHITE_PLAQUE = create("white_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val LIGHT_GRAY_PLAQUE = create("light_gray_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val GRAY_PLAQUE = create("gray_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val BLACK_PLAQUE = create("black_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val BROWN_PLAQUE = create("brown_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val RED_PLAQUE = create("red_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val ORANGE_PLAQUE = create("orange_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val YELLOW_PLAQUE = create("yellow_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val LIME_PLAQUE = create("lime_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val GREEN_PLAQUE = create("green_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val CYAN_PLAQUE = create("cyan_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val LIGHT_BLUE_PLAQUE = create("light_blue_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val BLUE_PLAQUE = create("blue_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val PURPLE_PLAQUE = create("purple_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val MAGENTA_PLAQUE = create("magenta_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
@JvmField
|
||||
val PINK_PLAQUE = create("pink_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
|
||||
|
||||
@JvmField
|
||||
val CLEANSE_TAG = create("cleanse_tag", WallAttachedStackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_PAPER_SMALL_SOUNDS).mapColor(MapColor.NONE).pushReaction(PushReaction.DESTROY).noOcclusion().noCollission(), WallAttachedStackableItemBlock.WallStackableItemBlockType.TAG))
|
||||
@JvmField
|
||||
val SPELL_TAG = create("spell_tag", WallAttachedStackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_PAPER_SMALL_SOUNDS).mapColor(MapColor.NONE).pushReaction(PushReaction.DESTROY).noOcclusion().noCollission(), WallAttachedStackableItemBlock.WallStackableItemBlockType.TAG))
|
||||
|
||||
@JvmField
|
||||
val BLUNDER_POLICY = create("blunder_policy", WallAttachedDirectionalShapeBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_PAPER_LARGE_SOUNDS).mapColor(MapColor.NONE).noOcclusion().noCollission(), 14, 12, 1))
|
||||
@JvmField
|
||||
val WEAKNESS_POLICY = create("weakness_policy", WallAttachedDirectionalShapeBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_PAPER_LARGE_SOUNDS).mapColor(MapColor.NONE).noOcclusion().noCollission(), 14, 12, 1))
|
||||
|
||||
@JvmField
|
||||
val FULL_HEAL = create("full_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
|
||||
@JvmField
|
||||
val ANTIDOTE = create("antidote", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
|
||||
@JvmField
|
||||
val AWAKENING = create("awakening", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
|
||||
@JvmField
|
||||
val BURN_HEAL = create("burn_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
|
||||
@JvmField
|
||||
val ICE_HEAL = create("ice_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
|
||||
@JvmField
|
||||
val PARALYZE_HEAL = create("paralyze_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
|
||||
|
||||
@JvmField
|
||||
val ETHER = create("ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
|
||||
@JvmField
|
||||
val MAX_ETHER = create("max_ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
|
||||
@JvmField
|
||||
val ELIXIR = create("elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
|
||||
@JvmField
|
||||
val MAX_ELIXIR = create("max_elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
|
||||
|
||||
@JvmField
|
||||
val POTION = create("potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
|
||||
@JvmField
|
||||
val SUPER_POTION = create("super_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
|
||||
@JvmField
|
||||
val HYPER_POTION = create("hyper_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
|
||||
@JvmField
|
||||
val MAX_POTION = create("max_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
|
||||
@JvmField
|
||||
val FULL_RESTORE = create("full_restore", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
|
||||
|
||||
@JvmField
|
||||
val DIRE_HIT = create("dire_hit", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val GUARD_SPEC = create("guard_spec", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
@JvmField
|
||||
val X_SPEED = create("x_${Stats.SPEED.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
|
||||
|
||||
@JvmField
|
||||
val MONITOR = create("monitor", MonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 13 else 0 }))
|
||||
@JvmField
|
||||
val DAMAGED_MONITOR = create("damaged_monitor", DamagedMonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { when (it.getValue(DamagedMonitorBlock.SCREEN)) { DamagedMonitorBlock.BrokenMonitorScreen.GLITCHING -> 10; else -> 0 } }))
|
||||
@JvmField
|
||||
val FOSSIL_ANALYZER = create("fossil_analyzer", FossilAnalyzerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
|
||||
@JvmField
|
||||
val RESTORATION_TANK = create("restoration_tank", RestorationTankBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.GLASS).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
|
||||
|
||||
@JvmField
|
||||
val HEALING_MACHINE = create("healing_machine", HealingMachineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F).noOcclusion().lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 12 else 5 }))
|
||||
val HEALING_MACHINE = create("healing_machine", HealingMachineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2f).noOcclusion().lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 12 else 5 }))
|
||||
|
||||
@JvmField
|
||||
val PC = create("pc", PCBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F).noOcclusion().lightLevel { if ((it.getValue(PCBlock.ON) as Boolean) && (it.getValue(PCBlock.PART) == PCBlock.PCPart.TOP)) 13 else 0 }))
|
||||
|
||||
val TM_MACHINE = create(
|
||||
"tm_machine",
|
||||
TMMachineBlock(
|
||||
BlockBehaviour.Properties.of()
|
||||
.mapColor(MapColor.COLOR_GREEN)
|
||||
.sound(SoundType.METAL)
|
||||
.pushReaction(PushReaction.BLOCK)
|
||||
.strength(2F)
|
||||
.noOcclusion()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@JvmField
|
||||
val LECTERN = create("lectern", LecternBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).sound(SoundType.WOOD).strength(2.5F).ignitedByLava().lightLevel { if (it.getValue(LecternBlock.EMIT_LIGHT) as Boolean) 13 else 0 }))
|
||||
|
||||
@JvmField
|
||||
val DISC_SHELF = create("disc_shelf", DiscShelfBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).sound(SoundType.METAL).strength(2.5F)))
|
||||
|
||||
@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()))
|
||||
|
||||
// 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)))
|
||||
// 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)))
|
||||
|
||||
@JvmField
|
||||
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 13 else 0 }))
|
||||
@@ -777,9 +566,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
|
||||
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))
|
||||
|
||||
private fun tumblestoneBlock(name: String, stage: Int, height: Int, xzOffset: Int, nextStage: Block?, mapColor: MapColor) : Block {
|
||||
private fun tumblestoneBlock(name: String, stage: Int, height: Int, xzOffset: Int, nextStage: Block?) : Block {
|
||||
return this.create(name, TumblestoneBlock(BlockBehaviour.Properties.of()
|
||||
.mapColor(mapColor)
|
||||
.pushReaction(PushReaction.DESTROY)
|
||||
.noOcclusion()
|
||||
.strength(1.5F)
|
||||
@@ -1008,28 +796,4 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
val block = BlocksInvoker.createLeavesBlock(SoundType.GRASS)
|
||||
return this.create(name, block)
|
||||
}
|
||||
|
||||
private fun typeGemBlock(name: String, mapColor: MapColor): Block {
|
||||
val typeGemBlock = this.create(name, Block(BlockBehaviour.Properties.of().mapColor(mapColor).strength(3.0F, 6.0F).sound(CobblemonSounds.TYPE_GEM_BLOCK_SOUNDS)))
|
||||
|
||||
val identifier = cobblemonResource(name)
|
||||
typeGemBlocks[identifier] = typeGemBlock
|
||||
|
||||
return typeGemBlock
|
||||
}
|
||||
|
||||
fun typeGemBlocks() = typeGemBlocks.toMap()
|
||||
|
||||
private fun typeGemCluster(name: String, gemBlock: Block, dropItemId: ResourceLocation, mapColor: MapColor): Block {
|
||||
val gemClusterBlock = this.create(name, TypeGemClusterBlock(BlockBehaviour.Properties.of().mapColor(mapColor).strength(2.0F, 3.0F).sound(CobblemonSounds.TYPE_GEM_CLUSTER_SOUNDS).pushReaction(PushReaction.DESTROY), gemBlock, dropItemId))
|
||||
|
||||
TypeGemClusterBlock.gemToClusterMap[gemBlock] = gemClusterBlock
|
||||
|
||||
val identifier = cobblemonResource(name)
|
||||
typeGemClusters[identifier] = gemClusterBlock
|
||||
|
||||
return gemClusterBlock
|
||||
}
|
||||
|
||||
fun typeGemClusters() = typeGemClusters.toMap()
|
||||
}
|
||||
}
|
||||
@@ -71,11 +71,10 @@ object CobblemonCommands {
|
||||
MarkGiveAllCommand.register(dispatcher)
|
||||
PcSearchCommand.register(dispatcher)
|
||||
PcTakeCommand.register(dispatcher)
|
||||
GiveTmCommand.register(dispatcher)
|
||||
TmCommand.register(dispatcher)
|
||||
|
||||
// Possibly lock down registration if and only if under dev environment or running in an environment
|
||||
// with a certain system environment variable set
|
||||
CobblemonInfoCommand.register(dispatcher)
|
||||
CalculateSeatPositionCommand.register(dispatcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.inventory.MenuType
|
||||
import net.minecraft.world.level.GameRules
|
||||
import net.minecraft.world.level.ItemLike
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
@@ -118,11 +117,6 @@ interface CobblemonImplementation {
|
||||
|
||||
fun registerEntitySubPredicates()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
fun registerMobEffects()
|
||||
|
||||
|
||||
/**
|
||||
* Add a feature to the current platform implementation.
|
||||
|
||||
@@ -69,12 +69,6 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
|
||||
.networkSynchronized(FoodColourComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
@JvmField
|
||||
val TM_MOVE: DataComponentType<TMMoveComponent> = create("tm_move", DataComponentType.builder<TMMoveComponent>()
|
||||
.persistent(TMMoveComponent.CODEC)
|
||||
.networkSynchronized(TMMoveComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
@JvmField
|
||||
val INGREDIENT: DataComponentType<IngredientComponent> = create("ingredient", DataComponentType.builder<IngredientComponent>()
|
||||
.persistent(IngredientComponent.CODEC)
|
||||
@@ -107,7 +101,6 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:flavour"), FLAVOUR)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:ride_boosts"), RIDE_BOOST)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food_colour"), FOOD_COLOUR)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:tm_move"), TM_MOVE)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:ingredient"), INGREDIENT)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food"), FOOD)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:mob_effects"), MOB_EFFECTS)
|
||||
|
||||
@@ -21,8 +21,8 @@ import com.cobblemon.mod.common.api.text.gray
|
||||
import com.cobblemon.mod.common.block.BerryBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotColor
|
||||
import com.cobblemon.mod.common.client.pokedex.PokedexType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotColor
|
||||
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
|
||||
import com.cobblemon.mod.common.item.*
|
||||
import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
|
||||
@@ -35,6 +35,7 @@ import com.cobblemon.mod.common.item.berry.HealingBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.PPRestoringBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.PortionHealingBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.StatusCuringBerryItem
|
||||
import com.cobblemon.mod.common.item.interactive.PonigiriItem
|
||||
import com.cobblemon.mod.common.item.food.SinisterTeaItem
|
||||
import com.cobblemon.mod.common.item.interactive.*
|
||||
import com.cobblemon.mod.common.item.interactive.ability.AbilityChangeItem
|
||||
@@ -452,16 +453,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val MONITOR = blockItem("monitor", CobblemonBlocks.MONITOR)
|
||||
@JvmField
|
||||
val DAMAGED_MONITOR = blockItem("damaged_monitor", CobblemonBlocks.DAMAGED_MONITOR)
|
||||
@JvmField
|
||||
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE, Rarity.UNCOMMON)
|
||||
@JvmField
|
||||
val PC = blockItem("pc", CobblemonBlocks.PC)
|
||||
@JvmField
|
||||
val TM_MACHINE = blockItem("tm_machine", CobblemonBlocks.TM_MACHINE)
|
||||
@JvmField
|
||||
val DISC_SHELF = blockItem("disc_shelf", CobblemonBlocks.DISC_SHELF)
|
||||
@JvmField
|
||||
val PASTURE = blockItem("pasture", CobblemonBlocks.PASTURE)
|
||||
@JvmField
|
||||
val DISPLAY_CASE = blockItem("display_case", CobblemonBlocks.DISPLAY_CASE)
|
||||
@@ -512,23 +507,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField val SCROLL_OF_DARKNESS = noSettingsItem("scroll_of_darkness")
|
||||
@JvmField val SCROLL_OF_WATERS = noSettingsItem("scroll_of_waters")
|
||||
|
||||
@JvmField val WHITE_PLAQUE = blockItem("white_plaque", CobblemonBlocks.WHITE_PLAQUE)
|
||||
@JvmField val LIGHT_GRAY_PLAQUE = blockItem("light_gray_plaque", CobblemonBlocks.LIGHT_GRAY_PLAQUE)
|
||||
@JvmField val GRAY_PLAQUE = blockItem("gray_plaque", CobblemonBlocks.GRAY_PLAQUE)
|
||||
@JvmField val BLACK_PLAQUE = blockItem("black_plaque", CobblemonBlocks.BLACK_PLAQUE)
|
||||
@JvmField val BROWN_PLAQUE = blockItem("brown_plaque", CobblemonBlocks.BROWN_PLAQUE)
|
||||
@JvmField val RED_PLAQUE = blockItem("red_plaque", CobblemonBlocks.RED_PLAQUE)
|
||||
@JvmField val ORANGE_PLAQUE = blockItem("orange_plaque", CobblemonBlocks.ORANGE_PLAQUE)
|
||||
@JvmField val YELLOW_PLAQUE = blockItem("yellow_plaque", CobblemonBlocks.YELLOW_PLAQUE)
|
||||
@JvmField val LIME_PLAQUE = blockItem("lime_plaque", CobblemonBlocks.LIME_PLAQUE)
|
||||
@JvmField val GREEN_PLAQUE = blockItem("green_plaque", CobblemonBlocks.GREEN_PLAQUE)
|
||||
@JvmField val CYAN_PLAQUE = blockItem("cyan_plaque", CobblemonBlocks.CYAN_PLAQUE)
|
||||
@JvmField val LIGHT_BLUE_PLAQUE = blockItem("light_blue_plaque", CobblemonBlocks.LIGHT_BLUE_PLAQUE)
|
||||
@JvmField val BLUE_PLAQUE = blockItem("blue_plaque", CobblemonBlocks.BLUE_PLAQUE)
|
||||
@JvmField val PURPLE_PLAQUE = blockItem("purple_plaque", CobblemonBlocks.PURPLE_PLAQUE)
|
||||
@JvmField val MAGENTA_PLAQUE = blockItem("magenta_plaque", CobblemonBlocks.MAGENTA_PLAQUE)
|
||||
@JvmField val PINK_PLAQUE = blockItem("pink_plaque", CobblemonBlocks.PINK_PLAQUE)
|
||||
|
||||
private val berries = mutableMapOf<ResourceLocation, BerryItem>()
|
||||
// Plants
|
||||
@JvmField val CHERI_BERRY = berryItem("cheri", StatusCuringBerryItem(CobblemonBlocks.CHERI_BERRY, Statuses.PARALYSIS))
|
||||
@@ -604,9 +582,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
|
||||
@JvmField val BERRY_JUICE = this.create("berry_juice", BerryJuiceItem())
|
||||
|
||||
@JvmField
|
||||
val HABITAT_BLOCK = blockItem("habitat_block", CobblemonBlocks.HABITAT_BLOCK)
|
||||
|
||||
@JvmField
|
||||
val GALARICA_NUTS = compostableItemNameBlockItem("galarica_nuts", CobblemonBlocks.GALARICA_NUT_BUSH)
|
||||
|
||||
@@ -724,15 +699,15 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
val MOOMOO_MILK = create("moomoo_milk", MoomooMilk(Item.Properties().craftRemainder(Items.GLASS_BOTTLE).stacksTo((16))))
|
||||
|
||||
@JvmField
|
||||
val POTION = create("potion", PotionItem(PotionType.POTION, CobblemonBlocks.POTION))
|
||||
val POTION = create("potion", PotionItem(PotionType.POTION))
|
||||
@JvmField
|
||||
val SUPER_POTION = create("super_potion", PotionItem(PotionType.SUPER_POTION, CobblemonBlocks.SUPER_POTION))
|
||||
val SUPER_POTION = create("super_potion", PotionItem(PotionType.SUPER_POTION))
|
||||
@JvmField
|
||||
val HYPER_POTION = create("hyper_potion", PotionItem(PotionType.HYPER_POTION, CobblemonBlocks.HYPER_POTION))
|
||||
val HYPER_POTION = create("hyper_potion", PotionItem(PotionType.HYPER_POTION))
|
||||
@JvmField
|
||||
val MAX_POTION = create("max_potion", PotionItem(PotionType.MAX_POTION, CobblemonBlocks.MAX_POTION))
|
||||
val MAX_POTION = create("max_potion", PotionItem(PotionType.MAX_POTION))
|
||||
@JvmField
|
||||
val FULL_RESTORE = create("full_restore", PotionItem(PotionType.FULL_RESTORE, CobblemonBlocks.FULL_RESTORE))
|
||||
val FULL_RESTORE = create("full_restore", PotionItem(PotionType.FULL_RESTORE))
|
||||
|
||||
@JvmField
|
||||
val HEAL_POWDER = create("heal_powder", HealPowderItem())
|
||||
@@ -817,27 +792,28 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val SERIOUS_MINT = mintItem("serious_mint", MintItem(Natures.SERIOUS))
|
||||
|
||||
@JvmField val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", XStatItem(Stats.ACCURACY, block = CobblemonBlocks.X_ACCURACY))
|
||||
@JvmField val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", XStatItem(Stats.ATTACK, block = CobblemonBlocks.X_ATTACK))
|
||||
@JvmField val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", XStatItem(Stats.DEFENCE, block = CobblemonBlocks.X_DEFENSE))
|
||||
@JvmField val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", XStatItem(Stats.SPECIAL_ATTACK, block = CobblemonBlocks.X_SP_ATK))
|
||||
@JvmField val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", XStatItem(Stats.SPECIAL_DEFENCE, block = CobblemonBlocks.X_SP_DEF))
|
||||
@JvmField val X_SPEED = create("x_${Stats.SPEED.identifier.path}", XStatItem(Stats.SPEED, block = CobblemonBlocks.X_SPEED))
|
||||
@JvmField val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", XStatItem(Stats.ACCURACY))
|
||||
@JvmField val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", XStatItem(Stats.ATTACK))
|
||||
@JvmField val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", XStatItem(Stats.DEFENCE))
|
||||
@JvmField val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", XStatItem(Stats.SPECIAL_ATTACK))
|
||||
@JvmField val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", XStatItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField val X_SPEED = create("x_${Stats.SPEED.identifier.path}", XStatItem(Stats.SPEED))
|
||||
|
||||
@JvmField val DIRE_HIT = create("dire_hit", DireHitItem(CobblemonBlocks.DIRE_HIT))
|
||||
@JvmField val GUARD_SPEC = create("guard_spec", GuardSpecItem(CobblemonBlocks.GUARD_SPEC))
|
||||
@JvmField val DIRE_HIT = create("dire_hit", DireHitItem())
|
||||
@JvmField val GUARD_SPEC = create("guard_spec", GuardSpecItem())
|
||||
|
||||
@JvmField val FULL_HEAL = create("full_heal", StatusCureItem("item.cobblemon.full_heal", *Statuses.getPersistentStatuses().toTypedArray(), block = CobblemonBlocks.FULL_HEAL))
|
||||
@JvmField val ANTIDOTE = create("antidote", StatusCureItem("item.cobblemon.antidote", Statuses.POISON, Statuses.POISON_BADLY, block = CobblemonBlocks.ANTIDOTE))
|
||||
@JvmField val AWAKENING = create("awakening", StatusCureItem("item.cobblemon.awakening", Statuses.SLEEP, block = CobblemonBlocks.AWAKENING))
|
||||
@JvmField val BURN_HEAL = create("burn_heal", StatusCureItem("item.cobblemon.burn_heal", Statuses.BURN, block = CobblemonBlocks.BURN_HEAL))
|
||||
@JvmField val ICE_HEAL = create("ice_heal", StatusCureItem("item.cobblemon.ice_heal", Statuses.FROZEN, block = CobblemonBlocks.ICE_HEAL))
|
||||
@JvmField val PARALYZE_HEAL = create("paralyze_heal", StatusCureItem("item.cobblemon.paralyze_heal", Statuses.PARALYSIS, block = CobblemonBlocks.PARALYZE_HEAL))
|
||||
@JvmField val BURN_HEAL = create("burn_heal", StatusCureItem("item.cobblemon.burn_heal", Statuses.BURN))
|
||||
@JvmField val PARALYZE_HEAL = create("paralyze_heal", StatusCureItem("item.cobblemon.paralyze_heal", Statuses.PARALYSIS))
|
||||
@JvmField val ICE_HEAL = create("ice_heal", StatusCureItem("item.cobblemon.ice_heal", Statuses.FROZEN))
|
||||
@JvmField val ANTIDOTE = create("antidote", StatusCureItem("item.cobblemon.antidote", Statuses.POISON, Statuses.POISON_BADLY))
|
||||
@JvmField val AWAKENING = create("awakening", StatusCureItem("item.cobblemon.awakening", Statuses.SLEEP))
|
||||
|
||||
@JvmField val ETHER = create("ether", EtherItem(max = false, CobblemonBlocks.ETHER))
|
||||
@JvmField val MAX_ETHER = create("max_ether", EtherItem(max = true, CobblemonBlocks.MAX_ETHER))
|
||||
@JvmField val ELIXIR = create("elixir", ElixirItem(max = false, CobblemonBlocks.ELIXIR))
|
||||
@JvmField val MAX_ELIXIR = create("max_elixir", ElixirItem(max = true, CobblemonBlocks.MAX_ELIXIR))
|
||||
@JvmField val FULL_HEAL = create("full_heal", StatusCureItem("item.cobblemon.full_heal"))
|
||||
|
||||
@JvmField val ETHER = create("ether", EtherItem(max = false))
|
||||
@JvmField val MAX_ETHER = create("max_ether", EtherItem(max = true))
|
||||
@JvmField val ELIXIR = create("elixir", ElixirItem(max = false))
|
||||
@JvmField val MAX_ELIXIR = create("max_elixir", ElixirItem(max = true))
|
||||
|
||||
@JvmField
|
||||
val ABILITY_CAPSULE = this.create("ability_capsule", AbilityChangeItem(AbilityChanger.COMMON_ABILITY))
|
||||
@@ -946,7 +922,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val BLACK_SLUDGE = heldItem("black_sludge")
|
||||
@JvmField
|
||||
val BLUNDER_POLICY = itemNameBlockItem("blunder_policy", CobblemonBlocks.BLUNDER_POLICY)
|
||||
val BLUNDER_POLICY = heldItem("blunder_policy")
|
||||
@JvmField
|
||||
val CELL_BATTERY = heldItem("cell_battery")
|
||||
@JvmField
|
||||
@@ -954,7 +930,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val CHOICE_SCARF = heldItem("choice_scarf")
|
||||
@JvmField
|
||||
val CLEANSE_TAG = itemNameBlockItem("cleanse_tag", CobblemonBlocks.CLEANSE_TAG)
|
||||
val CLEANSE_TAG = heldItem("cleanse_tag")
|
||||
@JvmField
|
||||
val CLEAR_AMULET = heldItem("clear_amulet")
|
||||
@JvmField
|
||||
@@ -1062,7 +1038,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val SOFT_SAND = heldItem("soft_sand")
|
||||
@JvmField
|
||||
val SPELL_TAG = itemNameBlockItem("spell_tag", CobblemonBlocks.SPELL_TAG)
|
||||
val SPELL_TAG = heldItem("spell_tag")
|
||||
@JvmField
|
||||
val SMOKE_BALL = heldItem("smoke_ball")
|
||||
@JvmField
|
||||
@@ -1080,7 +1056,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val UTILITY_UMBRELLA = heldItem("utility_umbrella")
|
||||
@JvmField
|
||||
val WEAKNESS_POLICY = itemNameBlockItem("weakness_policy", CobblemonBlocks.WEAKNESS_POLICY)
|
||||
val WEAKNESS_POLICY = heldItem("weakness_policy")
|
||||
@JvmField
|
||||
val WIDE_LENS = heldItem("wide_lens")
|
||||
@JvmField
|
||||
@@ -1216,83 +1192,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val BLACK_TUMBLESTONE_BLOCK = blockItem("black_tumblestone_block", CobblemonBlocks.BLACK_TUMBLESTONE_BLOCK)
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_CORE = blockItem("deepslate_crystal_core", CobblemonBlocks.TYPE_GEM_CORE)
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_NORMAL = blockItem("normal_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_NORMAL)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FIRE = blockItem("fire_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_FIRE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_WATER = blockItem("water_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_WATER)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_ELECTRIC = blockItem("electric_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_ELECTRIC)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_GRASS = blockItem("grass_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_GRASS)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_ICE = blockItem("ice_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_ICE)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FIGHTING = blockItem("fighting_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_FIGHTING)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_POISON = blockItem("poison_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_POISON)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_GROUND = blockItem("ground_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_GROUND)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FLYING = blockItem("flying_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_FLYING)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_PSYCHIC = blockItem("psychic_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_PSYCHIC)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_BUG = blockItem("bug_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_BUG)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_ROCK = blockItem("rock_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_ROCK)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_GHOST = blockItem("ghost_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_GHOST)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_DRAGON = blockItem("dragon_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_DRAGON)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_DARK = blockItem("dark_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_DARK)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_STEEL = blockItem("steel_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_STEEL)
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_FAIRY = blockItem("fairy_gem_cluster", CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY)
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_NORMAL = blockItem("normal_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_NORMAL)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FIRE = blockItem("fire_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_FIRE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_WATER = blockItem("water_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_WATER)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_ELECTRIC = blockItem("electric_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_ELECTRIC)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_GRASS = blockItem("grass_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_GRASS)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_ICE = blockItem("ice_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_ICE)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FIGHTING = blockItem("fighting_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_FIGHTING)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_POISON = blockItem("poison_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_POISON)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_GROUND = blockItem("ground_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_GROUND)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FLYING = blockItem("flying_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_FLYING)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_PSYCHIC = blockItem("psychic_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_PSYCHIC)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_BUG = blockItem("bug_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_BUG)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_ROCK = blockItem("rock_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_ROCK)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_GHOST = blockItem("ghost_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_GHOST)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_DRAGON = blockItem("dragon_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_DRAGON)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_DARK = blockItem("dark_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_DARK)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_STEEL = blockItem("steel_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_STEEL)
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_FAIRY = blockItem("fairy_gem_block", CobblemonBlocks.TYPE_GEM_BLOCK_FAIRY)
|
||||
|
||||
@JvmField
|
||||
val POKEROD_SMITHING_TEMPLATE = create("pokerod_smithing_template", SmithingTemplateItem(
|
||||
Component.translatable("item.minecraft.fishing_rod").blue(),
|
||||
@@ -1517,49 +1416,44 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
val RELIC_COIN_POUCH = blockItem("relic_coin_pouch", CobblemonBlocks.RELIC_COIN_POUCH)
|
||||
@JvmField
|
||||
val RELIC_COIN_SACK = blockItem("relic_coin_sack", CobblemonBlocks.RELIC_COIN_SACK)
|
||||
@JvmField
|
||||
val TECHNICAL_MACHINE = this.create("technical_machine", TechnicalMachineItem(Properties()))
|
||||
@JvmField
|
||||
val BLANK_TM = this.create("blank_tm", CobblemonItem(Item.Properties()))
|
||||
|
||||
// Type Gems
|
||||
@JvmField
|
||||
val NORMAL_GEM = this.create("normal_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_NORMAL))
|
||||
val NORMAL_GEM = noSettingsItem("normal_gem")
|
||||
@JvmField
|
||||
val FIRE_GEM = this.create("fire_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_FIRE))
|
||||
val FIRE_GEM = noSettingsItem("fire_gem")
|
||||
@JvmField
|
||||
val WATER_GEM = this.create("water_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_WATER))
|
||||
val WATER_GEM = noSettingsItem("water_gem")
|
||||
@JvmField
|
||||
val GRASS_GEM = this.create("grass_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_GRASS))
|
||||
val GRASS_GEM = noSettingsItem("grass_gem")
|
||||
@JvmField
|
||||
val ELECTRIC_GEM = this.create("electric_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_ELECTRIC))
|
||||
val ELECTRIC_GEM = noSettingsItem("electric_gem")
|
||||
@JvmField
|
||||
val ICE_GEM = this.create("ice_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_ICE))
|
||||
val ICE_GEM = noSettingsItem("ice_gem")
|
||||
@JvmField
|
||||
val FIGHTING_GEM = this.create("fighting_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_FIGHTING))
|
||||
val FIGHTING_GEM = noSettingsItem("fighting_gem")
|
||||
@JvmField
|
||||
val POISON_GEM = this.create("poison_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_POISON))
|
||||
val POISON_GEM = noSettingsItem("poison_gem")
|
||||
@JvmField
|
||||
val GROUND_GEM = this.create("ground_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_GROUND))
|
||||
val GROUND_GEM = noSettingsItem("ground_gem")
|
||||
@JvmField
|
||||
val FLYING_GEM = this.create("flying_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_FLYING))
|
||||
val FLYING_GEM = noSettingsItem("flying_gem")
|
||||
@JvmField
|
||||
val PSYCHIC_GEM = this.create("psychic_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_PSYCHIC))
|
||||
val PSYCHIC_GEM = noSettingsItem("psychic_gem")
|
||||
@JvmField
|
||||
val BUG_GEM = this.create("bug_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_BUG))
|
||||
val BUG_GEM = noSettingsItem("bug_gem")
|
||||
@JvmField
|
||||
val ROCK_GEM = this.create("rock_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_ROCK))
|
||||
val ROCK_GEM = noSettingsItem("rock_gem")
|
||||
@JvmField
|
||||
val GHOST_GEM = this.create("ghost_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_GHOST))
|
||||
val GHOST_GEM = noSettingsItem("ghost_gem")
|
||||
@JvmField
|
||||
val DRAGON_GEM = this.create("dragon_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_DRAGON))
|
||||
val DRAGON_GEM = noSettingsItem("dragon_gem")
|
||||
@JvmField
|
||||
val DARK_GEM = this.create("dark_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_DARK))
|
||||
val DARK_GEM = noSettingsItem("dark_gem")
|
||||
@JvmField
|
||||
val STEEL_GEM = this.create("steel_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_STEEL))
|
||||
val STEEL_GEM = noSettingsItem("steel_gem")
|
||||
@JvmField
|
||||
val FAIRY_GEM = this.create("fairy_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY))
|
||||
|
||||
val FAIRY_GEM = noSettingsItem("fairy_gem")
|
||||
//@JvmField
|
||||
//val BINDING_SOIL = blockItem("binding_soil", CobblemonBlocks.BINDING_SOIL)
|
||||
|
||||
@@ -1659,7 +1553,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
private fun heldItem(name: String, item: Item, remappedName: String? = null) = create(
|
||||
name = name,
|
||||
entry = item.also {
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
|
||||
import com.cobblemon.mod.common.block.tmmachine.TMMachineMenu
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
@@ -20,8 +19,7 @@ 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 TM_MACHINE = MenuType.register("tm_machine_menu", ::TMMachineMenu)
|
||||
val COOKING_POT = MenuType.register("cooking_pot", ::CookingPotMenu)
|
||||
|
||||
override val registry: Registry<MenuType<*>>
|
||||
get() = BuiltInRegistries.MENU
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.cooking.effects.CleanseAllEffect
|
||||
import com.cobblemon.mod.common.api.cooking.effects.CleanseNegativeEffect
|
||||
import com.cobblemon.mod.common.api.cooking.effects.MentalRestorationEffect
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
|
||||
object CobblemonMobEffects : PlatformRegistry<Registry<MobEffect>, ResourceKey<Registry<MobEffect>>, MobEffect>() {
|
||||
override val registry: Registry<MobEffect> = BuiltInRegistries.MOB_EFFECT
|
||||
override val resourceKey: ResourceKey<Registry<MobEffect>> = Registries.MOB_EFFECT
|
||||
|
||||
@JvmField
|
||||
val CLEANSE_NEGATIVE = create("cleanse_negative", CleanseNegativeEffect())
|
||||
|
||||
@JvmField
|
||||
val MENTAL_RESTORATION = create("mental_restoration", MentalRestorationEffect())
|
||||
|
||||
@JvmField
|
||||
val CLEANSE_ALL = create("cleanse_all", CleanseAllEffect())
|
||||
}
|
||||
@@ -1,55 +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
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.moves.MoveSelector
|
||||
import com.cobblemon.mod.common.api.moves.MovesetBuilder
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.MovesetBuilderAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.StringToObjectAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
|
||||
object CobblemonMovesetBuilders : JsonDataRegistry<MovesetBuilder> {
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(MovesetBuilder::class.java, MovesetBuilderAdapter)
|
||||
.registerTypeAdapter(MoveSelector::class.java, StringToObjectAdapter(MoveSelector.selectors))
|
||||
.create()
|
||||
|
||||
override val typeToken = TypeToken.get(MovesetBuilder::class.java)
|
||||
override val resourcePath = "moveset_builders"
|
||||
override val id: ResourceLocation = cobblemonResource("moveset_builders")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<CobblemonMovesetBuilders>()
|
||||
|
||||
val movesetBuilders = mutableMapOf<ResourceLocation, MovesetBuilder>()
|
||||
|
||||
fun getOrThrow(id: ResourceLocation): MovesetBuilder {
|
||||
return movesetBuilders[id]
|
||||
?: throw IllegalArgumentException("Unknown MovesetBuilder id: $id")
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayer) { /* These don't sync. But what if they did? Nah probably shouldn't sync. */ }
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, MovesetBuilder>) {
|
||||
movesetBuilders.clear()
|
||||
data.forEach { (id, value) -> value.id = id }
|
||||
movesetBuilders.putAll(data)
|
||||
observable.emit(this)
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.client.net.CalculateSeatPositionsHandler
|
||||
import com.cobblemon.mod.common.client.net.OpenBehaviourEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
|
||||
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
|
||||
@@ -32,10 +33,7 @@ import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.ExpGainedDataPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.PokedexUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SetActiveTMPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SetTMMachineContainerDataPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.habitat.OpenHabitatBlockEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.npc.CloseNPCEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.npc.OpenNPCEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.orientation.ClientboundUpdateOrientationHandler
|
||||
@@ -45,7 +43,6 @@ import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.UpdatePastureConflictFlagHandler
|
||||
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundSeatAssignmentPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
|
||||
import com.cobblemon.mod.common.client.net.riding.ClientboundUpdateDriverInputHandler
|
||||
@@ -71,6 +68,7 @@ import com.cobblemon.mod.common.client.net.trade.TradeProcessStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
|
||||
import com.cobblemon.mod.common.net.PacketRegisterInfo
|
||||
import com.cobblemon.mod.common.net.messages.client.CalculateSeatPositionsPacket
|
||||
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
|
||||
@@ -90,7 +88,6 @@ import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacke
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SaccharineLogBlockParticlesPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.habitat.OpenHabitatBlockEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.npc.CloseNPCEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.npc.OpenNPCEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateDriverInputPacket
|
||||
@@ -104,7 +101,6 @@ import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegis
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClearEvolutionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClientboundSeatAssignmentPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.RemoveEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.settings.OpenCobblemonConfigScreenPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
|
||||
@@ -131,7 +127,6 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.ChangeP
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.RequestPCBoxWallpapersPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.SetPCBoxWallpapersPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.tms.TechnicalMachineRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
|
||||
@@ -144,8 +139,6 @@ import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.ExpGainedDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.PokedexUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SetActiveTMPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SetTMMachineContainerDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengeResponsePacket
|
||||
@@ -163,7 +156,6 @@ import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.behaviour.DamageOnCollisionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.block.TMMachineTeachMovePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectedPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonSelectedPacket
|
||||
@@ -176,7 +168,6 @@ import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidin
|
||||
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.dialogue.EscapeDialoguePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.habitat.SaveHabitatBlockSettingsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pasture.PasturePokemonPacket
|
||||
@@ -194,12 +185,10 @@ import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePa
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdatePassengerPositionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateRiderRotationPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.SwapPCPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.PartyTutorialPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.ReleasePartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.*
|
||||
@@ -221,7 +210,6 @@ import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHan
|
||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.DamageOnCollisionPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.block.TMMachineTeachMoveHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectedHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSelectedHandler
|
||||
@@ -235,7 +223,6 @@ import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRiding
|
||||
import com.cobblemon.mod.common.net.serverhandling.dialogue.EscapeDialogueHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.dialogue.InputToDialogueHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.evolution.AcceptEvolutionHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.habitat.SaveHabitatBlockSettingsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.npc.SaveNPCHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.orientation.ServerboundUpdateOrientationHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pasture.PasturePokemonHandler
|
||||
@@ -252,7 +239,6 @@ import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHan
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.DismountPokemonPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.DriverInputPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.ServerboundUpdatePassengerPositionHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.ServerboundUpdateRiderRotationHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.starter.RequestStarterScreenHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.starter.SelectStarterPacketHandler
|
||||
@@ -261,7 +247,6 @@ import com.cobblemon.mod.common.net.serverhandling.storage.RequestMoveSwapHandle
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.SwapPCPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.MovePartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.PartyTutorialPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.ReleasePCPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.SwapPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.*
|
||||
@@ -340,8 +325,6 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideStaminaUpdatePacket.ID, RideStaminaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(AlphaUpdatePacket.ID, AlphaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(ScaleModifierUpdatePacket.ID, ScaleModifierUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
|
||||
// Evolution start
|
||||
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
|
||||
@@ -418,7 +401,6 @@ object CobblemonNetwork {
|
||||
// Data registries
|
||||
list.add(PacketRegisterInfo(AbilityRegistrySyncPacket.ID, AbilityRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(CobblemonMechanicsSyncPacket.ID, CobblemonMechanicsSyncPacket::decode, CobblemonMechanicsSyncHandler))
|
||||
list.add(PacketRegisterInfo(PokemonInteractionsSyncPacket.ID, PokemonInteractionsSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
@@ -440,7 +422,6 @@ 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(TechnicalMachineRegistrySyncPacket.ID, TechnicalMachineRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
// Effects
|
||||
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
|
||||
@@ -503,18 +484,16 @@ object CobblemonNetwork {
|
||||
// Pokédex scanning
|
||||
list.add(PacketRegisterInfo(ServerConfirmedRegisterPacket.ID, ServerConfirmedRegisterPacket::decode, ServerConfirmedRegisterHandler))
|
||||
|
||||
// Debug / cheats
|
||||
list.add(PacketRegisterInfo(CalculateSeatPositionsPacket.ID, CalculateSeatPositionsPacket::decode, CalculateSeatPositionsHandler))
|
||||
|
||||
// Riding
|
||||
list.add(PacketRegisterInfo(ClientboundUpdateRidingStatePacket.ID, ClientboundUpdateRidingStatePacket::decode, ClientboundUpdateRidingStateHandler))
|
||||
list.add(PacketRegisterInfo(ClientboundUpdateDriverInputPacket.ID, ClientboundUpdateDriverInputPacket::decode, ClientboundUpdateDriverInputHandler))
|
||||
list.add(PacketRegisterInfo(ClientboundSeatAssignmentPacket.ID, ClientboundSeatAssignmentPacket::decode, ClientboundSeatAssignmentPacketHandler))
|
||||
|
||||
// Habitat blocks
|
||||
list.add(PacketRegisterInfo(OpenHabitatBlockEditorPacket.ID, OpenHabitatBlockEditorPacket::decode, OpenHabitatBlockEditorHandler))
|
||||
|
||||
// Debug
|
||||
list.add(PacketRegisterInfo(OpenRidingStatsDebugGUIPacket.ID, OpenRidingStatsDebugGUIPacket::decode, OpenRidingStatsDebugGUIHandler))
|
||||
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -549,7 +528,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(ReleasePCPokemonPacket.ID, ReleasePCPokemonPacket::decode, ReleasePCPokemonHandler))
|
||||
list.add(PacketRegisterInfo(UnlinkPlayerFromPCPacket.ID, UnlinkPlayerFromPCPacket::decode, UnlinkPlayerFromPCHandler))
|
||||
|
||||
list.add(PacketRegisterInfo(RequestRenamePCBoxPacket.ID, RequestRenamePCBoxPacket::decode, RequestRenamePCBoxHandler))
|
||||
list.add(PacketRegisterInfo(RequestRenamePCBoxPacket.Companion.ID, RequestRenamePCBoxPacket.Companion::decode, RequestRenamePCBoxHandler))
|
||||
list.add(PacketRegisterInfo(PCBoxWallpapersPacket.ID, PCBoxWallpapersPacket::decode, PCBoxWallpapersHandler))
|
||||
list.add(PacketRegisterInfo(RequestChangePCBoxWallpaperPacket.ID, RequestChangePCBoxWallpaperPacket::decode, RequestChangePCBoxWallpaperHandler))
|
||||
list.add(PacketRegisterInfo(MarkPCBoxWallpapersSeenPacket.ID, MarkPCBoxWallpapersSeenPacket::decode, MarkPCBoxWallpapersSeenHandler))
|
||||
@@ -594,7 +573,6 @@ object CobblemonNetwork {
|
||||
|
||||
// Block entity
|
||||
list.add(PacketRegisterInfo(AdjustBlockEntityViewerCountPacket.ID, AdjustBlockEntityViewerCountPacket::decode, AdjustBlockEntityViewerCountHandler))
|
||||
list.add(PacketRegisterInfo(TMMachineTeachMovePacket.ID, TMMachineTeachMovePacket::decode, TMMachineTeachMoveHandler))
|
||||
|
||||
// Move select packets
|
||||
list.add(PacketRegisterInfo(MoveSelectedPacket.ID, MoveSelectedPacket::decode, MoveSelectedHandler))
|
||||
@@ -608,9 +586,6 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(PartyPokemonMoveSelectedPacket.ID, PartyPokemonMoveSelectedPacket::decode, PartyPokemonMoveSelectedHandler))
|
||||
list.add(PacketRegisterInfo(PartyMoveSelectCancelledPacket.ID, PartyMoveSelectCancelledPacket::decode, PartyMoveSelectCancelledHandler))
|
||||
|
||||
//Party move tutorial toasts packets
|
||||
list.add(PacketRegisterInfo(PartyTutorialPacket.ID, PartyTutorialPacket::decode, PartyTutorialPacketHandler))
|
||||
|
||||
// Dialogue packets
|
||||
list.add(PacketRegisterInfo(EscapeDialoguePacket.ID, EscapeDialoguePacket::decode, EscapeDialogueHandler))
|
||||
list.add(PacketRegisterInfo(InputToDialoguePacket.ID, InputToDialoguePacket::decode, InputToDialogueHandler))
|
||||
@@ -627,26 +602,17 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(DismountPokemonPacket.ID, DismountPokemonPacket::decode, DismountPokemonPacketHandler))
|
||||
list.add(PacketRegisterInfo(ServerboundUpdateDriverInputPacket.ID, ServerboundUpdateDriverInputPacket::decode, DriverInputPacketHandler))
|
||||
list.add(PacketRegisterInfo(ServerboundUpdateRiderRotationPacket.ID, ServerboundUpdateRiderRotationPacket::decode, ServerboundUpdateRiderRotationHandler))
|
||||
list.add(PacketRegisterInfo(ServerboundUpdatePassengerPositionPacket.ID, ServerboundUpdatePassengerPositionPacket::decode, ServerboundUpdatePassengerPositionHandler))
|
||||
|
||||
// Cooking
|
||||
list.add(PacketRegisterInfo(ToggleCookingPotLidPacket.ID, ToggleCookingPotLidPacket::decode, ToggleCookingPotLidHandler))
|
||||
|
||||
// TM Machine
|
||||
list.add(PacketRegisterInfo(SetActiveTMPacket.ID, SetActiveTMPacket::decode, SetActiveTMPacketHandler))
|
||||
list.add(PacketRegisterInfo(SetTMMachineContainerDataPacket.ID, SetTMMachineContainerDataPacket::decode, SetTMMachineContainerDataPacketHandler))
|
||||
|
||||
// Behaviour Packets
|
||||
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
|
||||
list.add(PacketRegisterInfo(DamageOnCollisionPacket.ID, DamageOnCollisionPacket::decode, DamageOnCollisionPacketHandler))
|
||||
|
||||
// Habitat blocks
|
||||
list.add(PacketRegisterInfo(SaveHabitatBlockSettingsPacket.ID, SaveHabitatBlockSettingsPacket::decode, SaveHabitatBlockSettingsHandler))
|
||||
|
||||
// Debug / cheats
|
||||
// Debug
|
||||
list.add(PacketRegisterInfo(RequestOpenRidingStatsDebugGUIPacket.ID, RequestOpenRidingStatsDebugGUIPacket::decode, RequestOpenRidingStatsDebugGUIHandler))
|
||||
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +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
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.npc.PartyComposition
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
|
||||
object CobblemonPartyCompositions : JsonDataRegistry<PartyComposition> {
|
||||
override val id: ResourceLocation = cobblemonResource("party_compositions")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val typeToken: TypeToken<PartyComposition> = TypeToken.get(PartyComposition::class.java)
|
||||
override val resourcePath: String = "party_compositions"
|
||||
override val observable = SimpleObservable<CobblemonPartyCompositions>()
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
val partyCompositions = mutableMapOf<ResourceLocation, PartyComposition>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
// probably worth syncing which exist, yeah. the deeper details probably not. I'll get to this eventually.
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PartyComposition>) {
|
||||
data.entries.forEach { it.value.id = it.key }
|
||||
partyCompositions.clear()
|
||||
partyCompositions.putAll(data)
|
||||
observable.emit(this)
|
||||
Cobblemon.LOGGER.info("Loaded ${data.size} party compositions.")
|
||||
}
|
||||
}
|
||||
@@ -1,60 +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
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.moves.MovesetBuilder
|
||||
import com.cobblemon.mod.common.api.npc.PartyPool
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.util.ScriptableIntRange
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IntRangeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.MovesetBuilderReferenceAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.PokemonPropertiesAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ScriptableIntRangeAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
|
||||
object CobblemonPartyPools : JsonDataRegistry<PartyPool> {
|
||||
override val id: ResourceLocation = cobblemonResource("party_pools")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val typeToken: TypeToken<PartyPool> = TypeToken.get(PartyPool::class.java)
|
||||
override val resourcePath: String = "party_pools"
|
||||
override val observable = SimpleObservable<CobblemonPartyPools>()
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(PokemonProperties::class.java, PokemonPropertiesAdapter(saveLong = false))
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapter(ScriptableIntRange::class.java, ScriptableIntRangeAdapter)
|
||||
.registerTypeAdapter(MovesetBuilder::class.java, MovesetBuilderReferenceAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
val partyPools = mutableMapOf<ResourceLocation, PartyPool>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
// probably worth syncing. Knowing the details might help exploit the server? lot of effort for little though.
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PartyPool>) {
|
||||
data.entries.forEach { it.value.id = it.key }
|
||||
partyPools.clear()
|
||||
partyPools.putAll(data)
|
||||
observable.emit(this)
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,6 @@ object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Regist
|
||||
// TODO after 1.7
|
||||
// @JvmField
|
||||
// val INCENSE_SWEET_KEY = createKey("incense_sweet", CobblemonBlocks.INCENSE_SWEET, 0, 1)
|
||||
@JvmField
|
||||
val HABITAT_BLOCK_KEY: ResourceKey<PoiType> = createKey("habitat_block", CobblemonBlocks.HABITAT_BLOCK, 0, 1)
|
||||
@JvmField
|
||||
val HABITAT_BLOCK = create(HABITAT_BLOCK_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.HABITAT_BLOCK), 0, 1))
|
||||
|
||||
private fun createKey(string: String, block: Block, maxTickets: Int, validRange: Int ): ResourceKey<PoiType> =
|
||||
ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string)).also { resourceKey ->
|
||||
|
||||
@@ -9,15 +9,14 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import net.minecraft.client.RecipeBookCategories
|
||||
import net.minecraft.world.inventory.RecipeBookType
|
||||
|
||||
enum class CobblemonRecipeCategories {
|
||||
|
||||
COOKING_POT_SEARCH("COBBLEMON_COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COBBLEMON_COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COBBLEMON_COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COBBLEMON_COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COBBLEMON_COOKING_POT_MISC");
|
||||
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COOKING_POT_MISC");
|
||||
|
||||
companion object {
|
||||
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
|
||||
@@ -36,9 +35,6 @@ enum class CobblemonRecipeCategories {
|
||||
fun toVanillaCategory(): RecipeBookCategories {
|
||||
return RecipeBookCategories.valueOf(this.id)
|
||||
}
|
||||
}
|
||||
|
||||
object CobblemonRecipeBookTypes {
|
||||
const val COOKING_POT_NAME = "COBBLEMON_COOKING_POT"
|
||||
val COOKING_POT: RecipeBookType = RecipeBookType.valueOf(COOKING_POT_NAME)
|
||||
|
||||
}
|
||||
@@ -37,9 +37,6 @@ object CobblemonSensors {
|
||||
@JvmField
|
||||
val POKEMON_DEFEND_OWNER = register("pokemon_owner_under_attack", ::DefendOwnerSensor)
|
||||
|
||||
@JvmField
|
||||
val ALPHA_LEVEL_MATCHING = register("alpha_level_matching", ::AlphaLevelMatchingSensor)
|
||||
|
||||
@JvmField
|
||||
val NEARBY_GROWABLE_CROPS = register("nearby_growable_crops", ::PokemonGrowableCropSensor)
|
||||
|
||||
|
||||
@@ -108,9 +108,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
@JvmField
|
||||
val LEVELUP = this.create("gui.levelup")
|
||||
|
||||
@JvmField
|
||||
val MOVE_LEARN = this.create("gui.move_learn")
|
||||
|
||||
@JvmField
|
||||
val PVN_BATTLE = this.create("battle.pvn.default")
|
||||
@JvmField
|
||||
@@ -139,15 +136,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
@JvmField
|
||||
val MULCH_REMOVE = this.create("block.mulch.remove")
|
||||
|
||||
@JvmField
|
||||
val MONITOR_BREAK = this.create("block.monitor.break")
|
||||
@JvmField
|
||||
val MONITOR_INSERT = this.create("block.monitor.insert")
|
||||
@JvmField
|
||||
val MONITOR_LOADING = this.create("block.monitor.loading")
|
||||
@JvmField
|
||||
val MONITOR_GLITCHING = this.create("block.monitor.glitching")
|
||||
|
||||
@JvmField
|
||||
val FOSSIL_MACHINE_ACTIVATE = this.create("block.fossil_machine.activate")
|
||||
@JvmField
|
||||
@@ -212,28 +200,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
@JvmField
|
||||
val TUMBLESTONE_STEP = this.create("block.tumblestone.step")
|
||||
|
||||
@JvmField
|
||||
val TM_USE = this.create("item.tm.use")
|
||||
@JvmField
|
||||
val TM_MACHINE_BURN_LOOP = this.create("block.tm_machine.burn_loop")
|
||||
@JvmField
|
||||
val TM_MACHINE_CRAFT = this.create("block.tm_machine.craft")
|
||||
@JvmField
|
||||
val TM_MACHINE_START = this.create("block.tm_machine.start")
|
||||
@JvmField
|
||||
val TM_MACHINE_OPEN = this.create("block.tm_machine.open")
|
||||
@JvmField
|
||||
val TM_MACHINE_CLOSE = this.create("block.tm_machine.close")
|
||||
@JvmField
|
||||
val TM_MACHINE_TM_INSERT = this.create("block.tm_machine.tm_insert")
|
||||
@JvmField
|
||||
val TM_MACHINE_TM_RETRIEVE = this.create("block.tm_machine.tm_retrieve")
|
||||
@JvmField
|
||||
val TM_MACHINE_ITEM_INSERT = this.create("block.tm_machine.item_insert")
|
||||
@JvmField
|
||||
val TM_MACHINE_ITEM_RETRIEVE = this.create("block.tm_machine.item_retrieve")
|
||||
|
||||
|
||||
@JvmField
|
||||
val EVOLUTION_STONE_BLOCK_BREAK = this.create("block.evolution_stone_block.break")
|
||||
@JvmField
|
||||
@@ -272,9 +238,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
@JvmField
|
||||
val BERRY_EAT_FULL = this.create("item.berry.eat.full")
|
||||
|
||||
@JvmField
|
||||
val APRICORN_HARVEST = this.create("block.apricorn.harvest")
|
||||
|
||||
@JvmField
|
||||
val BIG_ROOT_BREAK = this.create("block.big_root.break")
|
||||
@JvmField
|
||||
@@ -349,13 +312,9 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val RIDE_LOOP_LEATHER_MONO = create("ride.loop.leather.mono")
|
||||
val RIDE_LOOP_LEATHER = create("ride.loop.leather")
|
||||
@JvmField
|
||||
val RIDE_LOOP_PLUMAGE_MONO = create("ride.loop.plumage.mono")
|
||||
@JvmField
|
||||
val RIDE_LOOP_LEATHER_STEREO = create("ride.loop.leather.stereo")
|
||||
@JvmField
|
||||
val RIDE_LOOP_PLUMAGE_STEREO = create("ride.loop.plumage.stereo")
|
||||
val RIDE_LOOP_PLUMAGE = create("ride.loop.plumage")
|
||||
|
||||
@JvmField
|
||||
val MOVE_QUICKATTACK_TARGET = this.create("move.quickattack.target")
|
||||
@@ -421,35 +380,6 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
TUMBLESTONE_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_BREAK = this.create("block.type_gem_block.break")
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_BREAK = this.create("block.type_gem_cluster.break")
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_HIT = this.create("block.type_gem_block.hit")
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_PLACE = this.create("block.type_gem_block.place")
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_STEP = this.create("block.type_gem_block.step")
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_CLUSTER_SOUNDS = SoundType(1f, 1.1f,
|
||||
TYPE_GEM_CLUSTER_BREAK,
|
||||
TYPE_GEM_BLOCK_STEP,
|
||||
TYPE_GEM_BLOCK_PLACE,
|
||||
TYPE_GEM_BLOCK_HIT,
|
||||
TYPE_GEM_BLOCK_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val TYPE_GEM_BLOCK_SOUNDS = SoundType(1f, 1.1f,
|
||||
TYPE_GEM_BLOCK_BREAK,
|
||||
TYPE_GEM_BLOCK_STEP,
|
||||
TYPE_GEM_BLOCK_PLACE,
|
||||
TYPE_GEM_BLOCK_HIT,
|
||||
TYPE_GEM_BLOCK_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val EVOLUTION_STONE_BLOCK_SOUNDS = SoundType(1f, 1.1f,
|
||||
EVOLUTION_STONE_BLOCK_BREAK,
|
||||
@@ -631,31 +561,5 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
CAMPFIRE_POT_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val ITEM_BLOCK_PAPER_SMALL_PLACE = this.create("block.item_block.paper_small.place")
|
||||
@JvmField
|
||||
val ITEM_BLOCK_PAPER_SMALL_BREAK = this.create("block.item_block.paper_small.break")
|
||||
@JvmField
|
||||
val ITEM_BLOCK_PAPER_SMALL_SOUNDS = SoundType(1f, 1.1f,
|
||||
ITEM_BLOCK_PAPER_SMALL_BREAK,
|
||||
SoundEvents.WOOL_STEP,
|
||||
ITEM_BLOCK_PAPER_SMALL_PLACE,
|
||||
SoundEvents.WOOL_HIT,
|
||||
SoundEvents.WOOL_FALL
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val ITEM_BLOCK_PAPER_LARGE_PLACE = this.create("block.item_block.paper_large.place")
|
||||
@JvmField
|
||||
val ITEM_BLOCK_PAPER_LARGE_BREAK = this.create("block.item_block.paper_large.break")
|
||||
@JvmField
|
||||
val ITEM_BLOCK_PAPER_LARGE_SOUNDS = SoundType(1f, 1.1f,
|
||||
ITEM_BLOCK_PAPER_LARGE_BREAK,
|
||||
SoundEvents.WOOL_STEP,
|
||||
ITEM_BLOCK_PAPER_LARGE_PLACE,
|
||||
SoundEvents.WOOL_HIT,
|
||||
SoundEvents.WOOL_FALL
|
||||
)
|
||||
|
||||
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.createVariableRangeEvent(cobblemonResource(name)))
|
||||
}
|
||||
|
||||
@@ -89,14 +89,7 @@ object CobblemonTradeOffers {
|
||||
* @return The resulting list.
|
||||
*/
|
||||
fun resolveWanderingTradeOffers(): List<WandererTradeOffer> = listOf(
|
||||
WandererTradeOffer(false, listOf(
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 6, 1, 1, 6),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.SACCHARINE_SAPLING, 5, 1, 4, 1),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.HEARTY_GRAINS, 1, 1, 12, 1),
|
||||
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.CHIPPED_POT, 5, 1, 1, 2),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.MASTERPIECE_TEACUP, 5, 1, 1, 2)
|
||||
))
|
||||
WandererTradeOffer(false, listOf(VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6)))
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,9 +32,6 @@ object CobblemonCriteria : PlatformRegistry<Registry<CriterionTrigger<*>>, Resou
|
||||
@JvmField
|
||||
val CATCH_SHINY_POKEMON = this.create("catch_shiny_pokemon", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
|
||||
@JvmField
|
||||
val CATCH_ALPHA_POKEMON = this.create("catch_alpha_pokemon", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
|
||||
@JvmField
|
||||
val EGG_COLLECT = this.create("eggs_collected", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
|
||||
@@ -81,20 +78,8 @@ object CobblemonCriteria : PlatformRegistry<Registry<CriterionTrigger<*>>, Resou
|
||||
@JvmField
|
||||
val PLANT_TUMBLESTONE = this.create("plant_tumblestone", SimpleCriterionTrigger(PlantTumblestoneCriterion.CODEC))
|
||||
|
||||
@JvmField
|
||||
val PLANT_TYPE_GEM = this.create("plant_type_gem", SimpleCriterionTrigger(PlantTypeGemCriterion.CODEC))
|
||||
|
||||
val RIDING_STAT_BOOST = this.create("riding_stat_boost", SimpleCriterionTrigger(RidingStatBoostCriterion.CODEC))
|
||||
|
||||
@JvmField
|
||||
val LEARN_TM = this.create("has_learn_specific_tm", SimpleCriterionTrigger(LearnTMCriterion.CODEC))
|
||||
|
||||
@JvmField
|
||||
val LEARN_ALL_TM = this.create("has_learn_all_tm", SimpleCriterionTrigger(LearnAllTMCriterion.CODEC))
|
||||
|
||||
@JvmField
|
||||
val LEARN_TM_COUNT = this.create("tms_learned", SimpleCriterionTrigger(CountableCriterion.CODEC))
|
||||
|
||||
override val registry = BuiltInRegistries.TRIGGER_TYPES
|
||||
override val resourceKey = Registries.TRIGGER_TYPE
|
||||
}
|
||||
-50
@@ -1,50 +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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import java.util.Optional
|
||||
|
||||
class LearnTMContext(val tm: ResourceLocation)
|
||||
|
||||
class LearnTMCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val tm: String
|
||||
) : SimpleCriterionCondition<LearnTMContext>(playerCtx) {
|
||||
companion object {
|
||||
val CODEC: Codec<LearnTMCriterion> = RecordCodecBuilder.create { it.group(
|
||||
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(LearnTMCriterion::playerCtx),
|
||||
Codec.STRING.optionalFieldOf("tm", "any").forGetter(LearnTMCriterion::tm)
|
||||
).apply(it, ::LearnTMCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: LearnTMContext): Boolean {
|
||||
return tm == "any" || context.tm == tm.asIdentifierDefaultingNamespace()
|
||||
}
|
||||
}
|
||||
|
||||
class LearnAllTMContext
|
||||
|
||||
class LearnAllTMCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>
|
||||
) : SimpleCriterionCondition<LearnAllTMContext>(playerCtx) {
|
||||
companion object {
|
||||
val CODEC: Codec<LearnAllTMCriterion> = RecordCodecBuilder.create { it.group(
|
||||
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(LearnAllTMCriterion::playerCtx)
|
||||
).apply(it, ::LearnAllTMCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: LearnAllTMContext) = true
|
||||
}
|
||||
+39
-3
@@ -14,7 +14,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import java.util.*
|
||||
import java.util.Optional
|
||||
|
||||
class PlantTumblestoneContext(val pos: BlockPos, val block: TumblestoneBlock)
|
||||
|
||||
@@ -29,6 +29,42 @@ class PlantTumblestoneCriterion(
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: PlantTumblestoneContext): Boolean {
|
||||
return context.block.canGrow(player.level().getBlockState(context.pos), context.pos, player.level())
|
||||
return context.block.canGrow(context.pos, player.level())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///**
|
||||
// * A criterion condition for when a tumblestone block is planted
|
||||
// * @param id The identifier of the criterion
|
||||
// * @param predicate The predicate for the criterion
|
||||
// *
|
||||
// * @author Aethen
|
||||
// * @since 02/28/2024
|
||||
// */
|
||||
//class PlantTumblestoneCriterionCondition(id: Identifier, predicate: LootContextPredicate) :
|
||||
// SimpleCriterionCondition<PlantTumblestoneContext>(id, predicate) {
|
||||
// override fun toJson(json: JsonObject) {
|
||||
// // Add properties to json if needed. None needed for this criterion
|
||||
// }
|
||||
//
|
||||
// override fun fromJson(json: JsonObject) {
|
||||
// // Parse properties from json if needed. None needed for this criterion
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Checks if the tumblestone block can grow at the given position
|
||||
// * @param player The player that planted the tumblestone block
|
||||
// * @param context The context of the criterion
|
||||
// * @return True if the tumblestone block can grow at the given position, false otherwise
|
||||
// */
|
||||
// override fun matches(player: ServerPlayer, context: PlantTumblestoneContext): Boolean {
|
||||
// return context.tumbleStoneBlock.canGrow(context.pos, player.level())
|
||||
// }
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * The context of the [PlantTumblestoneCriterionCondition]
|
||||
// * @param pos The position of the tumblestone block
|
||||
// * @param tumbleStoneBlock The tumblestone block
|
||||
// */
|
||||
//open class PlantTumblestoneContext(var pos: BlockPos, var tumbleStoneBlock: TumblestoneBlock)
|
||||
-35
@@ -1,35 +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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.block.TypeGemClusterBlock
|
||||
import com.cobblemon.mod.common.block.TypeGemCoreBlock
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import java.util.*
|
||||
|
||||
class PlantTypeGemContext(val pos: BlockPos, val block: TypeGemClusterBlock)
|
||||
|
||||
class PlantTypeGemCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>
|
||||
): SimpleCriterionCondition<PlantTypeGemContext>(playerCtx) {
|
||||
|
||||
companion object {
|
||||
val CODEC: Codec<PlantTypeGemCriterion> = RecordCodecBuilder.create { it.group(
|
||||
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(PlantTypeGemCriterion::playerCtx)
|
||||
).apply(it, ::PlantTypeGemCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: PlantTypeGemContext): Boolean {
|
||||
return player.level().getBlockState(context.pos).block is TypeGemCoreBlock
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -48,7 +48,7 @@ class RidingStatBoostCriterion(
|
||||
val max = context.pokemon.pokemon.getMaxRideBoost(rideStat).toDouble()
|
||||
val min = context.pokemon.pokemon.getBaseRideStat(rideStat).toDouble()
|
||||
val value = context.pokemon.getRideStat(rideStat, ridingStyle, min, max)
|
||||
val isSufficient = (value >= this.statValue && this.statValue > 0.0) || !context.pokemon.pokemon.canApplyRideBoost(rideStat)
|
||||
val isSufficient = (value >= this.statValue && this.statValue > 0.0) || !context.pokemon.pokemon.canAddRideBoost(rideStat)
|
||||
if (isSufficient && this.rideStat == "any") {
|
||||
return true
|
||||
} else if (!isSufficient && this.rideStat == "all") {
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.DefendOwnerTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class DefendOwnerTaskConfig : SingleTaskConfig {
|
||||
|
||||
override fun getVariables(
|
||||
entity: LivingEntity,
|
||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||
): List<MoLangConfigVariable> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
behaviourConfigurationContext.addMemories(
|
||||
MemoryModuleType.ATTACK_TARGET,
|
||||
CobblemonMemories.NEAREST_VISIBLE_ATTACKER,
|
||||
)
|
||||
|
||||
return WrapperLivingEntityTask(
|
||||
DefendOwnerTask.create(),
|
||||
PokemonEntity::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -109,7 +109,7 @@ class PollinateFlowerTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
|
||||
override fun stop(level: ServerLevel, entity: LivingEntity, gameTime: Long) {
|
||||
hoverPos = null
|
||||
|
||||
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
|
||||
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
|
||||
}
|
||||
|
||||
@@ -105,7 +105,6 @@ interface TaskConfig {
|
||||
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
|
||||
cobblemonResource("manage_flight_in_battle") to ManageFlightInBattleTaskConfig::class.java,
|
||||
cobblemonResource("attack_hostile_mobs") to AttackHostileMobsTaskConfig::class.java,
|
||||
cobblemonResource("defend_owner") to DefendOwnerTaskConfig::class.java,
|
||||
cobblemonResource("move_to_sweet_berry_bush") to MoveToSweetBerryBushTaskConfig::class.java,
|
||||
cobblemonResource("stop_moving_to_sweet_berry_bush") to StopTryingToReachSweetBerryBushTaskConfig::class.java,
|
||||
cobblemonResource("harvest_sweet_berry_bush") to HarvestSweetBerryBushTaskConfig::class.java,
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangV
|
||||
import com.cobblemon.mod.common.entity.OmniPathingEntity
|
||||
import com.cobblemon.mod.common.entity.ai.CobblemonRandomSurfacePos
|
||||
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.mainThreadRuntime
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
@@ -185,12 +184,6 @@ class WanderTaskConfig : SingleTaskConfig {
|
||||
|
||||
if (targetVec == null) continue
|
||||
|
||||
// Ignore pathing targets outside of the pasture zone if the pokemon is pastured.
|
||||
val tethering = (entity as? PokemonEntity)?.tethering
|
||||
if (tethering?.canRoamTo(BlockPos.containing(targetVec)) == false) {
|
||||
continue
|
||||
}
|
||||
|
||||
pos = applyHeightConstraints(
|
||||
pos = BlockPos.containing(targetVec),
|
||||
minimumHeight = minimumHeight,
|
||||
|
||||
+17
-41
@@ -22,21 +22,18 @@ import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.FleeableBattleActor
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFleeAttemptEvent
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.BattleEvSource
|
||||
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.api.text.white
|
||||
import com.cobblemon.mod.common.api.text.yellow
|
||||
import com.cobblemon.mod.common.battles.ActiveBattlePokemon
|
||||
import com.cobblemon.mod.common.battles.BattleCaptureAction
|
||||
import com.cobblemon.mod.common.battles.BattleFormat
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.battles.BattleSide
|
||||
import com.cobblemon.mod.common.battles.FleeAttemptActionResponse
|
||||
import com.cobblemon.mod.common.battles.ForfeitActionResponse
|
||||
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
||||
import com.cobblemon.mod.common.battles.dispatch.BattleDispatch
|
||||
@@ -51,9 +48,7 @@ import com.cobblemon.mod.common.entity.npc.NPCBattleActor
|
||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.requirements.DefeatRequirement
|
||||
@@ -137,13 +132,11 @@ open class PokemonBattle(
|
||||
|
||||
var dispatchResult = GO
|
||||
val dispatches = ConcurrentLinkedDeque<BattleDispatch>()
|
||||
val afterDispatches = mutableListOf<() -> Unit>()
|
||||
|
||||
val captureActions = mutableListOf<BattleCaptureAction>()
|
||||
|
||||
val majorBattleActions = hashMapOf<UUID, BattleMessage>()
|
||||
|
||||
/** Monotonically increasing counter to track faint ordering within this battle. */
|
||||
var faintCounter = 0
|
||||
val minorBattleActions = hashMapOf<UUID, BattleMessage>()
|
||||
val contextManager = ContextManager()
|
||||
|
||||
@@ -251,23 +244,12 @@ open class PokemonBattle(
|
||||
|
||||
fun end() {
|
||||
ended = true
|
||||
val awardToFainted = Cobblemon.config.awardExperienceToFaintedPokemon
|
||||
val awardOnLoss = Cobblemon.config.awardExperienceOnBattleLoss
|
||||
this.actors.forEach { actor ->
|
||||
val faintedPokemons = actor.pokemonList.filter { it.health <= 0 }
|
||||
actor.getSide().getOppositeSide().actors.forEach { opponent ->
|
||||
val opponentPokemons = if (awardToFainted) opponent.pokemonList else opponent.pokemonList.filter { it.health > 0 }
|
||||
val opponentNonFaintedPokemons = opponent.pokemonList.filter { it.health > 0 }
|
||||
faintedPokemons.forEach { faintedPokemon ->
|
||||
for (opponentPokemon in opponentPokemons) {
|
||||
// Faint-order check: if awarding XP to fainted pokemon, only award for enemies that fainted before this pokemon did
|
||||
if (awardToFainted) {
|
||||
val enemyFaintedAt = faintedPokemon.faintedAt ?: continue
|
||||
val opponentFaintedAt = opponentPokemon.faintedAt
|
||||
if (opponentFaintedAt != null && opponentFaintedAt <= enemyFaintedAt) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
for (opponentPokemon in opponentNonFaintedPokemons) {
|
||||
val facedFainted = opponentPokemon.facedOpponents.contains(faintedPokemon)
|
||||
val pokemon = opponentPokemon.effectedPokemon
|
||||
if (facedFainted) {
|
||||
@@ -288,8 +270,7 @@ open class PokemonBattle(
|
||||
else -> continue
|
||||
}
|
||||
val experience = Cobblemon.experienceCalculator.calculate(opponentPokemon, faintedPokemon, multiplier)
|
||||
val enemyTeamWiped = actor.pokemonList.all { it.health <= 0 }
|
||||
if (experience > 0 && (enemyTeamWiped || awardOnLoss)) {
|
||||
if (experience > 0 && actor.pokemonList.all { it.health <= 0 }) {
|
||||
opponent.awardExperience(opponentPokemon, experience)
|
||||
}
|
||||
Cobblemon.evYieldCalculator.calculate(opponentPokemon, faintedPokemon).forEach { (stat, amount) ->
|
||||
@@ -323,8 +304,7 @@ open class PokemonBattle(
|
||||
.forEach{it.pokemon.heal()}
|
||||
actors.forEach { actor ->
|
||||
actor.pokemonList.forEach { battlePokemon ->
|
||||
battlePokemon.postBattlePokemonOperations.forEach { it(battlePokemon) }
|
||||
battlePokemon.entity?.let { entity -> battlePokemon.postBattleEntityOperations.forEach { it(entity) } }
|
||||
battlePokemon.entity?.let { entity -> battlePokemon.postBattleEntityOperation(entity) }
|
||||
if (battlePokemon.effectedPokemon.entity != null
|
||||
&& battlePokemon.effectedPokemon.entity?.beamMode == 0
|
||||
&& battlePokemon.effectedPokemon.entity?.platform != PlatformType.NONE) {
|
||||
@@ -399,10 +379,12 @@ open class PokemonBattle(
|
||||
|
||||
fun dispatch(dispatcher: () -> DispatchResult) {
|
||||
dispatches.add(BattleDispatch { dispatcher() })
|
||||
|
||||
}
|
||||
|
||||
fun dispatchToFront(dispatcher: () -> DispatchResult) {
|
||||
dispatches.addFirst(BattleDispatch { dispatcher() })
|
||||
|
||||
}
|
||||
|
||||
fun dispatchWaitingToFront(delaySeconds: Float = 1F, dispatcher: () -> Unit) {
|
||||
@@ -453,12 +435,21 @@ open class PokemonBattle(
|
||||
dispatches.addFirst(dispatcher)
|
||||
}
|
||||
|
||||
fun doWhenClear(action: () -> Unit) {
|
||||
afterDispatches.add(action)
|
||||
}
|
||||
|
||||
fun tick() {
|
||||
try {
|
||||
while (dispatchResult.canProceed()) {
|
||||
val dispatch = dispatches.poll() ?: break
|
||||
dispatchResult = dispatch(this)
|
||||
}
|
||||
|
||||
if (dispatches.isEmpty()) {
|
||||
afterDispatches.toList().forEach { it() }
|
||||
afterDispatches.clear()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LOGGER.error("Exception while ticking a battle. Saving battle log.", e)
|
||||
val message = battleLang("crash").red()
|
||||
@@ -507,13 +498,12 @@ open class PokemonBattle(
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
writeShowdownAction(">forcetie") // This will terminate the Showdown connection
|
||||
end()
|
||||
writeShowdownAction(">forcetie") // This will terminate the Showdown connection
|
||||
}
|
||||
|
||||
fun checkForInputDispatch() {
|
||||
if (checkForfeit()) return // ignore actors that are still choosing, their choices don't matter anymore
|
||||
if (checkFleeAttempt()) return
|
||||
val readyToInput = (actors.any { !it.mustChoose && it.responses.isNotEmpty() } && actors.none { it.mustChoose })
|
||||
if (readyToInput && captureActions.isEmpty()) {
|
||||
actors.filter { it.responses.isNotEmpty() }.forEach { it.writeShowdownResponse() }
|
||||
@@ -521,20 +511,6 @@ open class PokemonBattle(
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkFleeAttempt(): Boolean {
|
||||
val runner = actors.find { it.responses.any { it is FleeAttemptActionResponse } } as? PlayerBattleActor ?: return false
|
||||
CobblemonEvents.BATTLE_FLEE_ATTEMPT.post(BattleFleeAttemptEvent(this, runner))
|
||||
runner.responses.clear()
|
||||
|
||||
runner.mustChoose = true
|
||||
runner.request?.let { runner.sendUpdate(BattleQueueRequestPacket(it)) }
|
||||
runner.sendUpdate(BattleMakeChoicePacket())
|
||||
|
||||
runner.entity?.sendSystemMessage(battleLang("run_prompt").white())
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/** Forces Showdown to end the battle when a [BattleActor] chooses to forfeit. */
|
||||
private fun checkForfeit(): Boolean {
|
||||
val forfeit = actors.find { it.responses.any { it is ForfeitActionResponse } }
|
||||
|
||||
+5
-8
@@ -8,6 +8,8 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.battles.model.actor
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
@@ -74,7 +76,7 @@ abstract class BattleActor(
|
||||
fun turn() {
|
||||
val request = request ?: return
|
||||
responses.clear()
|
||||
if (activePokemon.any { it.isAlive() }) {
|
||||
if(activePokemon.any { it.isAlive() }) {
|
||||
mustChoose = true
|
||||
sendUpdate(BattleMakeChoicePacket())
|
||||
}
|
||||
@@ -88,15 +90,15 @@ abstract class BattleActor(
|
||||
}
|
||||
}
|
||||
|
||||
fun postUpdate() {
|
||||
fun upkeep() {
|
||||
val request = request ?: return
|
||||
val forceSwitchPokemon = request.forceSwitch.mapIndexedNotNull { index, b -> if (b) activePokemon[index] else null }
|
||||
if (forceSwitchPokemon.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
mustChoose = true // This must happen before the sendUpdate, not after, otherwise AI-driven actors will get locked (they may reply instantly)
|
||||
sendUpdate(BattleMakeChoicePacket())
|
||||
mustChoose = true
|
||||
}
|
||||
|
||||
fun setActionResponses(responses: List<ShowdownActionResponse>) {
|
||||
@@ -152,11 +154,6 @@ abstract class BattleActor(
|
||||
open fun sendMessage(component: Component) {
|
||||
sendUpdate(BattleMessagePacket(component))
|
||||
}
|
||||
/**
|
||||
* Called when this actor's Pokemon uses a move. Default implementation does nothing.
|
||||
* Subclasses (NPC-backed actors, players, etc) may override to trigger animations or UI.
|
||||
*/
|
||||
open fun onUseMove(user: BattlePokemon, target: BattlePokemon?) {}
|
||||
open fun awardExperience(battlePokemon: BattlePokemon, experience: Int) {}
|
||||
open fun sendUpdate(packet: NetworkPacket<*>) {}
|
||||
|
||||
|
||||
+109
-36
@@ -9,8 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.util.math.geometry.toDegrees
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import net.minecraft.util.FastColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
private val colourMap = mapOf(
|
||||
Flavour.SPICY to 0xFEB37D,
|
||||
@@ -29,30 +34,27 @@ private val bubbleColourMap = mapOf(
|
||||
)
|
||||
|
||||
fun getColourMixFromSeasonings(seasonings: List<ItemStack>, forBubbles: Boolean = false): Int? {
|
||||
val flavourValues = mutableMapOf<Flavour, Int>()
|
||||
for (seasoning in seasonings) {
|
||||
val flavours = Seasonings.getFlavoursFromItemStack(seasoning) ?: continue
|
||||
for ((flavour, value) in flavours.entries) {
|
||||
flavourValues[flavour] = (flavourValues[flavour] ?: 0) + value
|
||||
}
|
||||
}
|
||||
val flavors = seasonings
|
||||
.mapNotNull { Seasonings.getFlavoursFromItemStack(it) }
|
||||
.flatMap { it.entries }
|
||||
.groupingBy { it.key }
|
||||
.fold(0) { acc, entry -> acc + entry.value }
|
||||
|
||||
if (flavourValues.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
if (flavors.isEmpty()) return null
|
||||
|
||||
val maxFlavorValue = flavourValues.values.maxOrNull()
|
||||
val dominantFlavours = flavourValues.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
val maxFlavorValue = flavors.values.maxOrNull()
|
||||
val dominantFlavors = flavors.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
|
||||
return getColourMixFromFlavours(dominantFlavours, forBubbles)
|
||||
return getColourMixFromFlavours(dominantFlavors, forBubbles)
|
||||
}
|
||||
|
||||
fun getColourMixFromFlavours(dominantFlavours: List<Flavour>, forBubbles: Boolean = false): Int? {
|
||||
val colors =
|
||||
dominantFlavours
|
||||
.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
dominantFlavours.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
.map { FastColor.ARGB32.opaque(it) }
|
||||
|
||||
if (colors.isEmpty()) return null
|
||||
|
||||
return getColourMixFromColors(colors)
|
||||
}
|
||||
|
||||
@@ -60,33 +62,104 @@ fun getColourMixFromRideStatBoosts(dominantBoosts: Iterable<RidingStat>, forBubb
|
||||
return getColourMixFromFlavours(dominantBoosts.map { it.flavour }, forBubbles)
|
||||
}
|
||||
|
||||
// Mixing RGB colors directly often gives poor results
|
||||
// Converting them to HSL and averaging hues circularly produces more natural blends
|
||||
fun getColourMixFromColors(colors: List<Int>): Int? {
|
||||
if (colors.isEmpty()) return null
|
||||
if (colors.size == 1) return colors[0]
|
||||
|
||||
val firstWeight = 0.7f
|
||||
val otherWeightTotal = 1f - firstWeight
|
||||
val otherWeight = otherWeightTotal / (colors.size - 1)
|
||||
val hslColors = colors.map {
|
||||
val red = FastColor.ARGB32.red(it)
|
||||
val green = FastColor.ARGB32.green(it)
|
||||
val blue = FastColor.ARGB32.blue(it)
|
||||
|
||||
var alphaSum = 0f
|
||||
var redSum = 0f
|
||||
var greenSum = 0f
|
||||
var blueSum = 0f
|
||||
|
||||
for (i in colors.indices) {
|
||||
val weight = if (i == 0) firstWeight else otherWeight
|
||||
val color = colors[i]
|
||||
|
||||
alphaSum += FastColor.ARGB32.alpha(color) * weight
|
||||
redSum += FastColor.ARGB32.red(color) * weight
|
||||
greenSum += FastColor.ARGB32.green(color) * weight
|
||||
blueSum += FastColor.ARGB32.blue(color) * weight
|
||||
rgbToHsl(red, green, blue)
|
||||
}
|
||||
|
||||
return FastColor.ARGB32.color(
|
||||
alphaSum.toInt(),
|
||||
redSum.toInt(),
|
||||
greenSum.toInt(),
|
||||
blueSum.toInt()
|
||||
val hues = hslColors.map { it.h.toDouble() }
|
||||
val huesAverage = hueAverage(hues).toFloat()
|
||||
val saturations = hslColors.map { it.s }
|
||||
val saturationsAverage = average(saturations)
|
||||
val lightness = hslColors.map { it.l }
|
||||
val lightnessAverage = average(lightness)
|
||||
|
||||
val rgbColor = hslToRgb(huesAverage, saturationsAverage, lightnessAverage)
|
||||
|
||||
return FastColor.ARGB32.color(rgbColor.r, rgbColor.g, rgbColor.b)
|
||||
}
|
||||
|
||||
// Based on https://iter.ca/post/hue-avg
|
||||
fun hueAverage(hues: List<Double>): Float {
|
||||
val points = hues.map { hue ->
|
||||
val rad = hue.toRadians()
|
||||
Pair(cos(rad), sin(rad))
|
||||
}
|
||||
|
||||
val avgX = points.sumOf { it.first.toDouble() } / points.size
|
||||
val avgY = points.sumOf { it.second.toDouble() } / points.size
|
||||
|
||||
var degrees = atan2(avgY, avgX).toDegrees()
|
||||
if (degrees < 0) {
|
||||
degrees += 360f
|
||||
} else if (degrees > 360) {
|
||||
degrees -= 360f
|
||||
}
|
||||
|
||||
return degrees
|
||||
}
|
||||
|
||||
fun average(values: List<Float>): Float {
|
||||
if (values.isEmpty()) return 0f
|
||||
return values.sum() / values.size
|
||||
}
|
||||
|
||||
data class HSL(val h: Float, val s: Float, val l: Float)
|
||||
|
||||
fun rgbToHsl(r: Int, g: Int, b: Int): HSL {
|
||||
val rf = r / 255f
|
||||
val gf = g / 255f
|
||||
val bf = b / 255f
|
||||
|
||||
val max = maxOf(rf, gf, bf)
|
||||
val min = minOf(rf, gf, bf)
|
||||
val delta = max - min
|
||||
|
||||
var h = 0f
|
||||
val l = (max + min) / 2f
|
||||
val s = if (delta == 0f) 0f else delta / (1f - kotlin.math.abs(2f * l - 1f))
|
||||
|
||||
if (delta != 0f) {
|
||||
h = when (max) {
|
||||
rf -> ((gf - bf) / delta) % 6f
|
||||
gf -> ((bf - rf) / delta) + 2f
|
||||
else -> ((rf - gf) / delta) + 4f
|
||||
}
|
||||
h *= 60f
|
||||
if (h < 0) h += 360f
|
||||
}
|
||||
|
||||
return HSL(h, s, l)
|
||||
}
|
||||
|
||||
data class RGB(val r: Int, val g: Int, val b: Int)
|
||||
|
||||
fun hslToRgb(h: Float, s: Float, l: Float): RGB {
|
||||
val c = (1f - kotlin.math.abs(2f * l - 1f)) * s
|
||||
val x = c * (1f - kotlin.math.abs((h / 60f) % 2f - 1f))
|
||||
val m = l - c / 2f
|
||||
|
||||
val (rf, gf, bf) = when {
|
||||
h < 60f -> Triple(c, x, 0f)
|
||||
h < 120f -> Triple(x, c, 0f)
|
||||
h < 180f -> Triple(0f, c, x)
|
||||
h < 240f -> Triple(0f, x, c)
|
||||
h < 300f -> Triple(x, 0f, c)
|
||||
else -> Triple(c, 0f, x)
|
||||
}
|
||||
|
||||
return RGB(
|
||||
((rf + m) * 255).toInt().coerceIn(0, 255),
|
||||
((gf + m) * 255).toInt().coerceIn(0, 255),
|
||||
((bf + m) * 255).toInt().coerceIn(0, 255)
|
||||
)
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking.effects
|
||||
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectCategory
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class CleanseAllEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xFFFFFF) {
|
||||
override fun isInstantenous() = true
|
||||
override fun applyInstantenousEffect(source: Entity?, indirect: Entity?, target: LivingEntity, amplifier: Int, proximity: Double) {
|
||||
target.removeAllEffects()
|
||||
}
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = false
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking.effects
|
||||
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectCategory
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class CleanseNegativeEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xFFFFFF) {
|
||||
override fun isInstantenous() = true
|
||||
override fun applyInstantenousEffect(source: Entity?, indirect: Entity?, target: LivingEntity, amplifier: Int, proximity: Double) {
|
||||
val snapshot = target.activeEffects.toList()
|
||||
for (ei in snapshot) {
|
||||
if (ei.effect.value().category == MobEffectCategory.HARMFUL) {
|
||||
target.removeEffect(ei.effect)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = false
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking.effects
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.stats.Stats
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectCategory
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class MentalRestorationEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xAA66FF) {
|
||||
override fun applyEffectTick(entity: LivingEntity, amplifier: Int): Boolean {
|
||||
if (entity is ServerPlayer) {
|
||||
val stats = entity.stats
|
||||
val statType = Stats.CUSTOM.get(Stats.TIME_SINCE_REST)
|
||||
val current = stats.getValue(statType)
|
||||
val reduction = 31 * (amplifier + 1)// reduce by half a minute every second per level (30 ticks removed per tick + 1 to account for the tick passing)
|
||||
val newValue = Math.max(current - reduction, 0)
|
||||
stats.setValue(entity, statType, newValue)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.data
|
||||
|
||||
import com.cobblemon.mod.common.api.net.Decodable
|
||||
import com.cobblemon.mod.common.api.net.Encodable
|
||||
|
||||
// TODO this is implemented in multiple places but unused. Can we scratch this?
|
||||
/**
|
||||
* Represents an object that will possibly be synchronized to the client during datapack synchronization.
|
||||
*
|
||||
* @param T The type of the object being synchronized.
|
||||
*
|
||||
* @author Licious
|
||||
* @since October 14th, 2022
|
||||
*/
|
||||
interface ClientDataSynchronizer<T> : Decodable, Encodable {
|
||||
|
||||
/**
|
||||
* Compares an object of type [T] with this instance to see if synchronization is necessary.
|
||||
*
|
||||
* @param other The other instance of type [T].
|
||||
* @return If synchronization is necessary.
|
||||
*/
|
||||
fun shouldSynchronize(other: T): Boolean
|
||||
|
||||
}
|
||||
@@ -14,11 +14,9 @@ import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.toBlockPos
|
||||
import com.google.gson.JsonElement
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.core.component.DataComponentMap
|
||||
import net.minecraft.core.component.DataComponentPatch
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.RegistryOps
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
@@ -42,7 +40,7 @@ open class ItemDropEntry : DropEntry {
|
||||
override var maxSelectableTimes = 1
|
||||
open val dropMethod: ItemDropMethod? = null
|
||||
open var item = ResourceLocation.parse("minecraft:fish")
|
||||
open val components: JsonElement? = null
|
||||
open val components: DataComponentMap? = null
|
||||
|
||||
override fun drop(entity: LivingEntity?, world: ServerLevel, pos: Vec3, player: ServerPlayer?) {
|
||||
val item = world.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: return LOGGER.error("Unable to load drop item: $item")
|
||||
@@ -55,15 +53,11 @@ open class ItemDropEntry : DropEntry {
|
||||
it
|
||||
}
|
||||
}
|
||||
if (components != null) {
|
||||
val registryOps = RegistryOps.create(JsonOps.INSTANCE, world.registryAccess())
|
||||
val decodeResult = DataComponentPatch.CODEC.parse(registryOps, components)
|
||||
decodeResult.ifSuccess { patch ->
|
||||
stack.applyComponentsAndValidate(patch)
|
||||
}.ifError { error ->
|
||||
LOGGER.error("Unable to parse components for drop item $item: ${error.message()}")
|
||||
}
|
||||
val builder = DataComponentPatch.builder()
|
||||
components?.forEach {
|
||||
builder.set(it)
|
||||
}
|
||||
stack.applyComponentsAndValidate(builder.build())
|
||||
|
||||
if (dropMethod == ItemDropMethod.ON_PLAYER && player != null) {
|
||||
world.addFreshEntity(ItemEntity(player.level(), player.x, player.y, player.z, stack))
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.events
|
||||
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFaintedEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFleeAttemptEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleStartedEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleVictoryEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.instruction.FormeChangeEvent
|
||||
@@ -23,21 +22,9 @@ import com.cobblemon.mod.common.api.events.berry.BerryMutationResultEvent
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryYieldCalculationEvent
|
||||
import com.cobblemon.mod.common.api.events.cooking.PokeSnackSpawnPokemonEvent
|
||||
import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.PokemonEntityLoadEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveToWorldEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.SpawnBucketChosenEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.SpawnEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.*
|
||||
import com.cobblemon.mod.common.api.events.farming.ApricornHarvestEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.BaitConsumedEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.BaitEffectFunctionRegistryEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.BaitSetEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.BaitSpawnPokemonEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.BobberSpawnPokemonEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.PokerodCastEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.PokerodReelEvent
|
||||
import com.cobblemon.mod.common.api.events.habitats.HabitatSpawnActivatedEvent
|
||||
import com.cobblemon.mod.common.api.events.habitats.SaveHabitatBlockSettingsEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.*
|
||||
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokeball.PokeBallCaptureCalculatedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokeball.PokemonCatchRateEvent
|
||||
@@ -52,11 +39,7 @@ import com.cobblemon.mod.common.api.events.pokemon.healing.PokemonHealedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
|
||||
import com.cobblemon.mod.common.api.events.starter.StarterChosenEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.ChangePCBoxWallpaperEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.RenamePCBoxEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.WallpaperCollectionEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.WallpaperUnlockedEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.*
|
||||
import com.cobblemon.mod.common.api.events.world.BigRootPropagatedEvent
|
||||
import com.cobblemon.mod.common.api.reactive.CancelableObservable
|
||||
import com.cobblemon.mod.common.api.reactive.EventObservable
|
||||
@@ -127,9 +110,6 @@ object CobblemonEvents {
|
||||
@JvmField
|
||||
val BATTLE_STARTED_POST = EventObservable<BattleStartedEvent.Post>()
|
||||
|
||||
@JvmField
|
||||
val BATTLE_FLEE_ATTEMPT = EventObservable<BattleFleeAttemptEvent>()
|
||||
|
||||
@JvmField
|
||||
val BATTLE_FLED = EventObservable<BattleFledEvent>()
|
||||
|
||||
@@ -381,12 +361,4 @@ object CobblemonEvents {
|
||||
// -------------------------------------------------------------------------------------
|
||||
@JvmField
|
||||
val SELECT_DRIVER = EventObservable<SelectDriverEvent>()
|
||||
|
||||
// Habitats
|
||||
@JvmField
|
||||
val HABITAT_SPAWN_ACTIVATED = CancelableObservable<HabitatSpawnActivatedEvent>()
|
||||
@JvmField
|
||||
val HABITAT_SETTINGS_SAVED_PRE = CancelableObservable<SaveHabitatBlockSettingsEvent.Pre>()
|
||||
@JvmField
|
||||
val HABITAT_SETTINGS_SAVED_POST = EventObservable<SaveHabitatBlockSettingsEvent.Post>()
|
||||
}
|
||||
|
||||
+3
-6
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.api.events.battles
|
||||
|
||||
import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BattleContext
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
|
||||
@@ -26,8 +25,7 @@ import com.cobblemon.mod.common.util.asArrayValue
|
||||
data class BattleFaintedEvent(
|
||||
override val battle: PokemonBattle,
|
||||
val killed: BattlePokemon,
|
||||
val context: BattleContext,
|
||||
val pnx: String
|
||||
val context: BattleContext
|
||||
) : BattleEvent {
|
||||
val structContext = mutableMapOf<String, MoValue>(
|
||||
"battle" to battle.struct,
|
||||
@@ -35,7 +33,6 @@ data class BattleFaintedEvent(
|
||||
"npcs" to battle.actors.filter { it.type == ActorType.NPC }.asArrayValue { it.struct },
|
||||
"wild_pokemon" to battle.actors.filter { it.type == ActorType.WILD }.asArrayValue { it.struct },
|
||||
"pokemon" to killed.struct,
|
||||
"context" to context.getStruct(),
|
||||
"pnx" to StringValue(pnx)
|
||||
"context" to context.getStruct()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.battles
|
||||
|
||||
import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
|
||||
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
|
||||
/**
|
||||
* Event fired when a [PokemonBattle] is fled by a [PlayerBattleActor].
|
||||
*
|
||||
* @author saultsc
|
||||
* @since March 31th 2026
|
||||
*/
|
||||
|
||||
data class BattleFleeAttemptEvent(
|
||||
override val battle: PokemonBattle,
|
||||
val player: PlayerBattleActor
|
||||
) : BattleEvent {
|
||||
val context = mutableMapOf<String, MoValue>(
|
||||
"battle" to battle.struct,
|
||||
"players" to battle.actors.filter { it.type == ActorType.PLAYER }.asArrayValue { it.struct },
|
||||
"npcs" to battle.actors.filter { it.type == ActorType.NPC }.asArrayValue { it.struct },
|
||||
"wild_pokemon" to battle.actors.filter { it.type == ActorType.WILD }.asArrayValue { it.struct }
|
||||
)
|
||||
}
|
||||
+3
-5
@@ -25,8 +25,7 @@ import com.cobblemon.mod.common.util.asArrayValue
|
||||
data class FormeChangeEvent(
|
||||
override val battle: PokemonBattle,
|
||||
val pokemon: BattlePokemon,
|
||||
val formeName: String,
|
||||
val pnx: String
|
||||
val formeName: String
|
||||
) : BattleEvent {
|
||||
val context = mutableMapOf(
|
||||
"battle" to battle.struct,
|
||||
@@ -34,7 +33,6 @@ data class FormeChangeEvent(
|
||||
"npcs" to battle.actors.filter { it.type == ActorType.NPC }.asArrayValue { it.struct },
|
||||
"wild_pokemon" to battle.actors.filter { it.type == ActorType.WILD }.asArrayValue { it.struct },
|
||||
"pokemon" to pokemon.struct,
|
||||
"forme" to StringValue(formeName),
|
||||
"pnx" to StringValue(pnx)
|
||||
"forme" to StringValue(formeName)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events.entity
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
|
||||
@@ -20,7 +21,7 @@ class SpawnBucketChosenEvent(
|
||||
/** The cause of the spawn. */
|
||||
val spawnCause: SpawnCause,
|
||||
/** The bucket that was chosen. You can alter this. */
|
||||
var bucket: String,
|
||||
var bucket: SpawnBucket,
|
||||
/** The final weights that were used to make the choice. */
|
||||
val bucketWeights: Map<String, Float>
|
||||
val bucketWeights: Map<SpawnBucket, Float>
|
||||
)
|
||||
@@ -10,9 +10,7 @@ package com.cobblemon.mod.common.api.events.entity
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import net.minecraft.world.entity.Entity
|
||||
|
||||
/**
|
||||
@@ -23,9 +21,4 @@ import net.minecraft.world.entity.Entity
|
||||
* @author Hiroku
|
||||
* @since April 22nd, 2023
|
||||
*/
|
||||
class SpawnEvent<T : Entity>(val entity: T, val spawnablePosition: SpawnablePosition) : Cancelable() {
|
||||
val cause: SpawnCause
|
||||
get() = spawnablePosition.cause
|
||||
val spawner: Spawner
|
||||
get() = spawnablePosition.spawner
|
||||
}
|
||||
class SpawnEvent<T : Entity>(val entity: T, val spawnablePosition: SpawnablePosition) : Cancelable()
|
||||
+4
-3
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.api.events.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@@ -26,7 +27,7 @@ interface BaitSpawnPokemonEvent {
|
||||
*/
|
||||
data class Pre(
|
||||
val bobber: PokeRodFishingBobberEntity, // todo replace this with the bait entity
|
||||
val chosenBucket: String,
|
||||
val chosenBucket: SpawnBucket,
|
||||
val rod: ItemStack
|
||||
) : Cancelable(), BobberSpawnPokemonEvent
|
||||
|
||||
@@ -37,7 +38,7 @@ interface BaitSpawnPokemonEvent {
|
||||
* @param pokemon The Pokemon that is modified.
|
||||
*/
|
||||
data class Modify(
|
||||
val chosenBucket: String,
|
||||
val chosenBucket: SpawnBucket,
|
||||
val rod: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent
|
||||
@@ -51,7 +52,7 @@ interface BaitSpawnPokemonEvent {
|
||||
*/
|
||||
data class Post(
|
||||
val bobber: PokeRodFishingBobberEntity,
|
||||
val chosenBucket: String,
|
||||
val chosenBucket: SpawnBucket,
|
||||
val bait: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent
|
||||
|
||||
+3
-1
@@ -8,10 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
|
||||
/**
|
||||
* Event that is fired when a bucket is chosen by the bobber.
|
||||
* @param chosenBucket The bucket that is chosen.
|
||||
* @param buckets The list of buckets that the bobber can choose from.
|
||||
* @param luckOfTheSeaLevel The level of the Luck of the Sea enchantment on the rod.
|
||||
*/
|
||||
class BobberBucketChosenEvent(var chosenBucket: String, val buckets: MutableList<String>, val luckOfTheSeaLevel: Int)
|
||||
class BobberBucketChosenEvent(var chosenBucket: SpawnBucket, val buckets: MutableList<SpawnBucket>, val luckOfTheSeaLevel: Int)
|
||||
+5
-2
@@ -12,7 +12,10 @@ import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
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.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnAction
|
||||
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
@@ -70,8 +73,8 @@ interface BobberSpawnPokemonEvent {
|
||||
val bait: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent {
|
||||
val context = mutableMapOf(
|
||||
"chosen_bucket" to StringValue(spawnAction.bucket),
|
||||
val context = mutableMapOf<String, MoValue>(
|
||||
"chosen_bucket" to ObjectValue(spawnAction.bucket, { it.name }),
|
||||
"bait" to pokemon.level().itemRegistry.wrapAsHolder(bait.item).asMoLangValue(Registries.ITEM),
|
||||
"pokemon_entity" to pokemon.asMoLangValue()
|
||||
)
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.habitats
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.habitats.spawningstyle.ActivatedHabitatSpawning
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.FixedAreaSpawner
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
|
||||
/**
|
||||
* Event that fires when a habitat is about to attempt to spawn Pokémon. Cancelling this event will prevent
|
||||
* the habitat block from attempting to spawn anything for this activation.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 15th,2026
|
||||
*/
|
||||
class HabitatSpawnActivatedEvent(
|
||||
/** The habitat block entity that is responsible for the spawn. */
|
||||
val habitatBlockEntity: HabitatBlockEntity,
|
||||
/** The activation settings. You could have got it from the block entity but this is easier. */
|
||||
val activatedHabitatSpawning: ActivatedHabitatSpawning,
|
||||
/** The [SpawnCause] that will be used in the spawn action. This may contain a player that is nearest to the block. */
|
||||
var cause: SpawnCause,
|
||||
/** The maximum number of Pokémon the block will consider spawning (provided there is space). */
|
||||
var maxSpawns: Int
|
||||
) : Cancelable() {
|
||||
/** The spawner representing the habitat. */
|
||||
val spawner: FixedAreaSpawner
|
||||
get() = activatedHabitatSpawning.spawner
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.habitats
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.habitats.dto.HabitatSettingsDTO
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
interface SaveHabitatBlockSettingsEvent {
|
||||
val player: ServerPlayer
|
||||
val world: ServerLevel
|
||||
val blockPos: BlockPos
|
||||
val habitatBlockEntity: HabitatBlockEntity
|
||||
val settings: HabitatSettingsDTO
|
||||
|
||||
class Pre(
|
||||
override val player: ServerPlayer,
|
||||
override val world: ServerLevel,
|
||||
override val blockPos: BlockPos,
|
||||
override val habitatBlockEntity: HabitatBlockEntity,
|
||||
override val settings: HabitatSettingsDTO
|
||||
) : SaveHabitatBlockSettingsEvent, Cancelable()
|
||||
|
||||
class Post(
|
||||
override val player: ServerPlayer,
|
||||
override val world: ServerLevel,
|
||||
override val blockPos: BlockPos,
|
||||
override val habitatBlockEntity: HabitatBlockEntity,
|
||||
override val settings: HabitatSettingsDTO
|
||||
) : SaveHabitatBlockSettingsEvent
|
||||
}
|
||||
@@ -68,14 +68,11 @@ class SpawnBait(
|
||||
val TYPING = cobblemonResource("typing")
|
||||
val EGG_GROUP = cobblemonResource("egg_group")
|
||||
val SHINY_REROLL = cobblemonResource("shiny_reroll")
|
||||
val MARK_CHANCE = cobblemonResource("mark_chance")
|
||||
val DROPS_REROLL = cobblemonResource("drops_reroll")
|
||||
val HIDDEN_ABILITY_CHANCE = cobblemonResource("ha_chance")
|
||||
val ALPHA_CHANCE = cobblemonResource("alpha_chance")
|
||||
val POKEMON_CHANCE = cobblemonResource("pokemon_chance")
|
||||
val FRIENDSHIP = cobblemonResource("friendship")
|
||||
val RARITY_BUCKET = cobblemonResource("rarity_bucket")
|
||||
val SIZE = cobblemonResource("size")
|
||||
|
||||
fun registerEffect(type: ResourceLocation, effect: (PokemonEntity, Effect) -> Unit) {
|
||||
EFFECT_FUNCTIONS[type] = effect
|
||||
@@ -89,14 +86,11 @@ class SpawnBait(
|
||||
registerEffect(NATURE) { entity, effect -> FishingSpawnCause.alterNatureAttempt(entity, effect) }
|
||||
registerEffect(IV) { entity, effect -> FishingSpawnCause.alterIVAttempt(entity, effect) }
|
||||
registerEffect(SHINY_REROLL) { entity, effect -> FishingSpawnCause.shinyReroll(entity, effect) }
|
||||
registerEffect(MARK_CHANCE) { entity, effect -> FishingSpawnCause.alterMarksAttempt(entity, effect) }
|
||||
registerEffect(DROPS_REROLL) { entity, effect -> FishingSpawnCause.saveDropsReroll(entity, effect) }
|
||||
registerEffect(GENDER_CHANCE) { entity, effect -> FishingSpawnCause.alterGenderAttempt(entity, effect) }
|
||||
registerEffect(LEVEL_RAISE) { entity, effect -> FishingSpawnCause.alterLevelAttempt(entity, effect) }
|
||||
registerEffect(HIDDEN_ABILITY_CHANCE) { entity, _ -> FishingSpawnCause.alterHAAttempt(entity) }
|
||||
registerEffect(ALPHA_CHANCE) { entity, effect -> FishingSpawnCause.alterAlphaAttempt(entity) }
|
||||
registerEffect(FRIENDSHIP) { entity, effect -> FishingSpawnCause.alterFriendshipAttempt(entity, effect) }
|
||||
registerEffect(SIZE) { entity, effect -> FishingSpawnCause.alterSize(entity, effect) }
|
||||
CobblemonEvents.BAIT_EFFECT_REGISTRATION.post(BaitEffectFunctionRegistryEvent()) { event ->
|
||||
event.functions.forEach { (type, function) -> registerEffect(type, function) }
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import org.joml.Matrix4f
|
||||
import org.joml.Vector3f
|
||||
import org.lwjgl.opengl.GL30
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
@JvmOverloads
|
||||
fun blitk(
|
||||
@@ -355,10 +357,10 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
|
||||
val matrix: PoseStack.Pose = matrixStack.last()
|
||||
matrix.pose().translate(-1f, 0f, 0f)
|
||||
|
||||
RenderSystem.setShaderTexture(0, sprite)
|
||||
RenderSystem.setShaderTexture(0, sprite);
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader)
|
||||
|
||||
val buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
|
||||
var buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
|
||||
|
||||
buffer.addVertex(matrix, 2f, 0f, 0.0f).setUv(1f, 0f)
|
||||
buffer.addVertex(matrix, 0f, 0f, 0.0f).setUv(0f, 0f)
|
||||
@@ -367,3 +369,25 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
|
||||
|
||||
BufferUploader.drawWithShader(buffer.buildOrThrow())
|
||||
}
|
||||
|
||||
fun getPixelRGB(x: Int, y: Int): Triple<Int, Int, Int> {
|
||||
val window = Minecraft.getInstance().window
|
||||
val scale = window.guiScale
|
||||
val buffer = ByteBuffer.allocateDirect(4)
|
||||
|
||||
RenderSystem.readPixels(
|
||||
(x * scale).toInt(),
|
||||
(window.height - y * scale - scale).toInt(),
|
||||
1,
|
||||
1,
|
||||
GL30.GL_RGBA,
|
||||
GL30.GL_UNSIGNED_BYTE,
|
||||
buffer
|
||||
)
|
||||
|
||||
return Triple(
|
||||
buffer[0].toInt() and 0xFF,
|
||||
buffer[1].toInt() and 0xFF,
|
||||
buffer[2].toInt() and 0xFF
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.gui
|
||||
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import net.minecraft.client.gui.components.AbstractWidget
|
||||
import net.minecraft.client.gui.components.Renderable
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput
|
||||
import net.minecraft.network.chat.Component
|
||||
@@ -54,8 +55,6 @@ abstract class ParentWidget(
|
||||
}
|
||||
|
||||
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
|
||||
if (!active) return false
|
||||
|
||||
return children.any {
|
||||
it.mouseClicked(pMouseX, pMouseY, pButton)
|
||||
}
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.gui
|
||||
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
interface TreeNode<T> {
|
||||
val children: List<TreeNode<T>>
|
||||
}
|
||||
|
||||
class TreeDrawingNode<T>(
|
||||
val value: T,
|
||||
val children: List<TreeDrawingNode<T>>,
|
||||
) {
|
||||
var x = 0
|
||||
var y = 0
|
||||
var offset = 0
|
||||
}
|
||||
|
||||
fun <T> createDrawingTree(treeNode: TreeNode<T>): TreeDrawingNode<T> {
|
||||
val root = setup(treeNode, 0, mutableListOf<Int>(), mutableListOf<Int>())
|
||||
addMods(root, 0)
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T> setup(
|
||||
treeNode: TreeNode<T>,
|
||||
depth: Int,
|
||||
nexts: MutableList<Int>,
|
||||
offset: MutableList<Int>,
|
||||
): TreeDrawingNode<T> {
|
||||
val children = treeNode.children.map { child ->
|
||||
setup(child, depth + 1, nexts, offset)
|
||||
}
|
||||
|
||||
val treeDrawingNode = TreeDrawingNode<T>(treeNode as T, children)
|
||||
treeDrawingNode.y = depth
|
||||
|
||||
while (nexts.size <= depth) {
|
||||
nexts.add(0)
|
||||
}
|
||||
|
||||
while (offset.size <= depth) {
|
||||
offset.add(0)
|
||||
}
|
||||
|
||||
var place =
|
||||
if (children.isEmpty()) {
|
||||
nexts[depth]
|
||||
} else if (children.size == 1) {
|
||||
// children.first().x - 1
|
||||
children.first().x
|
||||
} else {
|
||||
// (children[0].x + children[1].x) / 2
|
||||
(children.first().x + children.last().x) / 2
|
||||
}
|
||||
|
||||
offset[depth] = max(offset[depth], nexts[depth] - place)
|
||||
|
||||
if (children.isEmpty()) {
|
||||
treeDrawingNode.x = place
|
||||
} else {
|
||||
treeDrawingNode.x = place + offset[depth]
|
||||
}
|
||||
|
||||
nexts[depth] += 2
|
||||
treeDrawingNode.offset = offset[depth]
|
||||
|
||||
return treeDrawingNode
|
||||
}
|
||||
|
||||
private fun <T> addMods(
|
||||
treeNode: TreeDrawingNode<T>,
|
||||
modSum: Int,
|
||||
) {
|
||||
treeNode.x += modSum
|
||||
val newModSum = modSum + treeNode.offset
|
||||
|
||||
treeNode.children.forEach { child ->
|
||||
addMods(child, newModSum)
|
||||
}
|
||||
}
|
||||
|
||||
data class TreeDrawingBounds(val minX: Int, val maxX: Int, val minY: Int, val maxY: Int) {
|
||||
val width = maxX - minX
|
||||
val height = maxY - minY
|
||||
val xCenter = (maxX + minX) / 2.0
|
||||
val yCenter = (maxY + minY) / 2.0
|
||||
}
|
||||
|
||||
fun <T> calculateBounds(treeDrawingNode: TreeDrawingNode<T>): TreeDrawingBounds {
|
||||
var minX = treeDrawingNode.x
|
||||
var maxX = treeDrawingNode.x
|
||||
var minY = treeDrawingNode.y
|
||||
var maxY = treeDrawingNode.y
|
||||
|
||||
for (child in treeDrawingNode.children) {
|
||||
val childBounds = calculateBounds(child)
|
||||
|
||||
minX = min(minX, childBounds.minX)
|
||||
maxX = max(maxX, childBounds.maxX)
|
||||
minY = min(minY, childBounds.minY)
|
||||
maxY = max(maxY, childBounds.maxY)
|
||||
}
|
||||
|
||||
return TreeDrawingBounds(minX, maxX, minY, maxY)
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats
|
||||
|
||||
import com.cobblemon.mod.common.api.habitats.spawningstyle.ActivatedHabitatSpawning
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnAction
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.world.entity.Entity
|
||||
|
||||
/**
|
||||
* Influence added to the activated habitat spawner blocks so that they can track the entity and apply block modifiers.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 15th, 2026
|
||||
*/
|
||||
class ActivatedHabitatSpawningInfluence(val activatedHabitatSpawning: ActivatedHabitatSpawning) : SpawningInfluence {
|
||||
override fun affectSpawn(action: SpawnAction<*>, entity: Entity) {
|
||||
if (entity is PokemonEntity) {
|
||||
activatedHabitatSpawning.habitatBlockEntity.modifiers.apply(entity)
|
||||
activatedHabitatSpawning.habitatBlockEntity.spawnedEntityIDs.add(entity.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats
|
||||
|
||||
/**
|
||||
* Controls how habitats change through all the possible phases.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 23rd, 2026
|
||||
*/
|
||||
enum class HabitatPhaseOrder {
|
||||
/** Literally in ascending order, 1-2-3-4. */
|
||||
SIMPLE,
|
||||
/** It randomly chooses an order then uses that order predictably. 3-1-4-2-3-1-4-2 for example */
|
||||
FIXED_RANDOM,
|
||||
/** Completely random phase each day. Like, 1-1-2-4-1-2-1-2-4-1-3 */
|
||||
FULL_RANDOM
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.spawning.detail.PokemonSpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* A pool of [HabitatSpawn]s. This is filled with [HabitatSpawn]s. The pool is responsible for converting
|
||||
* its spawns into [PokemonSpawnDetail]s.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 13th, 2026
|
||||
*/
|
||||
class HabitatPool {
|
||||
companion object {
|
||||
fun default() = HabitatPool().apply {
|
||||
id = ResourceLocation("cobblemon", "custom__default_pool")
|
||||
name = "Custom"
|
||||
}
|
||||
|
||||
fun writePoolToNBT(pool: HabitatPool, nbt: CompoundTag) {
|
||||
nbt.putString(DataKeys.HABITAT_POOL_ID, pool.id.toString())
|
||||
if (pool.id.path.startsWith("custom__")) {
|
||||
nbt.putString(DataKeys.HABITAT_POOL_NAME, pool.name)
|
||||
val spawnsListNBT = ListTag()
|
||||
for (spawn in pool.spawns) {
|
||||
val spawnTag = CompoundTag()
|
||||
spawn.writeToNBT(spawnTag)
|
||||
spawnsListNBT.add(spawnTag)
|
||||
}
|
||||
nbt.put(DataKeys.HABITAT_POOL_SPAWNS, spawnsListNBT)
|
||||
}
|
||||
}
|
||||
|
||||
fun readPoolFromNBT(nbt: CompoundTag): HabitatPool {
|
||||
val poolId = nbt.getString(DataKeys.HABITAT_POOL_ID).asIdentifierDefaultingNamespace()
|
||||
if (nbt.contains(DataKeys.HABITAT_POOL_NAME)) {
|
||||
// It's one that was stored on the block
|
||||
val pool = HabitatPool()
|
||||
pool.id = poolId
|
||||
pool.name = nbt.getString(DataKeys.HABITAT_POOL_NAME)
|
||||
val spawnsListNBT = nbt.getList(DataKeys.HABITAT_POOL_SPAWNS, Tag.TAG_COMPOUND.toInt())
|
||||
val spawns = mutableListOf<HabitatSpawn>()
|
||||
spawnsListNBT.forEach { spawnTag ->
|
||||
try {
|
||||
val spawn = HabitatSpawn().apply { readFromNBT(spawnTag as CompoundTag) }
|
||||
spawns.add(spawn)
|
||||
} catch (_: Exception) {
|
||||
// If there's an error reading a spawn, skip it and log the error.
|
||||
Cobblemon.LOGGER.error("Error reading activated habitat spawn from NBT for habitat block, skipping.")
|
||||
}
|
||||
}
|
||||
pool.spawns = spawns
|
||||
return pool
|
||||
} else {
|
||||
return HabitatPools.habitatPoolsById[poolId] ?: HabitatPool.default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var id: ResourceLocation
|
||||
var name: String = ""
|
||||
var spawns: List<HabitatSpawn> = listOf()
|
||||
|
||||
/** Whether a pool is editable is just down to whether it's not from a datapack. */
|
||||
@Transient
|
||||
var editable: Boolean = false
|
||||
|
||||
fun validate() {
|
||||
for (spawn in spawns) {
|
||||
if (SpawnablePosition.getByName(spawn.spawnablePositionType) == null) {
|
||||
throw IllegalArgumentException("$id mentions non-existent spawnable position type ${spawn.spawnablePositionType} on spawn for ${spawn.species}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createSpawnDetails(habitatBlockEntity: HabitatBlockEntity): List<PokemonSpawnDetail> {
|
||||
return spawns.mapNotNull { it.createSpawnDetail(habitatBlockEntity) }
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(id)
|
||||
buffer.writeUtf(name)
|
||||
buffer.writeCollection(spawns) { _, it -> it.encode(buffer) }
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
id = buffer.readResourceLocation()
|
||||
name = buffer.readUtf()
|
||||
spawns = buffer.readList { HabitatSpawn().apply { decode(buffer) } }
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.api.spawning.IntRanges
|
||||
import com.cobblemon.mod.common.api.spawning.TimeRange
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePositionType
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IntRangeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IntRangesAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.RegisteredSpawnablePositionAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.SpeciesAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.pokemonPropertiesShortAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.fromJson
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import java.io.File
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.world.level.storage.LevelResource
|
||||
|
||||
object HabitatPools : JsonDataRegistry<HabitatPool> {
|
||||
override val id = cobblemonResource("habitat_pools")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<HabitatPools>()
|
||||
override val typeToken: TypeToken<HabitatPool> = TypeToken.get(HabitatPool::class.java)
|
||||
override val resourcePath = "habitat_pools"
|
||||
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(SpawnablePositionType::class.java, RegisteredSpawnablePositionAdapter)
|
||||
.registerTypeAdapter(Species::class.java, SpeciesAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapter(TimeRange::class.java, TimeRange.adapter)
|
||||
.registerTypeAdapter(IntRanges::class.java, IntRangesAdapter.basic)
|
||||
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
private val datapacked = mutableMapOf<ResourceLocation, HabitatPool>()
|
||||
private val worldSaved = mutableMapOf<ResourceLocation, HabitatPool>()
|
||||
|
||||
val habitatPoolsById = mutableMapOf<ResourceLocation, HabitatPool>()
|
||||
|
||||
private lateinit var worldSavedPoolsFolder: File
|
||||
|
||||
override fun sync(player: ServerPlayer) {}
|
||||
|
||||
fun onServerLoading(server: MinecraftServer) {
|
||||
worldSavedPoolsFolder = server.getWorldPath(LevelResource.ROOT).resolve("habitat_pools").toFile()
|
||||
if (!worldSavedPoolsFolder.exists()) {
|
||||
return
|
||||
}
|
||||
|
||||
worldSavedPoolsFolder.listFiles { it.endsWith(".json") }.forEach {
|
||||
val identifier = ResourceLocation.parse(it.nameWithoutExtension)
|
||||
val habitat = gson.fromJson<HabitatPool>(it.reader())
|
||||
habitat.id = identifier
|
||||
habitat.validate()
|
||||
habitat.editable = true
|
||||
worldSaved[identifier] = habitat
|
||||
}
|
||||
setupHabitatPoolsById()
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, HabitatPool>) {
|
||||
datapacked.clear()
|
||||
datapacked.putAll(data)
|
||||
data.entries.forEach { (identifier, habitat) ->
|
||||
habitat.id = identifier
|
||||
habitat.validate()
|
||||
habitat.editable = false
|
||||
}
|
||||
setupHabitatPoolsById()
|
||||
}
|
||||
|
||||
fun setupHabitatPoolsById() {
|
||||
habitatPoolsById.clear()
|
||||
habitatPoolsById.putAll(datapacked)
|
||||
habitatPoolsById.putAll(worldSaved)
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.spawning.IntRanges
|
||||
import com.cobblemon.mod.common.api.spawning.TimeRange
|
||||
import com.cobblemon.mod.common.api.spawning.condition.AppendageCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.detail.PokemonSpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.adapters.IntRangeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IntRangesAdapter
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.math.intersection
|
||||
import com.cobblemon.mod.common.util.math.intersects
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
/**
|
||||
* A kind of simplified spawn definition for the purposes of spawning from [HabitatBlockEntity] instances.
|
||||
*
|
||||
* These have only a small subset of the properties that a regular [PokemonSpawnDetail] would have to align with the
|
||||
* fact that these are configured from a simple GUI. There are limits to how many properties and conditions could be
|
||||
* exposed in a GUI before it becomes too difficult for the average user to understand what's going on.
|
||||
*
|
||||
* [HabitatSpawn]s are loaded from datapacks as pools of spawns but can also be modified from in-game, though those
|
||||
* made from in-game are stored separately to datapacks. Only non-datapacked habitat spawns can be modified.
|
||||
*
|
||||
* Upon edits to a habitat block, the spawn details are regenerated based off of these definitions.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 13th, 2026
|
||||
*/
|
||||
class HabitatSpawn {
|
||||
/** The species that will be spawned. */
|
||||
lateinit var species: Species
|
||||
/** The kind of position the Pokémon will spawn in. Things like "grounded", "seafloor", "fishing". */
|
||||
lateinit var spawnablePositionType: String
|
||||
/** The bucket to spawn from. */
|
||||
var bucket: String = "common"
|
||||
|
||||
/** Selection weight. */
|
||||
var weight: Float = 1F
|
||||
/** The possible levels for this spawn. */
|
||||
var levelRange: IntRange = 1..Int.MAX_VALUE // I can't access the up-to-date config value here.
|
||||
/** Additional modifiers to apply to the Pokémon, such as alolan=true, ability=intimidate, etc. */
|
||||
var modifiers: PokemonProperties? = null
|
||||
/** Which phases of the habitat this spawn will run in. See [HabitatBlockEntity] for more information. */
|
||||
var phases: IntRanges? = null
|
||||
/** The Minecraft time ranges for this spawn. */
|
||||
var timeRange: TimeRange? = null
|
||||
/** The minimum light level that the Pokémon can spawn in. */
|
||||
var minLight: Int? = null
|
||||
/** The maximum light level that the Pokémon can spawn in. */
|
||||
var maxLight: Int? = null
|
||||
|
||||
open fun writeToNBT(nbt: CompoundTag) {
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_SPECIES, species.resourceIdentifier.toString())
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE, spawnablePositionType)
|
||||
nbt.putFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT, weight)
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_LEVEL_RANGE, IntRangeAdapter.serialize(levelRange))
|
||||
modifiers?.let { nbt.putString(DataKeys.HABITAT_POOL_SPAWN_MODIFIERS, it.asString()) }
|
||||
phases?.let { nbt.putString(DataKeys.HABITAT_POOL_SPAWN_PHASES, IntRangesAdapter.basic.serialize(it)) }
|
||||
timeRange?.let { nbt.putString(DataKeys.HABITAT_POOL_SPAWN_TIMES, TimeRange.adapter.serialize(it)) }
|
||||
minLight?.let { nbt.putInt(DataKeys.HABITAT_POOL_SPAWN_MIN_LIGHT, it) }
|
||||
maxLight?.let { nbt.putInt(DataKeys.HABITAT_POOL_SPAWN_MAX_LIGHT, it) }
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_BUCKET, bucket)
|
||||
}
|
||||
|
||||
open fun readFromNBT(nbt: CompoundTag) {
|
||||
species = PokemonSpecies.getByIdentifier(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_SPECIES).asIdentifierDefaultingNamespace())!!
|
||||
spawnablePositionType = nbt.getString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE)
|
||||
weight = nbt.getFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT)
|
||||
levelRange = IntRangeAdapter.deserialize(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_LEVEL_RANGE))
|
||||
modifiers = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_MODIFIERS)) PokemonProperties.parse(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_MODIFIERS)) else null
|
||||
phases = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_PHASES)) IntRangesAdapter.basic.deserialize(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_PHASES)) else null
|
||||
timeRange = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_TIMES)) TimeRange.adapter.deserialize(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_TIMES)) else null
|
||||
minLight = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_MIN_LIGHT)) nbt.getInt(DataKeys.HABITAT_POOL_SPAWN_MIN_LIGHT) else null
|
||||
maxLight = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_MAX_LIGHT)) nbt.getInt(DataKeys.HABITAT_POOL_SPAWN_MAX_LIGHT) else null
|
||||
bucket = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_BUCKET)) nbt.getString(DataKeys.HABITAT_POOL_SPAWN_BUCKET) else "common"
|
||||
}
|
||||
|
||||
open fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(species.resourceIdentifier)
|
||||
buffer.writeUtf(spawnablePositionType)
|
||||
buffer.writeFloat(weight)
|
||||
buffer.writeUtf(IntRangeAdapter.serialize(levelRange))
|
||||
buffer.writeNullable(modifiers) { _, value -> buffer.writeUtf(value.asString()) }
|
||||
buffer.writeNullable(phases) { _, value -> buffer.writeUtf(IntRangesAdapter.basic.serialize(value)) }
|
||||
buffer.writeNullable(timeRange) { _, value -> buffer.writeUtf(TimeRange.adapter.serialize(value)) }
|
||||
buffer.writeNullable(minLight) { _, value -> buffer.writeInt(value) }
|
||||
buffer.writeNullable(maxLight) { _, value -> buffer.writeInt(value) }
|
||||
buffer.writeUtf(bucket)
|
||||
}
|
||||
|
||||
open fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
species = PokemonSpecies.getByIdentifier(buffer.readResourceLocation())!!
|
||||
spawnablePositionType = buffer.readUtf()
|
||||
weight = buffer.readFloat()
|
||||
levelRange = IntRangeAdapter.deserialize(buffer.readUtf())
|
||||
modifiers = buffer.readNullable { _ -> PokemonProperties.parse(buffer.readUtf()) }
|
||||
phases = buffer.readNullable { _ -> IntRangesAdapter.basic.deserialize(buffer.readUtf()) }
|
||||
timeRange = buffer.readNullable { _ -> TimeRange.adapter.deserialize(buffer.readUtf()) }
|
||||
minLight = buffer.readNullable { _ -> buffer.readInt() }
|
||||
maxLight = buffer.readNullable { _ -> buffer.readInt() }
|
||||
bucket = buffer.readUtf()
|
||||
}
|
||||
|
||||
/** Creates the [PokemonSpawnDetail] that will be used in the spawner. This is done per habitat block. */
|
||||
open fun createSpawnDetail(habitatBlockEntity: HabitatBlockEntity): PokemonSpawnDetail? {
|
||||
val spawnDetail = PokemonSpawnDetail()
|
||||
|
||||
// If the habitat block specifies a level range, it restricts how and if this spawn exists
|
||||
if (!levelRange.intersects(habitatBlockEntity.levelRange)) {
|
||||
return null
|
||||
}
|
||||
|
||||
val spawnablePositionType = SpawnablePosition.getByName(this.spawnablePositionType) ?: return null // How'd they get bad data into here
|
||||
|
||||
val levelRange = levelRange.intersection(habitatBlockEntity.levelRange)
|
||||
|
||||
val condition = createCondition(habitatBlockEntity)
|
||||
val properties = modifiers?.copy() ?: PokemonProperties()
|
||||
properties.species = species.resourceIdentifier.path
|
||||
|
||||
spawnDetail.apply {
|
||||
this.id = "habitat_${species.resourceIdentifier}"
|
||||
this.pokemon = properties
|
||||
this.bucket = this@HabitatSpawn.bucket
|
||||
this.weight = this@HabitatSpawn.weight
|
||||
this.levelRange = levelRange
|
||||
this.conditions = mutableListOf(condition)
|
||||
this.spawnablePositionType = spawnablePositionType
|
||||
}
|
||||
|
||||
return spawnDetail
|
||||
}
|
||||
|
||||
fun createCondition(habitatBlockEntity: HabitatBlockEntity): SpawningCondition<*> {
|
||||
val clazz = SpawningCondition.getByName(SpawnablePosition.getByName(this.spawnablePositionType)!!.defaultCondition)!!
|
||||
val condition = clazz.getConstructor().newInstance()
|
||||
condition.timeRange = timeRange
|
||||
condition.minLight = minLight
|
||||
condition.maxLight = maxLight
|
||||
val phases = phases
|
||||
if (phases != null) {
|
||||
condition.appendages.add(PhaseAppendageCondition(habitatBlockEntity, phases))
|
||||
}
|
||||
return condition
|
||||
}
|
||||
|
||||
class PhaseAppendageCondition(val habitatBlockEntity: HabitatBlockEntity, val phases: IntRanges) : AppendageCondition {
|
||||
override fun fits(spawnablePosition: SpawnablePosition) = habitatBlockEntity.currentPhase in phases
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.dto
|
||||
|
||||
import com.cobblemon.mod.common.api.habitats.spawningstyle.ActivatedHabitatSpawning
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class ActivatedHabitatSettingsDTO() {
|
||||
var chance = 1F
|
||||
var trigger: ActivatedHabitatSpawning.Trigger = ActivatedHabitatSpawning.Trigger.REDSTONE
|
||||
var cancelledNaturalSpawningRange = -1
|
||||
var spawnRange = 16
|
||||
var maxSpawns = -1
|
||||
var maxSpawnsPerActivation = 1
|
||||
|
||||
constructor(activatedHabitatSpawning: ActivatedHabitatSpawning): this() {
|
||||
this.chance = activatedHabitatSpawning.chance
|
||||
this.trigger = activatedHabitatSpawning.trigger
|
||||
this.cancelledNaturalSpawningRange = activatedHabitatSpawning.cancelledNaturalSpawningRange
|
||||
this.spawnRange = activatedHabitatSpawning.spawnRange
|
||||
this.maxSpawns = activatedHabitatSpawning.maxSpawns
|
||||
this.maxSpawnsPerActivation = activatedHabitatSpawning.maxSpawnsPerActivation
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeFloat(chance)
|
||||
buffer.writeEnum(trigger)
|
||||
buffer.writeInt(cancelledNaturalSpawningRange)
|
||||
buffer.writeInt(spawnRange)
|
||||
buffer.writeInt(maxSpawns)
|
||||
buffer.writeInt(maxSpawnsPerActivation)
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
this.chance = buffer.readFloat()
|
||||
this.trigger = buffer.readEnum(ActivatedHabitatSpawning.Trigger::class.java)
|
||||
this.cancelledNaturalSpawningRange = buffer.readInt()
|
||||
this.spawnRange = buffer.readInt()
|
||||
this.maxSpawns = buffer.readInt()
|
||||
this.maxSpawnsPerActivation = buffer.readInt()
|
||||
}
|
||||
}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.dto
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.habitats.HabitatPool
|
||||
import com.cobblemon.mod.common.api.habitats.HabitatPools
|
||||
import com.cobblemon.mod.common.api.habitats.HabitatSpawn
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class HabitatPoolSettingsDTO() {
|
||||
lateinit var id: ResourceLocation
|
||||
var isReference = false
|
||||
|
||||
// Below properties are only there when it's not a reference, otherwise the handler will have to look them up from the id
|
||||
var name: String? = null
|
||||
var spawns: MutableList<HabitatSpawn>? = null
|
||||
|
||||
constructor(habitatPool: HabitatPool): this() {
|
||||
this.id = habitatPool.id
|
||||
this.isReference = !id.path.startsWith("custom__")
|
||||
if (!this.isReference) {
|
||||
this.name = habitatPool.name
|
||||
this.spawns = habitatPool.spawns.toMutableList()
|
||||
}
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(id)
|
||||
buffer.writeBoolean(isReference)
|
||||
if (!isReference) {
|
||||
buffer.writeUtf(name!!)
|
||||
buffer.writeCollection(spawns!!) { _, spawn ->
|
||||
spawn.encode(buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun decode(
|
||||
buffer: RegistryFriendlyByteBuf
|
||||
) {
|
||||
this.id = buffer.readResourceLocation()
|
||||
this.isReference = buffer.readBoolean()
|
||||
if (!isReference) {
|
||||
this.name = buffer.readUtf()
|
||||
this.spawns = buffer.readList {
|
||||
val spawn = HabitatSpawn()
|
||||
spawn.decode(buffer)
|
||||
spawn
|
||||
}.toMutableList()
|
||||
}
|
||||
}
|
||||
|
||||
fun toHabitatPool(): HabitatPool? {
|
||||
if (isReference) {
|
||||
val pool = HabitatPools.habitatPoolsById[id]
|
||||
if (pool == null) {
|
||||
Cobblemon.LOGGER.error("Could not find habitat pool with id $id")
|
||||
}
|
||||
return pool
|
||||
}
|
||||
val pool = HabitatPool()
|
||||
pool.id = id
|
||||
pool.name = name!!
|
||||
pool.spawns = spawns!!
|
||||
return pool
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.dto
|
||||
|
||||
import com.cobblemon.mod.common.api.habitats.HabitatPhaseOrder
|
||||
import com.cobblemon.mod.common.api.habitats.HabitatPool
|
||||
import com.cobblemon.mod.common.api.habitats.spawningstyle.ActivatedHabitatSpawning
|
||||
import com.cobblemon.mod.common.api.habitats.spawningstyle.NaturalHabitatSpawning
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class HabitatSettingsDTO() {
|
||||
var numberOfPhases = 1
|
||||
var phaseOrder = HabitatPhaseOrder.SIMPLE
|
||||
lateinit var levelRange: IntRange
|
||||
var modifiers: String = ""
|
||||
lateinit var mimicId: ResourceLocation
|
||||
var isActivatedSpawning = false
|
||||
var pool: HabitatPoolSettingsDTO = HabitatPoolSettingsDTO(HabitatPool.default())
|
||||
var activatedSettings: ActivatedHabitatSettingsDTO? = null
|
||||
var naturalSettings: NaturalHabitatSettingsDTO? = null
|
||||
|
||||
constructor(habitatBlockEntity: HabitatBlockEntity) : this() {
|
||||
this.numberOfPhases = habitatBlockEntity.numberOfPhases
|
||||
this.phaseOrder = habitatBlockEntity.phaseOrder
|
||||
this.levelRange = habitatBlockEntity.levelRange
|
||||
this.modifiers = habitatBlockEntity.modifiers.asString()
|
||||
this.mimicId = habitatBlockEntity.mimicId
|
||||
this.pool = HabitatPoolSettingsDTO(habitatBlockEntity.pool)
|
||||
val style = habitatBlockEntity.spawningStyle
|
||||
if (style is ActivatedHabitatSpawning) {
|
||||
this.isActivatedSpawning = true
|
||||
this.activatedSettings = ActivatedHabitatSettingsDTO(style)
|
||||
} else if (style is NaturalHabitatSpawning) {
|
||||
this.naturalSettings = NaturalHabitatSettingsDTO(style)
|
||||
}
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeInt(numberOfPhases)
|
||||
buffer.writeEnum(phaseOrder)
|
||||
buffer.writeInt(levelRange.first)
|
||||
buffer.writeInt(levelRange.last)
|
||||
buffer.writeUtf(modifiers)
|
||||
buffer.writeResourceLocation(mimicId)
|
||||
pool.encode(buffer)
|
||||
buffer.writeBoolean(isActivatedSpawning)
|
||||
if (isActivatedSpawning) {
|
||||
activatedSettings?.encode(buffer)
|
||||
} else {
|
||||
naturalSettings?.encode(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
this.numberOfPhases = buffer.readInt()
|
||||
this.phaseOrder = buffer.readEnum(HabitatPhaseOrder::class.java)
|
||||
val levelRangeStart = buffer.readInt()
|
||||
val levelRangeEnd = buffer.readInt()
|
||||
this.levelRange = levelRangeStart..levelRangeEnd
|
||||
this.modifiers = buffer.readUtf()
|
||||
this.mimicId = buffer.readResourceLocation()
|
||||
this.pool = HabitatPoolSettingsDTO()
|
||||
this.pool.decode(buffer)
|
||||
if (buffer.readBoolean()) {
|
||||
this.isActivatedSpawning = true
|
||||
this.naturalSettings = null
|
||||
val activatedSettings = ActivatedHabitatSettingsDTO()
|
||||
activatedSettings.decode(buffer)
|
||||
this.activatedSettings = activatedSettings
|
||||
} else {
|
||||
this.activatedSettings = null
|
||||
val naturalSettings = NaturalHabitatSettingsDTO()
|
||||
naturalSettings.decode(buffer)
|
||||
this.naturalSettings = naturalSettings
|
||||
}
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.dto
|
||||
|
||||
import com.cobblemon.mod.common.api.habitats.spawningstyle.NaturalHabitatSpawning
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class NaturalHabitatSettingsDTO() {
|
||||
var replaceSpawns = false
|
||||
var rangeOfInfluence = 16
|
||||
|
||||
constructor(naturalHabitatSpawning: NaturalHabitatSpawning): this() {
|
||||
this.replaceSpawns = naturalHabitatSpawning.replaceSpawns
|
||||
this.rangeOfInfluence = naturalHabitatSpawning.rangeOfInfluence
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeBoolean(replaceSpawns)
|
||||
buffer.writeInt(rangeOfInfluence)
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf, ) {
|
||||
this.replaceSpawns = buffer.readBoolean()
|
||||
this.rangeOfInfluence = buffer.readInt()
|
||||
}
|
||||
}
|
||||
-152
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.spawningstyle
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.habitats.HabitatSpawnActivatedEvent
|
||||
import com.cobblemon.mod.common.api.habitats.ActivatedHabitatSpawningInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.FixedAreaSpawner
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
|
||||
/**
|
||||
* A habitat spawning style defined by being triggered by something. The activation trigger, [trigger], is either
|
||||
* a redstone pulse, every tick, or every random tick.
|
||||
*
|
||||
* The spawn details are generated from the pool every time there is some change to the habitat block's settings,
|
||||
* then those spawn details are used for spawning Pokémon when the habitat block is triggered.
|
||||
*
|
||||
* The [chance] property is applied after the trigger logic so that not every activation necessarily results in a spawn
|
||||
* attempt.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 14th, 2026
|
||||
*/
|
||||
class ActivatedHabitatSpawning(val habitatBlockEntity: HabitatBlockEntity) : HabitatSpawningStyle {
|
||||
companion object {
|
||||
val TYPE = cobblemonResource("activated")
|
||||
}
|
||||
|
||||
enum class Trigger {
|
||||
/** Requires a redstone pulse. */
|
||||
REDSTONE,
|
||||
/** Tries every tick. */
|
||||
TICK,
|
||||
/** Tries every random tick. */
|
||||
RANDOM_TICK
|
||||
}
|
||||
|
||||
@Transient
|
||||
override val type = TYPE
|
||||
|
||||
/** The chance that an activation by the [trigger] will result in a spawn attempt. The spawn attempt may still fail. */
|
||||
var chance = 1F
|
||||
/** The thing that will activate the habitat block into attempting to spawn something. */
|
||||
var trigger = Trigger.REDSTONE
|
||||
/** What range, in blocks, around the habitat block in which natural spawning will not occur. */
|
||||
var cancelledNaturalSpawningRange = -1
|
||||
/** The range, in blocks, around the habitat block in which spawning will be attempted. */
|
||||
var spawnRange = 16
|
||||
/** The maximum number of Pokémon that can exist from this block's spawning before it pauses. -1 for infinite. */
|
||||
var maxSpawns = -1
|
||||
/** The maximum number of Pokémon that can spawn in a single activation. This will still be capped by [maxSpawns]. */
|
||||
var maxSpawnsPerActivation = 1
|
||||
|
||||
lateinit var spawner: FixedAreaSpawner
|
||||
|
||||
override fun writeToNBT(nbt: CompoundTag) {
|
||||
nbt.putString(DataKeys.HABITAT_SPAWNING_STYLE, type.toString())
|
||||
nbt.putFloat(DataKeys.HABITAT_ACTIVATED_CHANCE, chance)
|
||||
nbt.putString(DataKeys.HABITAT_ACTIVATED_TRIGGER, trigger.name)
|
||||
nbt.putInt(DataKeys.HABITAT_ACTIVATED_CANCEL_RANGE, cancelledNaturalSpawningRange)
|
||||
nbt.putInt(DataKeys.HABITAT_ACTIVATED_SPAWN_RANGE, spawnRange)
|
||||
nbt.putInt(DataKeys.HABITAT_ACTIVATED_MAX_SPAWNS, maxSpawns)
|
||||
nbt.putInt(DataKeys.HABITAT_ACTIVATED_MAX_SPAWNS_PER_ACTIVATION, maxSpawnsPerActivation)
|
||||
}
|
||||
|
||||
override fun readFromNBT(nbt: CompoundTag) {
|
||||
chance = nbt.getFloat(DataKeys.HABITAT_ACTIVATED_CHANCE)
|
||||
trigger = Trigger.valueOf(nbt.getString(DataKeys.HABITAT_ACTIVATED_TRIGGER) ?: Trigger.REDSTONE.name)
|
||||
cancelledNaturalSpawningRange = nbt.getInt(DataKeys.HABITAT_ACTIVATED_CANCEL_RANGE)
|
||||
spawnRange = nbt.getInt(DataKeys.HABITAT_ACTIVATED_SPAWN_RANGE)
|
||||
maxSpawns = nbt.getInt(DataKeys.HABITAT_ACTIVATED_MAX_SPAWNS)
|
||||
maxSpawnsPerActivation = nbt.getInt(DataKeys.HABITAT_ACTIVATED_MAX_SPAWNS_PER_ACTIVATION)
|
||||
}
|
||||
|
||||
fun generateSpawnDetails(world: ServerLevel, pos: BlockPos) {
|
||||
spawner = FixedAreaSpawner(
|
||||
name = "habitat_spawner_$pos",
|
||||
world = world,
|
||||
position = pos,
|
||||
spawnPool = SpawnPool("habitat_block").also {
|
||||
it.details.addAll(habitatBlockEntity.spawnDetails)
|
||||
it.precalculate()
|
||||
},
|
||||
buckets = Cobblemon.bestSpawner.config.activatedHabitatBuckets,
|
||||
maxPokemonPerChunk = 16F,
|
||||
verticalRadius = spawnRange,
|
||||
horizontalRadius = spawnRange
|
||||
)
|
||||
spawner.influences.add(ActivatedHabitatSpawningInfluence(this))
|
||||
}
|
||||
|
||||
fun activate(world: ServerLevel, pos: BlockPos) {
|
||||
// Check if the spawn attempt should even happen based on chance.
|
||||
if (chance < 1F && world.random.nextFloat() >= chance) {
|
||||
return
|
||||
} else if (habitatBlockEntity.spawnDetails.isEmpty()) {
|
||||
// If there are no spawn details, then there's no point in trying to spawn anything.
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the max spawns has been reached.
|
||||
if (maxSpawns != -1) {
|
||||
val existingSpawns = habitatBlockEntity.spawnedEntityIDs.size
|
||||
if (existingSpawns >= maxSpawns) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val cause = SpawnCause(
|
||||
spawner = spawner,
|
||||
entity = world.getNearestPlayer(
|
||||
pos.x.toDouble(),
|
||||
pos.y.toDouble(),
|
||||
pos.z.toDouble(),
|
||||
64.0,
|
||||
true
|
||||
)
|
||||
)
|
||||
|
||||
val remainingUntilMaxSpawns = if (maxSpawns == -1) Int.MAX_VALUE else maxSpawns - habitatBlockEntity.spawnedEntityIDs.size
|
||||
val maxSpawnsForActivation = if (maxSpawnsPerActivation == -1) Int.MAX_VALUE else maxSpawnsPerActivation
|
||||
val maxSpawns = minOf(remainingUntilMaxSpawns, maxSpawnsForActivation)
|
||||
|
||||
val event = HabitatSpawnActivatedEvent(
|
||||
habitatBlockEntity = habitatBlockEntity,
|
||||
activatedHabitatSpawning = this,
|
||||
cause = cause,
|
||||
maxSpawns = maxSpawns
|
||||
)
|
||||
|
||||
CobblemonEvents.HABITAT_SPAWN_ACTIVATED.postThen(event = event) {
|
||||
spawner.run(
|
||||
cause = event.cause,
|
||||
maxSpawns = event.maxSpawns
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.spawningstyle
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Holds habitat block specific details about the methodology behind how the habitat block will spawn Pokémon. This is
|
||||
* either an [ActivatedHabitatSpawning] or a [NaturalHabitatSpawning].
|
||||
*
|
||||
* @see ActivatedHabitatSpawning
|
||||
* @see NaturalHabitatSpawning
|
||||
* @author Hiroku
|
||||
* @since February 14th, 2026
|
||||
*/
|
||||
sealed interface HabitatSpawningStyle {
|
||||
val type: ResourceLocation
|
||||
|
||||
fun writeToNBT(nbt: CompoundTag)
|
||||
fun readFromNBT(nbt: CompoundTag)
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.habitats.spawningstyle
|
||||
|
||||
import com.cobblemon.mod.common.block.habitat.HabitatBlockEntity
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* A habitat spawning style defined by tapping into regular spawning methods. This works by adding to the spawn list
|
||||
* for spawning that's occurring nearby. When [replaceSpawns] is set to true, the original spawns will be
|
||||
* removed completely in favour of the spawns provided in this habitat's pool.
|
||||
*
|
||||
* The spawn details are generated from the pool every time there is some change to the habitat block's settings,
|
||||
* then those spawn details are used for spawning Pokémon when world spawning is occurring nearby.
|
||||
*
|
||||
* Whether or not this interactions with overworld or fishing spawns is determined by whether the habitat pool has
|
||||
* overworld or fishing spawns respectively.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since February 22nd, 2026
|
||||
*/
|
||||
class NaturalHabitatSpawning(val habitatBlockEntity: HabitatBlockEntity) : HabitatSpawningStyle {
|
||||
companion object {
|
||||
val TYPE = cobblemonResource("natural")
|
||||
}
|
||||
|
||||
@Transient
|
||||
override val type: ResourceLocation = TYPE
|
||||
|
||||
var replaceSpawns = false
|
||||
var rangeOfInfluence = 16
|
||||
|
||||
@Transient
|
||||
var affectsFishing = false
|
||||
@Transient
|
||||
var affectsOverworld = false
|
||||
|
||||
fun generateSpawnDetails() {
|
||||
affectsFishing = habitatBlockEntity.spawnDetails.any { it.spawnablePositionType.name == "fishing" }
|
||||
affectsOverworld = habitatBlockEntity.spawnDetails.any { it.spawnablePositionType.name != "fishing" }
|
||||
}
|
||||
|
||||
override fun writeToNBT(nbt: CompoundTag) {
|
||||
nbt.putBoolean(DataKeys.HABITAT_NATURAL_REPLACE_SPAWNS, replaceSpawns)
|
||||
nbt.putInt(DataKeys.HABITAT_NATURAL_RANGE_OF_INFLUENCE, rangeOfInfluence)
|
||||
}
|
||||
|
||||
override fun readFromNBT(nbt: CompoundTag) {
|
||||
replaceSpawns = nbt.getBoolean(DataKeys.HABITAT_NATURAL_REPLACE_SPAWNS)
|
||||
rangeOfInfluence = nbt.getInt(DataKeys.HABITAT_NATURAL_RANGE_OF_INFLUENCE)
|
||||
}
|
||||
}
|
||||
+21
-29
@@ -9,14 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.interaction
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.OwnerQueryRequirement
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PokemonInteractionsSyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
|
||||
import com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter
|
||||
import com.cobblemon.mod.common.pokemon.requirements.PokemonPropertiesRequirement
|
||||
@@ -30,11 +29,6 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.util.LowerCaseEnumTypeAdapterFactory
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.levelgen.structure.Structure
|
||||
import net.minecraft.world.level.material.Fluid
|
||||
|
||||
object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
||||
override val id = cobblemonResource("pokemon_interactions")
|
||||
@@ -49,42 +43,40 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
||||
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
|
||||
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Structure::class.java).type, StructureLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Fluid::class.java).type, FluidLikeConditionAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
val interactions = mutableListOf<PokemonInteractionSet>()
|
||||
val speciesInteractions = mutableListOf<PokemonInteractionSet>()
|
||||
val generalInteractions = mutableListOf<PokemonInteractionSet>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
PokemonInteractionsSyncPacket(interactions).sendToPlayer(player)
|
||||
}
|
||||
override fun sync(player: ServerPlayer) {}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>) {
|
||||
interactions.clear()
|
||||
val split = data.entries
|
||||
.partition {
|
||||
it.value.requirements.any { requirement -> requirement is PokemonPropertiesRequirement && requirement.target.species != null }
|
||||
}
|
||||
|
||||
// Put the species specific interactions first as they take priority
|
||||
interactions.addAll(split.first.map {it.value})
|
||||
interactions.addAll(split.second.map {it.value})
|
||||
|
||||
Cobblemon.LOGGER.info("Loaded {} Pokémon interaction sets", interactions.size)
|
||||
speciesInteractions.clear()
|
||||
generalInteractions.clear()
|
||||
val split = data.entries.partition { it.value.requirements.any { requirement -> requirement is PokemonPropertiesRequirement && requirement.target.species != null } }
|
||||
speciesInteractions.addAll(split.first.map {it.value})
|
||||
generalInteractions.addAll(split.second.map {it.value})
|
||||
Cobblemon.LOGGER.info("Loaded {} Pokémon interaction sets", data.size)
|
||||
}
|
||||
|
||||
fun findInteraction(pokemon: PokemonEntity): PokemonInteraction? {
|
||||
val setCheck: (PokemonInteractionSet) -> Boolean = { it.requirements.all { req -> req.check(pokemon.pokemon) }}
|
||||
val interactionCheck: (PokemonInteraction) -> Boolean = { it.requirements.all { req -> req.check(pokemon.pokemon) } && !pokemon.pokemon.isOnInteractionCooldown(it.grouping) }
|
||||
return interactions
|
||||
// species-specific interactions take priority
|
||||
val validInteractions = speciesInteractions
|
||||
.filter(setCheck)
|
||||
.flatMap { it.interactions }
|
||||
.firstOrNull(interactionCheck)
|
||||
.filter(interactionCheck)
|
||||
.toMutableList()
|
||||
if (validInteractions.isEmpty()) { // if all species-specific interactions are absent/on cooldown, fallback to more generic ones
|
||||
validInteractions.addAll(generalInteractions.filter(setCheck).flatMap { it.interactions }
|
||||
.filter(interactionCheck)
|
||||
)
|
||||
}
|
||||
|
||||
return validInteractions.randomOrNull()
|
||||
}
|
||||
}
|
||||
+20
-101
@@ -15,11 +15,11 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.giveOrDropItemStack
|
||||
import com.cobblemon.mod.common.util.withPlayerValue
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
@@ -28,80 +28,30 @@ import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
/**
|
||||
* A
|
||||
*/
|
||||
data class PokemonInteractionSet(
|
||||
val requirements: List<Requirement> = listOf(),
|
||||
val interactions: List<PokemonInteraction> = listOf(),
|
||||
) {
|
||||
fun encode(buffer: FriendlyByteBuf) {
|
||||
buffer.writeCollection(requirements) { it, requirement ->
|
||||
CobblemonRequirementAdapter.encode(requirement, it)
|
||||
}
|
||||
buffer.writeCollection(interactions) { it, interaction ->
|
||||
interaction.encode(it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun decode(buffer: FriendlyByteBuf): PokemonInteractionSet {
|
||||
val requirements = buffer.readList(CobblemonRequirementAdapter::decode)
|
||||
val interactions = buffer.readList(PokemonInteraction::decode)
|
||||
return PokemonInteractionSet(requirements, interactions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val interactions: List<PokemonInteraction> = listOf()
|
||||
)
|
||||
data class PokemonInteraction(
|
||||
val grouping: ResourceLocation,
|
||||
val requirements: List<Requirement> = listOf(),
|
||||
val effects: List<InteractionEffect> = listOf(),
|
||||
val cooldown: ExpressionLike = "0".asExpressionLike()
|
||||
) {
|
||||
// Not put as a necessary constructor parameter because then there isn't a default constructor
|
||||
// and that means Gson just gives null for everything in the constructor and falls back to the JSON
|
||||
// properties - completely ignoring the default values above.
|
||||
lateinit var grouping: ResourceLocation
|
||||
|
||||
fun encode(buffer: FriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(grouping)
|
||||
buffer.writeCollection(requirements) { it, requirement ->
|
||||
CobblemonRequirementAdapter.encode(requirement, it)
|
||||
}
|
||||
buffer.writeExpressionLike(cooldown)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun decode(buffer: FriendlyByteBuf): PokemonInteraction {
|
||||
val grouping = buffer.readResourceLocation()
|
||||
val requirements = buffer.readList { it ->
|
||||
CobblemonRequirementAdapter.decode(it)
|
||||
}
|
||||
|
||||
// No need to sync these for now
|
||||
val effects = emptyList<InteractionEffect>()
|
||||
val cooldown = buffer.readExpressionLike()
|
||||
|
||||
return PokemonInteraction(
|
||||
requirements,
|
||||
effects,
|
||||
cooldown,
|
||||
).also {
|
||||
it.grouping = grouping
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
interface InteractionEffect {
|
||||
fun applyEffect(pokemon: PokemonEntity, player: ServerPlayer)
|
||||
}
|
||||
|
||||
class DropItemEffect(val item: ResourceLocation, val amount: IntRange?) : InteractionEffect {
|
||||
class DropItemEffect(val item: ResourceLocation, val amount: IntRange?): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
) {
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException(
|
||||
"Cannot load item with id: $item"
|
||||
)
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException("Cannot load item with id: $item")
|
||||
val stack = ItemStack(item)
|
||||
stack.count = amount?.randomOrNull() ?: 1
|
||||
if (stack.isEmpty)
|
||||
@@ -118,14 +68,12 @@ class DropItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
|
||||
}
|
||||
}
|
||||
|
||||
class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : InteractionEffect {
|
||||
class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
) {
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException(
|
||||
"Cannot load item with id: $item"
|
||||
)
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException("Cannot load item with id: $item")
|
||||
val stack = ItemStack(item)
|
||||
stack.count = amount?.randomOrNull() ?: 1
|
||||
if (stack.isEmpty)
|
||||
@@ -138,54 +86,25 @@ class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
|
||||
}
|
||||
}
|
||||
|
||||
class PlaySoundEffect(
|
||||
val sound: ResourceLocation,
|
||||
val soundSource: SoundSource?,
|
||||
@SerializedName("playAround") private val _playAround: Boolean?,
|
||||
@SerializedName("distance") private val _distance: Double?,
|
||||
@SerializedName("volume") private val _volume: Float?,
|
||||
@SerializedName("pitch") private val _pitch: Float?,
|
||||
) : InteractionEffect {
|
||||
|
||||
class PlaySoundEffect(val sound: ResourceLocation, val soundSource: SoundSource?, val playAround: Boolean = true, val distance: Double = 64.0, val volume: Float = 1.0F, val pitch: Float = 1.0F): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
) {
|
||||
val packet = UnvalidatedPlaySoundS2CPacket(
|
||||
sound,
|
||||
soundSource ?: SoundSource.NEUTRAL,
|
||||
pokemon.x,
|
||||
pokemon.y,
|
||||
pokemon.z,
|
||||
volume,
|
||||
pitch
|
||||
)
|
||||
|
||||
val packet = UnvalidatedPlaySoundS2CPacket(sound, soundSource ?: SoundSource.NEUTRAL, pokemon.x, pokemon.y, pokemon.z, volume, pitch)
|
||||
if (playAround) {
|
||||
packet.sendToPlayersAround(pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
|
||||
packet.sendToPlayersAround( pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
|
||||
} else {
|
||||
packet.sendToPlayer(player)
|
||||
}
|
||||
}
|
||||
|
||||
val playAround: Boolean
|
||||
get() = _playAround != false
|
||||
|
||||
val distance: Double
|
||||
get() = _distance ?: 64.0
|
||||
|
||||
val volume: Float
|
||||
get() = _volume ?: 1.0F
|
||||
|
||||
val pitch: Float
|
||||
get() = _pitch ?: 1.0F
|
||||
|
||||
companion object {
|
||||
val ID = "play_sound"
|
||||
}
|
||||
}
|
||||
|
||||
class ShrinkItemEffect(val amount: Int = 1) : InteractionEffect {
|
||||
class ShrinkItemEffect(val amount: Int = 1): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
@@ -201,7 +120,7 @@ class ShrinkItemEffect(val amount: Int = 1) : InteractionEffect {
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptEffect(val script: ExpressionLike) : InteractionEffect {
|
||||
class ScriptEffect(val script: ExpressionLike): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
|
||||
@@ -38,7 +38,7 @@ import net.minecraft.world.phys.AABB
|
||||
* @since July 29th, 2023
|
||||
*/
|
||||
interface PokemonSelectingItem {
|
||||
fun use(player: ServerPlayer, stack: ItemStack, ignoreShift: Boolean = false): InteractionResultHolder<ItemStack> {
|
||||
fun use(player: ServerPlayer, stack: ItemStack): InteractionResultHolder<ItemStack> {
|
||||
val range = player.entityInteractionRange()
|
||||
val entity = player.level()
|
||||
.getEntities(player, AABB.ofSize(player.position(), range, range, range))
|
||||
@@ -60,7 +60,7 @@ interface PokemonSelectingItem {
|
||||
return interactWithSpecificBattle(player, stack, battlePokemon)
|
||||
}
|
||||
} ?: run {
|
||||
if (ignoreShift || !player.isShiftKeyDown) {
|
||||
if (!player.isShiftKeyDown) {
|
||||
return if (entity != null) {
|
||||
val pokemon = entity.pokemon
|
||||
if (entity.ownerUUID == player.uuid) {
|
||||
|
||||
@@ -27,9 +27,7 @@ class Mark(
|
||||
val replace: List<ResourceLocation>?,
|
||||
val group: String?,
|
||||
val chance: Float = 0F,
|
||||
val indexNumber: Int?,
|
||||
val aspects: List<String>?,
|
||||
val sortOrder: Int = 0,
|
||||
val indexNumber: Int?
|
||||
): StringRepresentable {
|
||||
|
||||
companion object {
|
||||
@@ -44,9 +42,7 @@ class Mark(
|
||||
buffer.readNullable { buffer.readList { buffer.readResourceLocation() } },
|
||||
buffer.readNullable { buffer.readString() },
|
||||
buffer.readFloat(),
|
||||
buffer.readNullable { buffer.readInt() },
|
||||
buffer.readNullable { buffer.readList { buffer.readString() } },
|
||||
buffer.readInt(),
|
||||
buffer.readNullable { buffer.readInt() }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -87,7 +83,5 @@ class Mark(
|
||||
buffer.writeNullable(group) { _, v -> buffer.writeString(v) }
|
||||
buffer.writeFloat(chance)
|
||||
buffer.writeNullable(indexNumber) { _, v -> buffer.writeInt(v) }
|
||||
buffer.writeNullable(aspects) { _, v -> buffer.writeCollection(v) { _, aspect -> buffer.writeString(aspect) } }
|
||||
buffer.writeInt(sortOrder)
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user