Skip to content

Commit

Permalink
Cobblemount fix
Browse files Browse the repository at this point in the history
Moved movement logic to clientside to be independent for ping
   Config syncs to client
Fixed on-ground movement animations
Added overwriting for flying pokemons (it may be useful for pokemons like beedrill that don't have flying type or what it is idk i'm not into pokemons)
  • Loading branch information
JumperOnJava committed Dec 22, 2023
1 parent 853517d commit 0e5f218
Show file tree
Hide file tree
Showing 17 changed files with 521 additions and 328 deletions.
11 changes: 8 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ plugins {
id 'fabric-loom' version '1.4-SNAPSHOT'
id 'maven-publish'
id("com.github.johnrengelman.shadow") version "8.1.1"
id("org.jetbrains.kotlin.jvm") version "1.8.10"

}

version = project.mod_version
Expand All @@ -31,7 +33,9 @@ repositories {
includeGroup("curse.maven")
}
}

maven {
url = "https://maven.impactdev.net/repository/development/"
}
maven {
name 'Fabric Permission API'
url 'https://oss.sonatype.org/content/repositories/snapshots'
Expand Down Expand Up @@ -60,8 +64,9 @@ dependencies {
// Required mod shit
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation('me.lucko:fabric-permissions-api:0.2-SNAPSHOT')
modImplementation("curse.maven:cobblemon-687131:${project.cobblemon_curse_file_id}")
compileOnly 'net.luckperms:api:5.4'
modImplementation("com.cobblemon:fabric:1.4.0+1.20.1")
modCompileOnly 'net.luckperms:api:5.4'

modImplementation("curse.maven:architectury-api-419699:4555749")

include(implementation('com.moandjiezana.toml:toml4j:0.7.2'))
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ yarn_mappings=1.20.1+build.1
loader_version=0.14.22

# Mod Properties
mod_version=1.1.2
mod_version=1.2.0
maven_group=net.ioixd
archives_base_name=cobblemounts

Expand Down
38 changes: 12 additions & 26 deletions src/client/java/net/ioixd/CobblemountsClient.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,25 @@
package net.ioixd;

import io.netty.buffer.Unpooled;
import net.fabricmc.api.ClientModInitializer;

import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.networking.v1.PacketType;
import net.minecraft.client.network.ClientPlayerEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CobblemountsClient implements ClientModInitializer {
public static final Identifier PLAYER_JUMP_PACKET = new Identifier("cobblemounts:player_jumped");
public static final Identifier PLAYER_CROUCH_PACKET = new Identifier("cobblemounts:player_crouched");
public static final String MOD_ID = "Cobblemounts";
public static final String MOD_ID = "cobblemounts";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

@Override
public static Config SYNCED_CONFIG = new Config();
private PacketType<Config> configPacketType = PacketType.create(Cobblemounts.CONFIG_SYNC_ID,Config::read);
public void onInitializeClient() {

ClientTickEvents.END_CLIENT_TICK.register(client -> {
while (client.options.jumpKey.wasPressed()) {
if (client.player != null) {
PacketByteBuf passedData = new PacketByteBuf(Unpooled.buffer());
passedData.writeUuid(client.player.getUuid());
ClientPlayNetworking.send(PLAYER_JUMP_PACKET, passedData);
}
}
while (client.options.sneakKey.wasPressed()) {
if (client.player != null) {
PacketByteBuf passedData = new PacketByteBuf(Unpooled.buffer());
passedData.writeUuid(client.player.getUuid());
ClientPlayNetworking.send(PLAYER_CROUCH_PACKET, passedData);
}
}
});
ClientPlayNetworking.registerGlobalReceiver(configPacketType, CobblemountsClient::onSyncPacket);
}
private static void onSyncPacket(Config packet, ClientPlayerEntity player, PacketSender responseSender) {
SYNCED_CONFIG = packet;
}

}
167 changes: 167 additions & 0 deletions src/client/java/net/ioixd/mixin/PokemonMovementHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package net.ioixd.mixin;

import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.Pokemon;

import net.ioixd.CobblemountsClient;
import net.ioixd.MountIsMoving;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.*;
import net.minecraft.entity.passive.TameableShoulderEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import java.util.concurrent.atomic.AtomicBoolean;

@Mixin(PokemonEntity.class)
public abstract class PokemonMovementHandler extends LivingEntity {
@Shadow public abstract void playAmbientSound();

int ticksInLiquid = 0;

protected PokemonMovementHandler(EntityType<? extends LivingEntity> entityType, World world) {
super(entityType, world);
}

protected void tickControlled(PlayerEntity player, Vec3d movement) {
//PlayerEntity player = (PlayerEntity) (Object) this;
//Entity entity = player.getVehicle();
var pokemon = (PokemonEntity) (Object) this;
//if (entity == null) return;
//if (!(entity instanceof PokemonEntity pokemon)) return;


movement = new Vec3d(player.sidewaysSpeed,0,player.forwardSpeed);
World world = pokemon.getWorld();
Pokemon pokemonData = pokemon.getPokemon();
pokemon.setYaw(player.getYaw());
pokemon.setPitch(pokemon.getPitch());
pokemon.setHeadYaw(player.getYaw());

Block water = pokemon.getBlockStateAtPos().getBlock();
boolean inLiquid = water instanceof FluidBlock;

float speedModifier = pokemonData.isLegendary() ? 0.0f : (float) CobblemountsClient.SYNCED_CONFIG.legendaryModifier;
AtomicBoolean isFlying = new AtomicBoolean(false);
Vec3d moveXZ = movement;//movement.rotateY((float) Math.toRadians(-player.getYaw()));
Vec3d forward = player.getRotationVector().normalize().multiply(movement.z);
//forward = movement.multiply(0, 0, 1).rotateY((float) Math.toRadians(-player.getYaw()));

Vec3d left = movement.multiply(1, 0, 0).rotateY((float) Math.toRadians(-player.getYaw()));

Vec3d flyMove = forward.add(left);
Vec3d moveY = movement.multiply(0, 0, 0);


double movementSpeed_ = (pokemonData.getSpeed() / 500.0f) + speedModifier;
if (CobblemountsClient.SYNCED_CONFIG.cappedSpeed) {
if (movementSpeed_ >= CobblemountsClient.SYNCED_CONFIG.flyingSpeedCap) {
movementSpeed_ = CobblemountsClient.SYNCED_CONFIG.flyingSpeedCap;
}
}
double[] movementSpeed = new double[]{movementSpeed_};
var pokemonName = pokemonData.getSpecies().getName().toLowerCase();
pokemonData.getTypes().forEach(ty -> {
var name = ty.getName();
if(CobblemountsClient.SYNCED_CONFIG.alsoFlyList.contains(pokemonName)){
name = "flying";
}
switch (name) {
case "water":
case "flying":
boolean condition;
EntityPose animation;
boolean flying;
switch (name) {
case "water":
if (!CobblemountsClient.SYNCED_CONFIG.allowSwimming) {
return;
}
condition = inLiquid;
animation = EntityPose.SWIMMING;
flying = false;
break;
case "flying":
if (!CobblemountsClient.SYNCED_CONFIG.allowFlying) {
return;
}
condition = !pokemon.isOnGround() && !inLiquid;
animation = EntityPose.FALL_FLYING;
flying = true;
break;
// We will never hit this part but we need to set the values anyways
// to make the compiler happy.
default:
condition = false;
animation = null;
flying = false;
break;
}
;
if (condition) {
if (flyMove.z != 0.0) {
//pokemon.updateVelocity(movementSpeed, player.getRotationVector());
pokemon.move(MovementType.SELF, flyMove.multiply(movementSpeed[0]));
isFlying.set(true);
}
if (flying) {
pokemon.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true);
}
pokemon.setPose(animation);
} else {
//pokemon.updateVelocity(0.0f, moveXZ);
pokemon.setPose(EntityPose.STANDING);
}
break;
}
});
if (!isFlying.get()) {
if (!(player instanceof ServerPlayerEntity) && MinecraftClient.getInstance().options.jumpKey.wasPressed() && pokemon.isOnGround()) {
pokemon.addVelocity(0, 0.7, 0);
}
pokemon.travel(moveXZ);
BlockPos forwardPos = getBlockPos(pokemon, player);
if (!isBlockPosTransparent(forwardPos, world)) {
BlockPos upperPos = new BlockPos(forwardPos.getX(), forwardPos.getY() + 1, forwardPos.getZ());
if (isBlockPosTransparent(upperPos, world)) {
BlockPos upperUpperPos = new BlockPos(upperPos.getX(), upperPos.getY() + 1,
upperPos.getZ());
if (isBlockPosTransparent(upperUpperPos, world)) {
pokemon.teleport(upperPos.getX(), upperPos.getY(), upperPos.getZ());
}
}
}
}
}
private static boolean isBlockPosTransparent(BlockPos pos, World world) {
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();
return block.isTransparent(state, world, pos) && !(block instanceof FluidBlock);
}
private static BlockPos getBlockPos(PokemonEntity living, PlayerEntity player) {
BlockPos forwardPos = living.getBlockPos();
int width = (int) Math.floor(living.getWidth());
for (int i = 0; i < width; i++) {
forwardPos = switch (player.getMovementDirection()) {
case NORTH -> forwardPos.north();
case SOUTH -> forwardPos.south();
case EAST -> forwardPos.east();
case WEST -> forwardPos.west();
default -> forwardPos;
};
}
return forwardPos;
}

}
70 changes: 70 additions & 0 deletions src/client/java/net/ioixd/mixin/PokemonUpdateTick.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package net.ioixd.mixin;

import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.Pokemon;
import net.ioixd.Cobblemounts;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.Vec3d;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(LivingEntity.class)
public class PokemonUpdateTick {
@Inject(at = @At("TAIL"), method = "travel")
private void tickMovement(Vec3d movement, CallbackInfo info) {
LivingEntity entity = ((LivingEntity) (Object) this);
if (entity instanceof PokemonEntity pokemonEntity) {
if (!pokemonEntity.hasPassengers()) {
pokemonEntity.setAiDisabled(false);
return;
}

pokemonEntity.fallDistance = 0;
pokemonEntity.setAiDisabled(true);
Pokemon pokemonData = pokemonEntity.getPokemon();
Entity firstPassenger = pokemonEntity.getFirstPassenger();
if (firstPassenger instanceof PlayerEntity player) {
// Make the Pokemon's position match the player's and set their position
// accordingly.
// accordinglypokemonEntity.bodyYaw = player.getYaw();
// pokemonEntity.headYaw = player.getYaw();
float speedModifier = pokemonData.isLegendary() ? 0.0f : (float) Cobblemounts.CONFIG.legendaryModifier;
float movementSpeed = player.getMovementSpeed() * (pokemonData.getSpeed() / 12.0f) + speedModifier;
if (Cobblemounts.CONFIG.cappedSpeed) {
if (movementSpeed >= Cobblemounts.CONFIG.speedCap) {
movementSpeed = (float) Cobblemounts.CONFIG.speedCap;
}
}
pokemonEntity.limbAnimator.setSpeed(pokemonEntity.getMovementSpeed() / 1.3f);

pokemonEntity.setMovementSpeed(movementSpeed);
pokemonEntity.setForwardSpeed(0);
pokemonEntity.setPitch(pokemonEntity.getPitch());

if (Cobblemounts.CONFIG.allowFlying) {
// If they're a flying type, set whether they have gravity or not.
pokemonData.getTypes().forEach(ty -> {
if (ty.getName().equals("flying")) {
pokemonEntity.setNoGravity(!pokemonEntity.isOnGround());
if (pokemonEntity.isOnGround() && pokemonEntity.getPose() == EntityPose.FALL_FLYING) {
pokemonEntity.setPose(EntityPose.STANDING);
pokemonEntity.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false);
pokemonEntity.updateVelocity(1.0f,
player.getRotationVector());
}
}
});
}

}
} else {
entity.setMovementSpeed(0.1f);
}
}
}
21 changes: 10 additions & 11 deletions src/main/java/net/ioixd/Cobblemounts.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
package net.ioixd;

import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import static net.minecraft.server.command.CommandManager.*;

import net.fabricmc.fabric.api.event.player.UseEntityCallback;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.item.Item;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import static net.minecraft.server.command.CommandManager.literal;

public class Cobblemounts implements ModInitializer {
public static final String MOD_ID = "Cobblemounts";
public static final String MOD_ID = "cobblemounts";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

public static final Identifier CONFIG_SYNC_ID = new Identifier(MOD_ID,"sync");
public static final Config CONFIG = new Config();

@Override
public void onInitialize() {

ServerPlayConnectionEvents.JOIN.register((networkHandler,packetSender,server)->{
ServerPlayNetworking.send(networkHandler.player,CONFIG);
});
CommandRegistrationCallback.EVENT
.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("cobblemounts")
.then(literal("reload")
.executes(context -> {
try {
Cobblemounts.CONFIG.update();
context.getSource().getServer().getPlayerManager().getPlayerList()
.forEach(p-> ServerPlayNetworking.send(p,CONFIG));
context.getSource().sendMessage(Text.literal("Reloaded configuration file."));
} catch (Exception ex) {
context.getSource().sendMessage(Text.literal(ex.getMessage()));
Expand Down Expand Up @@ -75,7 +76,5 @@ public void onInitialize() {
}
return ActionResult.PASS;
});
ServerPlayNetworking.registerGlobalReceiver(new Identifier("cobblemounts:player_jumped"), new PlayerJump());
ServerPlayNetworking.registerGlobalReceiver(new Identifier("cobblemounts:player_crouched"), new PlayerCrouch());
}
}
Loading

0 comments on commit 0e5f218

Please sign in to comment.