mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-11-02 06:19:55 -05:00
Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f01ea8343f | ||
|
|
51976262d3 | ||
|
|
211232a81f | ||
|
|
e6352acb61 | ||
|
|
766b101722 | ||
|
|
34adb0d7a0 | ||
|
|
562418e324 | ||
|
|
016db10de7 | ||
|
|
61d01d3731 | ||
|
|
0319ac9a87 | ||
|
|
a5aea7a75f | ||
|
|
058c06f56b | ||
|
|
28bee4189a | ||
|
|
3f0e21b6b3 | ||
|
|
9ca2d47562 | ||
|
|
94f0914aa8 | ||
|
|
60101876b5 | ||
|
|
b8a4dfbcb4 | ||
|
|
fbc5959c67 | ||
|
|
49f20fe1a4 | ||
|
|
3c4288d7fc | ||
|
|
e03bb51a74 | ||
|
|
8545de321f | ||
|
|
5e353e9a6d | ||
|
|
c1fd257f63 | ||
|
|
ea0ff3bfb9 | ||
|
|
d4b6e36aab | ||
|
|
0fb721702d | ||
|
|
0e5053b787 | ||
|
|
f3867e0b1d | ||
|
|
f785c5405f | ||
|
|
2dfca3ff89 |
No files matched your search
@@ -396,6 +396,7 @@
|
||||
- Fixed `/giveallpokemon` not respecting the min and max parameters
|
||||
- Fixed the choose starter toast not disappearing when capturing a Pokémon instead of opening the starter selection screen
|
||||
- Fixed an issue where certain Sinister Tea seasonings were only applying as instant effects and would not apply over time
|
||||
- Long config option labels now scroll instead of overflowing
|
||||
|
||||
### Developer
|
||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
||||
|
||||
@@ -32,6 +32,6 @@ final class ParticleManagerMixin {
|
||||
@Inject(at = @At("RETURN"), method = "<clinit>")
|
||||
private static void lodestone$addTypes(CallbackInfo ci) {
|
||||
RENDER_ORDER = ImmutableList.<ParticleRenderType>builder().addAll(RENDER_ORDER)
|
||||
.add(ParticleMaterials.INSTANCE.getXRAY(), ParticleMaterials.INSTANCE.getADD(), ParticleMaterials.INSTANCE.getALPHA(), ParticleMaterials.INSTANCE.getBLEND(), ParticleMaterials.INSTANCE.getOPAQUE()).build();
|
||||
.add(ParticleMaterials.INSTANCE.getADD(), ParticleMaterials.INSTANCE.getALPHA(), ParticleMaterials.INSTANCE.getBLEND(), ParticleMaterials.INSTANCE.getOPAQUE()).build();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ 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;
|
||||
@@ -68,39 +67,6 @@ 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(
|
||||
|
||||
@@ -24,13 +24,27 @@ 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.*
|
||||
import com.cobblemon.mod.common.client.net.gui.*
|
||||
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.gui.SynchronizeActiveTMHandler
|
||||
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.*
|
||||
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.pokedex.ServerConfirmedRegisterHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundSeatAssignmentPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
|
||||
@@ -49,7 +63,14 @@ 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.*
|
||||
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.net.PacketRegisterInfo
|
||||
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
|
||||
@@ -65,13 +86,21 @@ 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.*
|
||||
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.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.*
|
||||
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.pokedex.ServerConfirmedRegisterPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
||||
@@ -92,17 +121,47 @@ 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.*
|
||||
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.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.*
|
||||
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.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.client.ui.SynchronizeActiveTMPacket
|
||||
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.server.behaviour.DamageOnCollisionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
||||
@@ -129,7 +188,11 @@ 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.*
|
||||
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.evolution.AcceptEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
|
||||
@@ -142,12 +205,21 @@ 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.*
|
||||
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.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.UsePokeSkillHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.*
|
||||
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.behaviour.DamageOnCollisionPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
|
||||
@@ -175,7 +247,11 @@ 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.*
|
||||
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.riding.DismountPokemonPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.DriverInputPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.ServerboundUpdatePassengerPositionHandler
|
||||
@@ -191,7 +267,12 @@ 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.*
|
||||
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.util.server
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
@@ -261,7 +342,6 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideStaminaUpdatePacket.ID, RideStaminaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(SkillCooldownsUpdatePacket.ID, SkillCooldownsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(AlphaUpdatePacket.ID, AlphaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(ScaleModifierUpdatePacket.ID, ScaleModifierUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
|
||||
@@ -363,7 +443,6 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideSettingsSyncPacket.ID, RideSettingsSyncPacket::decode, RideSettingsSyncHandler))
|
||||
list.add(PacketRegisterInfo(PokeSkillsRegistrySyncPacket.ID, PokeSkillsRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(TechnicalMachineRegistrySyncPacket.ID, TechnicalMachineRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
// Effects
|
||||
@@ -456,7 +535,6 @@ 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))
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.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.pokeskills.PokeSkill
|
||||
import com.cobblemon.mod.common.entity.pokemon.pokeskills.PokeSkillTier
|
||||
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 getAccessiblePokeSkillTiers(player: Player, pokemon: Pokemon): List<PokeSkillTier> {
|
||||
return skills.values.mapNotNull { skill ->
|
||||
skill.tiers.lastOrNull { tier ->
|
||||
tier.canAccess(player, pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokeSkill>) {
|
||||
data.forEach { (id, skill) -> skill.id = id }
|
||||
|
||||
skills = data
|
||||
skills.values.forEach { skill ->
|
||||
skill.tiers.forEachIndexed { index, tier ->
|
||||
tier.initialize(skill, index + 1)
|
||||
}
|
||||
}
|
||||
|
||||
observable.emit(this)
|
||||
|
||||
val tiersCount = skills.values.sumOf { it.tiers.size }
|
||||
Cobblemon.LOGGER.info("Loaded ${skills.size} PokéSkills with $tiersCount tiers")
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
player.sendPacket(PokeSkillsRegistrySyncPacket(skills.values.toList()))
|
||||
}
|
||||
}
|
||||
@@ -286,15 +286,6 @@ object MoLangFunctions {
|
||||
}
|
||||
}
|
||||
|
||||
fun Any.asMostSpecificMoLangValue(): MoValue {
|
||||
return when (this) {
|
||||
is Number -> DoubleValue(this.toDouble())
|
||||
is String -> StringValue(this)
|
||||
is Boolean -> DoubleValue(if (this) 1.0 else 0.0)
|
||||
else -> StringValue(toString())
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Holder<T>.asMoLangValue(key: ResourceKey<Registry<T>>): ObjectValue<Holder<T>> {
|
||||
val value = ObjectValue(
|
||||
obj = this,
|
||||
@@ -302,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(value.obj.`is`(tag))
|
||||
return@put DoubleValue(if (value.obj.`is`(tag)) 1.0 else 0.0)
|
||||
}
|
||||
value.functions["is_of"] = Function put@{ params: MoParams ->
|
||||
val identifier = ResourceLocation.parse(params.getString(0))
|
||||
return@put DoubleValue(value.obj.`is`(identifier))
|
||||
return@put DoubleValue(if (value.obj.`is`(identifier)) 1.0 else 0.0)
|
||||
}
|
||||
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(drop.canDrop(pokemon))
|
||||
DoubleValue(if (drop.canDrop(pokemon)) 1.0 else 0.0)
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
+40
-83
@@ -25,8 +25,22 @@ import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.core.BlockPos
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.asResource
|
||||
import com.cobblemon.mod.common.util.asUUID
|
||||
import com.cobblemon.mod.common.util.cloneFrom
|
||||
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.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.registries.Registries
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
@@ -34,13 +48,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.*
|
||||
import java.util.UUID
|
||||
import kotlin.math.sqrt
|
||||
|
||||
object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
@@ -67,13 +78,8 @@ 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) },
|
||||
@@ -115,62 +121,6 @@ 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())
|
||||
@@ -202,14 +152,12 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
StringValue(it)
|
||||
} ?: DoubleValue.ZERO
|
||||
},
|
||||
"find_nearby_blocks" to { params ->
|
||||
"find_nearby_block" to findNearbyBlock@{ params ->
|
||||
val input = params.getString(0)
|
||||
val isTag = input.contains("#")
|
||||
val type = input.replace("#", "").asIdentifierDefaultingNamespace(namespace = "minecraft")
|
||||
|
||||
val range = params.getDoubleOrNull(1) ?: 10
|
||||
|
||||
val blockPosList = thisEntity.level().getBlockStatesWithPos(
|
||||
val blockPos = thisEntity.level().getBlockStatesWithPos(
|
||||
AABB.ofSize(
|
||||
thisEntity.position(),
|
||||
range.toDouble(),
|
||||
@@ -217,19 +165,28 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
range.toDouble()
|
||||
)
|
||||
)
|
||||
.filter { blockPosPair ->
|
||||
blockPosPair.first.blockHolder.let {
|
||||
if (isTag) it.`is`(
|
||||
TagKey.create(
|
||||
Registries.BLOCK,
|
||||
type
|
||||
)
|
||||
) else it.`is`(type)
|
||||
.filter { blockPosPair ->
|
||||
blockPosPair.first.blockHolder.let {
|
||||
if (isTag) it.`is`(
|
||||
TagKey.create(
|
||||
Registries.BLOCK,
|
||||
type
|
||||
)
|
||||
) else it.`is`(type)
|
||||
}
|
||||
}
|
||||
.minByOrNull { it.second.distSqr(thisEntity.blockPosition()) }
|
||||
?.second
|
||||
if (blockPos != null) {
|
||||
return@findNearbyBlock ArrayStruct(
|
||||
mapOf(
|
||||
"0" to DoubleValue(blockPos.x),
|
||||
"1" to DoubleValue(blockPos.y),
|
||||
"2" to DoubleValue(blockPos.z)
|
||||
)
|
||||
)
|
||||
}
|
||||
.map { blockPosPair -> blockPosPair.second }
|
||||
|
||||
blockPosList.map { it.toArrayStruct() }.asArrayValue()
|
||||
return@findNearbyBlock DoubleValue.ZERO
|
||||
},
|
||||
"get_nearby_entities" to { params ->
|
||||
val distance = params.getDouble(0)
|
||||
@@ -276,7 +233,7 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
val intangible = params.getBooleanOrNull(0) ?: true
|
||||
thisEntity.noPhysics = intangible
|
||||
DoubleValue.ONE
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
-18
@@ -39,7 +39,6 @@ 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
|
||||
@@ -124,23 +123,6 @@ 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
@@ -25,7 +25,6 @@ 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
|
||||
@@ -35,7 +34,6 @@ 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
|
||||
@@ -48,20 +46,15 @@ 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 com.cobblemon.mod.common.util.tmList
|
||||
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>() {
|
||||
@@ -406,61 +399,6 @@ 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
|
||||
|
||||
-28
@@ -15,7 +15,6 @@ 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
|
||||
@@ -27,9 +26,6 @@ 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
|
||||
@@ -451,30 +447,6 @@ 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)
|
||||
}
|
||||
// TODO remove this or figure a way to determine which tier of the pokeskill is being used
|
||||
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 ?: 0)
|
||||
return@put DoubleValue.ONE
|
||||
}
|
||||
|
||||
map["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||
map["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
|
||||
|
||||
+2
-23
@@ -40,7 +40,6 @@ 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
|
||||
@@ -62,26 +61,6 @@ 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
|
||||
@@ -149,13 +128,13 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
|
||||
val x = params.getDouble(0)
|
||||
val y = params.getDouble(1)
|
||||
val z = params.getDouble(2)
|
||||
val range = params.getDoubleOrNull(3) ?: 8.0
|
||||
val range = params.getDouble(3).toFloat()
|
||||
world.explode(
|
||||
null,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
range.toFloat(),
|
||||
range,
|
||||
ExplosionInteraction.valueOf(
|
||||
params.getStringOrNull(4)?.uppercase() ?: ExplosionInteraction.TNT.name
|
||||
)
|
||||
|
||||
+1
-2
@@ -50,7 +50,7 @@ class ActionEffectTimeline(
|
||||
}
|
||||
|
||||
fun chainKeyframes(context: ActionEffectContext, iterator: Iterator<ActionEffectKeyframe>, finalFuture: CompletableFuture<Unit>) {
|
||||
if (!iterator.hasNext() || context.cancelled) {
|
||||
if (!iterator.hasNext()) {
|
||||
finalFuture.complete(Unit)
|
||||
} else {
|
||||
val keyframe = iterator.next()
|
||||
@@ -70,7 +70,6 @@ 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
|
||||
) {
|
||||
|
||||
@@ -48,8 +48,6 @@ object ActionEffects : JsonDataRegistry<ActionEffectTimeline> {
|
||||
ActionEffectKeyframe.register<CannotInterruptActionEffectKeyframe>("cannot_interrupt")
|
||||
ActionEffectKeyframe.register<RemoveHoldsActionEffectKeyframe>("remove_holds")
|
||||
ActionEffectKeyframe.register<AddHoldsActionEffectKeyframe>("add_holds")
|
||||
ActionEffectKeyframe.register<PauseTasksActionEffectKeyframe>("pause_tasks")
|
||||
ActionEffectKeyframe.register<ResumeTasksActionEffectKeyframe>("resume_tasks")
|
||||
ActionEffectKeyframe.register<MoveToTargetActionEffectKeyframe>("move_to_target")
|
||||
ActionEffectKeyframe.register<ReturnToPositionActionEffectKeyframe>("return_to_position")
|
||||
ActionEffectKeyframe.register<PauseActionEffectKeyframe>("pause")
|
||||
@@ -59,7 +57,6 @@ 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
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.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)
|
||||
}
|
||||
}
|
||||
+6
-28
@@ -21,7 +21,6 @@ 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.
|
||||
@@ -66,36 +65,15 @@ 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 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()) {
|
||||
if (targetLocators == null) {
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators)
|
||||
packet.sendToPlayers(players)
|
||||
}
|
||||
else {
|
||||
targetEntities.forEach { targetEntity ->
|
||||
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)
|
||||
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locators, targetEntity.id, targetLocators!!.toList())
|
||||
packet.sendToPlayers(players)
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -8,6 +8,8 @@
|
||||
|
||||
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
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.moves.animations.keyframes
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonActivities
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.moves.animations.EntityProvider
|
||||
import com.cobblemon.mod.common.api.moves.animations.NPCProvider
|
||||
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class PauseTasksActionEffectKeyframe : ActionEffectKeyframe {
|
||||
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
|
||||
val entities = context.providers
|
||||
.filterIsInstance<EntityProvider>()
|
||||
.filter { it is UsersProvider || it is NPCProvider }
|
||||
.flatMap { it.entities }
|
||||
|
||||
for (entity in entities) {
|
||||
if (entity is LivingEntity) {
|
||||
entity.brain.setActiveActivityIfPossible(CobblemonActivities.ACTION_EFFECT)
|
||||
}
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(Unit)
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.moves.animations.keyframes
|
||||
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.moves.animations.EntityProvider
|
||||
import com.cobblemon.mod.common.api.moves.animations.NPCProvider
|
||||
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class ResumeTasksActionEffectKeyframe : ActionEffectKeyframe {
|
||||
override fun play(context: ActionEffectContext): CompletableFuture<Unit> {
|
||||
val entities = context.providers
|
||||
.filterIsInstance<EntityProvider>()
|
||||
.filter { it is UsersProvider || it is NPCProvider }
|
||||
.flatMap { it.entities }
|
||||
|
||||
for (entity in entities) {
|
||||
if (entity is LivingEntity) {
|
||||
val level = entity.level()
|
||||
entity.brain.updateActivityFromSchedule(level.dayTime, level.gameTime)
|
||||
}
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(Unit)
|
||||
}
|
||||
}
|
||||
+2
-25
@@ -8,8 +8,6 @@
|
||||
|
||||
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
|
||||
@@ -20,37 +18,16 @@ 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> {
|
||||
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()
|
||||
}
|
||||
return if (actionEffect != null) {
|
||||
ActionEffects.actionEffects[actionEffect]?.run(context)?.takeIf { waitForActionEffect } ?: 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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,5 @@ enum class ParticleMaterial {
|
||||
ALPHA,
|
||||
OPAQUE,
|
||||
BLEND,
|
||||
ADD,
|
||||
XRAY,
|
||||
ADD
|
||||
}
|
||||
@@ -24,7 +24,6 @@ object ParticleMaterials {
|
||||
override fun begin(tessellator: Tesselator, textureManager: TextureManager): BufferBuilder {
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.enableCull()
|
||||
RenderSystem.enableDepthTest()
|
||||
RenderSystem.depthMask(true)
|
||||
RenderSystem.setShader { GameRenderer.getParticleShader() }
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES)
|
||||
@@ -39,7 +38,6 @@ object ParticleMaterials {
|
||||
override fun begin(tessellator: Tesselator, textureManager: TextureManager): BufferBuilder {
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.disableCull()
|
||||
RenderSystem.enableDepthTest()
|
||||
RenderSystem.depthMask(true)
|
||||
RenderSystem.setShader { GameRenderer.getParticleShader() }
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES)
|
||||
@@ -54,7 +52,6 @@ object ParticleMaterials {
|
||||
override fun begin(tessellator: Tesselator, textureManager: TextureManager): BufferBuilder {
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.disableCull()
|
||||
RenderSystem.enableDepthTest()
|
||||
RenderSystem.depthMask(true)
|
||||
RenderSystem.setShader { GameRenderer.getParticleShader() }
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES)
|
||||
@@ -69,7 +66,6 @@ object ParticleMaterials {
|
||||
override fun begin(tessellator: Tesselator, textureManager: TextureManager): BufferBuilder {
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.enableCull()
|
||||
RenderSystem.enableDepthTest()
|
||||
RenderSystem.depthMask(true)
|
||||
RenderSystem.setShader { GameRenderer.getParticleShader() }
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES)
|
||||
@@ -77,21 +73,6 @@ object ParticleMaterials {
|
||||
return tessellator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE)
|
||||
}
|
||||
|
||||
override fun toString() = "OPAQUE"
|
||||
}
|
||||
|
||||
val XRAY = object : ParticleRenderType {
|
||||
override fun begin(tessellator: Tesselator, textureManager: TextureManager): BufferBuilder {
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.disableCull()
|
||||
RenderSystem.disableDepthTest()
|
||||
RenderSystem.depthMask(false)
|
||||
RenderSystem.setShader { GameRenderer.getParticleShader() }
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES)
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA)
|
||||
return tessellator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE)
|
||||
}
|
||||
|
||||
override fun toString() = "XRAY"
|
||||
override fun toString() = "OPAQUE"
|
||||
}
|
||||
}
|
||||
+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) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.minecraft.world.level.block.SoundType
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.entity.CommandBlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
@@ -80,11 +81,13 @@ class HabitatBlock(properties: Properties) : Block(properties), EntityBlock {
|
||||
}
|
||||
|
||||
override fun useWithoutItem(state: BlockState, level: Level, pos: BlockPos, player: Player, hitResult: BlockHitResult): InteractionResult {
|
||||
if (!level.isClientSide) {
|
||||
val be = level.getBlockEntity(pos) as? HabitatBlockEntity ?: return InteractionResult.PASS
|
||||
return be.onUse(player, hitResult)
|
||||
val blockEntity = level.getBlockEntity(pos)
|
||||
val be = level.getBlockEntity(pos) as? HabitatBlockEntity ?: return InteractionResult.PASS
|
||||
return if (blockEntity is HabitatBlockEntity && player.canUseGameMasterBlocks()) {
|
||||
be.onUse(player, hitResult)
|
||||
} else {
|
||||
InteractionResult.PASS
|
||||
}
|
||||
return InteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun getDrops(state: BlockState, params: LootParams.Builder): MutableList<ItemStack> {
|
||||
|
||||
@@ -179,8 +179,6 @@ 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)
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ class CobblemonConfigScreen(
|
||||
const val WIDGET_HEIGHT = SLOT_HEIGHT - PADDING
|
||||
const val LABEL_Y_OFFSET = 4
|
||||
const val WIDGET_Y_OFFSET = 0
|
||||
const val LABEL_MAX_WIDTH = SLOT_WIDTH - RESET_SLOT_WIDTH - WIDGET_WIDTH - PADDING * 2
|
||||
}
|
||||
|
||||
val clonedConfig = Cobblemon.config.clone()
|
||||
|
||||
+12
-8
@@ -8,17 +8,18 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.config.variable
|
||||
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.LABEL_Y_OFFSET
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.LABEL_MAX_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.RESET_SLOT_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.SLOT_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.WIDGET_HEIGHT
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.WIDGET_Y_OFFSET
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigVariableList
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigVariableList.CobblemonConfigVariableListEntry
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.drawScrollingText
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
import com.cobblemon.mod.common.config.CobblemonConfigField
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.gui.components.Tooltip
|
||||
@@ -91,12 +92,15 @@ abstract class CobblemonConfigVariable(
|
||||
val x = getX(left)
|
||||
val y = getY(top)
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = labelLang,
|
||||
x = getX(left),
|
||||
y = getY(top) + LABEL_Y_OFFSET,
|
||||
shadow = true
|
||||
drawScrollingText(
|
||||
context,
|
||||
Minecraft.getInstance().font,
|
||||
labelLang,
|
||||
x,
|
||||
y + WIDGET_Y_OFFSET,
|
||||
x + LABEL_MAX_WIDTH,
|
||||
y + WIDGET_Y_OFFSET + WIDGET_HEIGHT,
|
||||
-1
|
||||
)
|
||||
|
||||
resetButton.x = x + SLOT_WIDTH - RESET_SLOT_WIDTH
|
||||
|
||||
+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
|
||||
|
||||
open class InteractWheelGUI(private val options: Multimap<Orientation, InteractWheelOption>, title: Component) : Screen(title), CobblemonRenderable {
|
||||
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 @@ open class InteractWheelGUI(private val options: Multimap<Orientation, InteractW
|
||||
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||
}
|
||||
|
||||
protected val buttons = mutableListOf<InteractWheelButton>()
|
||||
private val buttons = mutableListOf<InteractWheelButton>()
|
||||
private var maxPage = 1
|
||||
private var currentPage = 0
|
||||
override fun renderBlurredBackground(delta: Float) { }
|
||||
@@ -104,7 +104,7 @@ open class InteractWheelGUI(private val options: Multimap<Orientation, InteractW
|
||||
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)}
|
||||
|
||||
+4
-71
@@ -9,25 +9,20 @@
|
||||
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.asTranslated
|
||||
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
|
||||
|
||||
@@ -35,7 +30,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()
|
||||
@@ -46,7 +41,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()
|
||||
@@ -57,7 +52,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()
|
||||
@@ -69,7 +64,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()
|
||||
@@ -182,68 +177,6 @@ fun createPlayerInteractGui(optionsPacket: PlayerInteractOptionsPacket): Interac
|
||||
return InteractWheelGUI(options, Component.translatable("cobblemon.ui.interact.player"))
|
||||
}
|
||||
|
||||
fun createPokeSkillGui(player: AbstractClientPlayer, pokemon: Pokemon): InteractWheelGUI {
|
||||
val accessibleSkills = CobblemonPokeSkills.getAccessiblePokeSkillTiers(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.asTranslated().string} ${getRomanNumeral(skill.tier)}",
|
||||
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 getRomanNumeral(number: Int): String {
|
||||
if (number <= 0) return number.toString()
|
||||
|
||||
val numerals = listOf(
|
||||
1000 to "M",
|
||||
900 to "CM",
|
||||
500 to "D",
|
||||
400 to "CD",
|
||||
100 to "C",
|
||||
90 to "XC",
|
||||
50 to "L",
|
||||
40 to "XL",
|
||||
10 to "X",
|
||||
9 to "IX",
|
||||
5 to "V",
|
||||
4 to "IV",
|
||||
1 to "I"
|
||||
)
|
||||
|
||||
var remaining = number
|
||||
val result = StringBuilder()
|
||||
|
||||
for ((value, numeral) in numerals) {
|
||||
while (remaining >= value) {
|
||||
result.append(numeral)
|
||||
remaining -= value
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
private fun getLangKey(status: PlayerInteractOptionsPacket.OptionStatus) : String {
|
||||
return when (status) {
|
||||
PlayerInteractOptionsPacket.OptionStatus.TOO_FAR -> "cobblemon.ui.interact.too_far"
|
||||
|
||||
+2
-2
@@ -12,9 +12,9 @@ import net.minecraft.resources.ResourceLocation
|
||||
import org.joml.Vector3f
|
||||
|
||||
data class InteractWheelOption(
|
||||
val iconResource: ResourceLocation? = null,
|
||||
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
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.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)
|
||||
}
|
||||
|
||||
}
|
||||
+21
-11
@@ -15,7 +15,6 @@ 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
|
||||
@@ -27,12 +26,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",
|
||||
@@ -40,17 +39,32 @@ 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
|
||||
@@ -91,8 +105,7 @@ 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 {
|
||||
@@ -114,13 +127,10 @@ 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-13
@@ -19,7 +19,6 @@ 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) {
|
||||
@@ -32,7 +31,6 @@ 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 ->
|
||||
@@ -42,16 +40,6 @@ 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,
|
||||
@@ -61,7 +49,7 @@ object SpawnSnowstormEntityParticleHandler : ClientNetworkPacketHandler<SpawnSno
|
||||
sourceVelocity = { sourceEntity.deltaMovement },
|
||||
sourceAlive = { !sourceEntity.isRemoved },
|
||||
sourceVisible = { !sourceEntity.isInvisible },
|
||||
targetPos = targetPos,
|
||||
targetPos = if (targetedEntity != null) { { targetedLocator?.let { targetState?.locatorStates?.get(it) }?.getOrigin() ?: targetedEntity.position() } } else null,
|
||||
entity = sourceEntity
|
||||
)
|
||||
|
||||
|
||||
@@ -18,17 +18,23 @@ import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.Font
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun renderScaledGuiItemIcon(itemStack: ItemStack, x: Double, y: Double, scale: Double = 1.0, zTranslation: Float = 100.0F, matrixStack: PoseStack? = null) {
|
||||
val itemRenderer = Minecraft.getInstance().itemRenderer
|
||||
@@ -97,6 +103,55 @@ fun getDepletableRedGreen(
|
||||
return r.toFloat() to g.toFloat()
|
||||
}
|
||||
|
||||
fun drawScrollingText(
|
||||
context: GuiGraphics,
|
||||
font: Font,
|
||||
text: Component,
|
||||
minX: Int,
|
||||
minY: Int,
|
||||
maxX: Int,
|
||||
maxY: Int,
|
||||
colour: Int,
|
||||
minScrollVelocity: Double? = 10.0
|
||||
) {
|
||||
val textWidth = font.width(text)
|
||||
val fittedMaxX = if (textWidth <= maxX - minX) minX + textWidth else maxX
|
||||
renderScrollingString(context, font, text, minX, minY, fittedMaxX, maxY, colour, minScrollVelocity)
|
||||
}
|
||||
|
||||
/** Copied from [net.minecraft.client.gui.components.AbstractWidget.renderScrollingString] **/
|
||||
fun renderScrollingString(
|
||||
context: GuiGraphics,
|
||||
font: Font,
|
||||
text: Component,
|
||||
minX: Int,
|
||||
minY: Int,
|
||||
maxX: Int,
|
||||
maxY: Int,
|
||||
colour: Int,
|
||||
minScrollVelocity: Double? = 10.0
|
||||
) {
|
||||
val textWidth = font.width(text)
|
||||
val centerY = (minY + maxY - 9) / 2 + 1
|
||||
val boxWidth = maxX - minX
|
||||
if (textWidth <= boxWidth) {
|
||||
val centerX = Mth.clamp((minX + maxX) / 2, minX + textWidth / 2, maxX - textWidth / 2)
|
||||
context.drawCenteredString(font, text, centerX, centerY, colour)
|
||||
return
|
||||
}
|
||||
|
||||
val overflow = textWidth - boxWidth
|
||||
var period = (overflow * 0.5).coerceAtLeast(3.0)
|
||||
if (minScrollVelocity != null) {
|
||||
period = period.coerceAtMost(2 * overflow / minScrollVelocity)
|
||||
}
|
||||
val time = Util.getMillis() / 1000.0
|
||||
val easedProgress = sin((Math.PI / 2) * cos(2 * Math.PI * time / period)) / 2.0 + 0.5
|
||||
val offset = Mth.lerp(easedProgress, 0.0, overflow.toDouble())
|
||||
context.enableScissor(minX, minY, maxX, maxY)
|
||||
context.drawString(font, text, minX - offset.toInt(), centerY, colour)
|
||||
context.disableScissor()
|
||||
}
|
||||
|
||||
fun drawScaledText(
|
||||
context: GuiGraphics,
|
||||
|
||||
@@ -124,7 +124,6 @@ class SnowstormParticle(
|
||||
ParticleMaterial.OPAQUE -> ParticleMaterials.OPAQUE
|
||||
ParticleMaterial.BLEND -> ParticleMaterials.BLEND
|
||||
ParticleMaterial.ADD -> ParticleMaterials.ADD
|
||||
ParticleMaterial.XRAY -> ParticleMaterials.XRAY
|
||||
}
|
||||
}
|
||||
storm.effect.particle.creationEvents.forEach { it.trigger(storm, this) }
|
||||
|
||||
-127
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
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.util.isBattling
|
||||
import com.cobblemon.mod.common.util.isUnderWater
|
||||
import com.cobblemon.mod.common.util.isInWater
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class ChinchouModel (root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("chinchou")
|
||||
|
||||
override var portraitScale = 1.75F
|
||||
override var portraitTranslation = Vec3(-0.3, -0.8, 0.0)
|
||||
|
||||
override var profileScale = 0.65F
|
||||
override var profileTranslation = Vec3(-0.05, 0.45, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var floating: CobblemonPose
|
||||
lateinit var swimming: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var watersleep: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var waterbattleidle: CobblemonPose
|
||||
|
||||
// override val cryAnimation = CryProvider { bedrockStateful("chinchou", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("chinchou", "blink")}
|
||||
val idleQuirk = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("chinchou", "ground_quirk")}
|
||||
val waterQuirk = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("chinchou", "water_idle_quirk")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleeping",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { !it.isInWater },
|
||||
animations = arrayOf(bedrock("chinchou", "sleep"))
|
||||
)
|
||||
|
||||
watersleep = registerPose(
|
||||
poseName = "water_sleeping",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { it.isInWater },
|
||||
animations = arrayOf(bedrock("chinchou", "water_sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.UI_POSES + PoseType.STAND,
|
||||
transformTicks = 10,
|
||||
condition = { !it.isBattling && !it.isInWater && !it.isUnderWater},
|
||||
quirks = arrayOf(blink, idleQuirk),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
transformTicks = 10,
|
||||
poseType = PoseType.WALK,
|
||||
condition = { !it.isInWater && !it.isUnderWater},
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
floating = registerPose(
|
||||
poseName = "floating",
|
||||
transformTicks = 10,
|
||||
poseType = PoseType.FLOAT,
|
||||
condition = { it.isInWater },
|
||||
quirks = arrayOf(blink, waterQuirk),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swimming = registerPose(
|
||||
poseName = "swimming",
|
||||
transformTicks = 10,
|
||||
condition = { it.isInWater },
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "water_swim"),
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling && !it.isInWater },
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "battle_idle")
|
||||
)
|
||||
)
|
||||
|
||||
waterbattleidle = registerPose(
|
||||
poseName = "water_battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling && it.isInWater },
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "water_battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, battleidle, sleep)) bedrockStateful("chinchou", "faint") else if (state.isPosedIn( waterbattleidle, watersleep, floating, swimming )) bedrockStateful("chinchou", "water_faint") else null
|
||||
}
|
||||
-1
@@ -368,7 +368,6 @@ object VaryingModelRepository {
|
||||
inbuilt("magcargo", ::MagcargoModel)
|
||||
inbuilt("slugma_shiny", ::SlugmaShinyModel)
|
||||
inbuilt("magcargo_shiny", ::MagcargoShinyModel)
|
||||
inbuilt("chinchou", ::ChinchouModel)
|
||||
inbuilt("clamperl", ::ClamperlModel)
|
||||
inbuilt("huntail", ::HuntailModel)
|
||||
inbuilt("gorebyss", ::GorebyssModel)
|
||||
|
||||
+32
@@ -219,4 +219,36 @@ fun generateAdditionalRideBoostsTooltip(stack: ItemStack): MutableList<Component
|
||||
}
|
||||
|
||||
return resultLines
|
||||
}
|
||||
|
||||
private fun getRomanNumeral(number: Int): String {
|
||||
if (number <= 0) return number.toString()
|
||||
|
||||
val numerals = listOf(
|
||||
1000 to "M",
|
||||
900 to "CM",
|
||||
500 to "D",
|
||||
400 to "CD",
|
||||
100 to "C",
|
||||
90 to "XC",
|
||||
50 to "L",
|
||||
40 to "XL",
|
||||
10 to "X",
|
||||
9 to "IX",
|
||||
5 to "V",
|
||||
4 to "IV",
|
||||
1 to "I"
|
||||
)
|
||||
|
||||
var remaining = number
|
||||
val result = StringBuilder()
|
||||
|
||||
for ((value, numeral) in numerals) {
|
||||
while (remaining >= value) {
|
||||
result.append(numeral)
|
||||
remaining -= value
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
}
|
||||
@@ -313,9 +313,6 @@ class CobblemonConfig {
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "infinite_tm_uses", SERVER)
|
||||
var infiniteTmUses = false
|
||||
|
||||
@CobblemonConfigField(Category.Pokemon, lang = "infinite_poke_skill_cooldown", SERVER)
|
||||
var infinitePokeSkillCooldown = false
|
||||
|
||||
@CobblemonConfigField(Category.Pokedex, lang = "hide_unimplemented_pokemon_in_the_pokedex", CLIENT)
|
||||
var hideUnimplementedPokemonInThePokedex = false
|
||||
|
||||
|
||||
@@ -10,13 +10,6 @@ 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
|
||||
@@ -80,7 +73,6 @@ 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)
|
||||
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
package com.cobblemon.mod.common.entity.pokemon.pokeskills
|
||||
|
||||
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.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.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.entity.projectile.ProjectileUtil
|
||||
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 requiredMoves/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? = null,
|
||||
val actionEffect: ActionEffectTimeline? = null,
|
||||
val icon: ResourceLocation? = null,
|
||||
val cooldownTicks: Int? = null,
|
||||
val accessCondition: ExpressionLike? = null,
|
||||
val useCondition: ExpressionLike? = null,
|
||||
|
||||
val targetType: PokeSkillTargetType? = null,
|
||||
val range: Double? = null,
|
||||
val targetCondition: ExpressionLike? = null,
|
||||
|
||||
val requiredMoves: List<String>? = null,
|
||||
val requiredAbilities: List<String>? = null,
|
||||
val requiredTypes: List<String>? = null,
|
||||
val requiredSpecies: List<String>? = null,
|
||||
|
||||
val hitDelay: ExpressionLike? = null,
|
||||
val hitEffect: ResourceLocation? = null,
|
||||
val fallbackActionEffect: ResourceLocation? = null,
|
||||
|
||||
val variables: Map<String, Any>? = null,
|
||||
|
||||
val tiers: List<PokeSkillTier>,
|
||||
) {
|
||||
companion object {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
// TODO add all fields to codec
|
||||
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) { name, enabled, actionEffect, icon, cooldownTicks, accessCondition, useCondition ->
|
||||
PokeSkill(
|
||||
name = name,
|
||||
enabled = enabled,
|
||||
actionEffect = actionEffect,
|
||||
icon = icon,
|
||||
cooldownTicks = cooldownTicks,
|
||||
accessCondition = accessCondition,
|
||||
useCondition = useCondition,
|
||||
targetType = null,
|
||||
range = null,
|
||||
targetCondition = null,
|
||||
requiredMoves = null,
|
||||
requiredAbilities = null,
|
||||
requiredTypes = null,
|
||||
requiredSpecies = null,
|
||||
hitDelay = null,
|
||||
hitEffect = null,
|
||||
fallbackActionEffect = null,
|
||||
tiers = emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val PACKET_CODEC = ByteBufCodecs.fromCodecWithRegistries(CODEC)
|
||||
}
|
||||
|
||||
@Transient
|
||||
lateinit var id: ResourceLocation
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
package com.cobblemon.mod.common.entity.pokemon.pokeskills
|
||||
|
||||
enum class PokeSkillTargetType {
|
||||
NONE, SELF, BLOCK, ENTITY, BOTH
|
||||
}
|
||||
-402
@@ -1,402 +0,0 @@
|
||||
package com.cobblemon.mod.common.entity.pokemon.pokeskills
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
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.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.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.UsersProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.entity.pokemon.pokeskills.PokeSkill.Companion.runtime
|
||||
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.isInBattle
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import net.minecraft.core.registries.Registries
|
||||
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.entity.projectile.ProjectileUtil
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.phys.HitResult
|
||||
import kotlin.collections.set
|
||||
|
||||
class PokeSkillTier(
|
||||
@SerializedName("enabled")
|
||||
private val _enabled: Boolean? = null,
|
||||
@SerializedName("actionEffect")
|
||||
private val _actionEffect: ActionEffectTimeline? = null,
|
||||
@SerializedName("icon")
|
||||
private val _icon: ResourceLocation? = null,
|
||||
@SerializedName("cooldownTicks")
|
||||
private val _cooldownTicks: Int? = null,
|
||||
@SerializedName("accessCondition")
|
||||
private val _accessCondition: ExpressionLike? = null,
|
||||
@SerializedName("useCondition")
|
||||
private val _useCondition: ExpressionLike? = null,
|
||||
|
||||
@SerializedName("targetType")
|
||||
private val _targetType: PokeSkillTargetType? = null,
|
||||
@SerializedName("range")
|
||||
private val _range: Double? = null,
|
||||
@SerializedName("targetCondition")
|
||||
private val _targetCondition: ExpressionLike? = null,
|
||||
|
||||
@SerializedName("requiredMoves")
|
||||
private val _requiredMoves: List<String>? = null,
|
||||
@SerializedName("requiredAbilities")
|
||||
private val _requiredAbilities: List<String>? = null,
|
||||
@SerializedName("requiredTypes")
|
||||
private val _requiredTypes: List<String>? = null,
|
||||
@SerializedName("requiredSpecies")
|
||||
private val _requiredSpecies: List<String>? = null,
|
||||
|
||||
@SerializedName("hitDelay")
|
||||
private val _hitDelay: ExpressionLike? = null,
|
||||
@SerializedName("hitEffect")
|
||||
private val _hitEffect: ResourceLocation? = null,
|
||||
@SerializedName("fallbackActionEffect")
|
||||
private val _fallbackActionEffect: ResourceLocation? = null,
|
||||
|
||||
@SerializedName("variables")
|
||||
private val _variables: Map<String, Any>? = null,
|
||||
) {
|
||||
|
||||
@Transient
|
||||
lateinit var pokeSkill: PokeSkill
|
||||
|
||||
@Transient
|
||||
var tier: Int = -1
|
||||
|
||||
fun initialize(skill: PokeSkill, tier: Int): PokeSkillTier {
|
||||
this.pokeSkill = skill
|
||||
this.tier = tier
|
||||
return this
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_ACTION_EFFECT = cobblemonResource("default_poke_skill")
|
||||
}
|
||||
|
||||
val id: ResourceLocation
|
||||
get() = pokeSkill.id
|
||||
val name: String
|
||||
get() = pokeSkill.name
|
||||
|
||||
val enabled: Boolean
|
||||
get() = _enabled ?: pokeSkill.enabled ?: true
|
||||
val actionEffect: ActionEffectTimeline?
|
||||
get() = _actionEffect ?: pokeSkill.actionEffect
|
||||
val icon: ResourceLocation?
|
||||
get() = _icon ?: pokeSkill.icon
|
||||
val cooldownTicks: Int
|
||||
get() = _cooldownTicks ?: pokeSkill.cooldownTicks ?: 0
|
||||
val accessCondition: ExpressionLike
|
||||
get() = _accessCondition ?: pokeSkill.accessCondition ?: "true".asExpressionLike()
|
||||
val useCondition: ExpressionLike
|
||||
get() = _useCondition ?: pokeSkill.useCondition ?: "true".asExpressionLike()
|
||||
|
||||
val targetType: PokeSkillTargetType?
|
||||
get() = _targetType ?: pokeSkill.targetType
|
||||
val range: Double?
|
||||
get() = _range ?: pokeSkill.range
|
||||
val targetCondition: ExpressionLike?
|
||||
get() = _targetCondition ?: pokeSkill.targetCondition
|
||||
|
||||
val requiredMoves: List<String>?
|
||||
get() = _requiredMoves ?: pokeSkill.requiredMoves
|
||||
val requiredAbilities: List<String>?
|
||||
get() = _requiredAbilities ?: pokeSkill.requiredAbilities
|
||||
val requiredTypes: List<String>?
|
||||
get() = _requiredTypes ?: pokeSkill.requiredTypes
|
||||
val requiredSpecies: List<String>?
|
||||
get() = _requiredSpecies ?: pokeSkill.requiredSpecies
|
||||
|
||||
val hitDelay: ExpressionLike?
|
||||
get() = _hitDelay ?: pokeSkill.hitDelay
|
||||
val hitEffect: ResourceLocation?
|
||||
get() = _hitEffect ?: pokeSkill.hitEffect
|
||||
val fallbackActionEffect: ResourceLocation?
|
||||
get() = _fallbackActionEffect ?: pokeSkill.fallbackActionEffect
|
||||
|
||||
val variables: Map<String, Any>?
|
||||
get() = _variables ?: pokeSkill.variables
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
val requiredMoves = requiredMoves
|
||||
val requiredAbilities = requiredAbilities
|
||||
val requiredTypes = requiredTypes
|
||||
val requiredSpecies = requiredSpecies
|
||||
|
||||
// Check granting lists — if any are populated, check if the player has any of the listed moves/abilities/types/species
|
||||
val hasGrantingLists = !requiredMoves.isNullOrEmpty() || !requiredAbilities.isNullOrEmpty() ||
|
||||
!requiredTypes.isNullOrEmpty() || !requiredSpecies.isNullOrEmpty()
|
||||
|
||||
if (hasGrantingLists) {
|
||||
val moveMatch = !requiredMoves.isNullOrEmpty() && requiredMoves.any { moveName ->
|
||||
pokemon.moveSet.any { it.template.name == moveName }
|
||||
}
|
||||
|
||||
val abilityMatch = !requiredAbilities.isNullOrEmpty() && requiredAbilities.any { abilityName ->
|
||||
pokemon.ability.name == abilityName
|
||||
}
|
||||
|
||||
val typeMatch = !requiredTypes.isNullOrEmpty() && requiredTypes.any { typeName ->
|
||||
pokemon.types.any { it.name.equals(typeName, ignoreCase = true) }
|
||||
}
|
||||
|
||||
val speciesMatch = !requiredSpecies.isNullOrEmpty() && requiredSpecies.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)
|
||||
}
|
||||
|
||||
fun canUse(player: Player, pokemon: Pokemon): Boolean {
|
||||
val status = pokemon.status?.status
|
||||
if ((!Cobblemon.config.infinitePokeSkillCooldown && 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 requiredMoves, or null if none match.
|
||||
*/
|
||||
fun resolveGrantingMove(pokemon: Pokemon): String? {
|
||||
val requiredMoves = requiredMoves
|
||||
if (requiredMoves.isNullOrEmpty()) return null // need this guard
|
||||
return requiredMoves.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 ?: PokeSkillTargetType.NONE
|
||||
val effectiveRange = range ?: 8.0
|
||||
|
||||
// Resolve the action effect to run
|
||||
val actionEffect = actionEffect
|
||||
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
|
||||
injectVariables(skillRuntime)
|
||||
|
||||
// Targeting — raycast based on targetType
|
||||
when (effectiveTargetType) {
|
||||
PokeSkillTargetType.SELF -> {
|
||||
injectEntityTarget(skillRuntime, player)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(1.0))
|
||||
}
|
||||
PokeSkillTargetType.BLOCK -> {
|
||||
val blockHit = getPlayerLookedBlock(player, effectiveRange) ?: return false
|
||||
injectBlockTarget(skillRuntime, blockHit, level)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(0.0))
|
||||
}
|
||||
PokeSkillTargetType.ENTITY -> {
|
||||
val entityHit = getPlayerLookedEntity(player, effectiveRange) ?: return false
|
||||
injectEntityTarget(skillRuntime, entityHit)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(1.0))
|
||||
}
|
||||
PokeSkillTargetType.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) ?: return false
|
||||
injectBlockTarget(skillRuntime, blockHit, level)
|
||||
skillRuntime.environment.setSimpleVariable("target_is_entity", DoubleValue(0.0))
|
||||
}
|
||||
}
|
||||
PokeSkillTargetType.NONE -> {}
|
||||
}
|
||||
|
||||
// Evaluate target condition
|
||||
val targetCondition = targetCondition
|
||||
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()))
|
||||
}
|
||||
|
||||
val hitDelay = hitDelay
|
||||
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
|
||||
if (!Cobblemon.config.infinitePokeSkillCooldown) {
|
||||
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())
|
||||
}
|
||||
|
||||
private fun injectVariables(runtime: MoLangRuntime) {
|
||||
variables?.forEach { (key, value) ->
|
||||
runtime.environment.setSimpleVariable(
|
||||
key,
|
||||
value.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 = ProjectileUtil.getEntityHitResult(
|
||||
player,
|
||||
eyePosition,
|
||||
reachVector,
|
||||
searchBox,
|
||||
{ entity -> !entity.isSpectator && entity.isPickable },
|
||||
range * range
|
||||
)
|
||||
|
||||
return entityHitResult?.entity
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,12 @@ object ServerTickHandler {
|
||||
|
||||
secondsTick++
|
||||
|
||||
// Party tick
|
||||
for (player in server.playerList.players) {
|
||||
val party = player.party()
|
||||
party.forEach { it.tickSkillCooldowns() }
|
||||
if (secondsTick == 20) {
|
||||
secondsTick = 0
|
||||
party.onSecondPassed(player)
|
||||
if (secondsTick == 20) {
|
||||
secondsTick = 0
|
||||
|
||||
// Party tick
|
||||
for (player in server.playerList.players) {
|
||||
player.party().onSecondPassed(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +316,6 @@ object CobblemonItemGroups {
|
||||
entries.accept(CobblemonItems.PASTURE)
|
||||
entries.accept(CobblemonItems.TM_MACHINE)
|
||||
entries.accept(CobblemonItems.DISC_SHELF)
|
||||
entries.accept(CobblemonItems.HABITAT_BLOCK)
|
||||
|
||||
entries.accept(CobblemonItems.GILDED_CHEST)
|
||||
entries.accept(CobblemonItems.YELLOW_GILDED_CHEST)
|
||||
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonPokeSkills
|
||||
import com.cobblemon.mod.common.entity.pokemon.pokeskills.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) }
|
||||
}
|
||||
}
|
||||
+2
-14
@@ -13,15 +13,10 @@ 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]
|
||||
*
|
||||
@@ -33,8 +28,7 @@ class SpawnSnowstormEntityParticlePacket(
|
||||
val sourceEntityId: Int,
|
||||
val sourceLocators: List<String> = listOf("root"),
|
||||
val targetedEntityId: Int? = null,
|
||||
val targetLocators: List<String>? = null,
|
||||
val targetPosition: Vec3? = null
|
||||
val targetLocators: List<String>? = null
|
||||
) : NetworkPacket<SpawnSnowstormEntityParticlePacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("spawn_snowstorm_entity_particle")
|
||||
@@ -45,8 +39,7 @@ class SpawnSnowstormEntityParticlePacket(
|
||||
val sourceLocators = buffer.readList { buffer.readString() }
|
||||
val targetedEntityId = buffer.readNullable { it.readInt() }
|
||||
val targetLocators = buffer.readNullable { buffer.readList { buffer.readString() }}
|
||||
val targetPosition = buffer.readNullable { Vec3(it.readDouble(), it.readDouble(), it.readDouble()) }
|
||||
return SpawnSnowstormEntityParticlePacket(effectId, sourceEntityId, sourceLocators, targetedEntityId, targetLocators, targetPosition)
|
||||
return SpawnSnowstormEntityParticlePacket(effectId, sourceEntityId, sourceLocators, targetedEntityId, targetLocators)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +55,5 @@ class SpawnSnowstormEntityParticlePacket(
|
||||
buffer.writeString(locator)
|
||||
}
|
||||
}
|
||||
buffer.writeNullable(targetPosition) { _, value ->
|
||||
buffer.writeDouble(value.x)
|
||||
buffer.writeDouble(value.y)
|
||||
buffer.writeDouble(value.z)
|
||||
}
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.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
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.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.getAccessiblePokeSkillTiers(player, pokemon).firstOrNull { it.id == packet.skillId } ?: return // What skill?
|
||||
if (skill.canUse(player, pokemon)) {
|
||||
skill.use(player, pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -766,8 +766,6 @@ 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 {
|
||||
@@ -1142,21 +1140,6 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
}
|
||||
}
|
||||
|
||||
fun tickSkillCooldowns() {
|
||||
val iterator = skillCooldownsTicks.entries.iterator()
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
val entry = iterator.next()
|
||||
val newValue = entry.value - 1
|
||||
|
||||
if (newValue <= 0) {
|
||||
iterator.remove()
|
||||
} else {
|
||||
entry.setValue(newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isOnInteractionCooldown(group: ResourceLocation): Boolean {
|
||||
return this.interactionCooldowns.getOrDefault(group, 0) > 0
|
||||
}
|
||||
@@ -2245,11 +2228,6 @@ 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) }
|
||||
}
|
||||
|
||||
-1
@@ -10,7 +10,6 @@ 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,7 +20,6 @@ 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,16 +100,10 @@ fun ServerPlayer.didSleep(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun Player.isInBattle() = if (this is ServerPlayer) {
|
||||
BattleRegistry.getBattleByParticipatingPlayer(this) != null
|
||||
} else {
|
||||
CobblemonClient.battle?.spectating == false
|
||||
}
|
||||
|
||||
fun ServerPlayer.isInBattle() = BattleRegistry.getBattleByParticipatingPlayer(this) != null
|
||||
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
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.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,8 +10,6 @@ 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
|
||||
@@ -31,17 +29,6 @@ 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
|
||||
|
||||
+3
-7
@@ -22,12 +22,10 @@ import net.minecraft.world.item.ItemStack
|
||||
import java.util.*
|
||||
|
||||
internal data class ClientPokemonP4(
|
||||
val skillCooldownTicks: Map<ResourceLocation, Int>,
|
||||
val originalTrainerFriendship: Optional<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
|
||||
}
|
||||
@@ -38,13 +36,11 @@ internal data class ClientPokemonP4(
|
||||
*/
|
||||
internal val CODEC: MapCodec<ClientPokemonP4> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
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)
|
||||
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,16 +13,13 @@ 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 skillCooldownTicks: Map<ResourceLocation, Int>,
|
||||
val originalTrainerFriendship: Optional<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
|
||||
@@ -31,20 +28,16 @@ internal data class PokemonP4(
|
||||
companion object {
|
||||
internal val CODEC: MapCodec<PokemonP4> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
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),
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(PokemonP4::originalTrainerFriendship)
|
||||
).apply(instance) {
|
||||
skillCooldownTicks,
|
||||
originalTrainerFriendship -> PokemonP4(
|
||||
skillCooldownTicks,
|
||||
originalTrainerFriendship,
|
||||
originalTrainerFriendship
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun from(pokemon: Pokemon): PokemonP4 = PokemonP4(
|
||||
pokemon.skillCooldownsTicks,
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship),
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship)
|
||||
)
|
||||
}
|
||||
}
|
||||
-464
@@ -1575,470 +1575,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.substitute.destroy_burst": {
|
||||
"animation_length": 3,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": ["-0.3*Math.cos((query.anim_time-0) * 90 * 0.5+90) *0.3", 0, "0.3*Math.cos((query.anim_time-0) * 90 * 0.5) *0.3"],
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.125": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0.25, 5],
|
||||
"post": [0, 0.25, 5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": {
|
||||
"post": [0, 0.25, 9.9],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [0, 0.25, 12.4],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [0, 0, 13.3],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4583": [0, 0, 13.3]
|
||||
},
|
||||
"scale": {
|
||||
"0.0": {
|
||||
"post": [1, 1, 1],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.0417": {
|
||||
"post": [1, 1, 1],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.125": {
|
||||
"post": [1.11, 1.05, 0.9],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [0.855, 1.025, 1.05],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [1, 1, 1],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"arm_left": {
|
||||
"rotation": {
|
||||
"0.0": ["-2.5-3*Math.cos((query.anim_time-0.25) * 90 * 1) *0.05", 7.5, 0],
|
||||
"0.0833": [-2.54822, 7.5, 0],
|
||||
"0.125": {
|
||||
"pre": [19.95178, 10, 0],
|
||||
"post": [19.95178, 10, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-2.05, -90, -17],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [-21.03, -80.89, -17.09],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": {
|
||||
"post": [32.35, -50.6, -22],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.625": {
|
||||
"post": [28.45, -46.5, -26],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7917": [28.45, -46.5, -26],
|
||||
"0.9583": {
|
||||
"pre": [32.01, -45.83, -30.71],
|
||||
"post": [32.01, -45.83, -30.71],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": {
|
||||
"post": [54.92, -41.5, -61],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.5": [54.92, -41.5, -61]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.125": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0.5, 0.25],
|
||||
"post": [0, 0.5, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": [0, 0.5, 0.25],
|
||||
"0.3333": {
|
||||
"pre": [0, -0.25, 0.25],
|
||||
"post": [0, -0.25, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7917": [0, -0.25, 0.25],
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0.25],
|
||||
"post": [0, 0, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.5": [0, 0, 0.25]
|
||||
}
|
||||
},
|
||||
"tail": {
|
||||
"rotation": {
|
||||
"0.0": ["2.5+2*Math.cos((query.anim_time-0.5) * 90 * 1) *0.025", 0, 0],
|
||||
"0.0833": [2.5, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [6, -2.5, 2.5],
|
||||
"post": [6, -2.5, 2.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": [6, -2.5, 2.5],
|
||||
"0.2917": {
|
||||
"pre": [6.5, 0, 0],
|
||||
"post": [6.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [4, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": {
|
||||
"post": [-11.8, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [-14.6, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.9583": {
|
||||
"post": [-17.14, 0, -1.02],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [-29.5, 0, -4.5]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.6667": [0, 0, 0],
|
||||
"1.25": [0, -0.3, 0]
|
||||
}
|
||||
},
|
||||
"tail2": {
|
||||
"rotation": {
|
||||
"0.0": ["15+2*Math.cos((query.anim_time-0.75) * 90 * 1) *0.025", 0, 0],
|
||||
"0.0417": [15.04735, 0, 0],
|
||||
"0.125": {
|
||||
"pre": [20, 0, 0],
|
||||
"post": [20, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": [0, 0, 0],
|
||||
"0.2917": {
|
||||
"pre": [-2.95, 0, 0],
|
||||
"post": [-2.95, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [-2.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4583": {
|
||||
"post": [12.5, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5833": [7.5, 0, 0]
|
||||
}
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": {
|
||||
"0.0": [5, 5, 0],
|
||||
"0.0833": [5, 5, 0],
|
||||
"0.125": {
|
||||
"pre": [5, 12.5, 0],
|
||||
"post": [5, 12.5, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [-7.5, -10, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [2.5, -7.5, -5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": [2.5, -7.5, -5],
|
||||
"0.6667": [2.5, -7.5, -5],
|
||||
"1.0": {
|
||||
"pre": [0.5, -7.5, 1.5],
|
||||
"post": [0.5, -7.5, 1.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [0.5, -7.5, 1.5]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.0833": [0, 0, 0],
|
||||
"0.4167": [0, -0.5, -0.08],
|
||||
"1.0": [0.25, -0.75, -0.25]
|
||||
},
|
||||
"scale": 1
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": {
|
||||
"0.0": [5, -5, 0],
|
||||
"0.0833": [5, -5, 0],
|
||||
"0.125": {
|
||||
"pre": [5, -12.5, 0],
|
||||
"post": [5, -12.5, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [-7.5, 10, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [2.5, 7.5, 5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": [2.5, 7.5, 5],
|
||||
"0.6667": [2.5, 7.5, 5],
|
||||
"1.0": {
|
||||
"pre": [2.5, 7.5, 2.5],
|
||||
"post": [2.5, 7.5, 2.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [2.5, 7.5, 2.5]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.0833": [0, 0, 0],
|
||||
"0.4167": [0, -0.5, -0.08]
|
||||
}
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": {
|
||||
"0.0": ["-2.5-3*Math.cos((query.anim_time-0.25) * 90 * 1) *0.05", -7.5, 0],
|
||||
"0.0833": [-2.54822, -7.5, 0],
|
||||
"0.125": {
|
||||
"pre": [19.95178, -10, 0],
|
||||
"post": [19.95178, -10, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-2.05, 90, 17],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.375": {
|
||||
"post": [-21.03, 80.89, 17.09],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.5": {
|
||||
"post": [32.35, 50.6, 22],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.625": {
|
||||
"post": [28.45, 46.5, 26],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7917": [28.45, 46.5, 26],
|
||||
"1.0417": {
|
||||
"pre": [40.18, 36.5, 36.67],
|
||||
"post": [40.18, 36.5, 36.67],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": {
|
||||
"post": [72.42, 9, 66],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.5": [72.42, 9, 66]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.125": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0.5, 0.25],
|
||||
"post": [0, 0.5, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": [0, 0.5, 0.25],
|
||||
"0.3333": {
|
||||
"pre": [0, -0.25, 0.25],
|
||||
"post": [0, -0.25, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7917": [0, -0.25, 0.25],
|
||||
"1.25": {
|
||||
"pre": [0, 0.25, 0.25],
|
||||
"post": [0, 0.25, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.5": [0, 0.25, 0.25]
|
||||
}
|
||||
},
|
||||
"torso": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [3.47, 0, 1.13],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.0833": {
|
||||
"post": [-7, 0.3, -2.4],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-12, 0, -3.2],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.3333": {
|
||||
"post": [-2.89, 0, -1.77],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.4167": {
|
||||
"post": [3, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.7917": {
|
||||
"post": [6.12, 0, 1.57],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.0": {
|
||||
"post": [8.28, 0, 3.68],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [15.78, 0, 4.18]
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.125": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0.25, 0.25],
|
||||
"post": [0, 0.25, 0.25],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2917": {
|
||||
"post": [0, 0.15, 0.15],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.3333": [0, 0, 0],
|
||||
"0.6667": [0, 0, 0],
|
||||
"0.7917": [0, 0, 0],
|
||||
"0.9167": {
|
||||
"pre": [0.05, 0, 0],
|
||||
"post": [0.05, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.25": [0.25, -0.6, 0]
|
||||
},
|
||||
"scale": {
|
||||
"0.0": [1, 1, 1],
|
||||
"0.875": [1, 1, 1],
|
||||
"1.1667": {
|
||||
"pre": [1, 0.92, 1],
|
||||
"post": [1, 0.92, 1],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"1.5": {
|
||||
"post": [1, 0.92, 1],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"head": {
|
||||
"relative_to": {
|
||||
"rotation": "entity"
|
||||
},
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0.01],
|
||||
"0.0833": {
|
||||
"pre": [12.17, 0, 5.33],
|
||||
"post": [12.17, 0, 5.33],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.125": {
|
||||
"post": [-7.5, 2.5, 7.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-5, "5-2*math.sin(q.anim_time*90*20+60)", "12.5+1*math.sin(q.anim_time*90*40+60)"],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0833": {
|
||||
"pre": [0, 0, 0.5],
|
||||
"post": [0, 0, 0.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.2083": {
|
||||
"post": [0, 0.5, 0.5],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": [0, 0, 0]
|
||||
},
|
||||
"scale": {
|
||||
"0.0": [1, 1, 1],
|
||||
"0.0833": {
|
||||
"pre": [1.05, 0.9, 1.05],
|
||||
"post": [1.05, 0.9, 1.05],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.125": [0.95, 1.2, 0.95],
|
||||
"0.1667": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"stuffing_neck": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2083": {"pre": [0, 0, 0], "post": [0, 0.3, 0]}
|
||||
}
|
||||
},
|
||||
"locator_neck_fluff": {
|
||||
"rotation": [-180, 0, 0]
|
||||
},
|
||||
"stuffing_shoulder_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2083": {"pre": [0, 0, 0], "post": [0.25, 0, 0]}
|
||||
}
|
||||
},
|
||||
"stuffing_arm_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2083": {"pre": [0, 0, 0], "post": [-0.25, 0, 0]}
|
||||
}
|
||||
},
|
||||
"stuffing_arm_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2083": {"pre": [0, 0, 0], "post": [0.25, 0, 0]}
|
||||
}
|
||||
},
|
||||
"stuffing_shoulder_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2083": {"pre": [0, 0, 0], "post": [-0.25, 0, 0]}
|
||||
}
|
||||
}
|
||||
},
|
||||
"particle_effects": {
|
||||
"0.1667": {
|
||||
"effect": "substitute_fluff",
|
||||
"locator": "neck_fluff"
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.substitute.flop_WIP": {
|
||||
"animation_length": 1.5,
|
||||
"bones": {
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:skill_sense_sparkle",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_xray",
|
||||
"texture": "textures/particles/generic/sparkle/glowingsparkle"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_steady": {
|
||||
"spawn_rate": 8.5,
|
||||
"max_particles": 100
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 5
|
||||
},
|
||||
"minecraft:emitter_shape_box": {
|
||||
"half_dimensions": [0.35, 0.35, 0.35],
|
||||
"direction": "outwards"
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 0.35
|
||||
},
|
||||
"minecraft:particle_initial_speed": 0,
|
||||
"minecraft:particle_motion_dynamic": {},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": [0.08, 0.08],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 8,
|
||||
"texture_height": 32,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [7, 8],
|
||||
"step_UV": [0, 8],
|
||||
"frames_per_second": 10,
|
||||
"max_frame": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "v.particle_random_1",
|
||||
"gradient": {
|
||||
"0.0": "#FFFFF0B6",
|
||||
"0.5": "#FFFFE45A",
|
||||
"1.0": "#FFAE521A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-4
@@ -1222,7 +1222,7 @@
|
||||
"position": [0, 0, "-0.2+math.cos(q.anim_time*90*16/3*2)*0.3"]
|
||||
},
|
||||
"hair2": {
|
||||
"rotation": ["-2.5-math.cos(q.anim_time*90*16/3*2+30)*9", 0, 0]
|
||||
"rotation": ["-1-math.cos(q.anim_time*90*16/3*2+30)*6", 0, 0]
|
||||
},
|
||||
"wings_closed": {
|
||||
"rotation": ["-math.cos(q.anim_time*90*16/3*2-45)*2", 0, "math.sin(q.anim_time*90*16/3)*-1"]
|
||||
@@ -1462,9 +1462,6 @@
|
||||
"bones": {
|
||||
"pidgey": {
|
||||
"position": [0, 0, "20-q.anim_time*16*0.95"]
|
||||
},
|
||||
"head": {
|
||||
"position": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+3
@@ -152,6 +152,9 @@
|
||||
},
|
||||
"claw_outer_right": {
|
||||
"rotation": [10, 0, 0]
|
||||
},
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+252
-60
@@ -207,6 +207,9 @@
|
||||
},
|
||||
"seat_1": {
|
||||
"rotation": [22.5, 0, 0]
|
||||
},
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1808,6 +1811,9 @@
|
||||
},
|
||||
"seat_1": {
|
||||
"rotation": [22.5, 0, 0]
|
||||
},
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2017,6 +2023,9 @@
|
||||
},
|
||||
"seat_1": {
|
||||
"rotation": [22.5, 0, 0]
|
||||
},
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3618,6 +3627,9 @@
|
||||
},
|
||||
"seat_1": {
|
||||
"rotation": [22.5, 0, 0]
|
||||
},
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4926,8 +4938,14 @@
|
||||
},
|
||||
"scale": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.24": {"pre": [0, 0, 0], "post": [1, 1, 1]},
|
||||
"2.12": {"pre": [1, 1, 1], "post": [0, 0, 0]}
|
||||
"0.24": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
},
|
||||
"2.12": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"wing_open_left2": {
|
||||
@@ -5619,15 +5637,27 @@
|
||||
"pupil_left": {
|
||||
"position": {
|
||||
"0.0": [-0.25, 0, 0],
|
||||
"0.4": {"pre": [-0.25, 0, 0], "post": [0, 0, 0]},
|
||||
"1.4": {"pre": [0, 0, 0], "post": [-0.25, 0, 0]}
|
||||
"0.4": {
|
||||
"pre": [-0.25, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.25, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"1.4": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
@@ -5898,8 +5928,14 @@
|
||||
},
|
||||
"scale": {
|
||||
"0.0": [1, 1, 1],
|
||||
"0.24": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"2.12": {"pre": [0, 0, 0], "post": [1, 1, 1]}
|
||||
"0.24": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.12": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"wing_closed_left1": {
|
||||
@@ -6141,15 +6177,27 @@
|
||||
"pupil_right": {
|
||||
"position": {
|
||||
"0.0": [-0.65, 0, 0],
|
||||
"0.4": {"pre": [-0.65, 0, 0], "post": [0, 0, 0]},
|
||||
"1.4": {"pre": [0, 0, 0], "post": [-0.65, 0, 0]}
|
||||
"0.4": {
|
||||
"pre": [-0.65, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.65, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"1.4": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"head_angle": {
|
||||
@@ -6161,33 +6209,69 @@
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.4": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.4": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_ditto": {
|
||||
"scale": {
|
||||
"0.92": [1, 1, 1],
|
||||
"1.32": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"1.68": {"pre": [0, 0, 0], "post": [1, 1, 1]},
|
||||
"1.76": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"2.04": {"pre": [0, 0, 0], "post": [1, 1, 1]}
|
||||
"1.32": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.68": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
},
|
||||
"1.76": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.04": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.92": [0, 0, 0],
|
||||
"1.32": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.68": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
|
||||
"1.76": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"2.04": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"1.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.68": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.76": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"2.04": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"seat_1": {
|
||||
@@ -6498,8 +6582,14 @@
|
||||
},
|
||||
"scale": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.24": {"pre": [0, 0, 0], "post": [1, 1, 1]},
|
||||
"2.12": {"pre": [1, 1, 1], "post": [0, 0, 0]}
|
||||
"0.24": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
},
|
||||
"2.12": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"wing_open_left2": {
|
||||
@@ -7191,15 +7281,27 @@
|
||||
"pupil_left": {
|
||||
"position": {
|
||||
"0.0": [-0.25, 0, 0],
|
||||
"0.4": {"pre": [-0.25, 0, 0], "post": [0, 0, 0]},
|
||||
"1.4": {"pre": [0, 0, 0], "post": [-0.25, 0, 0]}
|
||||
"0.4": {
|
||||
"pre": [-0.25, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.25, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"1.4": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"hair2": {
|
||||
@@ -7447,8 +7549,14 @@
|
||||
},
|
||||
"scale": {
|
||||
"0.0": [1, 1, 1],
|
||||
"0.24": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"2.12": {"pre": [0, 0, 0], "post": [1, 1, 1]}
|
||||
"0.24": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.12": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"wing_closed_left1": {
|
||||
@@ -7690,15 +7798,27 @@
|
||||
"pupil_right": {
|
||||
"position": {
|
||||
"0.0": [-0.65, 0, 0],
|
||||
"0.4": {"pre": [-0.65, 0, 0], "post": [0, 0, 0]},
|
||||
"1.4": {"pre": [0, 0, 0], "post": [-0.65, 0, 0]}
|
||||
"0.4": {
|
||||
"pre": [-0.65, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.65, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"1.4": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"head_angle": {
|
||||
@@ -7710,29 +7830,53 @@
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.4": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.32": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.4": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.4": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_ditto": {
|
||||
"scale": {
|
||||
"0.92": [1, 1, 1],
|
||||
"1.32": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"2.04": {"pre": [0, 0, 0], "post": [1, 1, 1]}
|
||||
"1.32": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.04": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.92": [0, 0, 0],
|
||||
"1.32": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"2.04": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"1.32": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"2.04": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"seat_1": {
|
||||
@@ -12788,19 +12932,43 @@
|
||||
"mouth_ditto": {
|
||||
"scale": {
|
||||
"0.0": [1, 1, 1],
|
||||
"0.4167": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"0.75": {"pre": [0, 0, 0], "post": [1, 1, 1]},
|
||||
"0.8333": {"pre": [1, 1, 1], "post": [0, 0, 0]},
|
||||
"1.125": {"pre": [0, 0, 0], "post": [1, 1, 1]}
|
||||
"0.4167": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.75": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
},
|
||||
"0.8333": {
|
||||
"pre": [1, 1, 1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.125": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [1, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.4167": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"0.75": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
|
||||
"0.8333": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.125": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"0.75": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.8333": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.125": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -12904,7 +13072,10 @@
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0.1, 0, -0.1],
|
||||
"0.2083": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
@@ -13185,7 +13356,10 @@
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [-0.1, 0, -0.1],
|
||||
"0.2083": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"wings": {
|
||||
@@ -13211,13 +13385,19 @@
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.2083": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.2083": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13228,25 +13408,37 @@
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0.1, 0, -0.1],
|
||||
"0.2083": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [-0.1, 0, -0.1],
|
||||
"0.2083": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.2083": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.2083": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.2083": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-26
@@ -162,7 +162,7 @@
|
||||
},
|
||||
"animation.chinchou.ground_walk": {
|
||||
"loop": true,
|
||||
"animation_length": 0.79167,
|
||||
"animation_length": 0.7917,
|
||||
"bones": {
|
||||
"stem_left": {
|
||||
"rotation": ["73.8265-0.5*math.sin(q.anim_time*90*10-30)*1", "-21.6937-3*math.sin(q.anim_time*90*5-150)*1", 6.1191]
|
||||
@@ -2294,7 +2294,7 @@
|
||||
}
|
||||
},
|
||||
"animation.chinchou.water_idle_quirk": {
|
||||
"animation_length": 3.79167,
|
||||
"animation_length": 3.7917,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": {
|
||||
@@ -2754,7 +2754,7 @@
|
||||
}
|
||||
},
|
||||
"animation.chinchou.blink": {
|
||||
"animation_length": 0.16667,
|
||||
"animation_length": 0.1667,
|
||||
"bones": {
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
@@ -2879,29 +2879,10 @@
|
||||
"1.25": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.chinchou.ground_walk speed test": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"chinchou": {
|
||||
"position": [0, 0, "-q.anim_time*90*0.12"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.chinchou.ground_run speed test": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"chinchou": {
|
||||
"position": [0, 0, "-q.anim_time*90*0.2"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.chinchou.water_swim speed test": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"chinchou": {
|
||||
"position": [0, 0, "-q.anim_time*90*0.2"]
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.0833": {
|
||||
"effect": "pokemon.chinchou.cry"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -3,7 +3,7 @@
|
||||
"animations": {
|
||||
"animation.metagross.ground_idle": {
|
||||
"loop": true,
|
||||
"animation_length": 0,
|
||||
"animation_length": 8,
|
||||
"bones": {
|
||||
"body2": {
|
||||
"position": [0, -11.9, 0]
|
||||
@@ -54,8 +54,7 @@
|
||||
},
|
||||
"torso": {
|
||||
"rotation": {
|
||||
"0.0": ["2+1*math.sin(q.anim_time*90*0.5)", "0.1*math.sin(q.anim_time*90*1-60)", "0.1*math.sin(q.anim_time*90*2-60)"],
|
||||
"11.4167": ["2.5796+1*math.sin(q.anim_time*90*0.5)", "0.3148+0.1*math.sin(q.anim_time*90*1-60)", "2.4153+0.1*math.sin(q.anim_time*90*2-60)"]
|
||||
"0.0": ["2+1*math.sin(q.anim_time*90*0.5)", "0.1*math.sin(q.anim_time*90*1-60)", "0.1*math.sin(q.anim_time*90*2-60)"]
|
||||
},
|
||||
"position": [0, "0.2*math.sin(q.anim_time*90*0.5-60)", 0]
|
||||
}
|
||||
|
||||
+7
-2
@@ -74,14 +74,19 @@
|
||||
"name": "neck",
|
||||
"parent": "torso2",
|
||||
"pivot": [0, 5.25, -7.5],
|
||||
"rotation": [52.5, 0, 0],
|
||||
"rotation": [52.5, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "neck_ai",
|
||||
"parent": "neck",
|
||||
"pivot": [0, 5.25, -7.5],
|
||||
"cubes": [
|
||||
{"origin": [-2.5, 4.75, -9], "size": [5, 5, 5], "inflate": -0.01, "uv": [22, 32]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "head",
|
||||
"parent": "neck",
|
||||
"parent": "neck_ai",
|
||||
"pivot": [0, 10, -6.5]
|
||||
},
|
||||
{
|
||||
|
||||
+2
-2
@@ -26,9 +26,9 @@
|
||||
{
|
||||
"name": "locator_root",
|
||||
"parent": "pidgeot",
|
||||
"pivot": [0, 32, 0],
|
||||
"pivot": [0, 0, 0],
|
||||
"locators": {
|
||||
"root": [0, 32, 0]
|
||||
"root": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+2
-2
@@ -69,9 +69,9 @@
|
||||
{
|
||||
"name": "locator_seat_1",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 25, 2],
|
||||
"pivot": [0, 22, 2],
|
||||
"locators": {
|
||||
"seat_1": [0, 25, 2]
|
||||
"seat_1": [0, 22, 2]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+2
-10
@@ -119,8 +119,8 @@
|
||||
"cubes": [
|
||||
{"origin": [19, 50, 0], "size": [2, 2, 2], "inflate": 0.01, "uv": [0, 45]},
|
||||
{"origin": [21, 49.5, -0.5], "size": [8, 3, 3], "inflate": 0.01, "uv": [8, 45]},
|
||||
{"origin": [-21, 50, 0], "size": [2, 2, 2], "inflate": 0.01, "pivot": [0, 51, 3.5], "rotation": [0, 0, 0], "uv": [0, 49], "mirror": true},
|
||||
{"origin": [-29, 49.5, -0.5], "size": [8, 3, 3], "inflate": 0.01, "pivot": [0, 51, 3], "rotation": [0, 0, 0], "uv": [8, 51], "mirror": true},
|
||||
{"origin": [-21, 50, 0], "size": [2, 2, 2], "inflate": 0.01, "uv": [0, 49], "mirror": true},
|
||||
{"origin": [-29, 49.5, -0.5], "size": [8, 3, 3], "inflate": 0.01, "uv": [8, 51], "mirror": true},
|
||||
{"origin": [18, 50, 0], "size": [2, 2, 2], "inflate": 0.01, "pivot": [0, 51, 3], "rotation": [0, 0, -55], "uv": [0, 53]},
|
||||
{"origin": [-20, 50, 0], "size": [2, 2, 2], "inflate": 0.01, "pivot": [0, 51, 3.5], "rotation": [0, 0, 55], "uv": [30, 43], "mirror": true},
|
||||
{"origin": [-28, 49.5, -0.5], "size": [8, 3, 3], "inflate": 0.01, "pivot": [0, 51, 3], "rotation": [0, 0, 55], "uv": [58, 46], "mirror": true},
|
||||
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+10
-5
@@ -12,7 +12,8 @@
|
||||
"standing": {
|
||||
"poseTypes": ["PORTRAIT", "PROFILE", "STAND", "NONE"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 35, -12.5, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 1.5, -12.5, 2.5, -2.5)",
|
||||
"q.bedrock('pidgey', 'ground_idle')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -41,7 +42,8 @@
|
||||
"walk": {
|
||||
"poseTypes": ["WALK"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 35, -12.5, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 1.5, -12.5, 2.5, -2.5)",
|
||||
"q.bedrock('pidgey', 'ground_walk')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -70,7 +72,8 @@
|
||||
"poseTypes": ["HOVER", "FLOAT"],
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 35, -12.5, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 1.5, -12.5, 2.5, -2.5)",
|
||||
"q.bedrock('pidgey', 'air_idle')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -182,7 +185,8 @@
|
||||
"shoulder_left": {
|
||||
"poseTypes": ["SHOULDER_LEFT"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 35, -12.5, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 1.5, -12.5, 2.5, -2.5)",
|
||||
"q.bedrock('pidgey', 'shoulder_left')"],
|
||||
"quirks": ["q.bedrock_quirk('pidgey', 'blink')"],
|
||||
"transformedParts": [
|
||||
@@ -211,7 +215,8 @@
|
||||
"shoulder_right": {
|
||||
"poseTypes": ["SHOULDER_RIGHT"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 35, -12.5, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 1.5, -12.5, 2.5, -2.5)",
|
||||
"q.bedrock('pidgey', 'shoulder_right')"],
|
||||
"quirks": ["q.bedrock_quirk('pidgey', 'blink')"],
|
||||
"transformedParts": [
|
||||
|
||||
+6
-21
@@ -18,27 +18,10 @@
|
||||
"standing": {
|
||||
"poseTypes": ["PORTRAIT", "PROFILE", "STAND", "NONE"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck_ai', 1, 1, 30, -20, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 3.5, -7.5, 1.5, -1.5)",
|
||||
"q.bedrock('pidgeotto', 'ground_idle')"
|
||||
],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "wing_open_left",
|
||||
"isVisible": false
|
||||
},
|
||||
{
|
||||
"part": "wing_open_right",
|
||||
"isVisible": false
|
||||
},
|
||||
{
|
||||
"part": "wing_closed_left",
|
||||
"isVisible": true
|
||||
},
|
||||
{
|
||||
"part": "wing_closed_right",
|
||||
"isVisible": true
|
||||
}
|
||||
],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('pidgeotto', 'blink')",
|
||||
"q.bedrock_primary_quirk('pidgeotto', 'ground_quirk', 10, 30, 1, q.curve('symmetrical'))"
|
||||
@@ -47,7 +30,8 @@
|
||||
"walk": {
|
||||
"poseTypes": ["WALK"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck_ai', 1, 1, 30, -20, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 3.5, -7.5, 1.5, -1.5)",
|
||||
"q.bedrock('pidgeotto', 'ground_walk')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -76,7 +60,8 @@
|
||||
"poseTypes": ["HOVER", "FLOAT"],
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck_ai', 1, 1, 30, -20, 7.5, -7.5)",
|
||||
"q.look('head_ai', 1, 1, 3.5, -7.5, 1.5, -1.5)",
|
||||
"q.bedrock('pidgeotto', 'air_idle')"
|
||||
],
|
||||
"transformedParts": [
|
||||
|
||||
+27
-36
@@ -24,8 +24,9 @@
|
||||
"isBattle": false,
|
||||
"condition": "!q.is_ridden",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'ground_idle')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -54,31 +55,14 @@
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'battle_idle')"
|
||||
],
|
||||
"namedAnimations": {
|
||||
"cry": "q.bedrock_primary('pidgeot', 'battle_cry', q.curve('symmetrical_wide'))"
|
||||
},
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "wing_open_left",
|
||||
"isVisible": false
|
||||
},
|
||||
{
|
||||
"part": "wing_open_right",
|
||||
"isVisible": false
|
||||
},
|
||||
{
|
||||
"part": "wing_closed_left",
|
||||
"isVisible": true
|
||||
},
|
||||
{
|
||||
"part": "wing_closed_right",
|
||||
"isVisible": true
|
||||
}
|
||||
],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('pidgeot', 'blink')"
|
||||
]
|
||||
@@ -87,8 +71,9 @@
|
||||
"poseTypes": ["WALK"],
|
||||
"condition": "!q.is_ridden",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'ground_walk')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -118,8 +103,9 @@
|
||||
"condition": "!q.is_ridden",
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'air_idle')"
|
||||
],
|
||||
"transformedParts": [
|
||||
@@ -263,8 +249,9 @@
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": false,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'mount_ground_idle')"
|
||||
],
|
||||
"condition": "q.has_entity && q.is_ridden && !q.in_air",
|
||||
@@ -293,8 +280,9 @@
|
||||
"isBattle": false,
|
||||
"condition": "q.is_ridden && !q.is_air && q.has_entity",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'ride_ground_walk')",
|
||||
"q.bedrock('pidgeot', 'mount_ground_walk')"
|
||||
],
|
||||
@@ -322,8 +310,9 @@
|
||||
"poseTypes": ["HOVER"],
|
||||
"condition": "!q.is_gliding && q.is_ridden && q.has_entity",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'ride_air_idle')",
|
||||
"q.bedrock('pidgeot', 'mount_air_idle')"
|
||||
],
|
||||
@@ -353,8 +342,9 @@
|
||||
"poseTypes": ["FLY"],
|
||||
"condition": "!q.is_gliding && q.is_ridden && q.has_entity",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'ride_air_fly')",
|
||||
"q.bedrock('pidgeot', 'mount_air_fly')"
|
||||
],
|
||||
@@ -385,8 +375,9 @@
|
||||
"condition": "q.is_gliding",
|
||||
"isBattle": false,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('hair3', -1, 1, 30, -60, 0, 0)",
|
||||
"q.look('neck2', 1, 1, 12.5, -15, 10, -10)",
|
||||
"q.look('head_ai', 1, 1, 1, -7.5, 2.5, -2.5)",
|
||||
"q.look('hair3', -1, 1, 10, -20, 0, 0)",
|
||||
"q.bedrock('pidgeot', 'air_glide')",
|
||||
{
|
||||
"condition": "q.is_ridden",
|
||||
|
||||
+20
-10
@@ -24,7 +24,8 @@
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'battle_idle')"
|
||||
],
|
||||
"quirks": [
|
||||
@@ -38,7 +39,8 @@
|
||||
"poseTypes": ["HOVER"],
|
||||
"isBattle": true,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'battle_air_idle')"
|
||||
],
|
||||
"quirks": [
|
||||
@@ -53,7 +55,8 @@
|
||||
"condition": "q.has_entity ? !q.in_air : 1.0",
|
||||
"isBattle": false,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'ground_idle')",
|
||||
{
|
||||
"condition": "q.is_ridden",
|
||||
@@ -77,7 +80,8 @@
|
||||
"poseTypes": ["WALK", "SWIM"],
|
||||
"condition": "q.has_entity ? !q.in_air && !q.is_sprinting : 1.0",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'ground_walk')",
|
||||
{
|
||||
"condition": "q.is_ridden",
|
||||
@@ -90,7 +94,8 @@
|
||||
"poseTypes": ["WALK", "SWIM"],
|
||||
"condition": "q.has_entity ? !q.in_air && q.is_sprinting : 0.0",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'ground_run')",
|
||||
{
|
||||
"condition": "q.is_ridden",
|
||||
@@ -106,7 +111,8 @@
|
||||
"isBattle": false,
|
||||
"condition": "!q.is_ridden",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'air_idle')"
|
||||
],
|
||||
"quirks": [
|
||||
@@ -118,7 +124,8 @@
|
||||
"isBattle": false,
|
||||
"condition": "q.is_ridden",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'air_idle')"
|
||||
],
|
||||
"quirks": [
|
||||
@@ -131,7 +138,8 @@
|
||||
"isBattle": false,
|
||||
"condition": "!q.is_gliding && !q.is_ridden",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'air_fly')"
|
||||
],
|
||||
"quirks": [
|
||||
@@ -143,7 +151,8 @@
|
||||
"isBattle": false,
|
||||
"condition": "!q.is_gliding && q.is_ridden",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'air_fly')",
|
||||
"q.bedrock('aerodactyl', 'ride_air_fly')"
|
||||
],
|
||||
@@ -157,7 +166,8 @@
|
||||
"isBattle": false,
|
||||
"condition": "q.is_gliding",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('neck', 1, 1, 25, -20, 20, -20)",
|
||||
"q.look('head', 1, 1, 22.5, -10, 15, -15)",
|
||||
"q.bedrock('aerodactyl', 'air_glide')",
|
||||
"q.bedrock('aerodactyl', 'air_dive')",
|
||||
{
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"portraitScale": 1.75,
|
||||
"portraitTranslation": [-0.3, -0.8, 0],
|
||||
"profileScale": 0.65,
|
||||
"profileTranslation": [-0.05, 0.45, 0],
|
||||
"rootBone": "chinchou",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('chinchou', 'cry')"
|
||||
},
|
||||
"poses": {
|
||||
"portrait": {
|
||||
"poseTypes": ["PORTRAIT", "PROFILE"],
|
||||
"animations": ["q.bedrock('chinchou', 'water_idle')"]
|
||||
},
|
||||
"battle-standing": {
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"animations": ["q.bedrock('chinchou', 'battle_idle')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('chinchou', 'blink')"
|
||||
]
|
||||
},
|
||||
"water-battle-standing": {
|
||||
"poseTypes": ["FLOAT"],
|
||||
"isBattle": true,
|
||||
"animations": ["q.bedrock('chinchou', 'water_battle_idle')"],
|
||||
"namedAnimations": {
|
||||
"faint": "q.bedrock('chinchou', 'water_faint', q.curve('one'))"
|
||||
},
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('chinchou', 'blink')"
|
||||
]
|
||||
},
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('chinchou', 'ground_idle')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('chinchou', 'blink')",
|
||||
"q.bedrock_quirk('chinchou', 'ground_quirk')"
|
||||
]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('chinchou', 'water_swim')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('chinchou', 'blink')"
|
||||
]
|
||||
},
|
||||
"floating": {
|
||||
"poseTypes": ["FLOAT"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('chinchou', 'water_idle')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('chinchou', 'blink')",
|
||||
"q.bedrock_quirk('chinchou', 'water_idle_quirk')"
|
||||
]
|
||||
},
|
||||
"swimming": {
|
||||
"poseTypes": ["SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('chinchou', 'water_swim')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('chinchou', 'blink')"
|
||||
]
|
||||
},
|
||||
"water-sleeping": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"isTouchingWater": true,
|
||||
"namedAnimations": {
|
||||
"cry": "q.bedrock_stateful('dummy', 'cry')"
|
||||
},
|
||||
"animations": ["q.bedrock('chinchou', 'water_sleep')"]
|
||||
},
|
||||
"sleeping": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"isTouchingWater": false,
|
||||
"namedAnimations": {
|
||||
"cry": "q.bedrock_stateful('dummy', 'cry')"
|
||||
},
|
||||
"animations": ["q.bedrock('chinchou', 'sleep')"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-8
@@ -26,15 +26,17 @@
|
||||
"battle-standing": {
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"animations": ["q.bedrock('lanturn', 'battle_idle')"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('lanturn', 'ground_battle_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"water-battle-standing": {
|
||||
"poseTypes": ["FLOAT"],
|
||||
"isBattle": true,
|
||||
"isTouchingWater": true,
|
||||
"animations": ["q.bedrock('lanturn', 'water_battle_idle')"],
|
||||
"namedAnimations": {
|
||||
"sleep": "q.bedrock('lanturn', 'water_faint', q.curve('one'))"
|
||||
"faint": "q.bedrock('lanturn', 'water_faint', q.curve('one'))"
|
||||
},
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
@@ -42,42 +44,49 @@
|
||||
"poseTypes": ["STAND", "WALK"],
|
||||
"condition": "q.in_air",
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"],
|
||||
"transformTicks": 3,
|
||||
"transformToTicks": 3
|
||||
},
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('lanturn', 'water_idle')"]
|
||||
"animations": ["q.bedrock('lanturn', 'water_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"]
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"surface-floating": {
|
||||
"poseTypes": ["STAND"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": false,
|
||||
"animations": ["q.bedrock('lanturn', 'water_idle')"]
|
||||
"animations": ["q.bedrock('lanturn', 'water_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"surface-swimming": {
|
||||
"poseTypes": ["WALK"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": false,
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"]
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"floating": {
|
||||
"poseTypes": ["FLOAT"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('lanturn', 'water_idle')"]
|
||||
"animations": ["q.bedrock('lanturn', 'water_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"swimming": {
|
||||
"poseTypes": ["SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"]
|
||||
"animations": ["q.bedrock('lanturn', 'water_swim')"],
|
||||
"quirks": ["q.bedrock_quirk('lanturn', 'blink')"]
|
||||
},
|
||||
"water-sleeping": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"namedAnimations": {
|
||||
"cry": "q.bedrock_primary('smeargle', 'battle_cry')"
|
||||
"cry": "q.bedrock_primary('smeargle', 'battle_cry', q.curve('symmetrical_wide'))"
|
||||
},
|
||||
"animations": ["q.look('head')", "q.bedrock('smeargle', 'battle_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('smeargle', 'blink')"]
|
||||
|
||||
-1
@@ -10,7 +10,6 @@
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
|
||||
"isBattle": false,
|
||||
"animations": ["q.look('head_ai')", "q.bedrock('snivy', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('snivy', 'blink')"]
|
||||
},
|
||||
|
||||
-1
@@ -10,7 +10,6 @@
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
|
||||
"isBattle": true,
|
||||
"animations": ["q.bedrock('dewpider', 'ground_idle')"]
|
||||
},
|
||||
"walking": {
|
||||
|
||||
-1
@@ -10,7 +10,6 @@
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
|
||||
"isBattle": true,
|
||||
"animations": ["q.bedrock('araquanid', 'ground_idle')"]
|
||||
},
|
||||
"walking": {
|
||||
|
||||
+1
@@ -6,6 +6,7 @@
|
||||
"rootBone": "tadbulb",
|
||||
"animations": {
|
||||
"faint": "q.bedrock_primary('tadbulb', 'faint', q.curve('one'))",
|
||||
"cry": "q.bedrock_stateful('tadbulb', 'cry')",
|
||||
"recoil": "q.bedrock_stateful('tadbulb', 'recoil')",
|
||||
"physical": "q.bedrock_primary('tadbulb', 'physical', q.curve('symmetrical_wide'))",
|
||||
"special": "q.bedrock_primary('tadbulb', 'special', q.curve('symmetrical'))",
|
||||
|
||||
+1
@@ -6,6 +6,7 @@
|
||||
"rootBone": "bellibolt",
|
||||
"animations": {
|
||||
"faint": "q.bedrock_primary('bellibolt', 'faint', q.curve('one'))",
|
||||
"cry": "q.bedrock_stateful('bellibolt', 'cry')",
|
||||
"recoil": "q.bedrock_stateful('bellibolt', 'recoil')",
|
||||
"physical": "q.bedrock_primary('bellibolt', 'physical', q.curve('symmetrical_wide'))",
|
||||
"special": "q.bedrock_primary('bellibolt', 'special', q.curve('symmetrical_wide'))",
|
||||
|
||||
+12
@@ -14,6 +14,18 @@
|
||||
"shiny"
|
||||
],
|
||||
"texture": "cobblemon:textures/pokemon/0475_gallade/gallade_shiny.png"
|
||||
},
|
||||
{
|
||||
"aspects": [
|
||||
"alpha_eyes"
|
||||
],
|
||||
"layers": [
|
||||
{
|
||||
"name": "alpha_eyes",
|
||||
"texture": "cobblemon:textures/pokemon/0475_gallade/gallade_alpha.png",
|
||||
"emissive": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+12
@@ -27,6 +27,18 @@
|
||||
"texture": "cobblemon:textures/pokemon/0486_regigigas/regigigas_emissive.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aspects": [
|
||||
"alpha_eyes"
|
||||
],
|
||||
"layers": [
|
||||
{
|
||||
"name": "alpha_eyes",
|
||||
"texture": "cobblemon:textures/pokemon/0486_regigigas/regigigas_alpha.png",
|
||||
"emissive": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+2
-1
@@ -16,7 +16,8 @@
|
||||
{
|
||||
"name": "translucent",
|
||||
"texture": "cobblemon:textures/pokemon/0751_dewpider/dewpider_translucent.png",
|
||||
"translucent": true
|
||||
"translucent": true,
|
||||
"translucent_cull": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@
|
||||
{
|
||||
"name": "translucent",
|
||||
"texture": "cobblemon:textures/pokemon/0752_araquanid/araquanid_translucent.png",
|
||||
"translucent": true
|
||||
"translucent": true,
|
||||
"translucent_cull": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -848,11 +848,6 @@
|
||||
"cobblemon.gender.male": "Male",
|
||||
"cobblemon.gender.genderless": "Genderless",
|
||||
"cobblemon.fossilmachine.protected": "This fossil belongs to %s!",
|
||||
|
||||
"cobblemon.poke_skill.quick_ride.name": "Quick Ride",
|
||||
"cobblemon.poke_skill.teleport.name": "Teleport",
|
||||
"cobblemon.poke_skill.iron_sense.name": "Iron Sense",
|
||||
|
||||
"itemGroup.cobblemon.blocks": "Cobblemon: Blocks",
|
||||
"itemGroup.cobblemon.utility_item": "Cobblemon: Utility Items",
|
||||
"itemGroup.cobblemon.agriculture": "Cobblemon: Agriculture",
|
||||
@@ -2537,8 +2532,6 @@
|
||||
"cobblemon.config.ui.unlock_all_move_dex_moves_by_default.tooltip": "If enabled, TM and level-up moves are unlocked and discovered in the TM Machine and Pokédex Move Dex.",
|
||||
"cobblemon.config.ui.infinite_tm_uses": "Infinite TM Uses",
|
||||
"cobblemon.config.ui.infinite_tm_uses.tooltip": "TMs are not consumed when teaching moves.",
|
||||
"cobblemon.config.ui.infinite_poke_skill_cooldown": "Infinite Poké Skill Cooldown",
|
||||
"cobblemon.config.ui.infinite_poke_skill_cooldown.tooltip": "Poké Skills do not go on cooldown after use.",
|
||||
"cobblemon.config.ui.hide_unimplemented_pokemon_in_the_pokedex": "Hide Unimplemented Pokémon in the Pokédex",
|
||||
"cobblemon.config.ui.hide_unimplemented_pokemon_in_the_pokedex.tooltip": "Whether to hide unimplemented Pokémon from the Pokédex.",
|
||||
"cobblemon.config.ui.summary_pokemon_follow_cursor": "Make Pokémon Follow Cursor",
|
||||
|
||||
@@ -977,6 +977,176 @@
|
||||
{ "name": "cobblemon:block/item_block/paper_large_break_3", "volume": 0.6 }
|
||||
]
|
||||
},
|
||||
"block.bright_powder.use": {
|
||||
"subtitle": "cobblemon.subtitle.item.bright_powder.use",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/bright_powder/bright_powder_use_1", "volume": 0.35 },
|
||||
{ "name": "cobblemon:block/bright_powder/bright_powder_use_2", "volume": 0.35 },
|
||||
{ "name": "cobblemon:block/bright_powder/bright_powder_use_3", "volume": 0.35 }
|
||||
]
|
||||
},
|
||||
"block.item_block.bottle_liquid.place": {
|
||||
"subtitle": "subtitles.block.generic.place",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_place_1", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_place_2", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_place_3", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_place_4", "volume": 0.4 }
|
||||
]
|
||||
},
|
||||
"block.item_block.bottle_liquid.break": {
|
||||
"subtitle": "subtitles.block.generic.break",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_break_1", "volume": 0.5 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_break_2", "volume": 0.5 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_break_3", "volume": 0.5 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_break_4", "volume": 0.5 }
|
||||
]
|
||||
},
|
||||
"block.item_block.bottle_liquid.step": {
|
||||
"subtitle": "subtitles.block.generic.footsteps",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_step_1", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_step_2", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_step_3", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_liquid_step_4", "volume": 0.2 }
|
||||
]
|
||||
},
|
||||
"block.item_block.bottle_pills.place": {
|
||||
"subtitle": "subtitles.block.generic.place",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_place_1", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_place_2", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_place_3", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_place_4", "volume": 0.4 }
|
||||
]
|
||||
},
|
||||
"block.item_block.bottle_pills.break": {
|
||||
"subtitle": "subtitles.block.generic.break",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_break_1", "volume": 0.5 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_break_2", "volume": 0.5 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_break_3", "volume": 0.5 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_break_4", "volume": 0.5 }
|
||||
]
|
||||
},
|
||||
"block.item_block.bottle_pills.step": {
|
||||
"subtitle": "subtitles.block.generic.footsteps",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_step_1", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_step_2", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_step_3", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/bottle_pills_step_4", "volume": 0.2 }
|
||||
]
|
||||
},
|
||||
"block.item_block.powder.place": {
|
||||
"subtitle": "subtitles.block.generic.place",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/powder_place_1", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/powder_place_2", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/powder_place_3", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/powder_place_4", "volume": 0.3 }
|
||||
]
|
||||
},
|
||||
"block.item_block.powder.break": {
|
||||
"subtitle": "subtitles.block.generic.break",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/powder_break_1", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/powder_break_2", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/powder_break_3", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/powder_break_4", "volume": 0.4 }
|
||||
]
|
||||
},
|
||||
"block.item_block.powder.step": {
|
||||
"subtitle": "subtitles.block.generic.footsteps",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/powder_step_1", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/powder_step_2", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/powder_step_3", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/powder_step_4", "volume": 0.2 }
|
||||
]
|
||||
},
|
||||
"block.item_block.dice.place": {
|
||||
"subtitle": "subtitles.block.generic.place",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/dice_place_1", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/dice_place_2", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/dice_place_3", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/dice_place_4", "volume": 0.3 }
|
||||
]
|
||||
},
|
||||
"block.item_block.dice.break": {
|
||||
"subtitle": "subtitles.block.generic.break",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/dice_break_1", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/dice_break_2", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/dice_break_3", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/dice_break_4", "volume": 0.4 }
|
||||
]
|
||||
},
|
||||
"block.item_block.dice.step": {
|
||||
"subtitle": "subtitles.block.generic.footsteps",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/dice_step_1", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/dice_step_2", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/dice_step_3", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/dice_step_4", "volume": 0.2 }
|
||||
]
|
||||
},
|
||||
"block.item_block.metal_can.place": {
|
||||
"subtitle": "subtitles.block.generic.place",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/metal_can_place_1", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_place_2", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_place_3", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_place_4", "volume": 0.3 }
|
||||
]
|
||||
},
|
||||
"block.item_block.metal_can.break": {
|
||||
"subtitle": "subtitles.block.generic.break",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/metal_can_break_1", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_break_2", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_break_3", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_break_4", "volume": 0.4 }
|
||||
]
|
||||
},
|
||||
"block.item_block.metal_can.step": {
|
||||
"subtitle": "subtitles.block.generic.footsteps",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/metal_can_step_1", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_step_2", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_step_3", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/metal_can_step_4", "volume": 0.2 }
|
||||
]
|
||||
},
|
||||
"block.item_block.jar_glass_liquid.place": {
|
||||
"subtitle": "subtitles.block.generic.place",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_place_1", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_place_2", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_place_3", "volume": 0.3 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_place_4", "volume": 0.3 }
|
||||
]
|
||||
},
|
||||
"block.item_block.jar_glass_liquid.break": {
|
||||
"subtitle": "subtitles.block.generic.break",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_break_1", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_break_2", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_break_3", "volume": 0.4 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_break_4", "volume": 0.4 }
|
||||
]
|
||||
},
|
||||
"block.item_block.jar_glass_liquid.step": {
|
||||
"subtitle": "subtitles.block.generic.footsteps",
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_step_1", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_step_2", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_step_3", "volume": 0.2 },
|
||||
{ "name": "cobblemon:block/item_block/jar_glass_liquid_step_4", "volume": 0.2 }
|
||||
]
|
||||
},
|
||||
"move.absorb.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/absorb/absorb_actor", "volume": 0.3 } ]
|
||||
},
|
||||
@@ -1346,7 +1516,7 @@
|
||||
"sounds": [ { "name": "cobblemon:move/icebeam/icebeam_target_1", "volume": 0.8 } ]
|
||||
},
|
||||
"move.icebeam.target_2": {
|
||||
"sounds": [ { "name": "cobblemon:move/icebeam/icebeam_target_2", "volume": 0.8 } ]
|
||||
"sounds": [ { "name": "cobblemon:move/icebeam/icebeam_target_2", "volume": 0.5 } ]
|
||||
},
|
||||
"move.infestation.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/infestation/infestation_actor", "volume": 0.8 } ]
|
||||
@@ -1453,6 +1623,57 @@
|
||||
"move.waterpulse.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/waterpulse/waterpulse_target", "volume": 0.8 } ]
|
||||
},
|
||||
"move.leafstorm.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/leafstorm/leafstorm_actor", "volume": 1.0 } ]
|
||||
},
|
||||
"move.leafstorm.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/leafstorm/leafstorm_target", "volume": 1.0 } ]
|
||||
},
|
||||
"move.suckerpunch.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/suckerpunch/suckerpunch_target", "volume": 1.0 } ]
|
||||
},
|
||||
"move.blizzard.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/blizzard/blizzard_actor", "volume": 1.0 } ]
|
||||
},
|
||||
"move.blizzard.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/blizzard/blizzard_target", "volume": 1.0 } ]
|
||||
},
|
||||
"move.hydropump.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/hydropump/hydropump_actor", "volume": 1.0 } ]
|
||||
},
|
||||
"move.hydropump.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/hydropump/hydropump_target", "volume": 1.0 } ]
|
||||
},
|
||||
"move.lightscreen.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/lightscreen/lightscreen_actor", "volume": 1.0 } ]
|
||||
},
|
||||
"move.horndrill.target_1": {
|
||||
"sounds": [ { "name": "cobblemon:move/horndrill/horndrill_target_1", "volume": 0.8 } ]
|
||||
},
|
||||
"move.horndrill.target_2": {
|
||||
"sounds": [ { "name": "cobblemon:move/horndrill/horndrill_target_2", "volume": 1.0 } ]
|
||||
},
|
||||
"move.playrough.actor_1": {
|
||||
"sounds": [ { "name": "cobblemon:move/playrough/playrough_actor_1", "volume": 1.0 } ]
|
||||
},
|
||||
"move.playrough.actor_2": {
|
||||
"sounds": [ { "name": "cobblemon:move/playrough/playrough_actor_2", "volume": 1.0 } ]
|
||||
},
|
||||
"move.playrough.actor_3": {
|
||||
"sounds": [ { "name": "cobblemon:move/playrough/playrough_actor_3", "volume": 1.0 } ]
|
||||
},
|
||||
"move.playrough.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/playrough/playrough_target", "volume": 1.0 } ]
|
||||
},
|
||||
"move.pyroball.actor": {
|
||||
"sounds": [ { "name": "cobblemon:move/pyroball/pyroball_actor", "volume": 1.0 } ]
|
||||
},
|
||||
"move.pyroball.actor_cinderace": {
|
||||
"sounds": [ { "name": "cobblemon:move/pyroball/pyroball_actor_cinderace", "volume": 1.0 } ]
|
||||
},
|
||||
"move.pyroball.target": {
|
||||
"sounds": [ { "name": "cobblemon:move/pyroball/pyroball_target", "volume": 1.0 } ]
|
||||
},
|
||||
"impact.normal": {
|
||||
"sounds": [
|
||||
{ "name": "cobblemon:move/impact_generic/impact_generic_fighting_1", "volume": 0.8 },
|
||||
@@ -6380,6 +6601,9 @@
|
||||
"pokemon.cherrim.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/cherrim/cherrim_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.cherrim_sunshine.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/cherrim/cherrim_sunshine_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.shellos.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/shellos/shellos_cry", "volume": 0.8 } ]
|
||||
},
|
||||
@@ -7403,8 +7627,14 @@
|
||||
"pokemon.rockruff.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/rockruff/rockruff_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.lycanroc.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/lycanroc/lycanroc_cry", "volume": 0.8 } ]
|
||||
"pokemon.lycanroc_midday.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/lycanroc/lycanroc_midday_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.lycanroc_midnight.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/lycanroc/lycanroc_midnight_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.lycanroc_dusk.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/lycanroc/lycanroc_dusk_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.wishiwashi.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/wishiwashi/wishiwashi_cry", "volume": 0.8 } ]
|
||||
@@ -7826,6 +8056,9 @@
|
||||
"pokemon.duraludon.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/duraludon/duraludon_cry", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.duraludon.bonk": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/duraludon/duraludon_bonk", "volume": 0.8 } ]
|
||||
},
|
||||
"pokemon.dreepy.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/dreepy/dreepy_cry", "volume": 0.8 } ]
|
||||
},
|
||||
@@ -8273,4 +8506,4 @@
|
||||
"pokemon.pecharunt.cry": {
|
||||
"sounds": [ { "name": "cobblemon:pokemon/pecharunt/pecharunt_cry", "volume": 0.8 } ]
|
||||
}
|
||||
}
|
||||
},
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Loaded 100 of 156 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user