Jump to content

Recommended Posts

Posted (edited)

So I'm creating an "ice" block of sorts that is supposed to freeze any entities that are inside of it's collision box in place (don't worry about how they would ever get in there, I've already got that covered). By "freeze them in place", I mean that their motion X, Y and Z should all be a constant 0 until the ice block breaks. By simply calling Entity#setVelocity in Block#onEntityCollidedWithBlock in my block class and setting each value to 0, it for whatever reason only makes the entities slightly slower. When using the aforementioned technique in conjunction with calling LivingEvent#LivingUpdateEvent and doing this:

@SubscribeEvent
public void onLivingUpdate(LivingEvent.LivingUpdateEvent event) {
	Entity entity = event.getEntity();
	AxisAlignedBB axisalignedbb = entity.getEntityBoundingBox();
	BlockPos.PooledMutableBlockPos blockpos = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.minX + 0.001D, axisalignedbb.minY + 0.001D, axisalignedbb.minZ + 0.001D);
	BlockPos.PooledMutableBlockPos blockpos1 = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.maxX - 0.001D, axisalignedbb.maxY - 0.001D, axisalignedbb.maxZ - 0.001D);
	BlockPos.PooledMutableBlockPos blockpos2 = BlockPos.PooledMutableBlockPos.retain();

	if (entity.world.isAreaLoaded(blockpos, blockpos1)) {
		for (int i = blockpos.getX(); i <= blockpos1.getX(); ++i) {
           	for (int j = blockpos.getY(); j <= blockpos1.getY(); ++j) {
           		for (int k = blockpos.getZ(); k <= blockpos1.getZ(); ++k)  {
            		blockpos2.setPos(i, j, k);
            		IBlockState iblockstate = entity.world.getBlockState(blockpos2);
                        
            		if(iblockstate.getBlock() == GadgetBlocks.freeze_ray_ice) {
            			entity.setVelocity(0, 0, 0);
            		}
            	}
            }
		}
	}
}

, I'm able to pretty much stop vertical movement as long as it isn't a flying player or a bat, and oddly enough, most vertical movement too; if I freeze for instance a sheep and lure it with wheat, it won't move, same with baiting a hostile mob - but if the mob decides to wander randomly, as they tend to do, it actually can move around (all be it, very slowly)! This is made extra clear when you as a player get caught; it's very easy to move around with the keyboard. So my question is, is there a way to like cancel all movement before it happens (including players pressing keys)? I can't seem to find an event for it that I can cancel, but there might be some other way I haven't thought of?

 

Thanks in advance.

 

 

(Block class in case it's needed)

package themattyboy.gadgetsngoodies.blocks;

import net.minecraft.block.BlockFrostedIce;
import net.minecraft.block.SoundType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class BlockFreezeRayIce extends BlockFrostedIce {

	public BlockFreezeRayIce() {
		this.setSoundType(SoundType.GLASS);
	}
	
	@Override
	protected void turnIntoWater(World worldIn, BlockPos pos) {
		worldIn.setBlockToAir(pos);
	}
	
	@Override
	public boolean causesSuffocation(IBlockState state) {
		return false;
	}
	
	@Override
	public void harvestBlock(World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity te, ItemStack stack) {
		player.addStat(StatList.getBlockStats(this));
        player.addExhaustion(0.005F);
	}
	
	@Override
	public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) {
		entity.setVelocity(0, 0, 0);
	}
}

 

Edited by TheMattyBoy

IGN: matte006

Played Minecraft since summer 2011.

Modding is my life now.

Please check out my mod :)

https://minecraft.curseforge.com/projects/gadgets-n-goodies-mod?gameCategorySlug=mc-mods&projectID=230028

Posted (edited)

I have a Tile-Entity that does something very similar.
However, it stops hostiles in a large-ish area (8 block radius)
It also handles logic to allow mobs to get hurt, or even killed when frozen. (Normally, entities get a small invulnerability time after getting hurt, which when the event is stopped, never passes)

The logic is based on checking if the mobs is near known blocks that have this tile, instead of checking each block around the entity for blocks that have this tile (important distinction there)

 

You have to stop the mob from updating, not merely setting speed to 0. Skeletons will still shoot arrows, creepers will still explode etc otherwise.


You can view the event here, and the "registry" of placed blocks here.

Edited by Matryoshika

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Posted (edited)

Two things: first, I actually do want skeletons to shoot arrows and creepers to explode and what not. I don't want to freeze time, I merely want to freeze mobs in place so that they can't move/fly.

 

Second, the player is an issue... If I allow the event on the client side, all mobs including the player start jittering like mad when stuck in the ice, and if I limit the event to server side only, it works fine for other mobs but the player doesn't get affected.

 

Edit: It also brings a whole lot of other problems, such as, as you said, they don't take damage unless you do something about it, same with drowning, suffocating, you can't eat when in the ice, and probably a whole lot more that I haven't thought of... I really don't feel like coding a special case for ALL of these situations.

Edited by TheMattyBoy

IGN: matte006

Played Minecraft since summer 2011.

Modding is my life now.

Please check out my mod :)

https://minecraft.curseforge.com/projects/gadgets-n-goodies-mod?gameCategorySlug=mc-mods&projectID=230028

Posted

Well, that being the case, why don't you just give the entity the Slowness potion effect? I believe I used something extreme like 20 or so, for the amplifier parameter in PotionEffect(potion, int, int), in an older project I had back for 1.7.
(You'd have to either A) continuously apply a very short duration to each entity, or B) a very long one, and then remove it once the entity leaves/is removed from the area )

 

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Posted (edited)

Well, there are a few reasons. First of all we have the annoying FOV change (I know I could probably fix this with an event). Slowness doesn't affect knockback, so you could just punch out the mobs (again, should be an easy fix but still). Also, I know it might sound dumb but I'd prefer it if you didn't have the slowness icon in the inventory. But the main reason is that slowness doesn't affect all mobs, such as bats, squid and flying players, and it doesn't block vertical movement, so it's easy to just jump out. If I were to use slowness together with constantly setting only motionY to 0, the game would treat mobs as though they were flying, and slowness would have no affect.

Edited by TheMattyBoy

IGN: matte006

Played Minecraft since summer 2011.

Modding is my life now.

Please check out my mod :)

https://minecraft.curseforge.com/projects/gadgets-n-goodies-mod?gameCategorySlug=mc-mods&projectID=230028

Posted (edited)

Okay, I sort of solved it by doing this:

entity.setVelocity(0, 0, 0);
if(entity.posX != entity.prevPosX || entity.posY != entity.prevPosY || entity.posZ != entity.prevPosZ) {
	entity.setPositionAndUpdate(entity.prevPosX, entity.prevPosY, entity.prevPosZ);
}

but when you try to move, it starts jittering (seen as I'm teleporting the player every tick). Is there a way to cancel keyboard input from only the buttons [W], [A], [D], [SPACE] and [SHIFT]? I seem to remember there was an event for handling keyboard input, but I can't seem to find one.

Edited by TheMattyBoy

IGN: matte006

Played Minecraft since summer 2011.

Modding is my life now.

Please check out my mod :)

https://minecraft.curseforge.com/projects/gadgets-n-goodies-mod?gameCategorySlug=mc-mods&projectID=230028

Posted (edited)

EDIT: I was rereading the previous posts and you actually do want to allow some stuff when they are stunned, such as allowing mobs/players to attack and stuff so this won't really work for you. You will probably have to code for all the special situations. 

 

    I'm currently implementing a stun spell in my mod. I use a capability to store whether or not the entity is stunned and how long they will be stunned for. I actually have two capabilities, one for the player and one for the mobs because I store a lot of other data in the player capability, but I'm pretty sure you could use one capability for both. 

    So if the entity is an instance of EntityLiving I just turn off the AI with Entity#setNoAI(true) and set the stun duration in the capability. When you turn off the AI they still take damage but they don't get knocked back interestingly enough. Then I use LivingUpdateEvent to handle the increment of ticks stunned, and when it reaches the stun duration I do Entity#setNoAI(false).

    Next if the entity is an instance of EntityPlayer I set the isStunned boolean in the player capability to true and set the stun duration. Then in PlayerTickEvent I check if (player.world.isRemote) and then I check the players capability to see if the player isStunned. if they are stunned I increment the ticksStunned and if it's less than the duration I use KeyBinding.unPressAllKeys(); else IsetIsStunned(false) and setTicksStunned(0) 

    For the player I don't think this stops knockback so you would probably have to do something like what you already do to stop that, but it prevents them from moving. I'm pretty sure you can still use the esc, inventory, and 123456...(to quick select from hotbar) hotkeys when using unPressAllKeys() but you can't activate/use any items or attack/defend.

    Also no Idea if I'm doing something I shouldn't but this is what I found works for what I'm trying to do.

Edited by Kriptikz
Posted
3 hours ago, TheMattyBoy said:

but when you try to move, it starts jittering (seen as I'm teleporting the player every tick). Is there a way to cancel keyboard input from only the buttons [W], [A], [D], [SPACE] and [SHIFT]? I seem to remember there was an event for handling keyboard input, but I can't seem to find one.

This is because the client is responsible for the player's motion and sends its changes to the server. The server is then resetting the values and updating the client.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
10 hours ago, Draco18s said:

This is because the client is responsible for the player's motion and sends its changes to the server. The server is then resetting the values and updating the client.

I know, I was just pointing out that it happens and that I need to cancel certain key presses to compensate.

13 hours ago, Kriptikz said:

if they are stunned I increment the ticksStunned and if it's less than the duration I use KeyBinding.unPressAllKeys()

Hey, thank you for bringing this to my attention! The KeyBinding class was just what I needed (even though I settled for a slightly different method in the end).

 

 

I do believe my problems are solved now, thank you to all of you for your help! I really appreciate it!

(For those wondering, this is what I settled on):

entity.setVelocity(0, 0, 0);
if(entity.posX != entity.prevPosX || entity.posY != entity.prevPosY || entity.posZ != entity.prevPosZ) {
    entity.setPositionAndUpdate(entity.prevPosX, entity.prevPosY, entity.prevPosZ);
}
if(entity == Minecraft.getMinecraft().player) {
    KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindForward.getKeyCode(), false);
    KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindBack.getKeyCode(), false);
    KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindLeft.getKeyCode(), false);
    KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindRight.getKeyCode(), false);
    if(((EntityPlayer)entity).capabilities.isFlying) {
        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindJump.getKeyCode(), false);
        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindSneak.getKeyCode(), false);
    }
}

 

IGN: matte006

Played Minecraft since summer 2011.

Modding is my life now.

Please check out my mod :)

https://minecraft.curseforge.com/projects/gadgets-n-goodies-mod?gameCategorySlug=mc-mods&projectID=230028

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



×
×
  • Create New...

Important Information

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