CraftTweaker

CraftTweaker

151M Downloads

[1.15.2] Function name overloading not working

IchHabeHunger54 opened this issue · 5 comments

commented

Issue Description:

Function names cannot be used multiple times (see below).

What happens:

I'm having a script:

function slab(rname as string, slab as IItemStack, block as IItemStack) {...} //calls the lower one with true as last param
function slab(rname as string, slab as IItemStack, block as IItemStack, revert as boolean) {...}

What you expected to happen:

To work just fine, even with two functions of the same name.

What happened instead:

[08:40:44.750][DONE][CLIENT][ERROR] wooden.zs:16:1 No compatible methods found: for every call of one of the two methods. However, when I remove the first one and only use the second one, it works just fine.


Affected Versions (Do not use "latest"):

  • Minecraft: 1.15.2
  • Forge: 31.2.41
  • Crafttweaker: 6.0.0.44
  • Using a server: no
commented

Unfortunately, top level function definition overloading is not a planned language feature.

Function Definitions are functions defined at the top level of the script, like so:

// Script start
function doThing() as void {}
// Script end

What you can do however, is make function definitions inside a class have overloads like so:

// Script start
public class Globals {
     public static doThing() as void {}
     public static doThing(name as string) as void {}
}
// Script end
commented

I'll see when I can look into it.
For now, you can just use default parameters:

function slab(rname as string, slab as IItemStack, block as IItemStack, revert as boolean = true) {...}
commented

This exists in Minecraft 1.16.5 with CraftTweaker-1.16.5-7.1.0.336, as well. However, it's arguably worse.

public class globals {
	val level_1_test = <item:minecraft:written_book>.withTag({"author":"§4§kUnknown"});
	val level_2_test = <item:minecraft:written_book>.withTag({"author":"§4your friend ♥"});
	val level_3_test = <item:minecraft:written_book>.withTag({"author":"§4your friend ♥♥♥"});
	val MAX_TEST_LEVEL = 3;

	public static getBookLevel(item as IItemStack, level as int) as int {
		if level >= MAX_TEST_LEVEL {
			return MAX_TEST_LEVEL;
		}
		if level_3_test.matches(item) {
			return 3;
		} else if level >= 2 {
			return 2;
		}
		if level_2_test.matches(item) {
			return 2;
		} else if level >= 1 {
			return 1;
		}
		if level_1_test.matches(item) {
			return 1;
		} else {
			return 0;
		}
	}
	public static getBookLevel(player as MCPlayerEntity) as int {
		return getBookLevel(player, 0);
	}
	public static getBookLevel(player as MCPlayerEntity, initial_level as int) as int {
		val inventory = player.getInventory(); 
		var max = initial_level;//bookLevel(inventory.itemStack, initial_level);
		if max >= MAX_TEST_LEVEL {
			return MAX_TEST_LEVEL;
		}

		var slot = inventory.getInventorySize();
		while(slot-- != 0) {
			var level = getBookLevel(inventory.getStackInSlot(slot), max);
			if level >= MAX_TEST_LEVEL {
				return MAX_TEST_LEVEL;
			} else if level > max {
				max = level;
			}
		}
		return max;
	}
}

When I comment out all of those method definitions, there is no problem. But with them uncommented, I get endless spam of
[18:19:22] [Render thread/INFO] [minecraft/NewChatGui]: [CHAT] [ERROR] Bad type on operand stack\nException Details:\n Location:\n scripts/globals.getBookLevel(Lnet/minecraft/entity/player/PlayerEntity;I)I @11: getfield\n Reason:\n Type 'net/minecraft/entity/player/PlayerEntity' (current frame, stack[1]) is not assignable to 'scripts/globals'\n Current Frame:\n bci: @11\n flags: { }\n locals: { 'net/minecraft/entity/player/PlayerEntity', integer, top, 'net/minecraft/entity/player/PlayerInventory', top, integer }\n stack: { integer, 'net/minecraft/entity/player/PlayerEntity' }\n Bytecode:\n 0x0000000: 2ab8 003c 4e1b 3605 1505 2ab4 001f a200\n 0x0000010: 0703 a700 0404 9900 082a b400 1fac 2db8\n 0x0000020: 0042 3607 1507 8407 ff12 089f 0007 03a7\n 0x0000030: 0004 0499 0007 03a7 0004 0499 003f 2d15\n 0x0000040: 07b8 0046 1505 b800 4836 0915 092a b400\n 0x0000050: 1fa2 0007 03a7 0004 0499 000b 2ab4 001f\n 0x0000060: ac00 00bf 1509 1505 a300 0703 a700 0404\n 0x0000070: 9900 0715 0936 05a7 ffad 1505 acbf \n Stackmap Table:\n full_frame(@21,{Object[#74],Integer,Top,Object[#76],Top,Integer},{})\n same_locals_1_stack_item_frame(@22,Integer)\n same_frame(@30)\n append_frame(@36,Top,Integer)\n same_frame(@50)\n same_locals_1_stack_item_frame(@51,Integer)\n same_frame(@58)\n same_locals_1_stack_item_frame(@59,Integer)\n append_frame(@88,Top,Integer)\n same_locals_1_stack_item_frame(@89,Integer)\n full_frame(@97,{},{Object[#50]})\n full_frame(@100,{Object[#74],Integer,Top,Object[#76],Top,Integer,Top,Integer,Top,Integer},{})\n same_frame(@111)\n same_locals_1_stack_item_frame(@112,Integer)\n same_frame(@119)\n chop_frame(@122,2)\n full_frame(@125,{},{Object[#50]})\n: Bad type on operand stack\nException Details:\n Location:\n scripts/globals.getBookLevel(Lnet/minecraft/entity/player/PlayerEntity;I)I @11: getfield\n Reason:\n Type 'net/minecraft/entity/player/PlayerEntity' (current frame, stack[1]) is not assignable to 'scripts/globals'\n Current Frame:\n bci: @11\n flags: { }\n locals: { 'net/minecraft/entity/player/PlayerEntity', integer, top, 'net/minecraft/entity/player/PlayerInventory', top, integer }\n stack: { integer, 'net/minecraft/entity/player/PlayerEntity' }\n Bytecode:\n 0x0000000: 2ab8 003c 4e1b 3605 1505 2ab4 001f a200\n 0x0000010: 0703 a700 0404 9900 082a b400 1fac 2db8\n 0x0000020: 0042 3607 1507 8407 ff12 089f 0007 03a7\n 0x0000030: 0004 0499 0007 03a7 0004 0499 003f 2d15\n 0x0000040: 07b8 0046 1505 b800 4836 0915 092a b400\n 0x0000050: 1fa2 0007 03a7 0004 0499 000b 2ab4 001f\n 0x0000060: ac00 00bf 1509 1505 a300 0703 a700 0404\n 0x0000070: 9900 0715 0936 05a7 ffad 1505 acbf \n Stackmap Table:\n full_frame(@21,{Object[#74],Integer,Top,Object[#76],Top,Integer},{})\n same_locals_1_stack_item_frame(@22,Integer)\n same_frame(@30)\n append_frame(@36,Top,Integer)\n same_frame(@50)\n same_locals_1_stack_item_frame(@51,Integer)\n same_frame(@58)\n same_locals_1_stack_item_frame(@59,Integer)\n append_frame(@88,Top,Integer)\n same_locals_1_stack_item_frame(@89,Integer)\n full_frame(@97,{},{Object[#50]})\n full_frame(@100,{Object[#74],Integer,Top,Object[#76],Top,Integer,Top,Integer,Top,Integer},{})\n same_frame(@111)\n same_locals_1_stack_item_frame(@112,Integer)\n same_frame(@119)\n chop_frame(@122,2)\n full_frame(@125,{},{Object[#50]})\n
which just repeats forever.

commented

@nerdywhiteguy You were accessing instance fields in static functions.
You should make these variables static. public static val level_1_test as IItemStack = <item:minecraft:written_book>.withTag({"author":"§4§kUnknown"});

commented

🤦‍♂️ You were 100% right, @friendlyhj. Thank you very much!

Somehow it wasn't throwing errors before upgrading from CraftTweaker-1.16.5-7.1.0.331. At least, if it was, it was more minor errors than just dumping stack traces every tick or so, which I was in the process of working through before trying the new build.

Since making all of those vals public static vals, everything works fine, even when I uncomment the dozens of other methods with the same name but slightly different arguments. And my "works fine", I mean "doesn't dump stack traces every tick just because the methods are defined". No comment on if the methods work as intended when called, though. 🙃