Jump to content

Why does trace result differs between ClientSide and ServerSide?


WeAthFolD

Recommended Posts

I've been trying to work out something like guns, and I tried to use Minecraft's RayTraceBlocks function,and I've met with a strange difficulty.

class BulletManager{
        ....Other methods
public static void Shoot(ItemStack itemStack, EntityLiving entityPlayer, World worldObj, String particle){

	if(!(itemStack.getItem() instanceof WeaponGeneral))
		return;

	WeaponGeneral item = (WeaponGeneral) itemStack.getItem();
	InformationWeapon inf = item.getInformation(itemStack).getProperInf(worldObj);
	int mode = inf.mode;
	int damage = item.damage[mode];
	int offset = item.offset[mode]; //load Information of the specfic ItemStack
	MotionXYZ prem = new MotionXYZ(entityPlayer, 0).updateMotion(0.5D); //right before player
	MotionXYZ afterm = new MotionXYZ(entityPlayer, 0).updateMotion(300D); //end position

	worldObj.spawnParticle(particle , prem.posX, prem.posY, prem.posZ, prem.motionX, prem.motionY, prem.motionZ);


	//do rayTrace
	Vec3 pre = prem.asVec3(worldObj), after = afterm.asVec3(worldObj);
	MovingObjectPosition result = doTrace(worldObj, pre, after, entityPlayer);//Trace both blocks and entities
                //*******SERVER AND CLIENT BEHAVES DIFFERENTLY,WHY?QaQ

	if(result != null)
		System.out.println("RayTrace result: " + result.typeOfHit + ",isRemote: " + worldObj.isRemote);

	switch(result.typeOfHit){
	case ENTITY:
		doEntityCollision(result, itemStack, worldObj, entityPlayer, prem);
		if( worldObj.getBlockId(result.blockX,result.blockY,result.blockZ) > 0 ){
			doBlockCollision(result, itemStack, worldObj, entityPlayer, prem);
		}
		break;
	case TILE:
		doBlockCollision(result, itemStack, worldObj, entityPlayer, prem);
		break;

	default:
		break;
	}
	return;

}

private static MovingObjectPosition doTrace(World world, Vec3 pre, Vec3 after, EntityLiving player){

	MovingObjectPosition result;

	result = world.rayTraceBlocks_do(pre, after, true);
	MotionXYZ var0 = new MotionXYZ(player,0).updateMotion(0.5D);
	int blocksAway = 0;
	if(result != null){
		after = result.hitVec;
		blocksAway = (int) Math.round((after.xCoord - var0.posX)/var0.motionX);
	} else {
		after = new MotionXYZ(player, 0).asVec3(world);
		blocksAway = ENTITY_TRACE_RANGE;
	}
	System.out.println("BlocksAway : " + blocksAway);
	AxisAlignedBB bBox;
	List list;

	for(int i = 0; i < blocksAway; i++){
		bBox = AxisAlignedBB.getBoundingBox(var0.posX-BB_SIZE, var0.posY-BB_SIZE, var0.posZ-BB_SIZE,
				var0.posX+BB_SIZE, var0.posY+BB_SIZE, var0.posZ+BB_SIZE);
		list = world.getEntitiesWithinAABBExcludingEntity(player, bBox);
		if(list.size() >0){
			Entity var1;
			for(int j=0; j< list.size(); j++){
				var1 = (Entity) list.get(j);
				if(var1 instanceof EntityLiving){
					if(result == null)
						result = new MovingObjectPosition(var1);
					result.entityHit = var1;
					result.typeOfHit = EnumMovingObjectType.ENTITY;
				}
			}
		}
		var0.updateMotion(2*BB_SIZE);
	}
	return result;

}

public static void doEntityCollision(MovingObjectPosition result, ItemStack itemStack, World worldObj, EntityLiving player, MotionXYZ begin){

	if(result == null)
		return;
	if(!(result.entityHit instanceof EntityLiving))
		return;

	WeaponGeneral item = (WeaponGeneral) itemStack.getItem();
	InformationWeapon inf = item.getInformation(itemStack).getProperInf(worldObj);
	int mode = inf.mode;
	double pf = item.pushForce[mode];
	double dx = begin.motionX * pf, dy = begin.motionY * pf, dz = begin.motionZ * pf;
	EntityLiving mob = (EntityLiving) result.entityHit;
	System.out.println("Hit side: " + worldObj.isRemote + ", Mob Side: " + mob.worldObj.isRemote);
                //Attack Mob and add Velocity,which doesn't work everytime(ACTUALLY A LOT OF TIME)
	mob.attackEntityFrom(DamageSource.causeMobDamage(player), item.damage[mode]);
	mob.addVelocity(dx, dy, dz);

}

}

MotionXYZ is a class I created which contains PosXYZ and MotionXYZ information.

BTW,0 on the constructor is offset,which make MotionXYZ a random range.

The Shoot Method is called within Item class when holding Right mouse.

I expected the result to work out just fine,but it turns out that the collision result I get from Server and Client side is really different.

Once shot, I can see the mob being hit(Velocity changed),but it wasn't hurt and comes back to its origin position few seconds later.

on console I can see that Trace results between Client and Server are totally different,one on the CLIENT is ENTITY, another one on the SERVER is TILE.

I was really confused. How could it be possibly different when I use the same Vec3 at almost exact same tick?How do I fix this?If I can't , can I use other ways such as Trace only in CLIENT and hurt the mob on Serverside?

Sorry for my bad English, and thanks for your reading and answering my question :D

Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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