Jump to content

Recommended Posts

Posted

Player starts casting skill, if certain movement occurs casting is interrupted. Now:

Smartest way to check:

- If player himself trigerred movement (movement = make acceleration, not slowing down, because that would require you to totally stop to zero before casting skill).

- If something else triggered movement (knockback/water).

 

My only idea is to save acceleration (x,y,z) every tick and compare, but how to track source? Maybe catch movement packcets, but I have no idea how.

 

Also: i could use some light on positioning fields.

there is posX, lastTickPosX, prevPosX, motionX, nextStepDistance, newPosX, damn, probably even more.

1.7.10 is no longer supported by forge, you are on your own.

Posted

Compare the previous posX, Y, and Z with the current posX, Y, and Z.  Comparing acceleration will not determine whether the player is moving, as you could have an acceleration of zero yet you still maintain your velocity. 

Posted

I'll just note: If you can think of it in 30sec or less, I alredy did/tried that. I need something creative, or rather "from experience". *wink*

Position != movement.

I need to track down SOURCE of movement, not the position changes. As said in main post - the fact that player is moving doesn't mean he's accellerating. And I mostly care about acceleration.

 

Offtopic:

@deadrecon98 - I'd write this in other thread, but since this one is mine I'm personally asking you to stop writing false/impolite stuff on support forums. If you don't plan on helping, don't trash people looking for help. It happens often when you appear on forums (look at your karma). And no, this is not about this thread, I am just politely pointing out.

1.7.10 is no longer supported by forge, you are on your own.

Posted

You want to know if the player has moved while the spell is being cast, correct?  Because checking for a change in your X, Y and Z coordinates greater than k units is how you can do that, just take the initial position during spell cast and compare.  Otherwise, please elaborate, because you stated that you want casting to stop if movement occurs. 

Posted

Player starts casting skill, if certain movement occurs casting is interrupted. Now:

Smartest way to check:

- If player himself trigerred movement (movement = make acceleration, not slowing down, because that would require you to totally stop to zero before casting skill).

- If something else triggered movement (knockback/water).

 

My only idea is to save acceleration (x,y,z) every tick and compare, but how to track source? Maybe catch movement packcets, but I have no idea how.

 

Also: i could use some light on positioning fields.

there is posX, lastTickPosX, prevPosX, motionX, nextStepDistance, newPosX, damn, probably even more.

 

It is really pity that this is impossible in minecraft system...

You cannot get the 'source' of a movement, Since it could just be from addVelocity or sth.

 

Actually I also wanted to do something similar for altering gravitation,

but LexManos said that even a PR on it would be rejected...

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

entity.motionX/Y/Z would generally work for your needs, as that is the current motion of any entity (if any motion > 0, stop casting); however, for EntityPlayer, there is the problem that sometimes player.motionX/Y/Z is different on the client side (which is where player motion usually begins via player input) or even never sent to the server (i.e. by mods), making it less than ideal.

 

entity.posY/X/Z is always the current position of the entity, and even for players this should always be the same between client <-> server due to update packets.

 

Those are the most important and most often used of the movement/position fields; the others, like lastTickPosX/Y/Z, are generally used for a specific internal use and not that useful to modders, though I'm sure there are some use cases.

 

Anyway, as the first reply to your topic suggested, your best bet here is to store the player's initial position when they begin casting, and each tick check the player's distance to that point; if it's greater than whatever threshold you decide, then the player has 'moved' and the casting cancelled.

 

Whether you need to use TickEvent or not depends on how your casting is handled, e.g. if you have access to any ticking method (usually #onUpdate of some sort), then you can check it from there instead.

 

EDIT: To clarify since you seem to want "acceleration" instead of "position" - how that makes sense at all when your title is 'Check if player moved' is your call - store the initial motionX/Y/Z instead of posX/Y/Z and keep track of the difference each tick, but keep in mind the note about EntityPlayer's motion as well as the fact that motion values (as well as position values) can be negative, so you'll probably want to get Pythagorean on them.

Posted

1. Player is running.

2. Stops running, but is sliding on ice.

* Movement occurs, but there is no player-made acceleration.

* Therefore I have to wait until I stop sliding before I can even start casting skill.

 

- That's what I mean by acceleration. You are moving but not because someone is pushing you, knockback, or your own movement, but because there is a leftover of your speed.

- Obviously I understand that I can save initial acceleration and just check if curent is bigger than initial, but that might allow caster to do "micro-steps" as long as he is in range of max acceleration. Well, unless I will update previous acceleration fields on every tick - in that case - it's perfect system.

 

Anyway, looking at it now I might be able to have some fun with distance from point 0 (where started casting) and actually make it close to "neat". This weekend's gonna be fun :)

1.7.10 is no longer supported by forge, you are on your own.

Posted

check if

moveStrafing

and

moveForward

are between 0.01F and -0.01F. Those determine the acceleration (strafing => acc. left & right; forward => acc. forward & backward)

 

Why check between values? Because both are floating point numbers and you can't check

float == value

reliably

Don't ask for support per PM! They'll get ignored! | If a post helped you, click the "Thank You" button at the top right corner of said post! |

mah twitter

This thread makes me sad because people just post copy-paste-ready code when it's obvious that the OP has little to no programming experience. This is not how learning works.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; 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.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.