Plugin [Développement] CraftItemEvent Questions

Raphew

Massacreur de Mouton
10 Août 2018
46
0
21
20
Bonjour,

Je travaille avec l'event CraftItemEvent, j'essaie de faire qu'à chaque craft fait, par exemple, ça envoie un message. Voici mon problème :
, pour le plugin, le craft est réussi alors que l'item est main est rempli, j'ai essayer de palier ça avec
Code:
ItemStack itC = e.getCurrentItem();
if(itC.getMaxStackSize() == e.getRecipe().getResult().getMaxStackSize()) return;
mais dès qu'on prend plus de 4 torches ça ne marche plus :/.

Quelqu'un aurait un moyen pour palier ce problème ?
Et aussi autre problème mais quand on appui sur shift + clic, ça compte que comme un craft réussi et pas comme plus. Une autre solution pour cette autre problème ?

Merci !
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 086
157
455
247
21
Mìlhüsa
Bonjour,

Qu'entends-tu par « le craft réussi alors que l'item en main est rempli » ?
Et en gros, tu veux savoir le nombre de fois que l'objet a été fabriqué, style une fois avec un simple clic, 64/4 avec un shift clic, et 0 fois si l'item en main est full ou du mauvais type ?

Cordialement,
ShE3py.
 

Raphew

Massacreur de Mouton
10 Août 2018
46
0
21
20
Salut,

Oui je peux le faire de cette façon, mais surtout de savoir si l'item du craft a été récupérer ou non, comme dans la vidéo, les torches dans la deuxième partie ne sont pas prise car la main est pleine (64), mais le plugin affiche et crois pourtant que l'item du craft a été pris.

PS : Je te met mon code ici, il est très simpliste et donc c'est surement pour ça que ça ne marche pas comme je le voudrais.
Java:
@EventHandler
    void onCraftEvent(CraftItemEvent e) {
        Player p = (Player) e.getWhoClicked();
        ItemStack itC = e.getCurrentItem();
        
        if(itC.getMaxStackSize() == e.getRecipe().getResult().getMaxStackSize()) return; // optionnel du coup
        if(e.isCancelled()) return;
        if(e.isAsynchronous()) return;
        
        if(itC.getType() == Material.TORCH) {
            p.sendMessage("craft réussi");
        }
        
    }
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 086
157
455
247
21
Mìlhüsa
Quelques petits rappels :
  • ItemStack#isSimilar(ItemStack): boolean renvoie true uniquement si les deux items sont égaux (type, enchantements, nom, etc.), mais ignore la quantité les items.
    Java:
    ItemStack stack1 = new ItemStack(Material.STONE);
    ItemStack stack2 = new ItemStack(Material.STONE, 2);
    
    boolean similar = stack1.isSimilar(stack2); // true
    boolean equal = stack1.equals(stack2); // false


  • Dans un switch, un case continuera d'exécuter le code tant qu'il ne rencontrera pas un break :
    Java:
    int i = 0;
          
    switch(i) {
        case 0:
            System.out.print("a");
                  
        case 1:
            System.out.print("b");
            break;
    }
    
    // Affiche "ab"

Du coup pour récupérer le nombre de fois que la recette a été utilisée :

Java:
public class CraftItemHandler implements Listener {
	@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
	public void onCraftItem(CraftItemEvent e) {
		Player p = (Player) e.getWhoClicked();
		ItemStack result = e.getRecipe().getResult();
		ItemStack cursor = e.getCursor();
		
		if(cursor != null && cursor.getType() != Material.AIR) {
			if(!result.isSimilar(cursor))
				return; // l'on ne peut pas stacker ensemble le curseur et le résultat
			
			if((cursor.getAmount() + result.getAmount()) > cursor.getMaxStackSize())
				return; // impossible de réunir le curseur et le résultat
			            // ex.: prendre 4 torches alors qu'on en a 62 dans notre main
		}
		
		if(e.getResult() == Event.Result.DENY)
			return; // un autre plugin refuse le craft
		
		int count = result.getAmount();
		
		switch(e.getClick()) {
			case NUMBER_KEY:
				if(p.getInventory().getItem(e.getHotbarButton()) != null)
					count = 0; // il y a déjà un item dans cet emplacement de la hotbar
				               // le comportement vanilla ne vérifie pas s'il peut éventuellement réunir les deux
				
				break;
			
			case DROP:
			case CONTROL_DROP:
				if(cursor != null && cursor.getType() != Material.AIR)
					count = 0; // on ne peut pas faire du craft-and-drop avec un item en main
				
				break;
			
			case SHIFT_RIGHT:
			case SHIFT_LEFT:
				int maxCraftable = getMaxCraftableQuantity(e.getInventory());
				int maxAddable = getMaxFillableQuantity(result, e.getView().getBottomInventory());
				
				if(maxAddable < maxCraftable)
					// pas assez de place dans l'inventaire
					maxCraftable = ((maxAddable + count - 1) / count) * count;
				
				count = maxCraftable;
				break;
				
			default:
				break;
		}
		
		if(count == 0)
			return;
		
		p.sendMessage("Craft réussi, recette utilisée " + count + " fois");
	}
	
	// renvoit la quantité maximale craftable à partir des ingrédients de l'inventaire
	public static int getMaxCraftableQuantity(CraftingInventory inventory) {
		if(inventory.getResult() == null)
			return 0;
		
		int resultQuantity = inventory.getResult().getAmount();
		int materialQuantity = Integer.MAX_VALUE;
		
		for(ItemStack stack : inventory.getMatrix())
			//noinspection ConstantConditions
			if(stack != null)
				materialQuantity = Math.min(materialQuantity, stack.getAmount());
		
		return resultQuantity * materialQuantity;
	}
	
	// renvoit la quantité maximale d'objets que l'on peut stocker dans l'inventaire spécifié
	public static int getMaxFillableQuantity(ItemStack stack, Inventory inventory) {
		int quantity = 0;
		
		for(ItemStack slot : inventory.getContents()) {
			//noinspection ConstantConditions
			if(slot == null)
				quantity += stack.getMaxStackSize();
			
			else if(slot.isSimilar(stack))
				quantity += Math.max(stack.getMaxStackSize() - slot.getAmount(), 0);
		}
		
		return quantity;
	}
}

Non testé.