Compare commits
39
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e80924c68 | ||
|
|
6749b39142 | ||
|
|
ff25416b07 | ||
|
|
e15ac73b1b | ||
|
|
6c6576c117 | ||
|
|
ebdfa7edc0 | ||
|
|
297e8eae77 | ||
|
|
ea8179018d | ||
|
|
14fccfae1d | ||
|
|
26386638ad | ||
|
|
5d1d99b64a | ||
|
|
eb2a5837eb | ||
|
|
93298d9a87 | ||
|
|
4d1f46c37c | ||
|
|
a2101b5759 | ||
|
|
187a190ec6 | ||
|
|
0d433ff394 | ||
|
|
d873399d05 | ||
|
|
56b5dba911 | ||
|
|
f0a66458e5 | ||
|
|
bb81a44a11 | ||
|
|
40dfca2294 | ||
|
|
5a40ced96b | ||
|
|
3eb97b29a1 | ||
|
|
d88de0b072 | ||
|
|
460c44248c | ||
|
|
a16668695c | ||
|
|
fe5ebb5444 | ||
|
|
c34e4c8bbc | ||
|
|
84e76a0a6d | ||
|
|
be70c1e8de | ||
|
|
fba40387bb | ||
|
|
1217e6d101 | ||
|
|
905c410aee | ||
|
|
cea0c826c6 | ||
|
|
dc3b17df3b | ||
|
|
5602dee9ac | ||
|
|
9e4137cc20 | ||
|
|
c92248f6e9 |
No files matched your search
+8
-24
@@ -59,13 +59,13 @@
|
||||
- Ice type Pokémon are now immune to Packed Snow
|
||||
|
||||
### New rideable Pokémon
|
||||
- Crobat
|
||||
- Skarmory
|
||||
- Milotic
|
||||
- Archeops
|
||||
- Goodra
|
||||
- Goodra (Hisuian Form)
|
||||
- Drampa
|
||||
- Archeops
|
||||
- Skarmory
|
||||
- Crobat
|
||||
- Goodra
|
||||
- Hisuian Goodra
|
||||
- Milotic
|
||||
|
||||
### Pokémon Added
|
||||
#### Generation 3
|
||||
@@ -171,14 +171,6 @@
|
||||
- Changed models for every existing regional bias
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
|
||||
- Happiny
|
||||
- Poliwrath
|
||||
- Zubat
|
||||
- Vulpix
|
||||
- Drowzee
|
||||
- Hypno
|
||||
- Noctowl
|
||||
- Skarmory
|
||||
- Skitty
|
||||
- Flygon
|
||||
@@ -210,16 +202,8 @@
|
||||
- Yamask
|
||||
- Cofagrigus
|
||||
- Luvdisc
|
||||
- Staryu
|
||||
- Starmie
|
||||
- Togetic
|
||||
- Rellor
|
||||
- Rabsca
|
||||
- Yungoos
|
||||
- Gumshoos
|
||||
|
||||
#### Added sounds to the following moves
|
||||
|
||||
- Absorb
|
||||
- Aurora Beam
|
||||
- Double Team
|
||||
@@ -248,12 +232,10 @@
|
||||
|
||||
### Fixes
|
||||
- Adjusted Croagunk's walkspeed
|
||||
- Adjusted Aerodactyl's walkspeed
|
||||
- Fixed Blitzle's base scale being `1` rather than the intended `0.8`
|
||||
- Fixed Magnezone's emissive layer for the shiny having the wrong name, thus displaying wrongly
|
||||
- Fixed Litleo not blinking
|
||||
- Fixed Garchomp T-posing when sleeping while out of battle.
|
||||
- Fixed Omanyte and Omastar incorrectly using water animations on land.
|
||||
- Sharp Beak can now be crafted
|
||||
- Metal Alloy can now be crafted
|
||||
- Ability Capsules can now be brewed
|
||||
@@ -318,6 +300,7 @@
|
||||
- Regional Foods will now prioritize being eaten instead of used for healing Pokémon, shift clicking will use it as healing
|
||||
- Resolved Z-Fighting on Pokédex Models
|
||||
- Restored Ninjask's ability to do barrel rolls
|
||||
- Fixed a crash caused by adding enchanted items to the Resurrection Machine
|
||||
|
||||
### Fixes
|
||||
- Fixed Croagunk's walkspeed
|
||||
@@ -378,6 +361,7 @@
|
||||
- Separated all the functions of MoLangFunctions.kt into their own files.
|
||||
- Spawn buckets and their base weights are now provided by the spawner, with different base weights for world, fishing, snack, and habitat spawn buckets.
|
||||
- Removed "SpawnBucket" class in favour of just storing maps of bucket names to weights.
|
||||
- Fixed nicknames not being applied to Pokémon spawned from `spawn_pool_world` files
|
||||
|
||||
### Molang & Datapacks
|
||||
- Added `moveset_builders` datapack folder for different styles of movesets.
|
||||
|
||||
@@ -10,16 +10,14 @@ package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.mixin.accessor.SinglePoolElementAccessor;
|
||||
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.util.RandomSource;
|
||||
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.JigsawPlacement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.LegacySinglePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
|
||||
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;
|
||||
@@ -28,24 +26,38 @@ 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.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(JigsawPlacement.class)
|
||||
public class JigsawPlacementMixin {
|
||||
|
||||
@Inject(
|
||||
method = "addPieces*",
|
||||
at = @At("HEAD"),
|
||||
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 cobblemon$cancelInvalidHeightRangeStart(
|
||||
CallbackInfoReturnable<Optional<Structure.GenerationStub>> cir,
|
||||
@Local(argsOnly = true, ordinal = 0) Structure.GenerationContext generationContext,
|
||||
@Local(argsOnly = true, ordinal = 0) Holder<StructureTemplatePool> startPool,
|
||||
@Local(argsOnly = true, ordinal = 0) BlockPos startPos
|
||||
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
|
||||
) {
|
||||
if (cobblemon$canAnyStartElementPlace(generationContext, startPool, startPos)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -58,19 +70,22 @@ public class JigsawPlacementMixin {
|
||||
Holder<StructureTemplatePool> startPool,
|
||||
BlockPos startPos
|
||||
) {
|
||||
List<StructurePoolElement> elements = startPool.value().getShuffledTemplates(RandomSource.create(0L));
|
||||
for (StructurePoolElement element : elements) {
|
||||
for (StructurePoolElement element : startPool.value().templates) {
|
||||
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(element);
|
||||
|
||||
if (heightRangeProcessor.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (heightRangeProcessor.get().isValidPlacement(
|
||||
HeightRangeStructureProcessor processor = heightRangeProcessor.get();
|
||||
boolean valid = processor.isValidPlacement(
|
||||
generationContext.chunkGenerator(),
|
||||
generationContext.heightAccessor(),
|
||||
generationContext.randomState(),
|
||||
startPos
|
||||
)) {
|
||||
);
|
||||
|
||||
if (valid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -93,5 +108,4 @@ public class JigsawPlacementMixin {
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.Cobblemon;
|
||||
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.gui.interact.wheel.InteractWheelGuiFactoryKt;
|
||||
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;
|
||||
@@ -67,6 +68,39 @@ public abstract class MouseHandlerMixin {
|
||||
|
||||
@Unique private double cobblemon$timeDelta;
|
||||
|
||||
@Inject(
|
||||
method = "onPress",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
public void cobblemon$pokeskillGuiControl(long windowPointer, int button, int action, int modifiers, CallbackInfo ci) {
|
||||
if (button == 0 && action == 1) {
|
||||
|
||||
// Make sure no menus are open already
|
||||
if (this.minecraft.screen == null && this.minecraft.getOverlay() == null) {
|
||||
// Check to see if party key is held
|
||||
if (PartySendBinding.INSTANCE.getWasDown()) {
|
||||
|
||||
// Don't want to send out a pokemon if we let go of the key
|
||||
PartySendBinding.INSTANCE.actioned();
|
||||
|
||||
//Open the actual gui
|
||||
var player = Minecraft.getInstance().player;
|
||||
var storage = CobblemonClient.INSTANCE.getStorage();
|
||||
var selectedPokemon = storage.getParty().get(storage.getSelectedSlot());
|
||||
if (selectedPokemon != null && player != null) {
|
||||
//canApplyChange = false
|
||||
var gui = InteractWheelGuiFactoryKt.createPokeSkillGui(player, selectedPokemon);
|
||||
Minecraft.getInstance().setScreen(gui);
|
||||
}
|
||||
|
||||
// Stop the rest of minecraft click logic like punching and using items
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "onScroll",
|
||||
at = @At(
|
||||
|
||||
@@ -308,7 +308,9 @@ object Cobblemon {
|
||||
this.config.maxPokemonLevel,
|
||||
this.config.maxPokemonFriendship,
|
||||
this.config.maxDynamaxLevel,
|
||||
this.config.unlockAllMoveDexMovesByDefault
|
||||
this.config.unlockAllMoveDexMovesByDefault,
|
||||
this.config.pokemonIntrinsicSizeMin,
|
||||
this.config.pokemonIntrinsicSizeMax
|
||||
).sendToPlayer(player)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,26 +24,13 @@ import com.cobblemon.mod.common.client.net.data.RideSettingsSyncHandler
|
||||
import com.cobblemon.mod.common.client.net.debug.OpenRidingStatsDebugGUIHandler
|
||||
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
|
||||
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.PokeSnackBlockParticlesHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.RunPosableMoLangHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.SaccharineLogBlockParticlesHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHandler
|
||||
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.effect.*
|
||||
import com.cobblemon.mod.common.client.net.gui.*
|
||||
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
|
||||
import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
|
||||
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.pasture.*
|
||||
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
|
||||
@@ -62,14 +49,7 @@ import com.cobblemon.mod.common.client.net.storage.party.SetPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.party.SetPartyReferenceHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.*
|
||||
import com.cobblemon.mod.common.client.net.toast.ToastPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeAcceptanceChangedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeCancelledHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeCompletedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
|
||||
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.client.net.trade.*
|
||||
import com.cobblemon.mod.common.net.PacketRegisterInfo
|
||||
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
|
||||
@@ -85,21 +65,13 @@ import com.cobblemon.mod.common.net.messages.client.data.*
|
||||
import com.cobblemon.mod.common.net.messages.client.debug.RequestOpenRidingStatsDebugGUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.PokeSnackBlockParticlesPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
|
||||
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.effect.*
|
||||
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
|
||||
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateOrientationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.ClosePasturePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonUnpasturedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.UpdatePastureConflictFlagPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
||||
@@ -120,45 +92,17 @@ import com.cobblemon.mod.common.net.messages.client.storage.party.InitializePart
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.MoveClientPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyReferencePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.OpenPCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.RenamePCBoxPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCBoxPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.*
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.ChangePCBoxWallpaperPacket
|
||||
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
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeCompletedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeProcessStartedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
|
||||
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
|
||||
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamLeavePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.*
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.*
|
||||
import com.cobblemon.mod.common.net.messages.server.*
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.*
|
||||
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
|
||||
@@ -185,11 +129,7 @@ import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPack
|
||||
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.StartScanningPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetActiveMarkPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetMarkingsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.*
|
||||
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
|
||||
@@ -202,21 +142,12 @@ import com.cobblemon.mod.common.net.messages.server.storage.party.PartyTutorialP
|
||||
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.*
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptancePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.PerformTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeResponseHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamLeaveHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.UsePokeSkillHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.*
|
||||
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
|
||||
@@ -244,11 +175,7 @@ import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandl
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanningHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.interact.InteractPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.ServerboundUpdateRidingStateHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetActiveMarkHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetItemHiddenHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.*
|
||||
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
|
||||
@@ -264,12 +191,7 @@ import com.cobblemon.mod.common.net.serverhandling.storage.party.PartyTutorialPa
|
||||
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.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.AcceptTradeRequestHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.CancelTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.PerformTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.*
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
@@ -339,6 +261,7 @@ 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(SkillCooldownsUpdatePacket.ID, SkillCooldownsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(AlphaUpdatePacket.ID, AlphaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(ScaleModifierUpdatePacket.ID, ScaleModifierUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
|
||||
@@ -439,6 +362,8 @@ 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(PokeSkillsRegistrySyncPacket.ID, PokeSkillsRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(TechnicalMachineRegistrySyncPacket.ID, TechnicalMachineRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
// Effects
|
||||
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
|
||||
@@ -530,6 +455,7 @@ object CobblemonNetwork {
|
||||
// Interaction Packets
|
||||
list.add(PacketRegisterInfo(InteractPokemonPacket.ID, InteractPokemonPacket::decode, InteractPokemonHandler))
|
||||
list.add(PacketRegisterInfo(RequestPlayerInteractionsPacket.ID, RequestPlayerInteractionsPacket::decode, RequestInteractionsHandler))
|
||||
list.add(PacketRegisterInfo(UsePokeSkillPacket.ID, UsePokeSkillPacket::decode, UsePokeSkillHandler))
|
||||
|
||||
// Storage Packets
|
||||
list.add(PacketRegisterInfo(SendOutPokemonPacket.ID, SendOutPokemonPacket::decode, SendOutPokemonHandler))
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokeSkill
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PokeSkillsRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.adapters.ActionEffectTimelineAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.TextAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.world.entity.player.Player
|
||||
|
||||
/**
|
||||
* The JSON data registry for all the possible [PokeSkill]s.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since August 31st, 2025
|
||||
*/
|
||||
object CobblemonPokeSkills : JsonDataRegistry<PokeSkill> {
|
||||
override val id = cobblemonResource("poke_skills")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<CobblemonPokeSkills>()
|
||||
override val typeToken = TypeToken.get(PokeSkill::class.java)
|
||||
override val resourcePath = "poke_skills"
|
||||
override val gson = GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(ActionEffectTimeline::class.java, ActionEffectTimelineAdapter)
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(Component::class.java, TextAdapter)
|
||||
.create()
|
||||
|
||||
var skills = mapOf<ResourceLocation, PokeSkill>()
|
||||
|
||||
fun getAccessibleSkills(player: Player, pokemon: Pokemon): List<PokeSkill> {
|
||||
return skills.values.filter { it.canAccess(player, pokemon) }
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokeSkill>) {
|
||||
data.forEach { (id, skill) -> skill.id = id }
|
||||
skills = data
|
||||
observable.emit(this)
|
||||
Cobblemon.LOGGER.info("Loaded ${skills.size} PokéSkills")
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
player.sendPacket(PokeSkillsRegistrySyncPacket(skills.values.toList()))
|
||||
}
|
||||
}
|
||||
@@ -293,11 +293,11 @@ object MoLangFunctions {
|
||||
)
|
||||
value.functions["is_in"] = Function put@{ params: MoParams ->
|
||||
val tag = TagKey.create(key, ResourceLocation.parse(params.getString(0).replace("#", "")))
|
||||
return@put DoubleValue(if (value.obj.`is`(tag)) 1.0 else 0.0)
|
||||
return@put DoubleValue(value.obj.`is`(tag))
|
||||
}
|
||||
value.functions["is_of"] = Function put@{ params: MoParams ->
|
||||
val identifier = ResourceLocation.parse(params.getString(0))
|
||||
return@put DoubleValue(if (value.obj.`is`(identifier)) 1.0 else 0.0)
|
||||
return@put DoubleValue(value.obj.`is`(identifier))
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ object DropEntryMoLangFunctions : AbstractMoLangFunctionHolder<DropEntry>() {
|
||||
map["max_selectable_times"] = { DoubleValue(drop.maxSelectableTimes.toDouble()) }
|
||||
map["can_drop"] = { params ->
|
||||
val pokemon = params.getOrNull<ObjectValue<Pokemon>>(0)?.obj
|
||||
DoubleValue(if (drop.canDrop(pokemon)) 1.0 else 0.0)
|
||||
DoubleValue(drop.canDrop(pokemon))
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
+67
-1
@@ -35,12 +35,14 @@ import com.cobblemon.mod.common.util.effectiveName
|
||||
import com.cobblemon.mod.common.util.getBlockStatesWithPos
|
||||
import com.cobblemon.mod.common.util.getBooleanOrNull
|
||||
import com.cobblemon.mod.common.util.getDoubleOrNull
|
||||
import com.cobblemon.mod.common.util.getIntOrNull
|
||||
import com.cobblemon.mod.common.util.getIsSubmerged
|
||||
import com.cobblemon.mod.common.util.getOrNull
|
||||
import com.cobblemon.mod.common.util.getStringOrNull
|
||||
import com.cobblemon.mod.common.util.isStandingOn
|
||||
import com.cobblemon.mod.common.util.resolve
|
||||
import com.cobblemon.mod.common.util.worldRegistry
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
@@ -48,7 +50,10 @@ import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.damagesource.DamageTypes
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.TamableAnimal
|
||||
import net.minecraft.world.level.block.BonemealableBlock
|
||||
import net.minecraft.world.level.block.CropBlock
|
||||
import net.minecraft.world.phys.AABB
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import java.util.UUID
|
||||
@@ -78,8 +83,13 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
"vertical_velocity" to { DoubleValue(thisEntity.deltaMovement.y) },
|
||||
"is_on_ground" to { _ -> DoubleValue(thisEntity.onGround()) },
|
||||
"world" to { _ -> thisEntity.level().worldRegistry.wrapAsHolder(thisEntity.level()).asWorldMoLangValue() },
|
||||
"dimension" to { StringValue(thisEntity.level().dimension().location().toString()) },
|
||||
"biome" to { _ -> thisEntity.level().getBiome(thisEntity.blockPosition()).asBiomeMoLangValue() },
|
||||
"is_passenger" to { DoubleValue(thisEntity.isPassenger) },
|
||||
"is_passenger" to isPassenger@{ params ->
|
||||
val passengerEntity = (params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? LivingEntity ?: return@isPassenger DoubleValue.ZERO
|
||||
DoubleValue(passengerEntity in thisEntity.passengers)
|
||||
},
|
||||
"discard" to { thisEntity.discard() },
|
||||
"is_sneaking" to { _ -> DoubleValue(thisEntity.isShiftKeyDown) },
|
||||
"is_sprinting" to { _ -> DoubleValue(thisEntity.isSprinting) },
|
||||
@@ -121,6 +131,62 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
listOf(thisEntity.deltaMovement.x, thisEntity.deltaMovement.y, thisEntity.deltaMovement.z)
|
||||
.asArrayValue(::DoubleValue)
|
||||
},
|
||||
"set_position" to { params ->
|
||||
val x = params.getDouble(0)
|
||||
val y = params.getDouble(1)
|
||||
val z = params.getDouble(2)
|
||||
thisEntity.setPos(x, y, z)
|
||||
DoubleValue.ONE
|
||||
},
|
||||
"fertilize_nearby_crops" to { params -> //TODO: pretty bespoke. Maybe should be moved or generalized?
|
||||
val radius = params.getIntOrNull(0) ?: 8
|
||||
val maxCrops = params.getIntOrNull(1) ?: 8
|
||||
|
||||
var fertilizedCount = 0
|
||||
val level = thisEntity.level()
|
||||
val centerPos = thisEntity.blockPosition()
|
||||
|
||||
// Find all bonemealable blocks within radius
|
||||
val bonemealableBlocks = mutableListOf<BlockPos>()
|
||||
|
||||
for (x in -radius..radius) {
|
||||
for (y in -3..3) { // Limited vertical range
|
||||
for (z in -radius..radius) {
|
||||
val pos = centerPos.offset(x, y, z)
|
||||
val blockState = level.getBlockState(pos)
|
||||
val block = blockState.block
|
||||
|
||||
// Check if block can be bonemealed
|
||||
if (block is BonemealableBlock && block is CropBlock && block.isValidBonemealTarget(level, pos, blockState)) {
|
||||
bonemealableBlocks.add(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle and take up to maxCrops blocks to fertilize
|
||||
bonemealableBlocks.shuffle()
|
||||
val blocksToFertilize = bonemealableBlocks.take(maxCrops)
|
||||
|
||||
for (pos in blocksToFertilize) {
|
||||
val blockState = level.getBlockState(pos)
|
||||
val block = blockState.block
|
||||
|
||||
if (block is BonemealableBlock && block.isValidBonemealTarget(level, pos, blockState)) {
|
||||
if (block.isBonemealSuccess(level, level.random, pos, blockState)) {
|
||||
block.performBonemeal(level as ServerLevel, level.random, pos, blockState)
|
||||
|
||||
// Add bonemeal particle
|
||||
val particlePos = block.getParticlePos(pos)
|
||||
level.levelEvent(1505, particlePos, 15) // Same event used for bonemealing in vanilla
|
||||
|
||||
fertilizedCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoubleValue(fertilizedCount.toDouble())
|
||||
},
|
||||
"tags" to {
|
||||
val tags = thisEntity.tags
|
||||
val array = ArrayStruct(hashMapOf())
|
||||
@@ -233,7 +299,7 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
val intangible = params.getBooleanOrNull(0) ?: true
|
||||
thisEntity.noPhysics = intangible
|
||||
DoubleValue.ONE
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
+18
@@ -39,6 +39,7 @@ import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.TamableAnimal
|
||||
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
|
||||
import net.minecraft.world.entity.ai.behavior.EntityTracker
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.ai.memory.MemoryStatus
|
||||
import net.minecraft.world.entity.ai.memory.WalkTarget
|
||||
@@ -123,6 +124,23 @@ object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>(
|
||||
duration.toLong()
|
||||
)
|
||||
}
|
||||
map["look_at_entity"] = put@{ params ->
|
||||
val targetEntity = params.get<MoValue>(0)
|
||||
val duration = params.getDoubleOrNull(1)?.toInt() ?: 20
|
||||
|
||||
val lookEntity = if (targetEntity is ObjectValue<*> && targetEntity.obj is Entity) {
|
||||
targetEntity.obj as Entity
|
||||
} else {
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
|
||||
// Set the current entity to track the looked for entity
|
||||
val brain = entity.brain
|
||||
val tracker = EntityTracker(lookEntity, true)
|
||||
brain.setMemoryWithExpiry(MemoryModuleType.LOOK_TARGET, tracker, duration.toLong())
|
||||
|
||||
DoubleValue.ONE
|
||||
}
|
||||
map["get_wander_control_memory"] = put@{
|
||||
val value = entity.brain.getMemorySafely(CobblemonMemories.WANDER_CONTROL).orElse(null)
|
||||
?: CobblemonWanderControl()
|
||||
|
||||
+62
@@ -23,6 +23,7 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.battles.BattleBuilder
|
||||
import com.cobblemon.mod.common.battles.BattleFormat
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
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.BattleMusicPacket
|
||||
@@ -32,6 +33,7 @@ import com.cobblemon.mod.common.util.activeDialogue
|
||||
import com.cobblemon.mod.common.util.asBlockPos
|
||||
import com.cobblemon.mod.common.util.asResource
|
||||
import com.cobblemon.mod.common.util.asUUID
|
||||
import com.cobblemon.mod.common.util.blockRegistry
|
||||
import com.cobblemon.mod.common.util.getBattleState
|
||||
import com.cobblemon.mod.common.util.getBooleanOrNull
|
||||
import com.cobblemon.mod.common.util.getDoubleOrNull
|
||||
@@ -44,14 +46,19 @@ import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.pc
|
||||
import com.cobblemon.mod.common.util.pokedex
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.cobblemon.mod.common.util.toArrayStruct
|
||||
import net.minecraft.client.player.AbstractClientPlayer
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.ClipContext
|
||||
import net.minecraft.world.level.GameType
|
||||
import net.minecraft.world.phys.HitResult
|
||||
import kotlin.collections.iterator
|
||||
|
||||
object PlayerMoLangFunctions : AbstractMoLangFunctionHolder<Player>() {
|
||||
@@ -379,6 +386,61 @@ object PlayerMoLangFunctions : AbstractMoLangFunctionHolder<Player>() {
|
||||
} ?: DoubleValue.ZERO
|
||||
}
|
||||
map["has_chosen_starter"] = { _ -> DoubleValue(Cobblemon.playerDataManager.getGenericData(player).starterSelected) }
|
||||
map["ride"] = put@{ params ->
|
||||
val entity = (params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? Entity ?: return@put DoubleValue.ZERO
|
||||
player.startRiding(entity)
|
||||
}
|
||||
map["has_respawn_position"] = {
|
||||
DoubleValue(player.respawnPosition != null)
|
||||
}
|
||||
map["respawn_position"] = {
|
||||
player.respawnPosition?.toArrayStruct() ?: DoubleValue.ZERO
|
||||
}
|
||||
map["respawn_dimension"] = {
|
||||
StringValue(player.respawnDimension.location().toString())
|
||||
}
|
||||
map["teleport_to_respawn"] = put@{
|
||||
val respawnPosition = player.respawnPosition?.center ?: return@put DoubleValue.ZERO
|
||||
player.teleportTo(respawnPosition.x, respawnPosition.y, respawnPosition.z)
|
||||
DoubleValue.ONE
|
||||
}
|
||||
map["get_looked_block"] = put@{ params ->
|
||||
// Get the block the player is looking at 'distance' units away
|
||||
val distance = params.getDoubleOrNull(0) ?: 8.0
|
||||
|
||||
// perform clip
|
||||
val level = player.level()
|
||||
val eye = player.eyePosition
|
||||
val view = player.getViewVector(1.0f)
|
||||
val lookPos = eye.add(view.scale(distance))
|
||||
val hitResult = level.clip(ClipContext(eye, lookPos, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player))
|
||||
|
||||
if (hitResult.type == HitResult.Type.BLOCK) {
|
||||
// Get base block info
|
||||
val blockPos = hitResult.blockPos
|
||||
val blockState = level.getBlockState(blockPos)
|
||||
val blockHolder = level.blockRegistry.wrapAsHolder(blockState.block)
|
||||
val blockValue = blockHolder.asMoLangValue(Registries.BLOCK)
|
||||
|
||||
// Attach the position to the blockValue return
|
||||
blockValue.addFunction("x") { DoubleValue(blockPos.x.toDouble()) }
|
||||
blockValue.addFunction("y") { DoubleValue(blockPos.y.toDouble()) }
|
||||
blockValue.addFunction("z") { DoubleValue(blockPos.z.toDouble()) }
|
||||
|
||||
return@put blockValue
|
||||
} else {
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
}
|
||||
map["is_battling"] = {
|
||||
DoubleValue(player.isInBattle())
|
||||
}
|
||||
}
|
||||
|
||||
if (player is AbstractClientPlayer) {
|
||||
map["is_battling"] = {
|
||||
DoubleValue(CobblemonClient.battle?.spectating == false) // Checks not-null and not-spectating at the same time, trust
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
|
||||
+27
@@ -15,6 +15,7 @@ import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonMovesetBuilders
|
||||
import com.cobblemon.mod.common.CobblemonPokeSkills
|
||||
import com.cobblemon.mod.common.api.mark.Marks
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.moves.BenchedMove
|
||||
@@ -26,6 +27,9 @@ import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||
import com.cobblemon.mod.common.pokemon.IVs
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.activestate.ActivePokemonState
|
||||
import com.cobblemon.mod.common.pokemon.activestate.SentOutState
|
||||
import com.cobblemon.mod.common.pokemon.activestate.ShoulderedState
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.getBooleanOrNull
|
||||
@@ -447,6 +451,29 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
||||
evolution?.forceEvolve(pokemon)
|
||||
StringValue(evolution.toString())
|
||||
}
|
||||
map["is_sent_out"] = {
|
||||
DoubleValue(pokemon.state is SentOutState)
|
||||
}
|
||||
map["is_shouldered"] = {
|
||||
DoubleValue(pokemon.state is ShoulderedState)
|
||||
}
|
||||
map["entity"] = {
|
||||
(pokemon.state as? ActivePokemonState)?.entity?.struct ?: DoubleValue.ZERO
|
||||
}
|
||||
map["is_rideable"] = put@{
|
||||
return@put DoubleValue(!pokemon.riding.behaviours.isNullOrEmpty())
|
||||
}
|
||||
map["has_status"] = put@{ params ->
|
||||
val status = params.getString(0).asIdentifierDefaultingNamespace()
|
||||
return@put DoubleValue(pokemon.status?.status?.name == status)
|
||||
}
|
||||
map["add_skill_cooldown"] = put@{ params ->
|
||||
val skillId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||
val cooldownTicks = params.getIntOrNull(1)
|
||||
val skill = CobblemonPokeSkills.skills[skillId] ?: return@put DoubleValue.ZERO
|
||||
pokemon.addSkillCooldown(skillId, cooldownTicks ?: skill.cooldownTicks)
|
||||
return@put DoubleValue.ONE
|
||||
}
|
||||
|
||||
map["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||
map["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
|
||||
|
||||
+23
-2
@@ -40,6 +40,7 @@ import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.Level.ExplosionInteraction
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity
|
||||
import net.minecraft.world.level.levelgen.Heightmap
|
||||
import net.minecraft.world.level.storage.loot.LootParams
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
|
||||
@@ -61,6 +62,26 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
|
||||
val time = world.dayTime % 24000
|
||||
return@put DoubleValue(timeOfDay.contains(time.toInt()))
|
||||
}
|
||||
map["add_furnace_fuel"] = put@{ params ->
|
||||
val x = params.getInt(0)
|
||||
val y = params.getInt(1)
|
||||
val z = params.getInt(2)
|
||||
val fuelTicks = params.getInt(3)
|
||||
|
||||
val blockEntity = world.getBlockEntity(BlockPos(x, y, z))
|
||||
if (blockEntity is AbstractFurnaceBlockEntity) {
|
||||
// Add fuel time to the furnace
|
||||
blockEntity.litTime += fuelTicks
|
||||
|
||||
// If this exceeds the litDuration then bump it up
|
||||
if (blockEntity.litTime >= blockEntity.litDuration) {
|
||||
blockEntity.litDuration = blockEntity.litTime
|
||||
}
|
||||
blockEntity.setChanged()
|
||||
return@put DoubleValue.ONE
|
||||
}
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
map["game_time"] = { _ -> DoubleValue(world.gameTime.toDouble()) }
|
||||
map["time_of_day"] = put@{
|
||||
val time = world.dayTime % 24000
|
||||
@@ -128,13 +149,13 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
|
||||
val x = params.getDouble(0)
|
||||
val y = params.getDouble(1)
|
||||
val z = params.getDouble(2)
|
||||
val range = params.getDouble(3).toFloat()
|
||||
val range = params.getDoubleOrNull(3) ?: 8.0
|
||||
world.explode(
|
||||
null,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
range,
|
||||
range.toFloat(),
|
||||
ExplosionInteraction.valueOf(
|
||||
params.getStringOrNull(4)?.uppercase() ?: ExplosionInteraction.TNT.name
|
||||
)
|
||||
|
||||
+2
-1
@@ -50,7 +50,7 @@ class ActionEffectTimeline(
|
||||
}
|
||||
|
||||
fun chainKeyframes(context: ActionEffectContext, iterator: Iterator<ActionEffectKeyframe>, finalFuture: CompletableFuture<Unit>) {
|
||||
if (!iterator.hasNext()) {
|
||||
if (!iterator.hasNext() || context.cancelled) {
|
||||
finalFuture.complete(Unit)
|
||||
} else {
|
||||
val keyframe = iterator.next()
|
||||
@@ -70,6 +70,7 @@ class ActionEffectContext(
|
||||
val runtime: MoLangRuntime,
|
||||
var canBeInterrupted: Boolean = false,
|
||||
var interrupted: Boolean = false,
|
||||
var cancelled: Boolean = false,
|
||||
var currentKeyframes: MutableList<ActionEffectKeyframe> = mutableListOf(),
|
||||
var level: Level? = null
|
||||
) {
|
||||
|
||||
@@ -57,6 +57,7 @@ object ActionEffects : JsonDataRegistry<ActionEffectTimeline> {
|
||||
ActionEffectKeyframe.register<RunActionEffectKeyframe>("run_action_effect")
|
||||
ActionEffectKeyframe.register<EntityParticlesActionEffectKeyframe>("entity_particles")
|
||||
ActionEffectKeyframe.register<EntitySoundActionEffectKeyframe>("entity_sound")
|
||||
ActionEffectKeyframe.register<CancelActionEffectKeyframe>("cancel")
|
||||
}
|
||||
|
||||
override val gson = GsonBuilder()
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.moves.animations.keyframes
|
||||
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
class CancelActionEffectKeyframe : ConditionalActionEffectKeyframe() {
|
||||
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
|
||||
context.cancelled = true
|
||||
return CompletableFuture.completedFuture(Unit)
|
||||
}
|
||||
}
|
||||
+28
-6
@@ -21,6 +21,7 @@ import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import net.minecraft.commands.arguments.EntityArgument.getPlayers
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
/**
|
||||
* Spawns particles on the entity based on the given particle effect and locator.
|
||||
@@ -65,15 +66,36 @@ class EntityParticlesActionEffectKeyframe : ConditionalActionEffectKeyframe(), E
|
||||
allEntities.any { player.distanceTo(it) <= visibilityRange }
|
||||
}
|
||||
|
||||
// Try to resolve a world-position target from runtime variables
|
||||
val runtimeTargetPosition: Vec3? = try {
|
||||
val x = "v.target_x".asExpressionLike().resolveDouble(context.runtime)
|
||||
val y = "v.target_y".asExpressionLike().resolveDouble(context.runtime)
|
||||
val z = "v.target_z".asExpressionLike().resolveDouble(context.runtime)
|
||||
if (x != 0.0 || y != 0.0 || z != 0.0) Vec3(x, y, z) else null
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
|
||||
sourceEntities.filter { it is PosableEntity }.forEach { entity ->
|
||||
if (targetLocators == null) {
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators)
|
||||
packet.sendToPlayers(players)
|
||||
}
|
||||
else {
|
||||
// If target entities are specified, send the particle using entity locators/position.
|
||||
// If there are no target entities then attempt to send to v.target world position or send without target.
|
||||
if (targetEntities.isNotEmpty()) {
|
||||
targetEntities.forEach { targetEntity ->
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators, targetEntity.id, targetLocators!!.toList())
|
||||
if (targetLocators != null) {
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators, targetEntity.id, targetLocators!!.toList())
|
||||
packet.sendToPlayers(players)
|
||||
} else {
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators, targetEntity.id)
|
||||
packet.sendToPlayers(players)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (runtimeTargetPosition != null) {
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators, targetPosition = runtimeTargetPosition)
|
||||
packet.sendToPlayers(players)
|
||||
} else {
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators)
|
||||
packet.sendToPlayers(players)
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -8,8 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.moves.animations.keyframes
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.scheduling.delayedFuture
|
||||
|
||||
+25
-2
@@ -8,6 +8,8 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.moves.animations.keyframes
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
|
||||
import java.util.concurrent.CompletableFuture
|
||||
@@ -18,16 +20,37 @@ import net.minecraft.resources.ResourceLocation
|
||||
* effect is marked complete only when the action effect it runs is complete unless [waitForActionEffect] is
|
||||
* false.
|
||||
*
|
||||
* If [expression] is set, it will be resolved at runtime to determine the action effect identifier.
|
||||
* This allows dynamic delegation based on MoLang variables (e.g. v.granting_move).
|
||||
* If [expression] is not set, the static [actionEffect] identifier is used instead.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since January 21st, 2024
|
||||
*/
|
||||
class RunActionEffectKeyframe : ConditionalActionEffectKeyframe() {
|
||||
val actionEffect: ResourceLocation? = null
|
||||
val expression: ExpressionLike? = null
|
||||
val waitForActionEffect = true
|
||||
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
|
||||
return if (actionEffect != null) {
|
||||
ActionEffects.actionEffects[actionEffect]?.run(context)?.takeIf { waitForActionEffect } ?: skip()
|
||||
val effectId = if (expression != null) {
|
||||
val resolved = expression.resolveString(context.runtime)
|
||||
if (resolved == "0" || resolved.isBlank()) {
|
||||
Cobblemon.LOGGER.warn("RunActionEffectKeyframe expression resolved to empty/zero string: $resolved")
|
||||
return skip()
|
||||
}
|
||||
try {
|
||||
ResourceLocation.parse(resolved)
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.warn("RunActionEffectKeyframe expression resolved to invalid resource location: $resolved with exception: $e")
|
||||
return skip()
|
||||
}
|
||||
} else {
|
||||
actionEffect
|
||||
}
|
||||
return if (effectId != null) {
|
||||
ActionEffects.actionEffects[effectId]?.run(context)?.takeIf { waitForActionEffect } ?: skip()
|
||||
} else {
|
||||
Cobblemon.LOGGER.warn("RunActionEffectKeyframe has no action effect identifier or expression to run")
|
||||
skip()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -759,6 +759,7 @@ open class PokemonProperties {
|
||||
shiny?.let { json.addProperty(DataKeys.POKEMON_SHINY, it) }
|
||||
gender?.let { json.addProperty(DataKeys.POKEMON_GENDER, it.name) }
|
||||
species?.let { json.addProperty(DataKeys.POKEMON_SPECIES_TEXT, it) }
|
||||
nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, it.string) }
|
||||
form?.let { json.addProperty(DataKeys.POKEMON_FORM_ID, it) }
|
||||
friendship?.let { json.addProperty(DataKeys.POKEMON_FRIENDSHIP, it) }
|
||||
fullness?.let { json.addProperty(DataKeys.POKEMON_FULLNESS, it) }
|
||||
@@ -795,6 +796,7 @@ open class PokemonProperties {
|
||||
shiny = json.get(DataKeys.POKEMON_SHINY)?.asBoolean
|
||||
gender = json.get(DataKeys.POKEMON_GENDER)?.asString?.let { Gender.valueOf(it) }
|
||||
species = json.get(DataKeys.POKEMON_SPECIES_TEXT)?.asString
|
||||
nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let(Component::literal)
|
||||
form = json.get(DataKeys.POKEMON_FORM_ID)?.asString
|
||||
friendship = json.get(DataKeys.POKEMON_FRIENDSHIP)?.asInt
|
||||
fullness = json.get(DataKeys.POKEMON_FULLNESS)?.asInt
|
||||
|
||||
+2
-2
@@ -102,7 +102,7 @@ open class PlayerPartyStore(
|
||||
for (pokemon in this) {
|
||||
// Awake from fainted
|
||||
if (pokemon.isFainted()) {
|
||||
//Skip awaken logic check if config value is 0
|
||||
// Skip awaken logic check if config value is 0
|
||||
if (Cobblemon.config.faintAwakenHealthPercent > 0) {
|
||||
pokemon.faintedTimer -= 1
|
||||
if (pokemon.faintedTimer <= -1) {
|
||||
@@ -119,7 +119,7 @@ open class PlayerPartyStore(
|
||||
}
|
||||
// Passive healing while less than full health
|
||||
else if (pokemon.currentHealth < pokemon.maxHealth) {
|
||||
//Skip passive healing logic check if config value is 0
|
||||
// Skip passive healing logic check if config value is 0
|
||||
if (Cobblemon.config.healPercent > 0) {
|
||||
pokemon.healTimer--
|
||||
if (pokemon.healTimer <= -1) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.moves.MoveTemplate
|
||||
import com.cobblemon.mod.common.api.moves.adapters.MoveTemplateAdapter
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.tms.TechnicalMachineRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.TMObtainMethodAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
@@ -70,5 +71,7 @@ object TechnicalMachines : JsonDataRegistry<TechnicalMachine> {
|
||||
|
||||
fun getByResourceLocation(resourceLocation: ResourceLocation) = tmMap[resourceLocation]
|
||||
fun getAllResourceLocations() = tmMap.keys.toSet()
|
||||
override fun sync(player: ServerPlayer) {}
|
||||
override fun sync(player: ServerPlayer) {
|
||||
TechnicalMachineRegistrySyncPacket(tmMap.values.toList()).sendToPlayer(player)
|
||||
}
|
||||
}
|
||||
+5
-27
@@ -16,24 +16,20 @@ import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.component.DataComponents
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.ContainerHelper
|
||||
import net.minecraft.world.Containers
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.ItemInteractionResult
|
||||
import net.minecraft.world.WorldlyContainer
|
||||
import net.minecraft.world.*
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.level.gameevent.GameEvent
|
||||
import java.util.OptionalInt
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import java.util.*
|
||||
import kotlin.math.pow
|
||||
|
||||
class DiscShelfBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(CobblemonBlockEntities.DISC_SHELF, pos, state), WorldlyContainer {
|
||||
@@ -134,25 +130,7 @@ class DiscShelfBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobbl
|
||||
return stack.item is TechnicalMachineItem
|
||||
|| stack.item == CobblemonItems.UPGRADE
|
||||
|| stack.item == CobblemonItems.DUBIOUS_DISC
|
||||
|| stack.item == Items.MUSIC_DISC_13
|
||||
|| stack.item == Items.MUSIC_DISC_CAT
|
||||
|| stack.item == Items.MUSIC_DISC_BLOCKS
|
||||
|| stack.item == Items.MUSIC_DISC_CHIRP
|
||||
|| stack.item == Items.MUSIC_DISC_FAR
|
||||
|| stack.item == Items.MUSIC_DISC_MALL
|
||||
|| stack.item == Items.MUSIC_DISC_MELLOHI
|
||||
|| stack.item == Items.MUSIC_DISC_STAL
|
||||
|| stack.item == Items.MUSIC_DISC_STRAD
|
||||
|| stack.item == Items.MUSIC_DISC_WARD
|
||||
|| stack.item == Items.MUSIC_DISC_11
|
||||
|| stack.item == Items.MUSIC_DISC_WAIT
|
||||
|| stack.item == Items.MUSIC_DISC_OTHERSIDE
|
||||
|| stack.item == Items.MUSIC_DISC_5
|
||||
|| stack.item == Items.MUSIC_DISC_RELIC
|
||||
|| stack.item == Items.MUSIC_DISC_PRECIPICE
|
||||
|| stack.item == Items.MUSIC_DISC_CREATOR
|
||||
|| stack.item == Items.MUSIC_DISC_CREATOR_MUSIC_BOX
|
||||
|| stack.item == Items.MUSIC_DISC_PIGSTEP
|
||||
|| stack.has(DataComponents.JUKEBOX_PLAYABLE)
|
||||
}
|
||||
|
||||
fun onNoteBlockPulse(level: Level, noteBlockPos: BlockPos, soundEvent: SoundEvent) {
|
||||
|
||||
+6
-2
@@ -630,7 +630,8 @@ class FossilMultiblockStructure (
|
||||
result.putInt(DataKeys.ORGANIC_MATERIAL, organicMaterialInside)
|
||||
val fossilInv = ListTag()
|
||||
|
||||
fossilInventory.forEach { fossilInv.add(ItemStack.CODEC.encodeStart(NbtOps.INSTANCE, it).orThrow) }
|
||||
val ops = registryLookup.createSerializationContext(NbtOps.INSTANCE)
|
||||
fossilInventory.forEach { fossilInv.add(ItemStack.CODEC.encodeStart(ops, it).getOrThrow()) }
|
||||
result.put(DataKeys.FOSSIL_INVENTORY, fossilInv)
|
||||
result.putString(DataKeys.CONNECTOR_DIRECTION, tankConnectorDirection?.toString())
|
||||
|
||||
@@ -669,7 +670,10 @@ class FossilMultiblockStructure (
|
||||
|
||||
val fossilInv = if (nbt.contains(DataKeys.FOSSIL_INVENTORY)) { (nbt.get(DataKeys.FOSSIL_INVENTORY) as ListTag) } else ListTag()
|
||||
val actualFossilList = mutableListOf<ItemStack>()
|
||||
fossilInv.forEach { ItemStack.parse(registryLookup, it).ifPresent(actualFossilList::add) }
|
||||
|
||||
val ops = registryLookup.createSerializationContext(NbtOps.INSTANCE)
|
||||
fossilInv.forEach { ItemStack.CODEC.parse(ops, it).result().ifPresent(actualFossilList::add) }
|
||||
|
||||
result.fossilInventory = actualFossilList
|
||||
result.tankConnectorDirection = Direction.byName(nbt.getString(DataKeys.CONNECTOR_DIRECTION))
|
||||
|
||||
|
||||
@@ -179,6 +179,8 @@ object CobblemonClient {
|
||||
return@subscribe
|
||||
}
|
||||
|
||||
storage.party.forEach { it?.tickSkillCooldowns() }
|
||||
|
||||
val nearbyPokemon = player.level().getEntities(
|
||||
player,
|
||||
AABB.ofSize(player.position(), 16.0, 16.0, 16.0)
|
||||
|
||||
+6
-6
@@ -28,7 +28,7 @@ class InteractWheelButton(
|
||||
private val tooltipText: String?,
|
||||
x: Int,
|
||||
y: Int,
|
||||
private val isEnabled: Boolean,
|
||||
private val isEnabled: () -> Boolean,
|
||||
private val colour: () -> Vector3f?,
|
||||
onPress: OnPress,
|
||||
private val canHover: (Double, Double) -> Boolean
|
||||
@@ -74,12 +74,12 @@ class InteractWheelButton(
|
||||
y = y,
|
||||
width = width,
|
||||
height = height,
|
||||
vOffset = if (isHovered(mouseX.toFloat(), mouseY.toFloat()) && isEnabled) height else 0,
|
||||
vOffset = if (isHovered(mouseX.toFloat(), mouseY.toFloat()) && isEnabled()) height else 0,
|
||||
textureHeight = height * 2,
|
||||
alpha = if (isEnabled) 1f else 0.4F
|
||||
alpha = if (isEnabled()) 1f else 0.4F
|
||||
)
|
||||
|
||||
if(isEnabled && isHovered(mouseX.toFloat(), mouseY.toFloat())){
|
||||
if (isEnabled() && isHovered(mouseX.toFloat(), mouseY.toFloat())){
|
||||
tooltipText?.let {
|
||||
context.renderTooltip(Minecraft.getInstance().font, Component.translatable(it), mouseX, mouseY)
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class InteractWheelButton(
|
||||
y = iconY,
|
||||
width = ICON_SIZE,
|
||||
height = ICON_SIZE,
|
||||
alpha = if (isEnabled) 1F else 0.2F,
|
||||
alpha = if (isEnabled()) 1F else 0.2F,
|
||||
red = colour.x,
|
||||
green = colour.y,
|
||||
blue = colour.z,
|
||||
@@ -114,7 +114,7 @@ class InteractWheelButton(
|
||||
y = iconY - ICON_SIZE,
|
||||
width = ICON_SIZE,
|
||||
height = ICON_SIZE,
|
||||
alpha = if (isEnabled) 1F else 0.4F,
|
||||
alpha = if (isEnabled()) 1F else 0.4F,
|
||||
red = colour.x,
|
||||
green = colour.y,
|
||||
blue = colour.z,
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.network.chat.Component
|
||||
import kotlin.math.max
|
||||
|
||||
class InteractWheelGUI(private val options: Multimap<Orientation, InteractWheelOption>, title: Component) : Screen(title), CobblemonRenderable {
|
||||
open class InteractWheelGUI(private val options: Multimap<Orientation, InteractWheelOption>, title: Component) : Screen(title), CobblemonRenderable {
|
||||
companion object {
|
||||
const val SIZE = 170
|
||||
private val backgroundResource = cobblemonResource("textures/gui/interact/interact_wheel_base.png")
|
||||
@@ -32,7 +32,7 @@ class InteractWheelGUI(private val options: Multimap<Orientation, InteractWheelO
|
||||
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||
}
|
||||
|
||||
private val buttons = mutableListOf<InteractWheelButton>()
|
||||
protected val buttons = mutableListOf<InteractWheelButton>()
|
||||
private var maxPage = 1
|
||||
private var currentPage = 0
|
||||
override fun renderBlurredBackground(delta: Float) { }
|
||||
@@ -104,7 +104,7 @@ class InteractWheelGUI(private val options: Multimap<Orientation, InteractWheelO
|
||||
tooltipText = option?.tooltipText,
|
||||
x = x,
|
||||
y = y,
|
||||
isEnabled = option != null && option.enabled,
|
||||
isEnabled = { option != null && option.enabled() },
|
||||
colour = option?.colour ?: { null },
|
||||
onPress = { option?.onPress?.invoke() },
|
||||
canHover = { a: Double, b: Double -> !isMouseInCenter(a, b)}
|
||||
|
||||
+37
-4
@@ -9,20 +9,24 @@
|
||||
package com.cobblemon.mod.common.client.gui.interact.wheel
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork
|
||||
import com.cobblemon.mod.common.CobblemonPokeSkills
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.gui.interact.battleRequest.BattleConfigureGUI
|
||||
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.UsePokeSkillPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.common.collect.ArrayListMultimap
|
||||
import com.google.common.collect.Multimap
|
||||
import java.util.UUID
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.player.AbstractClientPlayer
|
||||
import net.minecraft.network.chat.Component
|
||||
import org.joml.Vector3f
|
||||
|
||||
@@ -30,7 +34,7 @@ fun createPokemonInteractGui(pokemonID: UUID, canMountShoulder: Boolean, canGive
|
||||
val mountShoulder = InteractWheelOption(
|
||||
iconResource = cobblemonResource("textures/gui/interact/interact_wheel_icon_shoulder.png"),
|
||||
tooltipText = "cobblemon.ui.interact.mount.shoulder",
|
||||
enabled = canMountShoulder,
|
||||
enabled = { canMountShoulder },
|
||||
onPress = {
|
||||
if (canMountShoulder) {
|
||||
InteractPokemonPacket(pokemonID, InteractTypePokemon.SHOULDER).sendToServer()
|
||||
@@ -41,7 +45,7 @@ fun createPokemonInteractGui(pokemonID: UUID, canMountShoulder: Boolean, canGive
|
||||
val giveHeldItem = InteractWheelOption(
|
||||
iconResource = cobblemonResource("textures/gui/interact/interact_wheel_icon_held_item.png"),
|
||||
tooltipText = "cobblemon.ui.interact.give.item",
|
||||
enabled = canGiveHeld,
|
||||
enabled = { canGiveHeld },
|
||||
onPress = {
|
||||
if (canGiveHeld) {
|
||||
InteractPokemonPacket(pokemonID, InteractTypePokemon.HELD_ITEM).sendToServer()
|
||||
@@ -52,7 +56,7 @@ fun createPokemonInteractGui(pokemonID: UUID, canMountShoulder: Boolean, canGive
|
||||
val giveCosmeticItem = InteractWheelOption(
|
||||
iconResource = cobblemonResource("textures/gui/interact/interact_wheel_icon_cosmetic_item.png"),
|
||||
tooltipText = "cobblemon.ui.interact.give.cosmetic_item",
|
||||
enabled = canGiveCosmetic,
|
||||
enabled = { canGiveCosmetic },
|
||||
onPress = {
|
||||
if (canGiveCosmetic) {
|
||||
InteractPokemonPacket(pokemonID, InteractTypePokemon.COSMETIC_ITEM).sendToServer()
|
||||
@@ -64,7 +68,7 @@ fun createPokemonInteractGui(pokemonID: UUID, canMountShoulder: Boolean, canGive
|
||||
val ride = InteractWheelOption(
|
||||
iconResource = cobblemonResource("textures/gui/interact/interact_wheel_icon_ride.png"),
|
||||
tooltipText = "cobblemon.ui.interact.ride",
|
||||
enabled = canRide,
|
||||
enabled = { canRide },
|
||||
onPress = {
|
||||
if (canRide) {
|
||||
InteractPokemonPacket(pokemonID, InteractTypePokemon.RIDE).sendToServer()
|
||||
@@ -177,6 +181,35 @@ fun createPlayerInteractGui(optionsPacket: PlayerInteractOptionsPacket): Interac
|
||||
return InteractWheelGUI(options, Component.translatable("cobblemon.ui.interact.player"))
|
||||
}
|
||||
|
||||
fun createPokeSkillGui(player: AbstractClientPlayer, pokemon: Pokemon): InteractWheelGUI {
|
||||
val accessibleSkills = CobblemonPokeSkills.getAccessibleSkills(player, pokemon)
|
||||
val options: Multimap<Orientation, InteractWheelOption> = ArrayListMultimap.create()
|
||||
for (skill in accessibleSkills) {
|
||||
val skillOption = InteractWheelOption(
|
||||
iconResource = skill.icon,
|
||||
enabled = { skill.id !in pokemon.skillCooldownsTicks },
|
||||
tooltipText = skill.name,
|
||||
onPress = {
|
||||
CobblemonNetwork.sendToServer(UsePokeSkillPacket(skillId = skill.id, pokemonId = pokemon.uuid))
|
||||
closeGUI()
|
||||
}
|
||||
)
|
||||
when (options.size()) {
|
||||
0 -> options.put(Orientation.NORTH, skillOption)
|
||||
1 -> options.put(Orientation.NORTHEAST, skillOption)
|
||||
2 -> options.put(Orientation.SOUTHEAST, skillOption)
|
||||
3 -> options.put(Orientation.SOUTH, skillOption)
|
||||
4 -> options.put(Orientation.SOUTHWEST, skillOption)
|
||||
5 -> options.put(Orientation.NORTHWEST, skillOption)
|
||||
6 -> options.put(Orientation.WEST, skillOption)
|
||||
7 -> options.put(Orientation.EAST, skillOption)
|
||||
else -> break // We only have 8 slots
|
||||
}
|
||||
}
|
||||
|
||||
return PokeSkillWheelGUI(options, Component.translatable("cobblemon.ui.interact.poke_skill"))
|
||||
}
|
||||
|
||||
private fun getLangKey(status: PlayerInteractOptionsPacket.OptionStatus) : String {
|
||||
return when (status) {
|
||||
PlayerInteractOptionsPacket.OptionStatus.TOO_FAR -> "cobblemon.ui.interact.too_far"
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.joml.Vector3f
|
||||
data class InteractWheelOption(
|
||||
val iconResource: ResourceLocation,
|
||||
val secondaryIconResource: ResourceLocation? = null,
|
||||
val enabled: Boolean = true,
|
||||
val enabled: () -> Boolean = { true },
|
||||
val tooltipText: String?,
|
||||
val colour: () -> Vector3f? = { null },
|
||||
val onPress: () -> Unit
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.interact.wheel
|
||||
|
||||
import com.google.common.collect.Multimap
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
class PokeSkillWheelGUI(
|
||||
private val options: Multimap<Orientation, InteractWheelOption>,
|
||||
title: Component
|
||||
) : InteractWheelGUI(options, title) {
|
||||
|
||||
/**
|
||||
* Due to the button being held swallow the event
|
||||
*/
|
||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
if (button == 0) return false
|
||||
return super.mouseClicked(mouseX, mouseY, button)
|
||||
}
|
||||
|
||||
/**
|
||||
* On release will close the wheel and trigger the button press of the hovered button
|
||||
* TODO: make this wheel choose more like pizza slices.
|
||||
*/
|
||||
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
if (button == 0) {
|
||||
// Manually trigger the hovered button's press
|
||||
buttons.forEach { btn ->
|
||||
if (btn.isMouseOver(mouseX, mouseY)) {
|
||||
btn.onClick(mouseX, mouseY)
|
||||
return true
|
||||
}
|
||||
}
|
||||
Minecraft.getInstance().setScreen(null)
|
||||
return true
|
||||
}
|
||||
return super.mouseReleased(mouseX, mouseY, button)
|
||||
}
|
||||
|
||||
}
|
||||
+11
-21
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.battles.BattleFormat
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.battle.ClientBattle
|
||||
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
|
||||
import com.cobblemon.mod.common.client.gui.interact.wheel.createPokeSkillGui
|
||||
import com.cobblemon.mod.common.client.keybind.CobblemonBlockingKeyBinding
|
||||
import com.cobblemon.mod.common.client.keybind.KeybindCategories
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
@@ -26,12 +27,12 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.isUsingPokedex
|
||||
import com.cobblemon.mod.common.util.traceFirstEntityCollision
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import kotlin.math.pow
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.player.LocalPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.level.ClipContext
|
||||
import kotlin.math.pow
|
||||
|
||||
object PartySendBinding : CobblemonBlockingKeyBinding(
|
||||
"key.cobblemon.throwpartypokemon",
|
||||
@@ -39,32 +40,17 @@ object PartySendBinding : CobblemonBlockingKeyBinding(
|
||||
InputConstants.KEY_R,
|
||||
KeybindCategories.COBBLEMON_CATEGORY
|
||||
) {
|
||||
const val POKE_SKILL_TIME = 0.7F
|
||||
var canApplyChange = true
|
||||
var heldDownSeconds = 0F
|
||||
|
||||
fun actioned() {
|
||||
canApplyChange = false
|
||||
wasDown = true
|
||||
heldDownSeconds = 0F
|
||||
}
|
||||
|
||||
fun canAction() = canApplyChange && Minecraft.getInstance().player?.isUsingPokedex() == false
|
||||
|
||||
override fun onTick() {
|
||||
if (wasDown) {
|
||||
if (heldDownSeconds < 100) {
|
||||
heldDownSeconds += Minecraft.getInstance().timer.getGameTimeDeltaPartialTick(false)
|
||||
}
|
||||
} else {
|
||||
heldDownSeconds = 0F
|
||||
}
|
||||
|
||||
super.onTick()
|
||||
}
|
||||
|
||||
override fun onRelease() {
|
||||
val canAction = canAction()
|
||||
wasDown = false
|
||||
canApplyChange = true
|
||||
if (!canAction) {
|
||||
return
|
||||
@@ -105,7 +91,8 @@ object PartySendBinding : CobblemonBlockingKeyBinding(
|
||||
entityClass = LivingEntity::class.java,
|
||||
ignoreEntity = player,
|
||||
maxDistance = Cobblemon.config.battleSpectateMaxDistance,
|
||||
collideBlock = ClipContext.Fluid.NONE)
|
||||
collideBlock = ClipContext.Fluid.NONE
|
||||
)
|
||||
if (canSendOutPokemon(player, targetEntity)) {
|
||||
sendToServer(SendOutPokemonPacket(CobblemonClient.storage.selectedSlot))
|
||||
} else {
|
||||
@@ -127,10 +114,13 @@ object PartySendBinding : CobblemonBlockingKeyBinding(
|
||||
//The server sends a packet back that opens the player interaction menu with the proper options
|
||||
sendToServer(RequestPlayerInteractionsPacket(entity.uuid, entity.id, pokemon.uuid))
|
||||
}
|
||||
|
||||
is PokemonEntity -> {
|
||||
if (!entity.canBattle(player) || entity.position().distanceToSqr(player.position()) > Cobblemon.config.battleWildMaxDistance.pow(2)) return
|
||||
sendToServer(BattleChallengePacket(entity.id, pokemon.uuid, BattleFormat.GEN_9_SINGLES))
|
||||
}
|
||||
if (!entity.canBattle(player) || entity.position()
|
||||
.distanceToSqr(player.position()) > Cobblemon.config.battleWildMaxDistance.pow(2)
|
||||
) return
|
||||
sendToServer(BattleChallengePacket(entity.id, pokemon.uuid, BattleFormat.GEN_9_SINGLES))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -19,6 +19,7 @@ import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object SpawnSnowstormEntityParticleHandler : ClientNetworkPacketHandler<SpawnSnowstormEntityParticlePacket> {
|
||||
override fun handle(packet: SpawnSnowstormEntityParticlePacket, client: Minecraft) {
|
||||
@@ -31,6 +32,7 @@ object SpawnSnowstormEntityParticleHandler : ClientNetworkPacketHandler<SpawnSno
|
||||
val targetState = (targetedEntity as? PosableEntity)?.delegate as? PosableState
|
||||
val sourceLocators = packet.sourceLocators.firstNotNullOfOrNull { sourceState.getMatchingLocators(it).takeIf { it.isNotEmpty() } } ?: return
|
||||
val targetedLocator = packet.targetLocators?.firstOrNull { targetState?.getMatchingLocators(it)?.isNotEmpty() == true }
|
||||
val targetPosition = packet.targetPosition
|
||||
val rootMatrix = sourceState.locatorStates["root"]!!
|
||||
|
||||
sourceLocators.forEach { locator ->
|
||||
@@ -40,6 +42,16 @@ object SpawnSnowstormEntityParticleHandler : ClientNetworkPacketHandler<SpawnSno
|
||||
val particleRuntime = MoLangRuntime().setup().setupClient()
|
||||
particleRuntime.environment.query.addFunction("entity") { sourceState.runtime.environment.query }
|
||||
|
||||
// Target resolution priority: entity+locator > world position > none
|
||||
val targetPos: (() -> Vec3)? = if (targetedEntity != null) {
|
||||
{ targetedLocator?.let { targetState?.locatorStates?.get(it) }?.getOrigin() ?: targetedEntity.position() }
|
||||
} else if (targetPosition != null) {
|
||||
val pos = packet.targetPosition
|
||||
{ pos }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val storm = ParticleStorm(
|
||||
effect = effect,
|
||||
emitterSpaceMatrix = particleMatrix,
|
||||
@@ -49,7 +61,7 @@ object SpawnSnowstormEntityParticleHandler : ClientNetworkPacketHandler<SpawnSno
|
||||
sourceVelocity = { sourceEntity.deltaMovement },
|
||||
sourceAlive = { !sourceEntity.isRemoved },
|
||||
sourceVisible = { !sourceEntity.isInvisible },
|
||||
targetPos = if (targetedEntity != null) { { targetedLocator?.let { targetState?.locatorStates?.get(it) }?.getOrigin() ?: targetedEntity.position() } } else null,
|
||||
targetPos = targetPos,
|
||||
entity = sourceEntity
|
||||
)
|
||||
|
||||
|
||||
+2
@@ -22,6 +22,8 @@ object ServerSettingsPacketHandler : ClientNetworkPacketHandler<ServerSettingsPa
|
||||
ServerSettings.maxPokemonFriendship = packet.maxPokemonFriendship
|
||||
ServerSettings.maxDynamaxLevel = packet.maxDynamaxLevel
|
||||
ServerSettings.unlockAllMoveDexMovesByDefault = packet.unlockAllMoveDexMovesByDefault
|
||||
ServerSettings.pokemonIntrinsicSizeMin = packet.pokemonIntrinsicSizeMin
|
||||
ServerSettings.pokemonIntrinsicSizeMax = packet.pokemonIntrinsicSizeMax
|
||||
}
|
||||
|
||||
}
|
||||
+10
-3
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.LevelRenderer
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
@@ -39,13 +40,13 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
|
||||
private val leftMargin = 1f
|
||||
private val rightMargin = 1f
|
||||
private val topMargin = 1f
|
||||
private val bottomMargin = 1f
|
||||
private val interRowSpacing = 0f
|
||||
private val tmOverlayDepthOffset = -0.0002f
|
||||
private val slotBrightnessMultiplier = 0.65f
|
||||
|
||||
private val tmBaseTexture = cobblemonResource("textures/block/disc_shelf/technical_machine_base.png")
|
||||
private val tmOverlayTexture = cobblemonResource("textures/block/disc_shelf/technical_machine_overlay.png")
|
||||
private val musicDiscUnknownTexture = cobblemonResource("textures/block/disc_shelf/music_disc_unknown.png")
|
||||
|
||||
override fun render(
|
||||
entity: DiscShelfBlockEntity,
|
||||
@@ -77,7 +78,6 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
|
||||
val slotWidth = slotWidthPixels / textureSize
|
||||
val slotHeight = slotHeightPixels / textureSize
|
||||
val verticalSpacing = (slotHeightPixels + interRowSpacing) / textureSize
|
||||
val totalHeight = slotHeight * 7 + interRowSpacing * 6 / textureSize
|
||||
val startY = topMargin / textureSize
|
||||
|
||||
for ((index, item) in entity.items.withIndex()) {
|
||||
@@ -188,6 +188,13 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
|
||||
|
||||
private fun getItemTexture(itemStack: ItemStack): ResourceLocation {
|
||||
val id = BuiltInRegistries.ITEM.getKey(itemStack.item)
|
||||
return cobblemonResource("textures/block/disc_shelf/${id.path}.png")
|
||||
val resource = cobblemonResource("textures/block/disc_shelf/${id.path}.png")
|
||||
|
||||
val resourceManager = Minecraft.getInstance().resourceManager
|
||||
if (resourceManager.getResource(resource).isEmpty) {
|
||||
return musicDiscUnknownTexture
|
||||
}
|
||||
|
||||
return resource
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isInWater
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class TentacoolModel(root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("tentacool")
|
||||
|
||||
override var portraitScale = 1.2F
|
||||
override var portraitTranslation = Vec3(0.1, 1.1, 0.0)
|
||||
|
||||
override var profileScale = 0.6F
|
||||
override var profileTranslation = Vec3(0.0, 0.8, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var swim: CobblemonPose
|
||||
lateinit var float: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var watersleep: CobblemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("tentacool", "blink")}
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseType = PoseType.STAND,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseType = PoseType.WALK,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "ground_idle")
|
||||
//bedrock("tentacool", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
float = registerPose(
|
||||
poseName = "float",
|
||||
poseTypes = UI_POSES + PoseType.FLOAT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swim = registerPose(
|
||||
poseName = "swim",
|
||||
poseType = PoseType.SWIM,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "water_swim")
|
||||
)
|
||||
)
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { !it.isInWater },
|
||||
animations = arrayOf(bedrock("tentacool", "sleep"))
|
||||
)
|
||||
|
||||
watersleep = registerPose(
|
||||
poseName = "watersleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { it.isInWater },
|
||||
animations = arrayOf(bedrock("tentacool", "water_sleep"))
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("tentacool", "faint") else null
|
||||
}
|
||||
+1
@@ -285,6 +285,7 @@ object VaryingModelRepository {
|
||||
inbuilt("rapidash", ::RapidashModel)
|
||||
inbuilt("sandslash", ::SandslashModel)
|
||||
inbuilt("tangela", ::TangelaModel)
|
||||
inbuilt("tentacool", ::TentacoolModel)
|
||||
inbuilt("venomoth", ::VenomothModel)
|
||||
inbuilt("venonat", ::VenonatModel)
|
||||
inbuilt("elekid", ::ElekidModel)
|
||||
|
||||
@@ -28,5 +28,7 @@ object ServerSettings {
|
||||
var maxPokemonFriendship = Cobblemon.config.maxPokemonFriendship
|
||||
var maxDynamaxLevel = Cobblemon.config.maxDynamaxLevel
|
||||
var unlockAllMoveDexMovesByDefault = Cobblemon.config.unlockAllMoveDexMovesByDefault
|
||||
var pokemonIntrinsicSizeMin = Cobblemon.config.pokemonIntrinsicSizeMin
|
||||
var pokemonIntrinsicSizeMax = Cobblemon.config.pokemonIntrinsicSizeMax
|
||||
|
||||
}
|
||||
@@ -243,18 +243,6 @@ class CobblemonConfig {
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "pokemon_intrinsic_size_max", SERVER)
|
||||
var pokemonIntrinsicSizeMax = 1.05F
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_small_multiplier", SERVER)
|
||||
var alphaPokemonSizeSmallMultiplier = 1.70F
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_medium_multiplier", SERVER)
|
||||
var alphaPokemonSizeMediumMultiplier = 1.55F
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_large_multiplier", SERVER)
|
||||
var alphaPokemonSizeLargeMultiplier = 1.40F
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_extra_large_multiplier", SERVER)
|
||||
var alphaPokemonSizeExtraLargeMultiplier = 1.25F
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "baby_pokemon_level_duration", SERVER)
|
||||
var babyPokemonLevelDuration = 9
|
||||
|
||||
@@ -347,9 +335,6 @@ class CobblemonConfig {
|
||||
// @CobblemonConfigField(Category.Riding, lang = "third_person_view_bobbing", CLIENT)
|
||||
var thirdPersonViewBobbing = true
|
||||
|
||||
@CobblemonConfigField(Category.Riding, lang = "invert_roll", CLIENT)
|
||||
var invertRoll = false
|
||||
|
||||
@CobblemonConfigField(Category.Riding, lang = "invert_pitch", CLIENT)
|
||||
var invertPitch = false
|
||||
|
||||
@@ -365,9 +350,6 @@ class CobblemonConfig {
|
||||
@CobblemonConfigField(Category.Riding, lang = "swap_x_and_y_axes", CLIENT)
|
||||
var swapXAndYAxes = false
|
||||
|
||||
@CobblemonConfigField(Category.Riding, lang = "automatic_righting_delay", CLIENT)
|
||||
var rightingDelay = -1.0
|
||||
|
||||
@CobblemonConfigField(Category.Riding, lang = "disable_roll", CLIENT)
|
||||
var disableRoll = false
|
||||
|
||||
|
||||
@@ -10,6 +10,13 @@ package com.cobblemon.mod.common.data
|
||||
|
||||
import com.cobblemon.mod.common.*
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.CobblemonBehaviours
|
||||
import com.cobblemon.mod.common.CobblemonCallbacks
|
||||
import com.cobblemon.mod.common.CobblemonCosmeticItems
|
||||
import com.cobblemon.mod.common.CobblemonMechanics
|
||||
import com.cobblemon.mod.common.CobblemonPokeSkills
|
||||
import com.cobblemon.mod.common.CobblemonRideSettings
|
||||
import com.cobblemon.mod.common.CobblemonUnlockableWallpapers
|
||||
import com.cobblemon.mod.common.api.abilities.Abilities
|
||||
import com.cobblemon.mod.common.api.berry.Berries
|
||||
import com.cobblemon.mod.common.api.cooking.Seasonings
|
||||
@@ -73,6 +80,7 @@ object CobblemonDataProvider : DataProvider {
|
||||
this.register(GlobalSpeciesFeatures, reloadable = false)
|
||||
this.register(SpeciesFeatureAssignments, reloadable = false)
|
||||
this.register(ActionEffects, reloadable = true)
|
||||
this.register(CobblemonPokeSkills, reloadable = true)
|
||||
this.register(Moves, reloadable = false)
|
||||
this.register(CobblemonMovesetBuilders, reloadable = false)
|
||||
this.register(Abilities, reloadable = false)
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.entity.pokemon
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
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.setup
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
|
||||
import com.cobblemon.mod.common.api.moves.animations.TargetsProvider
|
||||
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.blockRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.codec.EXPRESSION_LIKE_CODEC
|
||||
import com.cobblemon.mod.common.util.isInBattle
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.phys.HitResult
|
||||
|
||||
/**
|
||||
* The reference object for a skill that a Pokémon can use in the overworld.
|
||||
*
|
||||
* Most skills are "wrapper" skills that play a move's action effect at a target and run
|
||||
* some MoLang on impact. Custom skills can define a full action effect timeline.
|
||||
*
|
||||
* Access is auto-derived from grantingMoves/Abilities/Types/Species lists. If none are
|
||||
* populated, accessCondition is used as a fallback.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since August 31st, 2025
|
||||
*/
|
||||
class PokeSkill(
|
||||
val name: String,
|
||||
val enabled: Boolean = true,
|
||||
val actionEffect: ActionEffectTimeline,
|
||||
val icon: ResourceLocation,
|
||||
val cooldownTicks: Int,
|
||||
val accessCondition: ExpressionLike = "true".asExpressionLike(),
|
||||
val useCondition: ExpressionLike = "true".asExpressionLike(),
|
||||
// Targeting
|
||||
val targetType: TargetType? = null,
|
||||
val range: Double? = null,
|
||||
val targetCondition: ExpressionLike? = null,
|
||||
// Granting
|
||||
val grantingMoves: List<String>? = null,
|
||||
val grantingAbilities: List<String>? = null,
|
||||
val grantingTypes: List<String>? = null,
|
||||
val grantingSpecies: List<String>? = null,
|
||||
// Wrapper skill fields
|
||||
val hitDelay: ExpressionLike? = null,
|
||||
val hitEffect: ResourceLocation? = null,
|
||||
val fallbackActionEffect: ResourceLocation? = null
|
||||
) {
|
||||
// Enum to determine what this skill will target.
|
||||
enum class TargetType {
|
||||
NONE, SELF, BLOCK, ENTITY, BOTH
|
||||
}
|
||||
|
||||
companion object {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
val CODEC = RecordCodecBuilder.create<PokeSkill> { instance ->
|
||||
instance.group(
|
||||
Codec.STRING.fieldOf("name").forGetter { it.name },
|
||||
Codec.BOOL.fieldOf("enabled").forGetter { it.enabled },
|
||||
Codec.unit<ActionEffectTimeline> { ActionEffectTimeline.NONE }.fieldOf("actionEffect").forGetter { it.actionEffect },
|
||||
ResourceLocation.CODEC.fieldOf("icon").forGetter { it.icon },
|
||||
Codec.INT.fieldOf("cooldownTicks").forGetter { it.cooldownTicks },
|
||||
EXPRESSION_LIKE_CODEC.fieldOf("accessCondition").forGetter { it.accessCondition },
|
||||
EXPRESSION_LIKE_CODEC.fieldOf("useCondition").forGetter { it.useCondition }
|
||||
).apply(instance, ::PokeSkill)
|
||||
}
|
||||
val PACKET_CODEC = ByteBufCodecs.fromCodecWithRegistries(CODEC)
|
||||
private val DEFAULT_ACTION_EFFECT = cobblemonResource("default_poke_skill")
|
||||
}
|
||||
|
||||
@Transient
|
||||
lateinit var id: ResourceLocation
|
||||
|
||||
|
||||
// fun canAccess(player: Player, pokemon: Pokemon): Boolean {
|
||||
// if (!enabled) {
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// runtime.withQueryValue("player", player.asMostSpecificMoLangValue())
|
||||
// runtime.withQueryValue("pokemon", pokemon.struct)
|
||||
// pokemon.entity?.let { runtime.withQueryValue("entity", it.asMostSpecificMoLangValue()) }
|
||||
// val hasAccess = runtime.resolveBoolean(accessCondition)
|
||||
// return hasAccess
|
||||
// }
|
||||
|
||||
/**
|
||||
* Determines access by checking the pokemons data against the granting lists.
|
||||
* If no granting lists are populated, accessCondition is used as a fallback.
|
||||
*/
|
||||
fun canAccess(player: Player, pokemon: Pokemon): Boolean {
|
||||
if (!enabled) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check granting lists — if any are populated, check if the player has any of the listed moves/abilities/types/species
|
||||
val hasGrantingLists = !grantingMoves.isNullOrEmpty() || !grantingAbilities.isNullOrEmpty() ||
|
||||
!grantingTypes.isNullOrEmpty() || !grantingSpecies.isNullOrEmpty()
|
||||
|
||||
if (hasGrantingLists) {
|
||||
val moveMatch = !grantingMoves.isNullOrEmpty() && grantingMoves.any { moveName ->
|
||||
pokemon.moveSet.any { it.template.name == moveName }
|
||||
}
|
||||
val abilityMatch = !grantingAbilities.isNullOrEmpty() && grantingAbilities.any { abilityName ->
|
||||
pokemon.ability.name == abilityName
|
||||
}
|
||||
val typeMatch = !grantingTypes.isNullOrEmpty() && grantingTypes.any { typeName ->
|
||||
pokemon.types.any { it.name.equals(typeName, ignoreCase = true) }
|
||||
}
|
||||
val speciesMatch = !grantingSpecies.isNullOrEmpty() && grantingSpecies.any { speciesName ->
|
||||
pokemon.species.name.equals(speciesName, ignoreCase = true)
|
||||
}
|
||||
|
||||
if (!(moveMatch || abilityMatch || typeMatch || speciesMatch)) return false
|
||||
}
|
||||
|
||||
// Always evaluate accessCondition — acts as additional gate when granting lists are present,
|
||||
// or as the sole gate when no granting lists are populated
|
||||
runtime.withQueryValue("player", player.asMostSpecificMoLangValue())
|
||||
runtime.withQueryValue("pokemon", pokemon.struct)
|
||||
pokemon.entity?.let { runtime.withQueryValue("entity", it.asMostSpecificMoLangValue()) }
|
||||
return runtime.resolveBoolean(accessCondition ?: "true".asExpressionLike())
|
||||
}
|
||||
|
||||
fun canUse(player: Player, pokemon: Pokemon): Boolean {
|
||||
val status = pokemon.status?.status
|
||||
if (id in pokemon.skillCooldownsTicks || player.isInBattle() || status == Statuses.SLEEP || status == Statuses.FROZEN) {
|
||||
return false
|
||||
}
|
||||
runtime.withQueryValue("player", player.asMostSpecificMoLangValue())
|
||||
runtime.withQueryValue("pokemon", pokemon.struct)
|
||||
val canUse = runtime.resolveBoolean(useCondition)
|
||||
return canUse
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves which move from the pokemon's moveset grants this skill.
|
||||
* Returns the first matching move name from grantingMoves, or null if none match.
|
||||
*/
|
||||
fun resolveGrantingMove(pokemon: Pokemon): String? {
|
||||
if (grantingMoves.isNullOrEmpty()) return null // need this guard
|
||||
return grantingMoves.firstOrNull { moveName ->
|
||||
pokemon.moveSet.any { it.template.name == moveName }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the action effect to use for the move visual.
|
||||
* Priority: granting move's action effect > fallbackActionEffect > null
|
||||
*/
|
||||
fun resolveVisualEffect(pokemon: Pokemon): ResourceLocation? {
|
||||
val grantingMove = resolveGrantingMove(pokemon)
|
||||
if (grantingMove != null) {
|
||||
val effectId = cobblemonResource(grantingMove)
|
||||
if (ActionEffects.actionEffects.containsKey(effectId)) return effectId
|
||||
Cobblemon.LOGGER.warn("PokeSkill '$id': granting move '$grantingMove' has no action effect at '$effectId'")
|
||||
}
|
||||
return fallbackActionEffect
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the skill on the given pokemon.
|
||||
* Populates context and runs targeting logic.
|
||||
*/
|
||||
fun use(
|
||||
player: ServerPlayer,
|
||||
pokemon: Pokemon,
|
||||
// context information!!!
|
||||
): Boolean {
|
||||
if (!canUse(player, pokemon)) return false
|
||||
val entity = pokemon.entity ?: return false
|
||||
val level = player.level() as? ServerLevel ?: return false
|
||||
// I think these should be defaulted but making them nullable means I don't have to adjust the
|
||||
// other jsons that don't populate them yet...
|
||||
val effectiveTargetType = targetType ?: TargetType.NONE
|
||||
val effectiveRange = range ?: 8.0
|
||||
|
||||
// Resolve the action effect to run
|
||||
val effectTimeline = if (actionEffect != null && actionEffect != ActionEffectTimeline.NONE) {
|
||||
actionEffect
|
||||
} else {
|
||||
ActionEffects.actionEffects[DEFAULT_ACTION_EFFECT] ?: run {
|
||||
Cobblemon.LOGGER.warn("PokeSkill '$id': default_poke_skill action effect not found")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Set up runtime
|
||||
val skillRuntime = MoLangRuntime().setup()
|
||||
skillRuntime.withQueryValue("player", player.asMostSpecificMoLangValue())
|
||||
skillRuntime.withQueryValue("pokemon", pokemon.struct)
|
||||
skillRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
skillRuntime.environment.setSimpleVariable("skill_id", StringValue(id.toString()))
|
||||
skillRuntime.environment.setSimpleVariable("target_type", StringValue(effectiveTargetType.name.lowercase()))
|
||||
skillRuntime.environment.query.addFunction("missed") { DoubleValue(0.0) } // move action effects use this to determine if the target particles should play. We want them to always play for skills I believe
|
||||
|
||||
|
||||
// Targeting — raycast based on targetType
|
||||
when (effectiveTargetType) {
|
||||
TargetType.SELF -> {
|
||||
injectEntityTarget(skillRuntime, player)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(1.0))
|
||||
}
|
||||
TargetType.BLOCK -> {
|
||||
val blockHit = getPlayerLookedBlock(player, effectiveRange)
|
||||
if (blockHit == null) return false
|
||||
injectBlockTarget(skillRuntime, blockHit, level)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(0.0))
|
||||
}
|
||||
TargetType.ENTITY -> {
|
||||
val entityHit = getPlayerLookedEntity(player, effectiveRange)
|
||||
if (entityHit == null) return false
|
||||
injectEntityTarget(skillRuntime, entityHit)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(1.0))
|
||||
}
|
||||
TargetType.BOTH -> {
|
||||
val entityHit = getPlayerLookedEntity(player, effectiveRange)
|
||||
if (entityHit != null) {
|
||||
injectEntityTarget(skillRuntime, entityHit)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(1.0))
|
||||
} else {
|
||||
val blockHit = getPlayerLookedBlock(player, effectiveRange)
|
||||
if (blockHit == null) return false
|
||||
injectBlockTarget(skillRuntime, blockHit, level)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(0.0))
|
||||
}
|
||||
}
|
||||
TargetType.NONE -> {}
|
||||
}
|
||||
|
||||
// Evaluate target condition
|
||||
if (targetCondition != null && !skillRuntime.resolveBoolean(targetCondition)) return false
|
||||
|
||||
// Inject wrapper skill variables
|
||||
val visualEffect = resolveVisualEffect(pokemon)
|
||||
if (visualEffect != null) {
|
||||
skillRuntime.environment.setSimpleVariable("granting_move", StringValue(visualEffect.toString()))
|
||||
}
|
||||
if (hitEffect != null) {
|
||||
skillRuntime.environment.setSimpleVariable("hit_effect", StringValue(hitEffect.toString()))
|
||||
}
|
||||
if (hitDelay != null) {
|
||||
skillRuntime.environment.setSimpleVariable("hit_delay", hitDelay.resolve(skillRuntime))
|
||||
}
|
||||
|
||||
|
||||
// Build providers
|
||||
val providers = mutableListOf<Any>(
|
||||
UsersProvider(entity)
|
||||
)
|
||||
|
||||
// Build and run context
|
||||
val context = ActionEffectContext(
|
||||
actionEffect = effectTimeline,
|
||||
runtime = skillRuntime,
|
||||
providers = providers,
|
||||
level = level
|
||||
)
|
||||
|
||||
effectTimeline.run(context).thenRun {
|
||||
// Auto-apply cooldown after effect completes
|
||||
pokemon.skillCooldownsTicks[id] = cooldownTicks
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility functions for setting up the runtime for a skill.
|
||||
*/
|
||||
private fun injectBlockTarget(runtime: MoLangRuntime, blockHit: BlockHitResult, level: ServerLevel) {
|
||||
val pos = blockHit.blockPos
|
||||
runtime.environment.setSimpleVariable("target_x", DoubleValue(pos.x + 0.5))
|
||||
runtime.environment.setSimpleVariable("target_y", DoubleValue(pos.y + 0.5))
|
||||
runtime.environment.setSimpleVariable("target_z", DoubleValue(pos.z + 0.5))
|
||||
runtime.environment.setSimpleVariable("target_block_x", DoubleValue(pos.x.toDouble()))
|
||||
runtime.environment.setSimpleVariable("target_block_y", DoubleValue(pos.y.toDouble()))
|
||||
runtime.environment.setSimpleVariable("target_block_z", DoubleValue(pos.z.toDouble()))
|
||||
|
||||
val blockState = level.getBlockState(pos)
|
||||
val blockHolder = level.blockRegistry.wrapAsHolder(blockState.block)
|
||||
val blockValue = blockHolder.asMoLangValue(Registries.BLOCK)
|
||||
|
||||
blockValue.addFunction("x") { DoubleValue(pos.x.toDouble()) }
|
||||
blockValue.addFunction("y") { DoubleValue(pos.y.toDouble()) }
|
||||
blockValue.addFunction("z") { DoubleValue(pos.z.toDouble()) }
|
||||
|
||||
runtime.environment.setSimpleVariable("target_block", blockValue)
|
||||
}
|
||||
|
||||
private fun injectEntityTarget(runtime: MoLangRuntime, entityHit: Entity) {
|
||||
runtime.environment.setSimpleVariable("target_x", DoubleValue(entityHit.x))
|
||||
runtime.environment.setSimpleVariable("target_y", DoubleValue(entityHit.y + entityHit.bbHeight / 2.0))
|
||||
runtime.environment.setSimpleVariable("target_z", DoubleValue(entityHit.z))
|
||||
runtime.environment.setSimpleVariable("target_entity", entityHit.asMostSpecificMoLangValue())
|
||||
}
|
||||
|
||||
/**
|
||||
* simple raycast to get the block the player is looking at.
|
||||
*/
|
||||
private fun getPlayerLookedBlock(player: ServerPlayer, range: Double): BlockHitResult? {
|
||||
val hitResult = player.pick(range, 0f, true)
|
||||
return if (hitResult.type == HitResult.Type.BLOCK) hitResult as BlockHitResult else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Raycast to determine the entity the player is looking at
|
||||
*/
|
||||
private fun getPlayerLookedEntity(player: ServerPlayer, range: Double): Entity? {
|
||||
val eyePosition = player.getEyePosition(1.0f)
|
||||
val lookVector = player.getViewVector(1.0f)
|
||||
val reachVector = eyePosition.add(lookVector.x * range, lookVector.y * range, lookVector.z * range)
|
||||
|
||||
// Create an outer bounding box to find potential candidates
|
||||
val searchBox = player.boundingBox.expandTowards(lookVector.scale(range)).inflate(1.0, 1.0, 1.0)
|
||||
|
||||
// Filter entities within the search box
|
||||
val entityHitResult = net.minecraft.world.entity.projectile.ProjectileUtil.getEntityHitResult(
|
||||
player,
|
||||
eyePosition,
|
||||
reachVector,
|
||||
searchBox,
|
||||
{ entity -> !entity.isSpectator && entity.isPickable },
|
||||
range * range
|
||||
)
|
||||
|
||||
return entityHitResult?.entity
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,13 @@ object ServerTickHandler {
|
||||
|
||||
secondsTick++
|
||||
|
||||
if (secondsTick == 20) {
|
||||
secondsTick = 0
|
||||
|
||||
// Party tick
|
||||
for (player in server.playerList.players) {
|
||||
player.party().onSecondPassed(player)
|
||||
// Party tick
|
||||
for (player in server.playerList.players) {
|
||||
val party = player.party()
|
||||
party.forEach { it.tickSkillCooldowns() }
|
||||
if (secondsTick == 20) {
|
||||
secondsTick = 0
|
||||
party.onSecondPassed(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonPokeSkills
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokeSkill
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class PokeSkillsRegistrySyncPacket(
|
||||
pokeSkills: Collection<PokeSkill>
|
||||
) : DataRegistrySyncPacket<PokeSkill, PokeSkillsRegistrySyncPacket>(pokeSkills) {
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encodeEntry(buffer: RegistryFriendlyByteBuf, entry: PokeSkill) {
|
||||
PokeSkill.PACKET_CODEC.encode(buffer, entry)
|
||||
}
|
||||
|
||||
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): PokeSkill? {
|
||||
return PokeSkill.PACKET_CODEC.decode(buffer)
|
||||
}
|
||||
|
||||
override fun synchronizeDecoded(entries: Collection<PokeSkill>) {
|
||||
CobblemonPokeSkills.reload(entries.associateBy { it.id })
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("poke_skill_sync")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = PokeSkillsRegistrySyncPacket(emptyList()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
+14
-2
@@ -13,10 +13,15 @@ import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHa
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
/**
|
||||
* Packet that spawns a snowstorm particle effect on a specified entity and specified locator.
|
||||
* Can specify an optional target+locator to pass through to the spawned particle
|
||||
* Can alternatively specify a [targetPosition] for entity-to-world-position targeting
|
||||
* (e.g. a Pokémon firing particles at a block).
|
||||
*
|
||||
* Target resolution priority: targetedEntityId + targetLocators > targetPosition > no target
|
||||
*
|
||||
* Handled by [SpawnSnowstormEntityParticleHandler]
|
||||
*
|
||||
@@ -28,7 +33,8 @@ class SpawnSnowstormEntityParticlePacket(
|
||||
val sourceEntityId: Int,
|
||||
val sourceLocators: List<String> = listOf("root"),
|
||||
val targetedEntityId: Int? = null,
|
||||
val targetLocators: List<String>? = null
|
||||
val targetLocators: List<String>? = null,
|
||||
val targetPosition: Vec3? = null
|
||||
) : NetworkPacket<SpawnSnowstormEntityParticlePacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("spawn_snowstorm_entity_particle")
|
||||
@@ -39,7 +45,8 @@ class SpawnSnowstormEntityParticlePacket(
|
||||
val sourceLocators = buffer.readList { buffer.readString() }
|
||||
val targetedEntityId = buffer.readNullable { it.readInt() }
|
||||
val targetLocators = buffer.readNullable { buffer.readList { buffer.readString() }}
|
||||
return SpawnSnowstormEntityParticlePacket(effectId, sourceEntityId, sourceLocators, targetedEntityId, targetLocators)
|
||||
val targetPosition = buffer.readNullable { Vec3(it.readDouble(), it.readDouble(), it.readDouble()) }
|
||||
return SpawnSnowstormEntityParticlePacket(effectId, sourceEntityId, sourceLocators, targetedEntityId, targetLocators, targetPosition)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,5 +62,10 @@ class SpawnSnowstormEntityParticlePacket(
|
||||
buffer.writeString(locator)
|
||||
}
|
||||
}
|
||||
buffer.writeNullable(targetPosition) { _, value ->
|
||||
buffer.writeDouble(value.x)
|
||||
buffer.writeDouble(value.y)
|
||||
buffer.writeDouble(value.z)
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.client.pokemon.update
|
||||
|
||||
import com.cobblemon.mod.common.net.IntSize
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readSizedInt
|
||||
import com.cobblemon.mod.common.util.writeSizedInt
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Packet that adds a single skill cooldown to a Pokémon's skill cooldowns map.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since August 31st, 2025
|
||||
*/
|
||||
class SkillCooldownsUpdatePacket(
|
||||
pokemon: () -> Pokemon?,
|
||||
val skillId: ResourceLocation,
|
||||
val cooldownTicks: Int
|
||||
) : SingleUpdatePacket<Pair<ResourceLocation, Int>, SkillCooldownsUpdatePacket>(pokemon, skillId to cooldownTicks) {
|
||||
override val id: ResourceLocation = ID
|
||||
|
||||
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(skillId)
|
||||
buffer.writeSizedInt(IntSize.U_SHORT, cooldownTicks)
|
||||
}
|
||||
|
||||
override fun set(pokemon: Pokemon, value: Pair<ResourceLocation, Int>) {
|
||||
val (skillId, cooldownTicks) = value
|
||||
pokemon.skillCooldownsTicks[skillId] = cooldownTicks
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("skill_cooldowns_update")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): SkillCooldownsUpdatePacket {
|
||||
val pokemon = decodePokemon(buffer)
|
||||
val skillId = buffer.readResourceLocation()
|
||||
val cooldownTicks = buffer.readSizedInt(IntSize.U_SHORT)
|
||||
return SkillCooldownsUpdatePacket(pokemon, skillId, cooldownTicks)
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-2
@@ -26,7 +26,9 @@ class ServerSettingsPacket internal constructor(
|
||||
val maxPokemonLevel: Int,
|
||||
val maxPokemonFriendship: Int,
|
||||
val maxDynamaxLevel: Int,
|
||||
val unlockAllMoveDexMovesByDefault: Boolean
|
||||
val unlockAllMoveDexMovesByDefault: Boolean,
|
||||
val pokemonIntrinsicSizeMin: Float,
|
||||
val pokemonIntrinsicSizeMax: Float
|
||||
) : NetworkPacket<ServerSettingsPacket> {
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -37,9 +39,14 @@ class ServerSettingsPacket internal constructor(
|
||||
buffer.writeInt(Cobblemon.config.maxPokemonFriendship)
|
||||
buffer.writeInt(Cobblemon.config.maxDynamaxLevel)
|
||||
buffer.writeBoolean(Cobblemon.config.unlockAllMoveDexMovesByDefault)
|
||||
buffer.writeFloat(Cobblemon.config.pokemonIntrinsicSizeMin)
|
||||
buffer.writeFloat(Cobblemon.config.pokemonIntrinsicSizeMax)
|
||||
}
|
||||
companion object {
|
||||
val ID = cobblemonResource("server_settings")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = ServerSettingsPacket(buffer.readBoolean(), buffer.readBoolean(), buffer.readBoolean(), buffer.readInt(), buffer.readInt(), buffer.readInt(), buffer.readBoolean())
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = ServerSettingsPacket(buffer.readBoolean(),
|
||||
buffer.readBoolean(), buffer.readBoolean(),
|
||||
buffer.readInt(), buffer.readInt(), buffer.readInt(),
|
||||
buffer.readBoolean(), buffer.readFloat(), buffer.readFloat())
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.server
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import java.util.UUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Packet sent by the client to the server to indicate that it wants to use a Poké Skill.
|
||||
*
|
||||
* The server will validate if the skill can be used, and if so, will execute it.
|
||||
*
|
||||
* @param skillId The ID of the skill to use.
|
||||
* @param pokemonId The UUID of the Pokémon using the skill.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since August 31st, 2025
|
||||
*/
|
||||
class UsePokeSkillPacket(
|
||||
val skillId: ResourceLocation,
|
||||
val pokemonId: UUID,
|
||||
) : NetworkPacket<UsePokeSkillPacket> {
|
||||
override val id: ResourceLocation = ID
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(skillId)
|
||||
buffer.writeUUID(pokemonId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = ResourceLocation("cobblemon", "use_poke_skill")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): UsePokeSkillPacket {
|
||||
return UsePokeSkillPacket(
|
||||
buffer.readResourceLocation(),
|
||||
buffer.readUUID()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.serverhandling
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonPokeSkills
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.net.messages.server.UsePokeSkillPacket
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
object UsePokeSkillHandler : ServerNetworkPacketHandler<UsePokeSkillPacket> {
|
||||
override fun handle(packet: UsePokeSkillPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val party = player.party()
|
||||
val pokemon = party[packet.pokemonId] ?: return // Who?
|
||||
val skill = CobblemonPokeSkills.getAccessibleSkills(player, pokemon).firstOrNull { it.id == packet.skillId } ?: return // What skill?
|
||||
if (skill.canUse(player, pokemon)) {
|
||||
skill.use(player, pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -767,6 +767,8 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
val riding: RidingProperties
|
||||
get() = this.form.riding
|
||||
|
||||
var skillCooldownsTicks: MutableMap<ResourceLocation, Int> = mutableMapOf()
|
||||
|
||||
init {
|
||||
storeCoordinates.subscribe { if (it != null && it.store !is PCStore && this.tetheringId != null) afterOnServer(seconds = 0.05F) { this.tetheringId = null } }
|
||||
storeCoordinates.subscribe {
|
||||
@@ -1141,6 +1143,16 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
}
|
||||
}
|
||||
|
||||
fun tickSkillCooldowns() {
|
||||
this.skillCooldownsTicks.entries.forEach { (key, value) ->
|
||||
val newValue = value - 1
|
||||
if (newValue <= 0)
|
||||
this.skillCooldownsTicks -= key
|
||||
else
|
||||
this.skillCooldownsTicks[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
fun isOnInteractionCooldown(group: ResourceLocation): Boolean {
|
||||
return this.interactionCooldowns.getOrDefault(group, 0) > 0
|
||||
}
|
||||
@@ -2229,6 +2241,11 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
return true
|
||||
}
|
||||
|
||||
fun addSkillCooldown(skillId: ResourceLocation, cooldownTicks: Int) {
|
||||
skillCooldownsTicks[skillId] = cooldownTicks
|
||||
onChange(SkillCooldownsUpdatePacket({ this }, skillId, cooldownTicks))
|
||||
}
|
||||
|
||||
fun notify(packet: PokemonUpdatePacket<*>) {
|
||||
storeCoordinates.get()?.run { sendPacketToPlayers(store.getObservingPlayers(), packet) }
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.client.settings.ServerSettings
|
||||
|
||||
enum class PokemonSizeCategory {
|
||||
XS,
|
||||
@@ -21,7 +21,7 @@ enum class PokemonSizeCategory {
|
||||
// Find which size category corresponds to the given scale modifier.
|
||||
// The scale modifier should be between the intrinsic min and max size.
|
||||
fun fromScale(scaleModifier: Float): PokemonSizeCategory {
|
||||
val config = Cobblemon.config
|
||||
val config = ServerSettings //Don't use cobblemon config here as it will be used by server AND client
|
||||
val minScale = config.pokemonIntrinsicSizeMin
|
||||
val maxScale = config.pokemonIntrinsicSizeMax
|
||||
val range = (maxScale - minScale).coerceAtLeast(0.0001F)
|
||||
|
||||
@@ -318,7 +318,7 @@ class OmniPathNodeMaker : NodeEvaluator() {
|
||||
|
||||
// Hitbox thing looks confusing but if the hitbox volume is more than like, 5, it starts getting pretty
|
||||
// fucking slow to use the findAcceptedNodeWalk function
|
||||
val strictlyWalkPathing = !canFly() && !mob.isInWater && mob.boundingBox.size < MAX_HITBOX_SIZE_FOR_WALKING
|
||||
val strictlyWalkPathing = !canFly() && !mob.isInWater
|
||||
val doVerticalNeighbourChecks = (canFly() || mob.isInWater) && mob.boundingBox.size < MAX_HITBOX_FOR_VERTICAL_NEIGHBOURS
|
||||
|
||||
// Non-diagonal surroundings in 3d space
|
||||
@@ -623,9 +623,11 @@ class OmniPathNodeMaker : NodeEvaluator() {
|
||||
|
||||
override fun getPathTypeOfMob(pfContext: PathfindingContext, x: Int, y: Int, z: Int, mob: Mob): PathType {
|
||||
val set = EnumSet.noneOf(PathType::class.java)
|
||||
val sizeX = (mob.boundingBox.maxX - mob.boundingBox.minX).toInt() + 1
|
||||
val sizeY = (mob.boundingBox.maxY - mob.boundingBox.minY).toInt() + 1
|
||||
val sizeZ = (mob.boundingBox.maxZ - mob.boundingBox.minZ).toInt() + 1
|
||||
// Capping the observed size of hitboxes here to put an upper limit on the cost of larger hitbox mobs
|
||||
// Mobs larger than these caps will inevitably become stuck on obstacles as their pathing will be flawed
|
||||
val sizeX = ((mob.boundingBox.maxX - mob.boundingBox.minX).toInt() + 1).coerceAtMost(2)
|
||||
val sizeY = ((mob.boundingBox.maxY - mob.boundingBox.minY).toInt() + 1).coerceAtMost(3)
|
||||
val sizeZ = ((mob.boundingBox.maxZ - mob.boundingBox.minZ).toInt() + 1).coerceAtMost(2)
|
||||
|
||||
// TODO -- This is experimental code to see if this is meaningful. We should clean this up later when time permits.
|
||||
val returnedEarlyPathType = mutableListOf<PathType>()
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.pokemon.status.statuses.persistent
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
|
||||
class FrozenStatus : PersistentStatus(
|
||||
name = cobblemonResource("frozen"),
|
||||
showdownName = "frz",
|
||||
|
||||
@@ -20,6 +20,7 @@ object DataKeys {
|
||||
const val POKEMON_FRIENDSHIP = "Friendship"
|
||||
const val POKEMON_FULLNESS = "Fullness"
|
||||
const val POKEMON_INTERACTION_COOLDOWN = "InteractionCooldown"
|
||||
const val POKEMON_SKILL_COOLDOWNS = "SkillCooldowns"
|
||||
const val POKEMON_ALPHA = "Alpha"
|
||||
|
||||
const val POKEMON_IVS = "IVs"
|
||||
|
||||
@@ -100,10 +100,16 @@ fun ServerPlayer.didSleep(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun ServerPlayer.isInBattle() = BattleRegistry.getBattleByParticipatingPlayer(this) != null
|
||||
fun Player.isInBattle() = if (this is ServerPlayer) {
|
||||
BattleRegistry.getBattleByParticipatingPlayer(this) != null
|
||||
} else {
|
||||
CobblemonClient.battle?.spectating == false
|
||||
}
|
||||
|
||||
var ServerPlayer.spawner: PlayerSpawner
|
||||
get() = (this as PlayerSpawnerAccessor).getPlayerSpawner()
|
||||
set(value) = (this as PlayerSpawnerAccessor).setPlayerSpawner(value)
|
||||
|
||||
fun ServerPlayer.getBattleState(): Pair<PokemonBattle, BattleActor>? {
|
||||
val battle = BattleRegistry.getBattleByParticipatingPlayer(this)
|
||||
if (battle != null) {
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.util.adapters
|
||||
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import java.lang.reflect.Type
|
||||
|
||||
/**
|
||||
* Adapter for deserializing a reference to an [ActionEffectTimeline] from its identifier.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since August 31st, 2025
|
||||
*/
|
||||
object ActionEffectTimelineAdapter : JsonDeserializer<ActionEffectTimeline> {
|
||||
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): ActionEffectTimeline {
|
||||
val identifier = json.asString.asIdentifierDefaultingNamespace()
|
||||
val timeline = ActionEffects.actionEffects[identifier]
|
||||
return timeline ?: throw IllegalArgumentException("No ActionEffectTimeline found for id $identifier")
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ package com.cobblemon.mod.common.util.codec
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.MoLang
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.getString
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.Codec.optionalField
|
||||
@@ -29,6 +31,17 @@ val EXPRESSION_CODEC = object : PrimitiveCodec<Expression> {
|
||||
}
|
||||
}
|
||||
|
||||
val EXPRESSION_LIKE_CODEC = object : PrimitiveCodec<ExpressionLike> {
|
||||
override fun <T> read(ops: DynamicOps<T>, input: T): DataResult<ExpressionLike> {
|
||||
return ops.getStringValue(input).map { it.asExpressionLike() }
|
||||
}
|
||||
|
||||
override fun <T> write(ops: DynamicOps<T>, value: ExpressionLike): T {
|
||||
return ops.createString(value.getString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// special codec that always writes default value
|
||||
// vanilla changed the behaviour of Codec#optionalFieldOf(String, A) so that it OMITS default values when encoding
|
||||
// later on decoding it assumes no value -> default, but we want some default being encoded anyways so it can be targeted by commands
|
||||
|
||||
+7
-3
@@ -22,10 +22,12 @@ import net.minecraft.world.item.ItemStack
|
||||
import java.util.*
|
||||
|
||||
internal data class ClientPokemonP4(
|
||||
val originalTrainerFriendship: Optional<Int>
|
||||
val skillCooldownTicks: Map<ResourceLocation, Int>,
|
||||
val originalTrainerFriendship: Optional<Int>,
|
||||
) : Partial<Pokemon> {
|
||||
|
||||
override fun into(other: Pokemon): Pokemon {
|
||||
other.skillCooldownsTicks = this.skillCooldownTicks.toMutableMap()
|
||||
this.originalTrainerFriendship.ifPresent { other.originalTrainerFriendship = it }
|
||||
return other
|
||||
}
|
||||
@@ -36,11 +38,13 @@ internal data class ClientPokemonP4(
|
||||
*/
|
||||
internal val CODEC: MapCodec<ClientPokemonP4> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(ClientPokemonP4::originalTrainerFriendship)
|
||||
).apply(instance, ::ClientPokemonP4)
|
||||
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).fieldOf(DataKeys.POKEMON_SKILL_COOLDOWNS).forGetter(ClientPokemonP4::skillCooldownTicks),
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(ClientPokemonP4::originalTrainerFriendship),
|
||||
).apply(instance, ::ClientPokemonP4)
|
||||
}
|
||||
|
||||
internal fun from(pokemon: Pokemon): ClientPokemonP4 = ClientPokemonP4(
|
||||
pokemon.skillCooldownsTicks,
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,13 +13,16 @@ import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import java.util.*
|
||||
|
||||
internal data class PokemonP4(
|
||||
val originalTrainerFriendship: Optional<Int>
|
||||
val skillCooldownTicks: Map<ResourceLocation, Int>,
|
||||
val originalTrainerFriendship: Optional<Int>,
|
||||
) : Partial<Pokemon> {
|
||||
|
||||
override fun into(other: Pokemon): Pokemon {
|
||||
other.skillCooldownsTicks = this.skillCooldownTicks.toMutableMap()
|
||||
this.originalTrainerFriendship.ifPresent { other.originalTrainerFriendship = it }
|
||||
other.refreshOriginalTrainer()
|
||||
return other
|
||||
@@ -28,16 +31,20 @@ internal data class PokemonP4(
|
||||
companion object {
|
||||
internal val CODEC: MapCodec<PokemonP4> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(PokemonP4::originalTrainerFriendship)
|
||||
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).optionalFieldOf(DataKeys.POKEMON_SKILL_COOLDOWNS, emptyMap<ResourceLocation, Int>()).forGetter { it.skillCooldownTicks },
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(PokemonP4::originalTrainerFriendship),
|
||||
).apply(instance) {
|
||||
skillCooldownTicks,
|
||||
originalTrainerFriendship -> PokemonP4(
|
||||
originalTrainerFriendship
|
||||
skillCooldownTicks,
|
||||
originalTrainerFriendship,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun from(pokemon: Pokemon): PokemonP4 = PokemonP4(
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship)
|
||||
pokemon.skillCooldownsTicks,
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship),
|
||||
)
|
||||
}
|
||||
}
|
||||
+57
-3206
File diff suppressed because it is too large.
Load diff
+45
-2872
File diff suppressed because it is too large.
Load diff
+8
-1185
File diff suppressed because it is too large.
Load diff
-452
@@ -96,458 +96,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.poliwrath.ground_walk": {
|
||||
"loop": true,
|
||||
"animation_length": 1.3333,
|
||||
"bones": {
|
||||
"waist": {
|
||||
"rotation": ["9 - math.sin( q.anim_time * 90 * 6 - 45)*-4", "-math.sin( q.anim_time * 90 * 3)*8", "math.sin( q.anim_time * 90 * 3)*4"],
|
||||
"position": [0, "-0.3+math.sin( q.anim_time * 90 * 6)*1.5", 0]
|
||||
},
|
||||
"torso": {
|
||||
"rotation": ["8 - math.sin( q.anim_time * 90 * 6 - 45)*8", "-math.sin( q.anim_time * 90 * 3 - 25)*-8", "math.sin( q.anim_time * 90 * 3 - 25)*-8"],
|
||||
"position": [0, "math.sin( q.anim_time * 90 * 6 + 45)*0.3", 0]
|
||||
},
|
||||
"head": {
|
||||
"rotation": ["-math.sin( q.anim_time * 90 * 6 - 45)*-4", "-math.sin( q.anim_time * 90 * 3 - 25)*-1", 0]
|
||||
},
|
||||
"arm_left1": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [-13.63, -16.48493, 36.18],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-41, 8.77773, 38.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.625": {
|
||||
"post": [-8.15, -36.46773, 42.45],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0833": {
|
||||
"post": [24.5, -46.5535, 23.9],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [-13.63, -16.48493, 36.18],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arm_left2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 61.31326, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [0, 70.51, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5833": {
|
||||
"post": [0, 45.6917, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.875": {
|
||||
"post": [0, 32.9252, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.125": {
|
||||
"post": [0, 33.79, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [0, 61.31326, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hand_left": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [-6.39933, 10.3524, 6.73624],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [-6.4, 10.35, 6.74],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [-6.39933, 10.3524, 6.73624],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"finger_front_left1": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"finger_front_left2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"finger_back_left1": {
|
||||
"rotation": [0, 0, 70]
|
||||
},
|
||||
"finger_back_left2": {
|
||||
"rotation": [0, 0, 72.5]
|
||||
},
|
||||
"thumb_left1": {
|
||||
"rotation": [35.65498, -41.23664, 27.4926]
|
||||
},
|
||||
"arm_right1": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [-8.15, 36.46773, -42.45],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [24.5, 46.5535, -23.9],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [-13.63, 16.48493, -36.18],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.9167": {
|
||||
"post": [-41, -8.77773, -38.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [-8.15, 36.46773, -42.45],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arm_right2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, -45.6917, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": {
|
||||
"post": [0, -32.9252, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4583": {
|
||||
"post": [0, -33.79, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [0, -61.31326, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.9583": {
|
||||
"post": [0, -70.51, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [0, -45.6917, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hand_right": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [-6.4, -10.35, -6.74],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [-6.39933, -10.3524, -6.73624],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0417": {
|
||||
"post": [-6.4, -10.35, -6.74],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [-6.4, -10.35, -6.74],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"finger_front_right1": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, -67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [0, 0, -67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [0, 0, -67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"finger_front_right2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, -67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [0, 0, -67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [0, 0, -67.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"finger_back_right1": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, -70],
|
||||
"0.6667": [0, 0, -70],
|
||||
"1.3333": [0, 0, -70]
|
||||
}
|
||||
},
|
||||
"finger_back_right2": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, -72.5],
|
||||
"0.6667": [0, 0, -72.5],
|
||||
"1.3333": [0, 0, -72.5]
|
||||
}
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": {
|
||||
"0.0": [-3.5, 0, 0],
|
||||
"0.25": [28, 0, 0],
|
||||
"0.3333": [27, 0, 0],
|
||||
"0.4583": [36, 0, 0],
|
||||
"0.6667": {
|
||||
"pre": [-1, 0, 0],
|
||||
"post": [-1, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.8333": {
|
||||
"post": [-57.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0833": [-35, 0, 0],
|
||||
"1.3333": [-3.5, 0, 0]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, -0.3, 0],
|
||||
"0.25": [0, -1.1, 2.3],
|
||||
"0.3333": [0, 0.25, 2.3],
|
||||
"0.4583": [0, 0.2, 1.8],
|
||||
"0.6667": {
|
||||
"pre": [0, 0.9, -0.4],
|
||||
"post": [0, 0.9, -0.4],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.8333": {
|
||||
"post": [0, 0.8, -2.3],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0": [0, -0.7, -2.3],
|
||||
"1.0833": [0, -1.3, -2.3],
|
||||
"1.3333": [0, -0.3, 0]
|
||||
}
|
||||
},
|
||||
"leg_left2": {
|
||||
"rotation": {
|
||||
"0.0": [9, 0, 0],
|
||||
"0.25": [5, 0, 0],
|
||||
"0.3333": [14, 0, 0],
|
||||
"0.4583": [33, 0, 0],
|
||||
"0.5417": {
|
||||
"pre": [57.7, 0, 0],
|
||||
"post": [57.7, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [53, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.8333": {
|
||||
"post": [34.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0": [17, 0, 0],
|
||||
"1.0833": [13, 0, 0],
|
||||
"1.3333": [9, 0, 0]
|
||||
}
|
||||
},
|
||||
"foot_left": {
|
||||
"rotation": {
|
||||
"0.0": [-5, 0, 0],
|
||||
"0.25": [-32, 0, 0],
|
||||
"0.3333": [1.5, 0, 0],
|
||||
"0.5": {
|
||||
"pre": [29, 0, 0],
|
||||
"post": [29, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [-1, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0": [-13, 0, 0],
|
||||
"1.0833": [22, 0, 0],
|
||||
"1.3333": [-5, 0, 0]
|
||||
}
|
||||
},
|
||||
"toes_left": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [0, 0, 0],
|
||||
"0.3333": [-41, 0, 0],
|
||||
"0.5": {
|
||||
"pre": [-19, 0, 0],
|
||||
"post": [-19, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.875": {
|
||||
"post": [-23.89, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0417": {
|
||||
"post": [-20.18, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0833": [0, 0, 0],
|
||||
"1.3333": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [-1, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.1667": {
|
||||
"post": [-57.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": [-35, 0, 0],
|
||||
"0.6667": [-3.5, 0, 0],
|
||||
"0.9167": [28, 0, 0],
|
||||
"1.0": [27, 0, 0],
|
||||
"1.125": [36, 0, 0],
|
||||
"1.3333": {
|
||||
"pre": [-1, 0, 0],
|
||||
"post": [-1, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"0.0": {
|
||||
"post": [0, 0.9, -0.4],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.1667": {
|
||||
"post": [0, 0.8, -2.3],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.3333": [0, -0.7, -2.3],
|
||||
"0.4167": [0, -1.3, -2.3],
|
||||
"0.6667": [0, -0.3, 0],
|
||||
"0.9167": [0, -1.1, 2.3],
|
||||
"1.0": [0, 0.25, 2.3],
|
||||
"1.125": [0, 0.2, 1.8],
|
||||
"1.3333": {
|
||||
"pre": [0, 0.9, -0.4],
|
||||
"post": [0, 0.9, -0.4],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leg_right2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [53, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.1667": {
|
||||
"post": [34.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.3333": [17, 0, 0],
|
||||
"0.4167": [13, 0, 0],
|
||||
"0.9167": [5, 0, 0],
|
||||
"1.0": [-1, 0, 0],
|
||||
"1.125": [33, 0, 0],
|
||||
"1.2083": {
|
||||
"pre": [57.7, 0, 0],
|
||||
"post": [57.7, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [53, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"foot_right": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [-1, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.3333": [-13, 0, 0],
|
||||
"0.4167": [22, 0, 0],
|
||||
"0.9167": [-32, 0, 0],
|
||||
"1.0": [-6, 0, 0],
|
||||
"1.1667": {
|
||||
"pre": [29, 0, 0],
|
||||
"post": [29, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [-1, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toes_right": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": {
|
||||
"post": [-23.89, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [-20.18, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": [0, 0, 0],
|
||||
"0.9167": [0, 0, 0],
|
||||
"1.0": [-41, 0, 0],
|
||||
"1.1667": {
|
||||
"pre": [-19, 0, 0],
|
||||
"post": [-19, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.poliwrath.battle_idle": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
|
||||
+1307
-3006
File diff suppressed because it is too large.
Load diff
+718
-4051
File diff suppressed because it is too large.
Load diff
-490
@@ -38,496 +38,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.staryu.physical": {
|
||||
"loop": true,
|
||||
"animation_length": 3,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0.2, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [12.8384, 24.0851, -4.3796],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [17.8384, 24.0851, -4.3796],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5417": [-90, 0, 0],
|
||||
"0.7917": [-90, 0, 0],
|
||||
"0.8333": [-90, 0, 0],
|
||||
"0.875": {"pre": [-90, 0, 0], "post": [-90, 360, 0]},
|
||||
"1.1667": [-90, 360, 0],
|
||||
"1.25": {
|
||||
"pre": [0, 277.5, 0],
|
||||
"post": [0, 277.5, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.4167": {
|
||||
"post": [6.39, 117.88, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.0": {
|
||||
"post": [5.48, -33.58, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.2083": {
|
||||
"post": [21.1183, -47.3658, -26.7217],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.5417": {
|
||||
"post": [0, 15, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"3.0": {
|
||||
"post": [0.2, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"0.0": {
|
||||
"post": [0, 0.18, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": {
|
||||
"post": [0, -0.82, -1],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [0, -0.82, -1.4],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": {
|
||||
"post": [6.02, 0.94, 0.77],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5833": {
|
||||
"post": [13.15, -0.88, 3.58],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.625": {
|
||||
"post": [15, -3, 5.6],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [14.57, -5.35, 6.54],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.75": {
|
||||
"post": [13.35, -3.68, 8.94],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.8333": {
|
||||
"post": [11.93, -5.63, 11.86],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.875": {
|
||||
"post": [11.18, -5.08, 13.37],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.9583": {
|
||||
"post": [7, -6, 14.6],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0417": {
|
||||
"post": [-6.26, -6.52, 13.55],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.125": {
|
||||
"post": [-15, -6, 1.6],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [1, 1.4, -20.4],
|
||||
"1.2917": [0.43, 1.45, -20.36],
|
||||
"1.3333": [-1.24, 1.49, -21.13],
|
||||
"1.375": [-1.88, 1.68, -22.94],
|
||||
"1.4167": [-1.54, 1.81, -24.12],
|
||||
"1.5417": [-0.88, 1.67, -23.04],
|
||||
"1.625": [-1.19, 1.92, -22.77],
|
||||
"1.75": [-2.72, 1.42, -23.27],
|
||||
"1.9167": [-3.9, 0.72, -26.2],
|
||||
"2.0": [-3.13, -0.04, -27.22],
|
||||
"2.125": {
|
||||
"pre": [-2.63, -1.14, -29.12],
|
||||
"post": [-2.63, -1.14, -29.12],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.2083": {
|
||||
"post": [-2.2, 5.12, -21.92],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.3333": {
|
||||
"post": [-1.31, 8.05, -13.11],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.4583": {
|
||||
"post": [-0.45, 6.18, -4.51],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.5417": {
|
||||
"post": [0, 0.18, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.7083": {
|
||||
"post": [0.03, -1.22, 0.37],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"3.0": {
|
||||
"post": [0, 0.18, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"body_limb_left3": {
|
||||
"rotation": {
|
||||
"0.0": [0, 2.5, 0],
|
||||
"3.0": [0, 2.5, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_bottom_left3": {
|
||||
"rotation": {
|
||||
"0.0": [-5, 0, 0],
|
||||
"3.0": [-5, 0, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_top3": {
|
||||
"rotation": {
|
||||
"0.0": [2.5, 0, 0],
|
||||
"3.0": [2.5, 0, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_left": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.2083": {
|
||||
"post": [0, 0, 7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.375": {
|
||||
"post": [-10, -20, 20],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.875": {
|
||||
"post": [0, 0, 7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.0": {
|
||||
"post": [5.1686, 19.3385, 5.9149],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.125": {
|
||||
"post": [4.7679, 3.7657, 12.0388],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.1667": {
|
||||
"post": [0, 5, 15],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"3.0": {
|
||||
"post": [0, 0, 7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
},
|
||||
"scale": {
|
||||
"2.125": [1, 1, 1],
|
||||
"2.1667": [1.2, 0.9, 1],
|
||||
"2.2083": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"body_limb_bottom_left": {
|
||||
"rotation": {
|
||||
"0.0": [0.3, 0, 2.15],
|
||||
"2.5833": [8.66217, -7.5105, 6.41838],
|
||||
"2.7083": [-2.3895, -8.7088, 4.394],
|
||||
"3.0": [0.3, 0, 2.15]
|
||||
}
|
||||
},
|
||||
"body_limb_right": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, -7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.2083": {
|
||||
"post": [0, 0, -7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.3333": {
|
||||
"post": [0, -15, -7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.8333": {
|
||||
"post": [0, 0, -7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"3.0": {
|
||||
"post": [0, 0, -7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"body_limb_bottom_right": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0.3, 0, -2.15],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-12.5699, -2.2333, 16.2155],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.3333": {
|
||||
"post": [-17.0419, 2.0337, 17.6707],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [-11.9836, 2.1592, 17.6561],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4583": {
|
||||
"post": [0.2897, -0.0776, 12.85],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5833": {
|
||||
"post": [0.3, 0, -2.15],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.5833": [-9.7324, -5.0125, 8.4786],
|
||||
"2.7083": [-21.5994, 2.9166, 17.3467],
|
||||
"3.0": {
|
||||
"pre": [0.3, 0, -2.15],
|
||||
"post": [0.3, 0, -2.15],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
},
|
||||
"scale": {
|
||||
"0.4167": [1, 1, 1],
|
||||
"0.4583": [1, 1.1, 1],
|
||||
"0.5": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"body_limb_bottom_right3": {
|
||||
"rotation": {
|
||||
"0.0": [-5, 0, 0],
|
||||
"3.0": [-5, 0, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_top": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"3.0": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"face": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"2.5833": [0, 0, 0],
|
||||
"2.7083": [0, -7.5, 0],
|
||||
"2.875": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_top2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": {
|
||||
"post": [-7.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [12.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5417": {
|
||||
"post": [-12.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [0, 0, 5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.1667": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"body_limb_left2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.1667": {
|
||||
"post": [0, -12.5, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [-0.0298, 17.7172, 0.0411],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": {
|
||||
"post": [-0.1175, -19.5709, 0.2845],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7083": {
|
||||
"post": [0, 0, 12.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0833": {
|
||||
"post": [0, 0, 12.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.2083": {
|
||||
"post": [-0.0112, -22.4314, 11.7901],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.375": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.0": [0, 0, 0],
|
||||
"2.0833": [13.4251, -35.9563, -26.0018],
|
||||
"2.125": [17.7735, -35.6335, -34.2819],
|
||||
"2.1667": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_right2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.1667": {
|
||||
"post": [0, 12.5, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [-0.0298, -17.7172, -0.0411],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": {
|
||||
"post": [-0.1175, 19.5709, -0.2845],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7083": {
|
||||
"post": [0, 0, 12.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0833": {
|
||||
"post": [0, 0, 12.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.2083": {
|
||||
"post": [-0.0112, 22.4314, 11.7901],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.375": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"body_limb_bottom_left2": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"2.5833": [0, 0, 0],
|
||||
"2.7083": [42.9952, 6.5597, 2.4923],
|
||||
"3.0": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"body_limb_bottom_right2": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-18.586, -7.5206, -21.2677],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [-22.8925, -9.0864, -26.0667],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4583": {
|
||||
"post": [20.9813, -9.8466, 17.4953],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5833": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.75": {
|
||||
"post": [0, 0, -10],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0833": {
|
||||
"post": [0, 0, -10],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.2083": {
|
||||
"post": [29.7624, 0.4222, -0.417],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.8333": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.25": {
|
||||
"post": [-13.6038, -3.6461, -10.334],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.4583": [-8.1623, 0.0203, 12.7371],
|
||||
"2.5833": [0, 0, 0],
|
||||
"2.7083": [35.3924, 9.0867, -26.0666],
|
||||
"3.0": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"torso": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [0, 0, 0],
|
||||
"0.2917": [0, 0, 0],
|
||||
"0.3333": {"pre": [0, 0, 0], "post": [0, 0, 1080]},
|
||||
"0.4167": [0, 0, 1080],
|
||||
"0.875": {
|
||||
"pre": [0, 0, 780],
|
||||
"post": [0, 0, 780],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [0, 0, 201],
|
||||
"1.8333": [0, 0, 153.14],
|
||||
"2.0833": {
|
||||
"pre": [0, 0, 148.3],
|
||||
"post": [0, 0, 148.3],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.2917": {
|
||||
"post": [0, 0, 153.14],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"2.5": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"3.0": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.staryu.ground_walk": {
|
||||
"loop": true,
|
||||
"animation_length": 1.6,
|
||||
|
||||
+98
-1897
File diff suppressed because it is too large.
Load diff
+97
-4905
File diff suppressed because it is too large.
Load diff
+144
-6944
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -281,7 +281,7 @@
|
||||
},
|
||||
"animation.luvdisc.ground_faint": {
|
||||
"loop": true,
|
||||
"animation_length": 3,
|
||||
"animation_length": 2.5,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": {
|
||||
|
||||
+312
-3442
File diff suppressed because it is too large.
Load diff
+1246
-718
File diff suppressed because it is too large.
Load diff
+1127
-320
File diff suppressed because it is too large.
Load diff
+378
-1657
File diff suppressed because it is too large.
Load diff
+161
-1075
File diff suppressed because it is too large.
Load diff
+105
-5650
File diff suppressed because it is too large.
Load diff
+114
-16856
File diff suppressed because it is too large.
Load diff
+114
-4699
File diff suppressed because it is too large.
Load diff
+85
-8314
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -55,7 +55,7 @@
|
||||
{
|
||||
"name": "torso",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8, -0.25],
|
||||
"pivot": [0, 8, 0.75],
|
||||
"cubes": [
|
||||
{"origin": [-5.5, 4.5, -6.5], "size": [11, 9, 12], "uv": [1, 1]}
|
||||
]
|
||||
@@ -63,7 +63,7 @@
|
||||
{
|
||||
"name": "upper_torso",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 12.5, 0.75],
|
||||
"pivot": [0, 12.5, 1.75],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 12, -5.25], "size": [9, 5, 10], "uv": [2, 24]}
|
||||
]
|
||||
|
||||
+4
-12
@@ -134,12 +134,12 @@
|
||||
{
|
||||
"name": "nose",
|
||||
"parent": "head_angle",
|
||||
"pivot": [0, 27.25, -4.75],
|
||||
"pivot": [0.5, 24.55, -4.75],
|
||||
"rotation": [17.5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-1.5, 23.88496, -8.81691], "size": [3, 1, 4], "inflate": 0.01, "uv": [65, 28]},
|
||||
{"origin": [-1.5, 24.90496, -6.81691], "size": [3, 1, 3], "inflate": 0.01, "uv": [60, 52]},
|
||||
{"origin": [-1.5, 24.8963, -9.08986], "size": [3, 1, 5], "pivot": [0.03, 25.8863, -7.08986], "rotation": [30, 0, 0], "uv": [46, 26]}
|
||||
{"origin": [-1.5, 23.76, -8.005], "size": [3, 1, 4], "inflate": 0.01, "uv": [65, 28]},
|
||||
{"origin": [-1.5, 24.78, -6.005], "size": [3, 1, 3], "inflate": 0.01, "uv": [60, 52]},
|
||||
{"origin": [-1.5, 24.77134, -8.27795], "size": [3, 1, 5], "pivot": [0.03, 25.76134, -6.27795], "rotation": [30, 0, 0], "uv": [46, 26]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -334,14 +334,6 @@
|
||||
{"origin": [-2, 23.5, -4.65], "size": [4, 2, 0], "inflate": 0.01, "uv": [67, 61]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "mouth_o",
|
||||
"parent": "head_angle",
|
||||
"pivot": [0, 24, 1.35],
|
||||
"cubes": [
|
||||
{"origin": [-0.5, 23.5, -4.65], "size": [1, 2, 0], "inflate": 0.01, "uv": [76, 53]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "neck_fluff",
|
||||
"parent": "upper_torso",
|
||||
|
||||
-8
@@ -334,14 +334,6 @@
|
||||
{"origin": [-2, 23.5, -4.65], "size": [4, 2, 0], "inflate": 0.01, "uv": [67, 61]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "mouth_o",
|
||||
"parent": "head_angle",
|
||||
"pivot": [0, 24, 1.35],
|
||||
"cubes": [
|
||||
{"origin": [-0.5, 23.5, -4.65], "size": [1, 2, 0], "inflate": 0.01, "uv": [76, 53]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "neck_fluff",
|
||||
"parent": "upper_torso",
|
||||
|
||||
+28
-33
@@ -18,20 +18,41 @@
|
||||
{
|
||||
"name": "body",
|
||||
"parent": "staryu",
|
||||
"pivot": [0, 8.35, -0.25]
|
||||
},
|
||||
{
|
||||
"name": "torso",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8.35, -0.25],
|
||||
"pivot": [0, 8.75, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [-3, 5.3, -2.1], "size": [6, 6, 5], "inflate": -0.05, "uv": [0, 0]},
|
||||
{"origin": [-0.5, 9.27, 1.87], "size": [1, 2, 1], "inflate": -0.01, "uv": [1, 2]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "face",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8.25, -0.9],
|
||||
"cubes": [
|
||||
{"origin": [-3.5, 4.75, -3.1], "size": [7, 7, 1], "inflate": 0.11, "uv": [0, 20]},
|
||||
{"origin": [-4, 4.25, -3.25], "size": [8, 8, 1], "inflate": 0.25, "uv": [0, 11]},
|
||||
{"origin": [-1.5, 6.75, -4.15], "size": [3, 3, 1], "inflate": 0.1, "uv": [17, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_eye",
|
||||
"parent": "face",
|
||||
"pivot": [0, 8.2, -4.25],
|
||||
"locators": {
|
||||
"eye1": [0, 8.2, -4.25]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gem_emissive",
|
||||
"parent": "face",
|
||||
"pivot": [0, 8.25, -3.65],
|
||||
"cubes": [
|
||||
{"origin": [-1.5, 6.75, -4.15], "size": [3, 3, 1], "inflate": 0.11, "uv": [36, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "body_limbs",
|
||||
"parent": "torso",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8.5, -0.25]
|
||||
},
|
||||
{
|
||||
@@ -118,32 +139,6 @@
|
||||
"cubes": [
|
||||
{"origin": [-1.75, -1.55, -1], "size": [3, 4, 2], "inflate": 0.15, "uv": [52, 21], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "face",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 8.25, -0.9],
|
||||
"cubes": [
|
||||
{"origin": [-3.5, 4.75, -3.1], "size": [7, 7, 1], "inflate": 0.11, "uv": [0, 20]},
|
||||
{"origin": [-4, 4.25, -3.25], "size": [8, 8, 1], "inflate": 0.25, "uv": [0, 11]},
|
||||
{"origin": [-1.5, 6.75, -4.15], "size": [3, 3, 1], "inflate": 0.1, "uv": [17, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_eye",
|
||||
"parent": "face",
|
||||
"pivot": [0, 8.2, -4.25],
|
||||
"locators": {
|
||||
"eye1": [0, 8.2, -4.25]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gem_emissive",
|
||||
"parent": "face",
|
||||
"pivot": [0, 8.25, -3.65],
|
||||
"cubes": [
|
||||
{"origin": [-1.5, 6.75, -4.15], "size": [3, 3, 1], "inflate": 0.11, "uv": [36, 0]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+1
-2
@@ -42,8 +42,7 @@
|
||||
"parent": "face",
|
||||
"pivot": [0, 12.5, -8.4],
|
||||
"locators": {
|
||||
"eye1": [0, 12.5, -8.4],
|
||||
"special": [0, 12.5, -8.4]
|
||||
"eye1": [0, 12.5, -8.4]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+3
-19
@@ -6,7 +6,7 @@
|
||||
"identifier": "geometry.noctowl",
|
||||
"texture_width": 128,
|
||||
"texture_height": 128,
|
||||
"visible_bounds_width": 7,
|
||||
"visible_bounds_width": 6,
|
||||
"visible_bounds_height": 3.5,
|
||||
"visible_bounds_offset": [0, 1.25, 0]
|
||||
},
|
||||
@@ -361,21 +361,13 @@
|
||||
"parent": "wing_open_left2",
|
||||
"pivot": [19, 23.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [19, 11.5, 0], "size": [7, 13, 0], "inflate": 0.02, "uv": [16, 101]},
|
||||
{"origin": [19, 10.5, 0], "size": [14, 14, 0], "inflate": 0.02, "uv": [0, 63]},
|
||||
{"origin": [17, 10.5, 0], "size": [2, 14, 0], "inflate": 0.02, "uv": [56, 92]},
|
||||
{"origin": [19, 17.5, -0.5], "size": [6, 7, 1], "inflate": 0.02, "uv": [84, 25]},
|
||||
{"origin": [19, 17.5, -0.5], "size": [6, 0, 1], "inflate": 0.02, "pivot": [22, 17.5, 0], "rotation": [0.5, 0, 0], "uv": [60, 23]},
|
||||
{"origin": [25, 17.5, -0.5], "size": [0, 7, 1], "inflate": 0.02, "pivot": [25, 21, 0], "rotation": [0, -0.5, 0], "uv": [54, 79]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wing_open_left4",
|
||||
"parent": "wing_open_left3",
|
||||
"pivot": [25, 23.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [25, 14.5, 0], "size": [8, 9, 0], "inflate": 0.02, "uv": [18, 115]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wing_open_right1",
|
||||
"parent": "wings_open",
|
||||
@@ -410,21 +402,13 @@
|
||||
"parent": "wing_open_right2",
|
||||
"pivot": [-19, 23.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-26, 11.5, 0], "size": [7, 13, 0], "inflate": 0.02, "uv": [1, 101]},
|
||||
{"origin": [-33, 10.5, 0], "size": [14, 14, 0], "inflate": 0.02, "uv": [28, 65]},
|
||||
{"origin": [-19, 10.5, 0], "size": [2, 14, 0], "inflate": 0.02, "uv": [68, 92]},
|
||||
{"origin": [-25, 17.5, -0.5], "size": [6, 7, 1], "inflate": 0.02, "uv": [88, 73]},
|
||||
{"origin": [-25, 17.5, -0.5], "size": [6, 0, 1], "inflate": 0.02, "pivot": [-22, 17.5, 0], "rotation": [0.5, 0, 0], "uv": [60, 24]},
|
||||
{"origin": [-25, 17.5, -0.5], "size": [0, 7, 1], "inflate": 0.02, "pivot": [-25, 21, 0], "rotation": [0, 0.5, 0], "uv": [96, 3]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wing_open_right4",
|
||||
"parent": "wing_open_right3",
|
||||
"pivot": [-25, 23.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-33, 14.5, 0], "size": [8, 9, 0], "inflate": 0.02, "uv": [1, 115]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wings_closed",
|
||||
"parent": "torso",
|
||||
|
||||
+2
-2
@@ -39,11 +39,11 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"name": "locator_seat1",
|
||||
"parent": "thorax",
|
||||
"pivot": [0, 11, 0],
|
||||
"locators": {
|
||||
"seat_1": [0, 11, 1]
|
||||
"seat1": [0, 11, 1]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@
|
||||
"parent": "torso",
|
||||
"pivot": [0, 21, 3.75],
|
||||
"locators": {
|
||||
"seat_1": [0, 21, 3.75]
|
||||
"seat_2": [0, 21, 3.75]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@
|
||||
"parent": "torso",
|
||||
"pivot": [0, 21, 3.75],
|
||||
"locators": {
|
||||
"seat_1": [0, 21, 3.75]
|
||||
"seat_2": [0, 21, 3.75]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+2
-2
@@ -377,11 +377,11 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"name": "locator_seat1",
|
||||
"parent": "saddle",
|
||||
"pivot": [0, 23.525, 0],
|
||||
"locators": {
|
||||
"seat_1": [0, 23.525, 0]
|
||||
"seat1": [0, 23.525, 0]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
-8
@@ -30,14 +30,6 @@
|
||||
"parent": "body_rotation",
|
||||
"pivot": [0, 8.5, 0]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "waist_rotation",
|
||||
"pivot": [0, 36, 0],
|
||||
"locators": {
|
||||
"seat_1": [0, 35.75, 8.5]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "waist_scale",
|
||||
"parent": "waist_rotation",
|
||||
|
||||
+22
-18
@@ -188,10 +188,12 @@
|
||||
"parent": "eyes",
|
||||
"pivot": [-1.51, 13.3, -1],
|
||||
"cubes": [
|
||||
{"origin": [-1.52, 12.8, -2], "size": [0, 1, 1], "uv": [62, 15]},
|
||||
{"origin": [-1.53, 12.8, -1.5], "size": [0, 1, 3], "uv": [56, 13]},
|
||||
{"origin": [-1.51, 11.3, -2], "size": [0, 2, 3], "uv": [56, 14]},
|
||||
{"origin": [-1.52, 11.3, 0.5], "size": [0, 2, 1], "uv": [62, 16]}
|
||||
{"origin": [-1.51, 12.8, -2], "size": [0, 1, 2], "uv": [60, 14]},
|
||||
{"origin": [-1.51, 12.8, -0.5], "size": [0, 1, 2], "uv": [56, 14]},
|
||||
{"origin": [-1.51, 11.3, -2], "size": [0, 1, 2], "uv": [60, 16]},
|
||||
{"origin": [-1.51, 11.3, -0.5], "size": [0, 1, 2], "uv": [56, 16]},
|
||||
{"origin": [-1.51, 11.8, -2], "size": [0, 1, 2], "uv": [60, 15]},
|
||||
{"origin": [-1.51, 11.8, -0.5], "size": [0, 1, 2], "uv": [56, 15]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -199,8 +201,8 @@
|
||||
"parent": "eye_right",
|
||||
"pivot": [-1.51, 13.8, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [-1.53, 13.8, -1.5], "size": [0, 1, 3], "uv": [56, 12]},
|
||||
{"origin": [-1.52, 13.8, -2], "size": [0, 1, 1], "uv": [62, 14]}
|
||||
{"origin": [-1.51, 13.8, -0.5], "size": [0, 1, 2], "uv": [56, 13]},
|
||||
{"origin": [-1.51, 13.8, -2], "size": [0, 1, 2], "uv": [60, 13]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -221,7 +223,7 @@
|
||||
"parent": "pupil_right",
|
||||
"pivot": [-1.52, 13, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [-1.54, 12.5, -0.75], "size": [0, 1, 1], "uv": [1, 0]}
|
||||
{"origin": [-1.52, 12.5, -0.75], "size": [0, 1, 1], "uv": [1, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -238,7 +240,7 @@
|
||||
"parent": "pupil_right",
|
||||
"pivot": [-1.42, 13, -1.25],
|
||||
"cubes": [
|
||||
{"origin": [-1.44, 12.5, -1.75], "size": [0, 1, 1], "uv": [1, 1]}
|
||||
{"origin": [-1.42, 12.5, -1.75], "size": [0, 1, 1], "uv": [1, 1]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -246,7 +248,7 @@
|
||||
"parent": "pupil_right",
|
||||
"pivot": [-1.42, 13, 0.75],
|
||||
"cubes": [
|
||||
{"origin": [-1.44, 12.5, 0.25], "size": [0, 1, 1], "uv": [1, 2]}
|
||||
{"origin": [-1.42, 12.5, 0.25], "size": [0, 1, 1], "uv": [1, 2]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -270,10 +272,12 @@
|
||||
"parent": "eyes",
|
||||
"pivot": [1.51, 13.3, -1],
|
||||
"cubes": [
|
||||
{"origin": [1.52, 12.8, -2], "size": [0, 1, 1], "uv": [54, 15], "mirror": true},
|
||||
{"origin": [1.53, 12.8, -1.5], "size": [0, 1, 3], "uv": [48, 13], "mirror": true},
|
||||
{"origin": [1.51, 11.3, -2], "size": [0, 2, 3], "uv": [48, 14], "mirror": true},
|
||||
{"origin": [1.52, 11.3, 0.5], "size": [0, 2, 1], "uv": [54, 16], "mirror": true}
|
||||
{"origin": [1.51, 12.8, -2], "size": [0, 1, 2], "uv": [52, 14], "mirror": true},
|
||||
{"origin": [1.51, 12.8, -0.5], "size": [0, 1, 2], "uv": [48, 14], "mirror": true},
|
||||
{"origin": [1.51, 11.3, -2], "size": [0, 1, 2], "uv": [52, 16], "mirror": true},
|
||||
{"origin": [1.51, 11.3, -0.5], "size": [0, 1, 2], "uv": [48, 16], "mirror": true},
|
||||
{"origin": [1.51, 11.8, -2], "size": [0, 1, 2], "uv": [52, 15], "mirror": true},
|
||||
{"origin": [1.51, 11.8, -0.5], "size": [0, 1, 2], "uv": [48, 15], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -281,8 +285,8 @@
|
||||
"parent": "eye_left",
|
||||
"pivot": [1.51, 13.8, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [1.53, 13.8, -1.5], "size": [0, 1, 3], "uv": [48, 12], "mirror": true},
|
||||
{"origin": [1.52, 13.8, -2], "size": [0, 1, 1], "uv": [54, 14], "mirror": true}
|
||||
{"origin": [1.51, 13.8, -0.5], "size": [0, 1, 2], "uv": [48, 13], "mirror": true},
|
||||
{"origin": [1.51, 13.8, -2], "size": [0, 1, 2], "uv": [52, 13], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -303,7 +307,7 @@
|
||||
"parent": "pupil_left",
|
||||
"pivot": [1.52, 13, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [1.54, 12.5, -0.75], "size": [0, 1, 1], "uv": [3, 0], "mirror": true}
|
||||
{"origin": [1.52, 12.5, -0.75], "size": [0, 1, 1], "uv": [3, 0], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -320,7 +324,7 @@
|
||||
"parent": "pupil_left",
|
||||
"pivot": [1.42, 13, -1.25],
|
||||
"cubes": [
|
||||
{"origin": [1.44, 12.5, -1.75], "size": [0, 1, 1], "uv": [3, 1], "mirror": true}
|
||||
{"origin": [1.42, 12.5, -1.75], "size": [0, 1, 1], "uv": [3, 1], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -328,7 +332,7 @@
|
||||
"parent": "pupil_left",
|
||||
"pivot": [1.42, 13, 0.75],
|
||||
"cubes": [
|
||||
{"origin": [1.44, 12.5, 0.25], "size": [0, 1, 1], "uv": [3, 2], "mirror": true}
|
||||
{"origin": [1.42, 12.5, 0.25], "size": [0, 1, 1], "uv": [3, 2], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+20
-16
@@ -188,10 +188,12 @@
|
||||
"parent": "eyes",
|
||||
"pivot": [-1.51, 13.3, -1],
|
||||
"cubes": [
|
||||
{"origin": [-1.52, 12.8, -2], "size": [0, 1, 1], "uv": [62, 13]},
|
||||
{"origin": [-1.53, 12.8, -1.5], "size": [0, 1, 3], "uv": [56, 11]},
|
||||
{"origin": [-1.51, 11.3, -2], "size": [0, 2, 3], "uv": [56, 12]},
|
||||
{"origin": [-1.52, 11.3, 0.5], "size": [0, 2, 1], "uv": [62, 14]}
|
||||
{"origin": [-1.51, 12.8, -2], "size": [0, 1, 2], "uv": [60, 12]},
|
||||
{"origin": [-1.51, 12.8, -0.5], "size": [0, 1, 2], "uv": [56, 12]},
|
||||
{"origin": [-1.51, 11.3, -2], "size": [0, 1, 2], "uv": [60, 14]},
|
||||
{"origin": [-1.51, 11.3, -0.5], "size": [0, 1, 2], "uv": [56, 14]},
|
||||
{"origin": [-1.51, 11.8, -2], "size": [0, 1, 2], "uv": [60, 13]},
|
||||
{"origin": [-1.51, 11.8, -0.5], "size": [0, 1, 2], "uv": [56, 13]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -199,8 +201,8 @@
|
||||
"parent": "eye_right",
|
||||
"pivot": [-1.51, 13.8, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [-1.53, 13.8, -1.5], "size": [0, 1, 3], "uv": [56, 10]},
|
||||
{"origin": [-1.52, 13.8, -2], "size": [0, 1, 1], "uv": [62, 12]}
|
||||
{"origin": [-1.51, 13.8, -0.5], "size": [0, 1, 2], "uv": [56, 11]},
|
||||
{"origin": [-1.51, 13.8, -2], "size": [0, 1, 2], "uv": [60, 11]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -209,7 +211,7 @@
|
||||
"pivot": [-1.31, 11.6, 1.3],
|
||||
"cubes": [
|
||||
{"origin": [-1.81, 10.6, 0.3], "size": [1, 2, 2], "inflate": -0.3, "uv": [58, 17]},
|
||||
{"origin": [-1.62, 10.4, 1.5], "size": [1, 1, 1], "inflate": -0.1, "uv": [48, 19]}
|
||||
{"origin": [-1.61, 10.4, 1.5], "size": [1, 1, 1], "inflate": -0.1, "uv": [48, 19]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -222,7 +224,7 @@
|
||||
"parent": "pupil_right",
|
||||
"pivot": [-1.52, 13, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [-1.54, 12.5, -0.75], "size": [0, 1, 1], "uv": [1, 0]}
|
||||
{"origin": [-1.52, 12.5, -0.75], "size": [0, 1, 1], "uv": [1, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -255,10 +257,12 @@
|
||||
"parent": "eyes",
|
||||
"pivot": [1.51, 13.3, -1],
|
||||
"cubes": [
|
||||
{"origin": [1.52, 12.8, -2], "size": [0, 1, 1], "uv": [54, 13], "mirror": true},
|
||||
{"origin": [1.53, 12.8, -1.5], "size": [0, 1, 3], "uv": [48, 11], "mirror": true},
|
||||
{"origin": [1.51, 11.3, -2], "size": [0, 2, 3], "uv": [48, 12], "mirror": true},
|
||||
{"origin": [1.52, 11.3, 0.5], "size": [0, 2, 1], "uv": [54, 14], "mirror": true}
|
||||
{"origin": [1.51, 12.8, -2], "size": [0, 1, 2], "uv": [52, 12], "mirror": true},
|
||||
{"origin": [1.51, 12.8, -0.5], "size": [0, 1, 2], "uv": [48, 12], "mirror": true},
|
||||
{"origin": [1.51, 11.3, -2], "size": [0, 1, 2], "uv": [52, 14], "mirror": true},
|
||||
{"origin": [1.51, 11.3, -0.5], "size": [0, 1, 2], "uv": [48, 14], "mirror": true},
|
||||
{"origin": [1.51, 11.8, -2], "size": [0, 1, 2], "uv": [52, 13], "mirror": true},
|
||||
{"origin": [1.51, 11.8, -0.5], "size": [0, 1, 2], "uv": [48, 13], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -266,8 +270,8 @@
|
||||
"parent": "eye_left",
|
||||
"pivot": [1.51, 13.8, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [1.53, 13.8, -1.5], "size": [0, 1, 3], "uv": [48, 10], "mirror": true},
|
||||
{"origin": [1.52, 13.8, -2], "size": [0, 1, 1], "uv": [54, 12], "mirror": true}
|
||||
{"origin": [1.51, 13.8, -0.5], "size": [0, 1, 2], "uv": [48, 11], "mirror": true},
|
||||
{"origin": [1.51, 13.8, -2], "size": [0, 1, 2], "uv": [52, 11], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -276,7 +280,7 @@
|
||||
"pivot": [1.31, 11.6, 1.3],
|
||||
"cubes": [
|
||||
{"origin": [0.81, 10.6, 0.3], "size": [1, 2, 2], "inflate": -0.3, "uv": [52, 17], "mirror": true},
|
||||
{"origin": [0.62, 10.4, 1.5], "size": [1, 1, 1], "inflate": -0.1, "uv": [48, 17], "mirror": true}
|
||||
{"origin": [0.61, 10.4, 1.5], "size": [1, 1, 1], "inflate": -0.1, "uv": [48, 17], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -289,7 +293,7 @@
|
||||
"parent": "pupil_left",
|
||||
"pivot": [1.52, 13, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [1.54, 12.5, -0.75], "size": [0, 1, 1], "uv": [3, 0], "mirror": true}
|
||||
{"origin": [1.52, 12.5, -0.75], "size": [0, 1, 1], "uv": [3, 0], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
-8
@@ -274,14 +274,6 @@
|
||||
"parent": "lower_gear_rotation",
|
||||
"pivot": [0, 9, -6]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "lower_gear_rotation",
|
||||
"pivot": [0, 10.5, -4.5],
|
||||
"locators": {
|
||||
"seat_1": [0, 10.5, -4.5]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gear4",
|
||||
"parent": "lower_gear",
|
||||
|
||||
-8
@@ -447,14 +447,6 @@
|
||||
"cubes": [
|
||||
{"origin": [0, -24.5, -8], "size": [0, 12, 7], "uv": [98, 109]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "body",
|
||||
"pivot": [0, 54, -10],
|
||||
"locators": {
|
||||
"seat_1": [0, 54, -10]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
-8
@@ -494,14 +494,6 @@
|
||||
"tail_tip": [0, 12.25, 19.25]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "tail",
|
||||
"pivot": [0, 16, 12],
|
||||
"locators": {
|
||||
"seat_1": [0, 16, 12]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "legs",
|
||||
"parent": "body",
|
||||
|
||||
+448
-437
@@ -1,439 +1,450 @@
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.rabsca",
|
||||
"texture_width": 256,
|
||||
"texture_height": 128,
|
||||
"visible_bounds_width": 4,
|
||||
"visible_bounds_height": 5.5,
|
||||
"visible_bounds_offset": [0, 2.25, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "rabsca",
|
||||
"pivot": [0, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "body2",
|
||||
"parent": "rabsca",
|
||||
"pivot": [0, 26, 0]
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"parent": "body2",
|
||||
"pivot": [0, 10, 0]
|
||||
},
|
||||
{
|
||||
"name": "torso",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8, 0],
|
||||
"cubes": [
|
||||
{"origin": [-4, 10, -2.5], "size": [8, 8, 5], "uv": [0, 9]},
|
||||
{"origin": [-3.5, 10.52, 2.52], "size": [7, 7, 0], "uv": [52, 28]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "legs",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 14, -2.5]
|
||||
},
|
||||
{
|
||||
"name": "leg_left",
|
||||
"parent": "legs",
|
||||
"pivot": [3.5, 14, -2.5],
|
||||
"rotation": [0, 5, 0],
|
||||
"cubes": [
|
||||
{"origin": [2, 13.5, -2.5], "size": [6, 2, 0], "uv": [23, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_left2",
|
||||
"parent": "leg_left",
|
||||
"pivot": [8, 15.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [5, 15.5, -2.5], "size": [4, 5, 0], "inflate": 0.01, "uv": [35, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_left3",
|
||||
"parent": "leg_left2",
|
||||
"pivot": [9, 20.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [4, 20.5, -2.5], "size": [5, 5, 0], "inflate": 0.02, "uv": [26, 10]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_right",
|
||||
"parent": "legs",
|
||||
"pivot": [-3.5, 14, -2.5],
|
||||
"rotation": [0, -5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-8, 13.5, -2.5], "size": [6, 2, 0], "uv": [23, 2], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_right2",
|
||||
"parent": "leg_right",
|
||||
"pivot": [-8, 15.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-9, 15.5, -2.5], "size": [4, 5, 0], "inflate": 0.01, "uv": [28, 5], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_right3",
|
||||
"parent": "leg_right2",
|
||||
"pivot": [-9, 20.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-9, 20.5, -2.5], "size": [5, 5, 0], "inflate": 0.02, "uv": [36, 5], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "head",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 10.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 6.5, -2.5], "size": [9, 4, 5], "inflate": 0.01, "uv": [0, 0]},
|
||||
{"origin": [1.25, 4.75, -0.25], "size": [0, 4, 3], "pivot": [1.25, 8.25, 2.6], "rotation": [15, 0, -5], "uv": [0, 19]},
|
||||
{"origin": [2.5, 5, -0.25], "size": [0, 4, 3], "pivot": [2.5, 8.25, 2.6], "rotation": [15, 0, -20], "uv": [0, 23]},
|
||||
{"origin": [-1.25, 4.75, -0.25], "size": [0, 4, 3], "pivot": [-1.25, 8.25, 2.6], "rotation": [15, 0, 5], "uv": [6, 19], "mirror": true},
|
||||
{"origin": [-2.5, 5, -0.25], "size": [0, 4, 3], "pivot": [-2.5, 8.25, 2.6], "rotation": [15, 0, 20], "uv": [6, 23], "mirror": true},
|
||||
{"origin": [-0.5, 6.71716, -2.67], "size": [1, 1, 1], "inflate": -0.15, "pivot": [0, 7.21716, -2.17], "rotation": [0, 0, 45], "uv": [21, 9]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nose",
|
||||
"parent": "head",
|
||||
"pivot": [0, 10.5, -2.5],
|
||||
"rotation": [12.5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-1, 9.5, -2.51], "size": [2, 2, 1], "pivot": [0, 10.5, -2], "rotation": [0, 0, -45], "uv": [57, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard",
|
||||
"parent": "head",
|
||||
"pivot": [0, 10.5, -2.5],
|
||||
"rotation": [5, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "beard_middle",
|
||||
"parent": "beard",
|
||||
"pivot": [0, 10.5, -2.5],
|
||||
"rotation": [2.5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-3, 10.25, -2.5], "size": [6, 2, 0], "uv": [26, 15]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left",
|
||||
"parent": "beard",
|
||||
"pivot": [2.5, 10.5, -2.5],
|
||||
"rotation": [0, 0, 42.5]
|
||||
},
|
||||
{
|
||||
"name": "beard_left_rotation",
|
||||
"parent": "beard_left",
|
||||
"pivot": [2.5, 10.5, -2.5],
|
||||
"rotation": [5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [2.5, 10, -2.5], "size": [2, 4, 0], "uv": [26, 17]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left2",
|
||||
"parent": "beard_left_rotation",
|
||||
"pivot": [2.5, 14, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [2.5, 14, -2.5], "size": [4, 3, 0], "inflate": 0.01, "uv": [38, 15]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left3",
|
||||
"parent": "beard_left2",
|
||||
"pivot": [6.5, 16, -2.5],
|
||||
"rotation": [0, 0, 5],
|
||||
"cubes": [
|
||||
{"origin": [6.5, 14, -2.5], "size": [6, 4, 0], "inflate": 0.02, "uv": [46, 17]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left4",
|
||||
"parent": "beard_left3",
|
||||
"pivot": [12.5, 18, -2.5],
|
||||
"rotation": [0, 0, 5],
|
||||
"cubes": [
|
||||
{"origin": [12.5, 13, -2.5], "size": [8, 5, 0], "inflate": 0.01, "uv": [36, 21]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right",
|
||||
"parent": "beard",
|
||||
"pivot": [-2.5, 10.5, -2.5],
|
||||
"rotation": [0, 0, -42.5]
|
||||
},
|
||||
{
|
||||
"name": "beard_right_rotation",
|
||||
"parent": "beard_right",
|
||||
"pivot": [-2.5, 10.5, -2.5],
|
||||
"rotation": [5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 10, -2.5], "size": [2, 4, 0], "uv": [30, 17], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right2",
|
||||
"parent": "beard_right_rotation",
|
||||
"pivot": [-2.5, 14, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-6.5, 14, -2.5], "size": [4, 3, 0], "inflate": 0.01, "uv": [34, 18], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right3",
|
||||
"parent": "beard_right2",
|
||||
"pivot": [-6.5, 16, -2.5],
|
||||
"rotation": [0, 0, -5],
|
||||
"cubes": [
|
||||
{"origin": [-12.5, 14, -2.5], "size": [6, 4, 0], "inflate": 0.02, "uv": [52, 21], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right4",
|
||||
"parent": "beard_right3",
|
||||
"pivot": [-12.5, 18, -2.5],
|
||||
"rotation": [0, 0, -5],
|
||||
"cubes": [
|
||||
{"origin": [-20.5, 13, -2.5], "size": [8, 5, 0], "inflate": 0.01, "uv": [36, 26], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eyebrow_left",
|
||||
"parent": "head",
|
||||
"pivot": [1.5, 6.5, -2.52],
|
||||
"rotation": [-2.5, 0, -15],
|
||||
"cubes": [
|
||||
{"origin": [1.5, 1, -2.52], "size": [3, 7, 0], "uv": [57, 3]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eyebrow_right",
|
||||
"parent": "head",
|
||||
"pivot": [-1.5, 6.5, -2.52],
|
||||
"rotation": [-2.5, 0, 15],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 1, -2.52], "size": [3, 7, 0], "uv": [56, 10], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eyes",
|
||||
"parent": "head",
|
||||
"pivot": [0, 9, -2.52]
|
||||
},
|
||||
{
|
||||
"name": "eye_left",
|
||||
"parent": "eyes",
|
||||
"pivot": [2, 9.5, -2.52],
|
||||
"rotation": [0, 0, 10]
|
||||
},
|
||||
{
|
||||
"name": "eye_open_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [2, 9.5, -2.42],
|
||||
"cubes": [
|
||||
{"origin": [1, 8.8, -2.41], "size": [2, 1.4, 0], "inflate": 0.01, "uv": [0, 9]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pupil_left",
|
||||
"parent": "eye_open_left",
|
||||
"pivot": [2, 9.5, -2.43],
|
||||
"cubes": [
|
||||
{"origin": [1.5, 9, -2.43], "size": [1, 1, 0], "pivot": [2, 9.5, -2.43], "rotation": [0, 0, 45], "uv": [0, 11]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eye_closed_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [2, 9.5, -2.52],
|
||||
"cubes": [
|
||||
{"origin": [1, 9, -2.52], "size": [2, 1, 0], "uv": [0, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eye_right",
|
||||
"parent": "eyes",
|
||||
"pivot": [-2, 9.5, -2.52],
|
||||
"rotation": [0, 0, -10]
|
||||
},
|
||||
{
|
||||
"name": "eye_open_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2, 9.5, -2.42],
|
||||
"cubes": [
|
||||
{"origin": [-3, 8.8, -2.41], "size": [2, 1.4, 0], "inflate": 0.01, "uv": [0, 10], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pupil_right",
|
||||
"parent": "eye_open_right",
|
||||
"pivot": [-2, 9.5, -2.43],
|
||||
"cubes": [
|
||||
{"origin": [-2.5, 9, -2.43], "size": [1, 1, 0], "pivot": [-2, 9.5, -2.43], "rotation": [0, 0, -45], "uv": [0, 12], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eye_closed_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2, 9.5, -2.52],
|
||||
"cubes": [
|
||||
{"origin": [-3, 9, -2.52], "size": [2, 1, 0], "uv": [0, 1], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arms",
|
||||
"parent": "body",
|
||||
"pivot": [0, 9.75, -2.5]
|
||||
},
|
||||
{
|
||||
"name": "arm_left",
|
||||
"parent": "arms",
|
||||
"pivot": [4, 9.75, -2.5],
|
||||
"rotation": [0, 5, 0],
|
||||
"cubes": [
|
||||
{"origin": [2.5, 8.25, -2.5], "size": [7, 2, 0], "uv": [43, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_left2",
|
||||
"parent": "arm_left",
|
||||
"pivot": [9.5, 8.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [6.5, 3.25, -2.5], "size": [5, 5, 0], "inflate": 0.01, "uv": [46, 4]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_left3",
|
||||
"parent": "arm_left2",
|
||||
"pivot": [8.5, 3.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [6.5, 0.25, -2.5], "size": [5, 3, 0], "inflate": 0.02, "uv": [46, 9]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_right",
|
||||
"parent": "arms",
|
||||
"pivot": [-4, 9.75, -2.5],
|
||||
"rotation": [0, -5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-9.5, 8.25, -2.5], "size": [7, 2, 0], "uv": [43, 2], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_right2",
|
||||
"parent": "arm_right",
|
||||
"pivot": [-9.5, 8.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-11.5, 3.25, -2.5], "size": [5, 5, 0], "inflate": 0.01, "uv": [36, 10], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_right3",
|
||||
"parent": "arm_right2",
|
||||
"pivot": [-8.5, 3.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-11.5, 0.25, -2.5], "size": [5, 3, 0], "inflate": 0.02, "uv": [46, 12], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ball",
|
||||
"parent": "body2",
|
||||
"pivot": [0, 39, 0]
|
||||
},
|
||||
{
|
||||
"name": "ball_rotation",
|
||||
"parent": "ball",
|
||||
"pivot": [0, 39, 0]
|
||||
},
|
||||
{
|
||||
"name": "ball_inactive",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-10, 29, -10], "size": [20, 20, 0], "inflate": 0.01, "uv": [0, 88]},
|
||||
{"origin": [-10, 29, 10], "size": [20, 20, 0], "inflate": 0.01, "uv": [0, 108]},
|
||||
{"origin": [-10, 49, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [-20, 48]},
|
||||
{"origin": [-10, 29, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [-20, 68]},
|
||||
{"origin": [10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [40, 29]},
|
||||
{"origin": [-10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [40, 49], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ball_active",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-10, 29, -10], "size": [20, 20, 0], "inflate": 0.01, "uv": [108, 40]},
|
||||
{"origin": [-10, 29, 10], "size": [20, 20, 0], "inflate": 0.01, "uv": [108, 60]},
|
||||
{"origin": [-10, 49, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [96, 0]},
|
||||
{"origin": [-10, 29, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [96, 20]},
|
||||
{"origin": [10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [108, 60]},
|
||||
{"origin": [-10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [118, 80], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inner_ball_rotation",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0]
|
||||
},
|
||||
{
|
||||
"name": "inner_ball",
|
||||
"parent": "inner_ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-6, 33, -6], "size": [12, 12, 12], "uv": [0, 24]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inner_ball_active",
|
||||
"parent": "inner_ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-6, 33, -6], "size": [12, 12, 12], "uv": [156, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "grub",
|
||||
"parent": "inner_ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-3.5, 38, -3.5], "size": [7, 3, 7], "uv": [48, 35]},
|
||||
{"origin": [-2.5, 36, -2.5], "size": [5, 2, 5], "uv": [66, 28]},
|
||||
{"origin": [-1.5, 34, -1.5], "size": [3, 2, 3], "uv": [40, 31]},
|
||||
{"origin": [-2.5, 40.75, -2.5], "size": [5, 2, 5], "inflate": 0.1, "uv": [81, 30]},
|
||||
{"origin": [-0.5, 42.25, -0.5], "size": [1, 2, 1], "uv": [82, 30]},
|
||||
{"origin": [0.4, 41.2, -2.61], "size": [2, 1, 0], "pivot": [1.5, 41.75, -2.61], "rotation": [0, 0, 30], "uv": [81, 28]},
|
||||
{"origin": [-2.4, 41.2, -2.61], "size": [2, 1, 0], "pivot": [-1.5, 41.75, -2.61], "rotation": [0, 0, -30], "uv": [81, 29], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ball_cloud",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-13, 26, -6.5], "size": [26, 26, 13], "uv": [40, 89]},
|
||||
{"origin": [-13, 52, -7], "size": [26, 0, 7], "pivot": [0, 52, 0], "rotation": [-12.5, 0, 0], "uv": [57, 0]},
|
||||
{"origin": [-13, 52, 0], "size": [26, 0, 7], "pivot": [0, 52, 0], "rotation": [12.5, 0, 0], "uv": [57, 7]},
|
||||
{"origin": [-13, 26, -7], "size": [26, 0, 7], "pivot": [0, 26, 0], "rotation": [12.5, 0, 0], "uv": [57, 14]},
|
||||
{"origin": [-13, 26, 0], "size": [26, 0, 7], "pivot": [0, 26, 0], "rotation": [-12.5, 0, 0], "uv": [57, 21]},
|
||||
{"origin": [13, 26, -7], "size": [0, 26, 7], "pivot": [13, 39, 0], "rotation": [0, -12.5, 0], "uv": [80, 30]},
|
||||
{"origin": [13, 26, 0], "size": [0, 26, 7], "pivot": [13, 39, 0], "rotation": [0, 12.5, 0], "uv": [94, 30]},
|
||||
{"origin": [-13, 26, -7], "size": [0, 26, 7], "pivot": [-13, 39, 0], "rotation": [0, 12.5, 0], "uv": [80, 56], "mirror": true},
|
||||
{"origin": [-13, 26, 0], "size": [0, 26, 7], "pivot": [-13, 39, 0], "rotation": [0, -12.5, 0], "uv": [94, 56], "mirror": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.rabsca",
|
||||
"texture_width": 256,
|
||||
"texture_height": 128,
|
||||
"visible_bounds_width": 4,
|
||||
"visible_bounds_height": 4.5,
|
||||
"visible_bounds_offset": [0, 1.75, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "rabsca",
|
||||
"pivot": [0, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"parent": "rabsca",
|
||||
"pivot": [0, 10, 0]
|
||||
},
|
||||
{
|
||||
"name": "torso",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8, 0],
|
||||
"cubes": [
|
||||
{"origin": [-4, 10, -2.5], "size": [8, 8, 5], "uv": [0, 9]},
|
||||
{"origin": [-3.5, 10.52, 2.52], "size": [7, 7, 0], "uv": [52, 28]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "legs",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 14, -2.5]
|
||||
},
|
||||
{
|
||||
"name": "leg_left",
|
||||
"parent": "legs",
|
||||
"pivot": [3.5, 14, -2.5],
|
||||
"rotation": [0, 5, 0],
|
||||
"cubes": [
|
||||
{"origin": [2, 13.5, -2.5], "size": [6, 2, 0], "uv": [23, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_left2",
|
||||
"parent": "leg_left",
|
||||
"pivot": [8, 15.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [5, 15.5, -2.5], "size": [4, 5, 0], "inflate": 0.01, "uv": [35, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_left3",
|
||||
"parent": "leg_left2",
|
||||
"pivot": [9, 20.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [4, 20.5, -2.5], "size": [5, 5, 0], "inflate": 0.02, "uv": [26, 10]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_right",
|
||||
"parent": "legs",
|
||||
"pivot": [-3.5, 14, -2.5],
|
||||
"rotation": [0, -5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-8, 13.5, -2.5], "size": [6, 2, 0], "uv": [23, 2], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_right2",
|
||||
"parent": "leg_right",
|
||||
"pivot": [-8, 15.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-9, 15.5, -2.5], "size": [4, 5, 0], "inflate": 0.01, "uv": [28, 5], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leg_right3",
|
||||
"parent": "leg_right2",
|
||||
"pivot": [-9, 20.5, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-9, 20.5, -2.5], "size": [5, 5, 0], "inflate": 0.02, "uv": [36, 5], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "head",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 10.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 6.5, -2.5], "size": [9, 4, 5], "inflate": 0.01, "uv": [0, 0]},
|
||||
{"origin": [1.25, 4.75, -0.25], "size": [0, 4, 3], "pivot": [1.25, 8.25, 2.6], "rotation": [15, 0, -5], "uv": [0, 19]},
|
||||
{"origin": [2.5, 5, -0.25], "size": [0, 4, 3], "pivot": [2.5, 8.25, 2.6], "rotation": [15, 0, -20], "uv": [0, 23]},
|
||||
{"origin": [-1.25, 4.75, -0.25], "size": [0, 4, 3], "pivot": [-1.25, 8.25, 2.6], "rotation": [15, 0, 5], "uv": [6, 19], "mirror": true},
|
||||
{"origin": [-2.5, 5, -0.25], "size": [0, 4, 3], "pivot": [-2.5, 8.25, 2.6], "rotation": [15, 0, 20], "uv": [6, 23], "mirror": true},
|
||||
{"origin": [-0.5, 6.71716, -2.67], "size": [1, 1, 1], "inflate": -0.15, "pivot": [0, 7.21716, -2.17], "rotation": [0, 0, 45], "uv": [21, 9]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nose",
|
||||
"parent": "head",
|
||||
"pivot": [0, 10.5, -2.5],
|
||||
"rotation": [12.5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-1, 9.5, -2.51], "size": [2, 2, 1], "pivot": [0, 10.5, -2], "rotation": [0, 0, -45], "uv": [57, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard",
|
||||
"parent": "head",
|
||||
"pivot": [0, 10.5, -2.5],
|
||||
"rotation": [5, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "beard_middle",
|
||||
"parent": "beard",
|
||||
"pivot": [0, 10.5, -2.5],
|
||||
"rotation": [2.5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-3, 10.25, -2.5], "size": [6, 2, 0], "uv": [26, 15]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left",
|
||||
"parent": "beard",
|
||||
"pivot": [2.5, 10.5, -2.5],
|
||||
"rotation": [0, 0, 42.5]
|
||||
},
|
||||
{
|
||||
"name": "beard_left_rotation",
|
||||
"parent": "beard_left",
|
||||
"pivot": [2.5, 10.5, -2.5],
|
||||
"rotation": [5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [2.5, 10, -2.5], "size": [2, 4, 0], "uv": [26, 17]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left2",
|
||||
"parent": "beard_left_rotation",
|
||||
"pivot": [2.5, 14, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [2.5, 14, -2.5], "size": [4, 3, 0], "inflate": 0.01, "uv": [38, 15]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left3",
|
||||
"parent": "beard_left2",
|
||||
"pivot": [6.5, 16, -2.5],
|
||||
"rotation": [0, 0, 5],
|
||||
"cubes": [
|
||||
{"origin": [6.5, 14, -2.5], "size": [6, 4, 0], "inflate": 0.02, "uv": [46, 17]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_left4",
|
||||
"parent": "beard_left3",
|
||||
"pivot": [12.5, 18, -2.5],
|
||||
"rotation": [0, 0, 5],
|
||||
"cubes": [
|
||||
{"origin": [12.5, 13, -2.5], "size": [8, 5, 0], "inflate": 0.01, "uv": [36, 21]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right",
|
||||
"parent": "beard",
|
||||
"pivot": [-2.5, 10.5, -2.5],
|
||||
"rotation": [0, 0, -42.5]
|
||||
},
|
||||
{
|
||||
"name": "beard_right_rotation",
|
||||
"parent": "beard_right",
|
||||
"pivot": [-2.5, 10.5, -2.5],
|
||||
"rotation": [5, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 10, -2.5], "size": [2, 4, 0], "uv": [30, 17], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right2",
|
||||
"parent": "beard_right_rotation",
|
||||
"pivot": [-2.5, 14, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-6.5, 14, -2.5], "size": [4, 3, 0], "inflate": 0.01, "uv": [34, 18], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right3",
|
||||
"parent": "beard_right2",
|
||||
"pivot": [-6.5, 16, -2.5],
|
||||
"rotation": [0, 0, -5],
|
||||
"cubes": [
|
||||
{"origin": [-12.5, 14, -2.5], "size": [6, 4, 0], "inflate": 0.02, "uv": [52, 21], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "beard_right4",
|
||||
"parent": "beard_right3",
|
||||
"pivot": [-12.5, 18, -2.5],
|
||||
"rotation": [0, 0, -5],
|
||||
"cubes": [
|
||||
{"origin": [-20.5, 13, -2.5], "size": [8, 5, 0], "inflate": 0.01, "uv": [36, 26], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eyebrow_left",
|
||||
"parent": "head",
|
||||
"pivot": [1.5, 6.5, -2.52],
|
||||
"rotation": [-2.5, 0, -15],
|
||||
"cubes": [
|
||||
{"origin": [1.5, 1, -2.52], "size": [3, 7, 0], "uv": [57, 3]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eyebrow_right",
|
||||
"parent": "head",
|
||||
"pivot": [-1.5, 6.5, -2.52],
|
||||
"rotation": [-2.5, 0, 15],
|
||||
"cubes": [
|
||||
{"origin": [-4.5, 1, -2.52], "size": [3, 7, 0], "uv": [56, 10], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eyes",
|
||||
"parent": "head",
|
||||
"pivot": [0, 9, -2.52]
|
||||
},
|
||||
{
|
||||
"name": "eye_left",
|
||||
"parent": "eyes",
|
||||
"pivot": [2, 9.5, -2.52],
|
||||
"rotation": [0, 0, 10]
|
||||
},
|
||||
{
|
||||
"name": "eye_open_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [-2, 9.5, -2.42],
|
||||
"cubes": [
|
||||
{"origin": [1, 8.8, -2.41], "size": [2, 1.4, 0], "inflate": 0.01, "uv": [0, 9]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pupil_left",
|
||||
"parent": "eye_open_left",
|
||||
"pivot": [-2, 9.5, -2.43],
|
||||
"cubes": [
|
||||
{"origin": [1.5, 9, -2.43], "size": [1, 1, 0], "pivot": [2, 9.5, -2.43], "rotation": [0, 0, 45], "uv": [0, 11]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eye_closed_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [-2, 9.5, -2.52],
|
||||
"cubes": [
|
||||
{"origin": [1, 9, -2.52], "size": [2, 1, 0], "uv": [0, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_eye_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [2, 9.5, -2.5],
|
||||
"locators": {
|
||||
"eye2": [2, 9.5, -2.5]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "eye_right",
|
||||
"parent": "eyes",
|
||||
"pivot": [-2, 9.5, -2.52],
|
||||
"rotation": [0, 0, -10]
|
||||
},
|
||||
{
|
||||
"name": "eye_open_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2, 9.5, -2.42],
|
||||
"cubes": [
|
||||
{"origin": [-3, 8.8, -2.41], "size": [2, 1.4, 0], "inflate": 0.01, "uv": [0, 10], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pupil_right",
|
||||
"parent": "eye_open_right",
|
||||
"pivot": [-2, 9.5, -2.43],
|
||||
"cubes": [
|
||||
{"origin": [-2.5, 9, -2.43], "size": [1, 1, 0], "pivot": [-2, 9.5, -2.43], "rotation": [0, 0, -45], "uv": [0, 12], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eye_closed_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2, 9.5, -2.52],
|
||||
"cubes": [
|
||||
{"origin": [-3, 9, -2.52], "size": [2, 1, 0], "uv": [0, 1], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_eye_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2, 9.5, -2.5],
|
||||
"locators": {
|
||||
"eye1": [-2, 9.5, -2.5]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "arms",
|
||||
"parent": "body",
|
||||
"pivot": [0, 9.75, -2.5]
|
||||
},
|
||||
{
|
||||
"name": "arm_left",
|
||||
"parent": "arms",
|
||||
"pivot": [4, 9.75, -2.5],
|
||||
"rotation": [0, 5, 0],
|
||||
"cubes": [
|
||||
{"origin": [2.5, 8.25, -2.5], "size": [7, 2, 0], "uv": [43, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_left2",
|
||||
"parent": "arm_left",
|
||||
"pivot": [9.5, 8.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [6.5, 3.25, -2.5], "size": [5, 5, 0], "inflate": 0.01, "uv": [46, 4]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_left3",
|
||||
"parent": "arm_left2",
|
||||
"pivot": [8.5, 3.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [6.5, 0.25, -2.5], "size": [5, 3, 0], "inflate": 0.02, "uv": [46, 9]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_right",
|
||||
"parent": "arms",
|
||||
"pivot": [-4, 9.75, -2.5],
|
||||
"rotation": [0, -5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-9.5, 8.25, -2.5], "size": [7, 2, 0], "uv": [43, 2], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_right2",
|
||||
"parent": "arm_right",
|
||||
"pivot": [-9.5, 8.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-11.5, 3.25, -2.5], "size": [5, 5, 0], "inflate": 0.01, "uv": [36, 10], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arm_right3",
|
||||
"parent": "arm_right2",
|
||||
"pivot": [-8.5, 3.25, -2.5],
|
||||
"cubes": [
|
||||
{"origin": [-11.5, 0.25, -2.5], "size": [5, 3, 0], "inflate": 0.02, "uv": [46, 12], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ball",
|
||||
"parent": "rabsca",
|
||||
"pivot": [0, 39, 0]
|
||||
},
|
||||
{
|
||||
"name": "ball_rotation",
|
||||
"parent": "ball",
|
||||
"pivot": [0, 39, 0]
|
||||
},
|
||||
{
|
||||
"name": "ball_inactive",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-10, 29, -10], "size": [20, 20, 0], "inflate": 0.01, "uv": [0, 88]},
|
||||
{"origin": [-10, 29, 10], "size": [20, 20, 0], "inflate": 0.01, "uv": [0, 108]},
|
||||
{"origin": [-10, 49, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [-20, 48]},
|
||||
{"origin": [-10, 29, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [-20, 68]},
|
||||
{"origin": [10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [40, 29]},
|
||||
{"origin": [-10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [40, 49], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ball_active",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-10, 29, -10], "size": [20, 20, 0], "inflate": 0.01, "uv": [108, 40]},
|
||||
{"origin": [-10, 29, 10], "size": [20, 20, 0], "inflate": 0.01, "uv": [108, 60]},
|
||||
{"origin": [-10, 49, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [96, 0]},
|
||||
{"origin": [-10, 29, -10], "size": [20, 0, 20], "inflate": 0.01, "uv": [96, 20]},
|
||||
{"origin": [10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [108, 60]},
|
||||
{"origin": [-10, 29, -10], "size": [0, 20, 20], "inflate": 0.01, "uv": [118, 80], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inner_ball_rotation",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0]
|
||||
},
|
||||
{
|
||||
"name": "inner_ball",
|
||||
"parent": "inner_ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-6, 33, -6], "size": [12, 12, 12], "uv": [0, 24]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inner_ball_active",
|
||||
"parent": "inner_ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-6, 33, -6], "size": [12, 12, 12], "uv": [156, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "grub",
|
||||
"parent": "inner_ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-3.5, 38, -3.5], "size": [7, 3, 7], "uv": [48, 35]},
|
||||
{"origin": [-2.5, 36, -2.5], "size": [5, 2, 5], "uv": [66, 28]},
|
||||
{"origin": [-1.5, 34, -1.5], "size": [3, 2, 3], "uv": [40, 31]},
|
||||
{"origin": [-2.5, 40.75, -2.5], "size": [5, 2, 5], "inflate": 0.1, "uv": [81, 30]},
|
||||
{"origin": [-0.5, 42.25, -0.5], "size": [1, 2, 1], "uv": [82, 30]},
|
||||
{"origin": [0.4, 41.2, -2.61], "size": [2, 1, 0], "pivot": [1.5, 41.75, -2.61], "rotation": [0, 0, 30], "uv": [81, 28]},
|
||||
{"origin": [-2.4, 41.2, -2.61], "size": [2, 1, 0], "pivot": [-1.5, 41.75, -2.61], "rotation": [0, 0, -30], "uv": [81, 29], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ball_cloud",
|
||||
"parent": "ball_rotation",
|
||||
"pivot": [0, 39, 0],
|
||||
"cubes": [
|
||||
{"origin": [-13, 26, -6.5], "size": [26, 26, 13], "uv": [40, 89]},
|
||||
{"origin": [-13, 52, -7], "size": [26, 0, 7], "pivot": [0, 52, 0], "rotation": [-12.5, 0, 0], "uv": [57, 0]},
|
||||
{"origin": [-13, 52, 0], "size": [26, 0, 7], "pivot": [0, 52, 0], "rotation": [12.5, 0, 0], "uv": [57, 7]},
|
||||
{"origin": [-13, 26, -7], "size": [26, 0, 7], "pivot": [0, 26, 0], "rotation": [12.5, 0, 0], "uv": [57, 14]},
|
||||
{"origin": [-13, 26, 0], "size": [26, 0, 7], "pivot": [0, 26, 0], "rotation": [-12.5, 0, 0], "uv": [57, 21]},
|
||||
{"origin": [13, 26, -7], "size": [0, 26, 7], "pivot": [13, 39, 0], "rotation": [0, -12.5, 0], "uv": [80, 30]},
|
||||
{"origin": [13, 26, 0], "size": [0, 26, 7], "pivot": [13, 39, 0], "rotation": [0, 12.5, 0], "uv": [94, 30]},
|
||||
{"origin": [-13, 26, -7], "size": [0, 26, 7], "pivot": [-13, 39, 0], "rotation": [0, 12.5, 0], "uv": [80, 56], "mirror": true},
|
||||
{"origin": [-13, 26, 0], "size": [0, 26, 7], "pivot": [-13, 39, 0], "rotation": [0, -12.5, 0], "uv": [94, 56], "mirror": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
-61
@@ -474,67 +474,6 @@
|
||||
"cubes": [
|
||||
{"origin": [27, 10.5, 5], "size": [15, 19, 0], "uv": [223, 39]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 30, -19],
|
||||
"locators": {
|
||||
"seat_1": [0, 30, -19]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_2",
|
||||
"parent": "torso",
|
||||
"pivot": [13, 30, -14],
|
||||
"rotation": [0, -90, 0],
|
||||
"locators": {
|
||||
"seat_2": [13, 30, -14]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_3",
|
||||
"parent": "torso",
|
||||
"pivot": [-13, 30, -14],
|
||||
"rotation": [0, 90, 0],
|
||||
"locators": {
|
||||
"seat_3": [-13, 30, -14]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_4",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 34, -3],
|
||||
"locators": {
|
||||
"seat_4": [0, 34, -3]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_5",
|
||||
"parent": "torso",
|
||||
"pivot": [13, 30, 2],
|
||||
"rotation": [0, -90, 0],
|
||||
"locators": {
|
||||
"seat_5": [13, 30, 2]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_6",
|
||||
"parent": "torso",
|
||||
"pivot": [-13, 30, 2],
|
||||
"rotation": [0, 90, 0],
|
||||
"locators": {
|
||||
"seat_6": [-13, 30, 2]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_7",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 33, 7],
|
||||
"rotation": [0, 180, 0],
|
||||
"locators": {
|
||||
"seat_7": [0, 33, 7]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
-8
@@ -620,14 +620,6 @@
|
||||
{"origin": [-4.98, 15.25, 20.99], "size": [0, 2, 2], "inflate": 0.01, "uv": [93, 70], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "torso_back",
|
||||
"pivot": [0, 11, 14],
|
||||
"locators": {
|
||||
"seat_1": [0, 11, 14]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "legs",
|
||||
"parent": "body",
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@
|
||||
"portraitScale": 1.03,
|
||||
"portraitTranslation": [-0.31, 0.12, 0],
|
||||
"profileScale": 0.47,
|
||||
"profileTranslation": [0.07, 0.98, 0.0],
|
||||
"profilePokedexTranslation": [0, 0.98, 0],
|
||||
"profileTranslation": [0, 0.98, 0.0],
|
||||
"rootBone": "venusaur",
|
||||
"firstPersonCameraOffset": {
|
||||
"seat_1": [0, 0.25, 0]
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"portraitScale": 1.89,
|
||||
"portraitTranslation": [-0.13, 0.91, 0],
|
||||
"profileScale": 0.77,
|
||||
"profileTranslation": [0, 0.65, 0],
|
||||
"profileScale": 0.63,
|
||||
"profileTranslation": [0, 0.81, 0],
|
||||
"rootBone": "charmeleon",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('charmeleon', 'cry')"
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"portraitScale": 2.1,
|
||||
"portraitTranslation": [-1.11, 2.43, 0],
|
||||
"profileScale": 0.54,
|
||||
"profileTranslation": [0, 0.92, -10],
|
||||
"profileTranslation": [0, 0.96, -10],
|
||||
"rootBone": "charizard",
|
||||
"firstPersonCameraOffset": {
|
||||
"seat_1": [0, 0.45, 0]
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"portraitScale": 1.89,
|
||||
"portraitTranslation": [-0.8, 1.36, 0.0],
|
||||
"profileScale": 0.57,
|
||||
"profileTranslation": [0, 0.81, 0.0],
|
||||
"profileScale": 0.59,
|
||||
"profileTranslation": [0, 0.84, 0.0],
|
||||
"rootBone": "nidoking",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('nidoking', 'cry')",
|
||||
|
||||
Loaded 100 of 199 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user