<commit_before>package net.mcft.copy.backpacks.misc;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;

import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;

import net.mcft.copy.backpacks.WearableBackpacks;
import net.mcft.copy.backpacks.api.BackpackHelper;
import net.mcft.copy.backpacks.api.IBackpack;
import net.mcft.copy.backpacks.api.IBackpackData;
import net.mcft.copy.backpacks.api.IBackpackType;
import net.mcft.copy.backpacks.misc.util.MiscUtils;
import net.mcft.copy.backpacks.misc.util.NbtUtils;
import net.mcft.copy.backpacks.misc.util.NbtUtils.NbtType;
import net.mcft.copy.backpacks.network.MessageBackpackUpdate;

/** Concrete implementation of the IBackpack interface and capability, used for entities. */
public class BackpackCapability implements IBackpack {
	
	public static final String TAG_STACK = "stack";
	public static final String TAG_TYPE  = "type";
	public static final String TAG_DATA  = "data";
	
	public static final ResourceLocation IDENTIFIER =
		new ResourceLocation("wearablebackpacks:backpack");
	
	
	public final EntityLivingBase entity;
	
	public ItemStack stack = ItemStack.EMPTY;
	public IBackpackData data = null;
	public int playersUsing = 0;
	public int lidTicks = 0;
	public int prevLidTicks = 0;
	
	// This is also null if the backpack is not equipped to the chestplate slot.
	public IBackpackType lastType = null;
	
	public BackpackCapability(EntityLivingBase entity) { this.entity = entity; }
	
	/** Returns if the entity is wearing the backpack in the chest armor slot. */
	public boolean isChestArmor() {
		return ((lastType != null) || (BackpackHelper.getBackpackType(
			entity.getItemStackFromSlot(EntityEquipmentSlot.CHEST)) != null));
	}
	
	// IBackpack implementation
	
	@Override
	public ItemStack getStack() {
		if (!stack.isEmpty()) return stack;
		ItemStack chestArmor = entity.getItemStackFromSlot(EntityEquipmentSlot.CHEST);
		return ((BackpackHelper.getBackpackType(chestArmor) != null) ? chestArmor : ItemStack.EMPTY);
	}
	
	@Override
	public void setStack(ItemStack value) {
		ItemStack lastStack = stack;
		boolean chestArmorChanged = false;
		
		// Remove previous backpack from chest armor slot, if any.
		if (isChestArmor()) {
			entity.setItemStackToSlot(EntityEquipmentSlot.CHEST, ItemStack.EMPTY);
			chestArmorChanged = true;
		}
		
		// Equip backpack to chest armor slot if config option is set to enabled.
		if (BackpackHelper.equipAsChestArmor) {
			stack = ItemStack.EMPTY;
			lastType = ((!value.isEmpty()) ? BackpackHelper.getBackpackType(value) : null);
			entity.setItemStackToSlot(EntityEquipmentSlot.CHEST, value);
			chestArmorChanged = true;
		// Otherwise store it inside the capability.
		} else {
			stack = value;
			lastType = null;
		}
		
		if (!entity.world.isRemote) {
			// If chest armor was changed and this is a player, send the updated stack.
			if (chestArmorChanged && (entity instanceof EntityPlayer))
				((EntityPlayer)entity).inventoryContainer.detectAndSendChanges();
			// If backpack capability stack was changed, send it to everyone who can see the entity.
			if (stack != lastStack)
				WearableBackpacks.CHANNEL.sendToAllTracking(
					MessageBackpackUpdate.stack(entity, stack), entity, true);
		}
	}
	
	@Override
	public IBackpackData getData() { return data; }
	@Override
	public void setData(IBackpackData value) { data = value; }
	
	@Override
	public int getPlayersUsing() { return playersUsing; }
	@Override
	public void setPlayersUsing(int value) {
		// If the backpack is being opened or closed (# of players
		// using changed from 0 to non-zero or the other way around),
		// send an update to anyone who can see this entity.
		if ((value > 0) != (playersUsing > 0))
			WearableBackpacks.CHANNEL.sendToAllTracking(
				MessageBackpackUpdate.open(entity, (value > 0)), entity, true);
		playersUsing = value;
	}
	
	@Override
	public int getLidTicks() { return lidTicks; }
	@Override
	public int getPrevLidTicks() { return prevLidTicks; }
	@Override
	public void setLidTicks(int value) { prevLidTicks = lidTicks; lidTicks = value; }<commit_msg>Fix rare case of backpacks overwriting chest armor<commit_after>package net.mcft.copy.backpacks.misc;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;

import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;

import net.mcft.copy.backpacks.WearableBackpacks;
import net.mcft.copy.backpacks.api.BackpackHelper;
import net.mcft.copy.backpacks.api.IBackpack;
import net.mcft.copy.backpacks.api.IBackpackData;
import net.mcft.copy.backpacks.api.IBackpackType;
import net.mcft.copy.backpacks.misc.util.MiscUtils;
import net.mcft.copy.backpacks.misc.util.NbtUtils;
import net.mcft.copy.backpacks.misc.util.NbtUtils.NbtType;
import net.mcft.copy.backpacks.network.MessageBackpackUpdate;

/** Concrete implementation of the IBackpack interface and capability, used for entities. */
public class BackpackCapability implements IBackpack {
	
	public static final String TAG_STACK = "stack";
	public static final String TAG_TYPE  = "type";
	public static final String TAG_DATA  = "data";
	
	public static final ResourceLocation IDENTIFIER =
		new ResourceLocation("wearablebackpacks:backpack");
	
	
	public final EntityLivingBase entity;
	
	public ItemStack stack = ItemStack.EMPTY;
	public IBackpackData data = null;
	public int playersUsing = 0;
	public int lidTicks = 0;
	public int prevLidTicks = 0;
	
	// This is also null if the backpack is not equipped to the chestplate slot.
	public IBackpackType lastType = null;
	
	public BackpackCapability(EntityLivingBase entity) { this.entity = entity; }
	
	/** Returns if the entity is wearing the backpack in the chest armor slot. */
	public boolean isChestArmor() {
		return ((lastType != null) || (BackpackHelper.getBackpackType(
			entity.getItemStackFromSlot(EntityEquipmentSlot.CHEST)) != null));
	}
	
	// IBackpack implementation
	
	@Override
	public ItemStack getStack() {
		if (!stack.isEmpty()) return stack;
		ItemStack chestArmor = entity.getItemStackFromSlot(EntityEquipmentSlot.CHEST);
		return ((BackpackHelper.getBackpackType(chestArmor) != null) ? chestArmor : ItemStack.EMPTY);
	}
	
	@Override
	public void setStack(ItemStack value) {
		boolean setChestArmor = !value.isEmpty()
			// If backpack is being set, use equipAsChestArmor to
			// determine whether the chest armor slot is set or not.
			? BackpackHelper.equipAsChestArmor
			// If being removed, use whether it actually is equipped there.
			: isChestArmor();
		
		if (setChestArmor) {
			stack = ItemStack.EMPTY;
			lastType = BackpackHelper.getBackpackType(value);
			entity.setItemStackToSlot(EntityEquipmentSlot.CHEST, value);
			
			// Send the updated equipment to all players.
			if (entity instanceof EntityPlayer)
				((EntityPlayer)entity).inventoryContainer.detectAndSendChanges();
		} else {
			stack = value;
			lastType = null;
			
			// Send new value to everyone who can see the entity.
			WearableBackpacks.CHANNEL.sendToAllTracking(
				MessageBackpackUpdate.stack(entity, stack), entity, true);
		}
	}
	
	@Override
	public IBackpackData getData() { return data; }
	@Override
	public void setData(IBackpackData value) { data = value; }
	
	@Override
	public int getPlayersUsing() { return playersUsing; }
	@Override
	public void setPlayersUsing(int value) {
		// If the backpack is being opened or closed (# of players
		// using changed from 0 to non-zero or the other way around),
		// send an update to anyone who can see this entity.
		if ((value > 0) != (playersUsing > 0))
			WearableBackpacks.CHANNEL.sendToAllTracking(
				MessageBackpackUpdate.open(entity, (value > 0)), entity, true);
		playersUsing = value;
	}
	
	@Override
	public int getLidTicks() { return lidTicks; }
	@Override
	public int getPrevLidTicks() { return prevLidTicks; }
	@Override
	public void setLidTicks(int value) { prevLidTicks = lidTicks; lidTicks = value; }
{'fraction_non_alphanumeric': 0.09382658419885634, 'fraction_numerical': 0.0016337962422686427, 'mean_word_length': 4.679257786613651, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '829131', 'n_tokens_mistral': 2859, 'n_tokens_neox': 2638, 'n_words': 706}