Example #1
0
func (player *Player) PacketPlayerBlockHit(status DigStatus, target *BlockXyz, face Face) {
	player.lock.Lock()
	defer player.lock.Unlock()

	// This packet handles 'throwing' an item as well, with status = 4, and
	// the zero values for target and face, so check for that.
	if status == DigDropItem && target.IsZero() && face == 0 {
		blockLoc := player.position.ToBlockXyz()
		shardClient, _, ok := player.chunkSubs.ShardClientForBlockXyz(blockLoc)
		if !ok {
			return
		}

		var itemToThrow gamerules.Slot
		player.inventory.TakeOneHeldItem(&itemToThrow)
		if !itemToThrow.IsEmpty() {
			velocity := physics.VelocityFromLook(player.look, 0.50)
			position := player.position
			position.Y += player.height
			shardClient.ReqDropItem(itemToThrow, position, velocity, TicksPerSecond/2)
		}
		return
	}

	// Validate that the player is actually somewhere near the block.
	targetAbsPos := target.MidPointToAbsXyz()
	if !targetAbsPos.IsWithinDistanceOf(&player.position, MaxInteractDistance) {
		log.Printf("Player/PacketPlayerBlockHit: ignoring player dig at %v (too far away)", target)
		return
	}

	// TODO measure the dig time on the target block and relay to the shard to
	// stop speed hacking (based on block type and tool used - non-trivial).

	shardClient, _, ok := player.chunkSubs.ShardClientForBlockXyz(target)
	if ok {
		held, _ := player.inventory.HeldItem()
		shardClient.ReqHitBlock(held, *target, status, face)
	}
}