CraftTweaker

CraftTweaker

151M Downloads

[Issue/Question] addPlayerOnlyDrop not working as expected

CREEATION opened this issue Ā· 7 comments

commented

What happens:

Killing modified mobs (see attached script) sometimes doesn't drop any items at all (producing an error, see "most recent log files"). It seems that items only drop if the mob will 100% drop leather when killed.

What you expected to happen:

Normal vanilla drops, just with leather added via addPlayerOnlyDrop.

Script used:

https://hastebin.com/xotemarilu.log

crafttweaker.log file:

https://hastebin.com/azuyiyonak.log


Affected Versions:

  • Minecraft: 1.12.2
  • Forge: 14.23.5.2776
  • Crafttweaker: 4.1.15
  • Using a server: no

Most recent log files:

https://paste.dimdev.org/rayabumuta.mccrash (killed sheep)
https://paste.dimdev.org/suvuwojafo.mccrash (killed pig)

commented

Don't use 0 as minimum drop, that is already handled by the weight, always start with at least one.

commented

Makes sense, thanks for the quick reply! Just for future reference and others who might find this issue, here is the current working (not accounting for baby mobs) script (see the Minecraft Drops Wiki for common drop chances):

# add leather drops to various animals
# reference: https://en.wikipedia.org/wiki/Leather#From_other_animals

import crafttweaker.mods.ILoadedMods;
import crafttweaker.entity.IEntityDefinition;
import crafttweaker.item.WeightedItemStack;

val item_leather = <minecraft:leather>;
val chance_leather = 33;
val drop_leather = item_leather % chance_leather;

val entity_sheep = <entity:minecraft:sheep>;
entity_sheep.addPlayerOnlyDrop(drop_leather, 1, 1);

val entity_pig = <entity:minecraft:pig>;
entity_pig.addPlayerOnlyDrop(drop_leather, 1, 1);

if ( loadedMods has "exoticbirds" ) {
    val entity_ostrich = <entity:exoticbirds:ostrich>;
    entity_ostrich.addPlayerOnlyDrop(drop_leather, 1, 1);
}

if ( loadedMods has "familiarfauna" ) {
    val entity_deer = <entity:familiarfauna:familiarfauna.deer>;
    entity_deer.addPlayerOnlyDrop(drop_leather, 1, 2);
}
commented

@kindlich I can't seem to get this suggestion to work. I get

Cannot cast ZenTypeNative: crafttweaker.entity.IEntity to ZenTypeNative: crafttweaker.entity.IEntityLivingBase

with this line:

val living_entity = entity as IEntityLivingBase;

Mind pushing me in the right direction here?

commented

If you are certain that the entity is always an EntityLivingBase you can cast it unchecked using

val living_entity as IEntityLivingBase = entity;

Apart from that, try to use the entity unless you specifically need to access its methods.

commented

@kindlich I'm getting this crash report now. The crafttweaker.log doesn't show anything apart from loading the scripts successfully.

For reference, my current test script:

import crafttweaker.entity.IEntity;
import crafttweaker.entity.IEntityDefinition;
import crafttweaker.entity.IEntityDropFunction;
import crafttweaker.entity.IEntityLivingBase;

var entity_sheep = <entity:minecraft:sheep>;

entity_sheep.addDropFunction(function(entity, dmgSource) {
    val living_entity as IEntityLivingBase = entity;
    
    if ( living_entity.isChild ) {
        print("don't hurt ma baby");
    } else {
        print("murder it");
    }
    
    return null;
});

//e: Ah, sure. It's already dead (and also just a reference to the entity) so it doesn't work like that I suppose?
//eĀ²: Now looking into event handlers.

commented

@kindlich Hello again.

So, I think I'm on the right path right now with this script (some imports might be redundant, haven't really looked at them for a while while testing):

// add leather drops to various animals
// reference: https://en.wikipedia.org/wiki/Leather#From_other_animals

import crafttweaker.entity.IEntity;
import crafttweaker.entity.IEntityDefinition;
import crafttweaker.entity.IEntityLivingBase;
import crafttweaker.events.IEventManager;
import crafttweaker.event.EntityLivingDeathDropsEvent;
import crafttweaker.item.IItemStack;
import crafttweaker.item.WeightedItemStack;
import crafttweaker.mods.ILoadedMods;

// add vanilla animals here
var additionalLeatherAnimals = {
    <entity:minecraft:sheep>    : 1,
    <entity:minecraft:pig>      : 1
} as int[IEntityDefinition];

// don't edit below here
events.onEntityLivingDeathDrops(function(event as EntityLivingDeathDropsEvent) {
    val animalEntity = event.entityLivingBase;
    
    // leather only drops if animal isn't a baby
    if ( !animalEntity.isChild ) {
        print("not a baby, yay!");
        
        if ( additionalLeatherAnimals.keys has animalEntity.definition ) { // <--- error
            print("got one!");
        }
    }
});

However, I'm getting the following error which I don't quite understand (Bad local variable type?):

[INITIALIZATION][CLIENT][ERROR] [crafttweaker]: Error executing {[0:crafttweaker]: entitydrop_leather.zs}: Bad local variable type
Exception Details:
  Location:
    ZenClassCrafttweakerEntitydrop_leather0.handle(Lcrafttweaker/api/event/EntityLivingDeathDropsEvent;)V @23: aload
  Reason:
    Type top (current frame, locals[5]) is not assignable to reference type
  Current Frame:
    bci: @23
    flags: { }
    locals: { 'ZenClassCrafttweakerEntitydrop_leather0', 'crafttweaker/api/event/EntityLivingDeathDropsEvent', top, 'crafttweaker/api/entity/IEntityLivingBase' }
    stack: { }
  Bytecode:
    0x0000000: 2bb9 0013 0100 4e2d b900 1901 0004 8299
    0x0000010: 002c 121b b800 2119 05b9 0027 0100 03bd
    0x0000020: 0029 b900 2f02 00c0 0031 2db9 0037 0100
    0x0000030: b800 3d99 0008 123f b800 21b1          
  Stackmap Table:
    append_frame(@59,Top,Object[#21])

java.lang.VerifyError: Bad local variable type

From what I've read in the documentation, IEntityLivingBase extends IEntity which in turn has the ZenGetter definition, which I'm trying to use to check if the killed entity is indeed in my "leather drop whitelist" defined in the script. Does it not work that way? šŸ™

commented

Different Scopes.
Different Scopes.
Different Scopes.

vars declared outside a function cannot be accessed from inside a function expression.
Try declaring the map int[IED] as static