Работа с картой

Версия Minecraft
1.7.10

Led

291
3
0
Долго думал, как не встрять в подобное, и все таки встрял.
Получилось так, что у меня есть карта, установленная на сервере.
Там есть игроки, и у них есть итемы и блоки из мода.
Мне нужно глобально выборочно заменять одни блоки и итемы на другие.
Конкретнее:
у меня есть блок, допустим это мрамор. мне нужно, что бы весь мрамор на карте (и в мире, и в инвентарях) заменился на другой блок.

такая же ситуация с итемами.

Заранее спасибо, за помощь!
 
Решение
Вроде так.
Код:
@SubscribeEvent
public void playerOpenContainerEvent(PlayerOpenContainerEvent event) {

	Item find_item = Item.getItemFromBlock(Blocks.tnt);

	Container container = event.entityPlayer.openContainer;
	if (container != null) {
		for (int i = 0; i < container.inventorySlots.size(); ++i) {
			Slot slot = container.getSlot(i);
			if (slot != null && slot.getHasStack()) {
				ItemStack item = slot.getStack();
				if (item.getItem() == find_item) {
					//int stackSize = item.stackSize;
					slot.putStack(null);
					/*for (int j = 0; j < stackSize; ++j) {
						event.entityPlayer.inventory.addItemStackToInventory(new ItemStack(Blocks.sand, 4));
						event.entityPlayer.inventory.addItemStackToInventory(new...

timaxa007

Модератор
5,831
409
672
1. Возможно использовать эвент ChunkEvent.Load, проверять в чанке на нужные блоки и заменять на не нужные. Или создать команду, которая проверяла в мире на созданные чанки, в них на нужные блоки и заменять на нужные блоки.
2. Если игроки в игре, то проверять через MinecraftServer на присутствие этих игроков на сервере и проверять каждый их инвентарь на нужные итемы и заменять на нужные итемы. Если игроки не в игре, то изменять их профили искать в них нужные предметы и заменять на нужные предметы.
 
7,099
324
1,509
А может, через asm заменять имена классов и их реализацию?(такое, наверное, возможно, если сначала применяются все трансформеры, а только потом загружаются классы) И мир не нужно будет перелопачивать
 

timaxa007

Модератор
5,831
409
672
Led написал(а):
как проверять инвентари игроков
Можно эвентом на update игрока или entity (на проверку, что оно является игроком) и/или ...

Led написал(а):
и сундуков и тд
эвентом PlayerOpenContainerEvent, проверяя каждый слот, о наличии нужно предмета которого надо заменит.
 

Led

291
3
0
timaxa007 написал(а):
Led написал(а):
как проверять инвентари игроков
Можно эвентом на update игрока или entity (на проверку, что оно является игроком) и/или ...

Led написал(а):
и сундуков и тд
эвентом PlayerOpenContainerEvent, проверяя каждый слот, о наличии нужно предмета которого надо заменит.

Спасибо большое, но можно еще подробнее, как проверять слоты и тд
Ибо с этим еще не сталкивался и даже не знаю как искать информацию по этому вопросу
 

timaxa007

Модератор
5,831
409
672
Вроде так.
Код:
@SubscribeEvent
public void playerOpenContainerEvent(PlayerOpenContainerEvent event) {

	Item find_item = Item.getItemFromBlock(Blocks.tnt);

	Container container = event.entityPlayer.openContainer;
	if (container != null) {
		for (int i = 0; i < container.inventorySlots.size(); ++i) {
			Slot slot = container.getSlot(i);
			if (slot != null && slot.getHasStack()) {
				ItemStack item = slot.getStack();
				if (item.getItem() == find_item) {
					//int stackSize = item.stackSize;
					slot.putStack(null);
					/*for (int j = 0; j < stackSize; ++j) {
						event.entityPlayer.inventory.addItemStackToInventory(new ItemStack(Blocks.sand, 4));
						event.entityPlayer.inventory.addItemStackToInventory(new ItemStack(Items.gunpowder, 4));
					}*/
				}
			}
		}
	}

}
Код работает.
 

Led

291
3
0
timaxa007 написал(а):
Вроде так.
Код:
@SubscribeEvent
public void playerOpenContainerEvent(PlayerOpenContainerEvent event) {

 Item find_item = Item.getItemFromBlock(Blocks.tnt);

 Container container = event.entityPlayer.openContainer;
 if (container != null) {
 for (int i = 0; i < container.inventorySlots.size(); ++i) {
 Slot slot = container.getSlot(i);
 if (slot != null && slot.getHasStack()) {
 ItemStack item = slot.getStack();
 if (item.getItem() == find_item) {
 //int stackSize = item.stackSize;
 slot.putStack(null);
 /*for (int j = 0; j < stackSize; ++j) {
 event.entityPlayer.inventory.addItemStackToInventory(new ItemStack(Blocks.sand, 4));
 event.entityPlayer.inventory.addItemStackToInventory(new ItemStack(Items.gunpowder, 4));
 }*/
 }
 }
 }
 }

}
Код работает.

А как это к списку подключить правильно?
Список по типу итем стак, который надо удалить - итем стак который надо дать вместо?
 

timaxa007

Модератор
5,831
409
672
Что-то типа этого:
Код:
	static HashMap<ItemStack, ItemStack> map = new HashMap<ItemStack, ItemStack>();
	static {
		map.put(new ItemStack(Blocks.tnt), new ItemStack(Items.gunpowder));
		map.put(new ItemStack(Blocks.bedrock), null);
	}

	@SubscribeEvent
	public void playerOpenContainerEvent(PlayerOpenContainerEvent event) {
		Container container = event.entityPlayer.openContainer;
		if (container != null) {
			for (int i = 0; i < container.inventorySlots.size(); ++i) {
				Slot slot = container.getSlot(i);
				if (slot != null && slot.getHasStack()) {
					ItemStack item = slot.getStack();
					for (Map.Entry<ItemStack, ItemStack> entry : map.entrySet()) {
						ItemStack key = entry.getKey();
						if (key != null && key.isItemEqual(item)) {
							if (entry.getValue() == null)
								slot.putStack(null);
							else {
								ItemStack value = entry.getValue().copy();
								value.stackSize = item.stackSize;
								slot.putStack(value);
							}
						}
					}

				}
			}
		}
	}
 

timaxa007

Модератор
5,831
409
672
Хм... Возможно будет лучше map сделать публичной или создать метод который-бы добавлял в эту переменную нужные значения и эти нужные добавления добавить в preInit'е. Других вариантов у меня пока-что нету, в чём дело.
 
Сверху