示例#1
0
func (chunk *Chunk) reqInteractBlock(player gamerules.IPlayerClient, held gamerules.Slot, target *BlockXyz, againstFace Face) {
	// TODO use held item to better check of if the player is trying to place a
	// block vs. perform some other interaction (e.g hoeing dirt). This is
	// perhaps best solved by sending held item type and the face to
	// blockType.Aspect.Interact()

	blockInstance, blockType, ok := chunk.blockInstanceAndType(target)
	if !ok {
		return
	}

	if _, isBlockHeld := held.ItemTypeId.ToBlockId(); isBlockHeld && blockType.Attachable {
		// The player is interacting with a block that can be attached to.

		// Work out the position to put the block at.
		dx, dy, dz := againstFace.Dxyz()
		destLoc := target.AddXyz(dx, dy, dz)
		if destLoc == nil {
			// there is overflow with the translation, so do nothing
			return
		}

		player.PlaceHeldItem(*destLoc, held)
	} else {
		// Player is otherwise interacting with the block.
		blockType.Aspect.Interact(blockInstance, player)
	}

	return
}
示例#2
0
func cmdSay(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) {
	args := strings.Split(message, " ")
	if len(args) < 2 {
		player.EchoMessage(sayUsage)
		return
	}
	msg := strings.Join(args[1:], " ")
	cmdHandler.BroadcastMessage("§d" + msg)
}
示例#3
0
func cmdTell(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) {
	args := strings.Split(message, " ")
	if len(args) < 3 {
		player.EchoMessage(tellUsage)
		return
	}
	/* TODO Get player to send message, too
	player := args[1]
	message := strings.Join(args[2:], " ")
	*/
	player.EchoMessage(msgNotImplemented)
}
示例#4
0
func cmdTp(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) {
	args := strings.Split(message, " ")
	if len(args) < 3 {
		player.EchoMessage(tpUsage)
		return
	}

	teleportee := cmdHandler.PlayerByName(args[1])
	destination := cmdHandler.PlayerByName(args[2])
	if teleportee == nil {
		msg := fmt.Sprintf("'%s' is not logged in", args[1])
		player.EchoMessage(msg)
		return
	}
	if destination == nil {
		msg := fmt.Sprintf("'%s' is not logged in", args[2])
		player.EchoMessage(msg)
		return
	}

	pos, look := destination.PositionLook()

	// TODO: Remove this hack or figure out what needs to happen instead
	pos.Y += 1.63

	teleportee.EchoMessage(fmt.Sprintf("Hold still! You are being teleported to %s", args[2]))
	msg := fmt.Sprintf("Teleporting %s to %s at (%.2f, %.2f, %.2f)", args[1], args[2], pos.X, pos.Y, pos.Z)
	log.Printf("Message: %s", msg)
	player.EchoMessage(msg)

	teleportee.SetPositionLook(pos, look)
}
示例#5
0
func (chunk *Chunk) reqTakeItem(player gamerules.IPlayerClient, entityId EntityId) {
	if entity, ok := chunk.entities[entityId]; ok {
		if item, ok := entity.(*gamerules.Item); ok {
			player.GiveItemAtPosition(*item.Position(), *item.GetSlot())

			// Tell all subscribers to animate the item flying at the
			// player.
			buf := new(bytes.Buffer)
			proto.WriteItemCollect(buf, entityId, player.GetEntityId())
			chunk.reqMulticastPlayers(-1, buf.Bytes())
			chunk.removeEntity(item)
		}
	}
}
示例#6
0
func (chunk *Chunk) reqSubscribeChunk(entityId EntityId, player gamerules.IPlayerClient, notify bool) {
	if _, ok := chunk.subscribers[entityId]; ok {
		// Already subscribed.
		return
	}

	chunk.subscribers[entityId] = player

	// Transmit the chunk data to the new player.
	buf := new(bytes.Buffer)
	// chunk.shard.pktSerial.WritePacketsBuffer(buf, &proto.PacketPreChunk{ //@TODO 1.5.1
	//     ChunkLoc: chunk.loc,
	//     Mode:     ChunkInit,
	// })
	player.TransmitPacket(buf.Bytes())
	player.TransmitPacket(chunk.chunkPacket())
	if notify {
		player.NotifyChunkLoad()
	}

	// Send spawn packets for all entities in the chunk to the player.
	if len(chunk.entities) > 0 {
		buf := new(bytes.Buffer)
		for _, entity := range chunk.entities {
			pkts := entity.SpawnPackets(nil)
			chunk.shard.pktSerial.WritePacketsBuffer(buf, pkts...)
		}
		player.TransmitPacket(buf.Bytes())
	}

	// Spawn existing players for new player.
	if len(chunk.playersData) > 0 {
		buf := new(bytes.Buffer)
		for _, existing := range chunk.playersData {
			if existing.entityId != entityId {
				pkts := existing.SpawnPackets(nil)
				chunk.shard.pktSerial.WritePacketsBuffer(buf, pkts...)
			}
		}
		player.TransmitPacket(buf.Bytes())
	}
}
示例#7
0
func (chunk *Chunk) reqSubscribeChunk(entityId EntityId, player gamerules.IPlayerClient, notify bool) {
	if _, ok := chunk.subscribers[entityId]; ok {
		// Already subscribed.
		return
	}

	chunk.subscribers[entityId] = player

	buf := new(bytes.Buffer)
	proto.WritePreChunk(buf, &chunk.loc, ChunkInit)
	player.TransmitPacket(buf.Bytes())

	player.TransmitPacket(chunk.chunkPacket())
	if notify {
		player.NotifyChunkLoad()
	}

	// Send spawns packets for all entities in the chunk.
	if len(chunk.entities) > 0 {
		buf := new(bytes.Buffer)
		for _, e := range chunk.entities {
			e.SendSpawn(buf)
		}
		player.TransmitPacket(buf.Bytes())
	}

	// Spawn existing players for new player.
	if len(chunk.playersData) > 0 {
		playersPacket := new(bytes.Buffer)
		for _, existing := range chunk.playersData {
			if existing.entityId != entityId {
				existing.sendSpawn(playersPacket)
			}
		}
		player.TransmitPacket(playersPacket.Bytes())
	}
}
示例#8
0
func cmdKill(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) {
	// TODO inflict damage to player
	player.EchoMessage(msgNotImplemented)
}
示例#9
0
func cmdGive(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) {
	args := strings.Split(message, " ")
	if len(args) < 3 || len(args) > 5 {
		player.EchoMessage(giveUsage)
		return
	}
	args = args[1:]

	// Check to make sure this is a valid player name (at the moment command
	// is being run, the player may log off before command completes).
	target := cmdHandler.PlayerByName(args[0])

	if target == nil {
		msg := fmt.Sprintf("'%s' is not logged in", args[0])
		player.EchoMessage(msg)
		return
	}

	itemNum, err := strconv.Atoi(args[1])
	itemType, ok := cmdHandler.ItemTypeById(itemNum)
	if err != nil || !ok {
		msg := fmt.Sprintf("'%s' is not a valid item id", args[1])
		player.EchoMessage(msg)
		return
	}

	quantity := 1
	if len(args) >= 3 {
		quantity, err = strconv.Atoi(args[2])
		if err != nil {
			player.EchoMessage(giveUsage)
			return
		}

		if quantity > 512 {
			msg := "Cannot give more than 512 items at once"
			player.EchoMessage(msg)
			return
		}
	}

	data := 0
	if len(args) >= 4 {
		data, err = strconv.Atoi(args[2])
		if err != nil {
			player.EchoMessage(giveUsage)
			return
		}
	}

	// Perform the actual give
	msg := fmt.Sprintf("Giving %d of '%s' to %s", quantity, itemType.Name, args[0])
	player.EchoMessage(msg)

	maxStack := int(itemType.MaxStack)

	for quantity > 0 {
		count := quantity
		if count > maxStack {
			count = maxStack
		}

		item := gamerules.Slot{
			ItemTypeId: itemType.Id,
			Count:      ItemCount(count),
			Data:       ItemData(data),
		}
		target.GiveItem(item)
		quantity -= count
	}

	if player != target {
		msg = fmt.Sprintf("%s gave you %d of '%s'", player, quantity, itemType.Name)
		target.EchoMessage(msg)
	}
}
示例#10
0
func cmdHelp(player gamerules.IPlayerClient, message string, cmdFramework *CommandFramework, cmdHandler gamerules.IGame) {
	args := strings.Split(message, " ")
	if len(args) > 2 {
		player.EchoMessage(helpUsage)
		return
	}
	cmds := cmdFramework.Commands()
	if len(args) == 2 {
		cmd := args[1]
		if command, ok := cmds[cmd]; ok {
			player.EchoMessage("Command: " + cmdFramework.Prefix() + command.Trigger)
			player.EchoMessage("Usage: " + command.Usage)
			player.EchoMessage("Description: " + command.Description)
			return
		}
		player.EchoMessage(msgUnknownCommand)
		return
	}
	var resp string
	if len(cmds) == 0 {
		resp = "No commands available."
	} else {
		resp = "Commands:"
		for trigger, _ := range cmds {
			resp += " " + trigger + ","
		}
		resp = resp[:len(resp)-1]
	}
	player.EchoMessage(resp)
}