First of all - props for the good analysis
You are correct that these "preprocessor directives" (iirc) are evaluated before the script is run, with no understanding of the surrounding context
There is an exception though - i'm not sure how it works, but the PROMPT command can be used to collect values during runtime
No. The hotkey I've set doesn't execute the file if I press it while the inventory is open. Is there a way to let the code know to check the inventory regardless?
I'm just trying to make a basic "notification" script that works with a cobblestone generator. The idea is that it mines automatically, and when the inventory fills up entirely, it'll give me a noise which lets me know to empty it.
In my testing, slot 35 fills up last. Hotbar first, then top-down left-right in the inventory. If it can't check the inventory slots unless it's open, it can't mine at the same time, and therefore isn't automatic.
When your inventory isn't open, it doesn't exist - there is no slot 35 then
Some options:
Periodically open and close the inventory to check
Mine until hotbar is full - shift click into inventory - repeat
Use a hopper or similar to eliminate the need to pick up items in the first place
Hey all, fairly new to this mod although I have some prior (albeit limited and very basic) coding experience. I've been doing a lot of testing around with the GETSLOTITEM command and I can't get this file to execute properly.
This code logs "Didn't Work." no matter what is in slot 35, which means something about my assumptions for the function GETSLOTITEM is incorrect. I'm trying to only play the sound when slot 35 contains cobblestone, which has an item ID of 4. GETSLOTITEM returns the id of the item found in said slot, so what am I missing here?
1) Cobblestone does not have an item ID of 4, not since minecraft 1.7 (which was like 5 years ago now)
The id is now 'minecraft:cobblestone' or just 'cobblestone'
2) The lexer/parser in this mod is handmade and rather simplistic - it assumes you are giving it a simple sequence of commands, it doesn't build an AST.
So the command IF(GETSLOTITEM(35,&idvar) == cobblestone); is interpreted as a simple string comparison, which is never true
What you want instead is either
GETSLOTITEM(35,&idvar)
IF(&idvar == cobblestone)
or
&idvar = GETSLOTITEM(35); // new return-value syntax, available since
IF(&idvar == cobblestone)
addendum) A tip for any type of coding
When your program doesn't work, you need to forget / test ALL of your assumptions - the best way to do that is to work in small steps, implementing the simplest feature that gets you closer to the end goal.
For example, this is how i would build up the script
// Test Log first because having some visible output is always useful for debugging
Log(true) // works
// Test GetSlotItem
GetSlotItem(35,&id)
Log(&id) // Logs &id, how do i get the value?
GetSlotItem(35,&id)
Log(%&id%) // Logs cobblestone (oh, didn't expect that, okay, will keep it in mind)
// Test the IF statement
GetSlotItem(35,&id)
Log(%&id%)
IF(&id == cobblestone) // Seems to work so far, now let's try removing logs and simplifying
Log(true)
ELSE
Log(false)
ENDIF
// Test nesting
IF(GetSlotItem(35,&id) == cobblestone); // Only change was the indroduction of nesting - i guess nesting doesn't work, revert to previous
Log(true)
ELSE
Log(false)
ENDIF
Lots of good information here - i've only got two little things to add
Firstly, If you're unfamiliar with boolean operations (&&, ||, !=), you can test them right in your browser by opening the dev console (F12 on chrome, probably other browsers as well)
Note, however, that in the browser you MUST use lowercase 'true' and 'false'
Secondly - you mentioned variable assignment with a single equals sign.
This was actually included in the mod at one point, so now you can indeed write 'x = true' or '#foo = 12' - most commands also have a 'return value'
for example '#len = ARRAYSIZE(&names[])'
This is usable strictly only as the right hand side of a variable assignment, you still can't nest commands.
when editing a macro i get this color selection screen but i have no idea how it got opened or how to close it & it prevents me from typing anything in the box
AFAIK that should open when you hold the 'macro override' key while editing - not sure how i could get stuck open though.. - double check your controls just in case
i am making a script that automaticly grabs iron out of chests.
Only problem i have is that iron gets refilled very fast and the script always takes the one refilled iron.
So my question: is there a way that it only grabs iron over 32? or only full stacks?
Ty
I'm not sure i understand what the problem is.., what do you want it to do?
SlotClick only clicks on the slot you specify, and only once... GetSlotItem returns the number of items through the optional third variable
GetSlotItem(40,&id,#amount)
IF(%&id% != "iron_ingot"); Log("It's not iron"); Stop; ENDIF;
IF(#amount < 32); Log("It's iron, but there's not enough of it"); Stop; ENDIF
Log("Looks like a bit of iron there")
SlotClick(32);
Also .. is it possible to make a script run perfectly 1 block to the left or to the right?
Not really, since the only inputs you have are analog (movement key inputs), you have imperfect information (position rounded to a whole integer, or 1/10 if using the POS10 module, no information about speed), and there are hard-to.predict factors like friction/inertia, lag, and other external influences
Generally you can work around it, depending on what actual problem you're trying to solve
Can this mod be used to bind two actions to the same key? I mean keybinds, those you can access from the controls menu. Normally, when there's a conflict, only one action will trigger. I've been trying to find a mod that allows you to bind the same key to many actions, without luck. There seems to be only one mod, but it's outdated and buggy.
No built-in way, although for vanilla actions you can write a script that does both and bind it to a key, so kinda?
I'm doing a simple project that replies in chat to a simple greeting.
I use the chat filter section for that and so far it goes well except that when I want to add a delay it doesn't seem to recognize the "wait" command.
Am I doing something wrong? a bit of help would be much appreciated.
//replying hello
IFMATCHES(%CHAT%, "hello");
WAIT(5s)
ECHO("hi, how can I help you?")
endif
The Chat Filter 'event' is a blocking event - it doesn't allow you to use Wait() because that would prevent you from receiving any messages until your script has finished (or maybe even block your game entirely)
The purpose of blocking is to enable your script to modify or even cancel the message before it is displayed
If you only want to react to chat without touching it, use the onChat event instead instead
In any case, be careful that you don't accidentally create a feedback loop where your script accidentally replies to its' own messages
for example, what you've currently written will reply to any instance of hello in chat, regardless of context - so if someone's name is hello_kitty it will respond to all of their messages.
Likewise if someone mentions a hellovator or some other long word that contains 'hello' inside it
And, of course, if other people reply to the hello with a hello of their own, your script would reply to all of them
First of all, thanks for this amazing mod. But, I'm having a problem: i'm trying to play in a server with that mod, but i'm getting detected and kicked from it. I'd like to know how they're doing this and how I can bypass it. I'd be so grateful if u help me.
There is no stealth mode, and for good reason
If you suspect that the autokick is configured too agressively and the mod would otherwise be allowed, consider notifying an owner/admin and asking if they can add a whitelist entry for it.
What would be the purpose of launching a separate task if you're going to wait for it to finish anyway?
Did you mean to use a file include? $$<somefile.txt>
I have tried the command in quotation marks, yes. However due to the item id also being in quotation marks, I think the command read only between the first and second ". Not the first and last, like I feel that it should.
Just tested it again and ${ECHO("/summon item ~ ~2 ~ {Item:{Id:"apple",Count:1}}")}$ resulted in Data tag parsing failed: Expected '}' but got '"'at: {Item:{Id:apple"<--[HERE]
So I think it might be misinterpreting the quote marks and after the quote it sees the next comma as another line. Although then again that might not be the case, as nothing else entered the chat, which would've happened if the echo dumped the rest.
Not sure if that's supported, but two things you could try are:
Using different quotes (' around and " inside, or vice versa, f.ex. Echo("this is 'an' example"); Echo('and so is "this" now'))
Also it might be possible to escape quotes as in Echo("this is an \"escaped\" example")
Hehe, you're hard to spot without the Pony picture! I got it working, however IF(SPACE), doesn't work. Also tried it with input KEYDOWN(jump) and then KEYUP(jump) worked for me. The script looks like this:
There is an issue now with going up while using flight and autojumping. You can't go up now anymore, because the script doesn't run it continously. Any way to hold keydown(jump) while holding the key down? I imagine it would look something like
DO;
Key(jump)
WHILE(SPACE)
ENDIF;
ENDIF;
Or something, but the problem is that "SPACE" doesn't work.
Use a key state macro?
Key Down: $${KeyDown(jump); // Rest of the script }$$
Key held:
Key up: $${KeyUp(jump);}$$
I'm not sure where to report bugs, but I believe I found an annoying one that prevents summoning with data tags when within an ECHO().
For example if I were to use this command to summon a feather:
/summon minecraft:item ~ ~2 ~ {Item:{id:"minecraft:feather",Count:1},PickupDelay:20}
1 feather is dropped above the player with a slight pickup delay, exactly as expected.
However, if I were to use the same in an ECHO()
${ECHO(/summon minecraft:item ~0.3 ~0.25 ~-0.3 {Item:{id:"minecraft:feather",Count:1},PickupDelay:20,Motion:[0.0,0.2,0.0]})}$
It results in : Data tag parsing failed: Expected '}' but got 'C' at : {Item:{id:"minecraft:feather" C<--[HERE]
After looking at where it ends, it seems echo removed the comma, which is where it went wrong.
It's a little annoying as I'm writing a macro which enables an interaction with leaves to have a chance of an apple dropping, and I require the co-ordinates of the block in question in order for the item to drop at the block's previous position, which is only possible through ECHO().
So for your command, a simple version would possibly be
${
IF(SPACE);
WAIT(250ms);
ECHO(<command for spell>);
ENDIF
}$
If space is down wait 250 milliseconds then send the command for the spell.
The reason 250 would suit better is it'll trigger while you're already in the air rather than the double jump triggering just as you leave the ground.
You could possibly optimize it further by using DO, GETIDREL, and UNTIL after you jump to keep checking if the block below you is air, which will be at the top most of your jump, and when it is it will send the command then, but simple usually works best.
This only checks space once, so even if you don't hold it down, it'll still trigger after 250ms
you could also check after the wait, in which case you'd actually have to hold it (or press it again just before the wait finishes)
Well on the server im playin is the possiblity to execute the command /near , I still could not figure out howto extract only the name of the nearest player from the chat. Basicly I'm trying to archive that once a new item is added to the inventory the "Bot" executes /near (Works already)
The Chatformat is the following:
RANK: NAME(METERS)
Spieler: MyPlayerName(5m)
Any way I can get the closest name, all names are sperated by a ,
The messages appear separately, so what you need is at least two scripts
One that sends the commands
And another that runs for every message, checking if it's a name, checking if it's closer, and if it is - saving it
It would also have to detect when the server is done sending names...
Is there a specific message at the end of the list that could help with this?
Isn't there like a way to get the playername of a player that dropped the item to you?
I can't find any way =(
No, and that is information that i don't believe even exists
When you pick up an item, the server only tells the client that their inventory has changed and which 'dropped item' entity to animate, it doesn't specify the 'last owner' because it's irrelevant - i doubt the server even remembers
The same applies even to the moment when the item is dropped - the server doesn't say "That player dropped X item in Y direction", rather it just says "There's a new dropped item entity at position Z moving in direction Y with speed Q"
So the only way for a mod to be able to tell you who dropped an item would be to painstakingly track every new entity that appears and check if it was near another player, and just assume it was dropped by them
This would be a bunch of code, and still wouldn't work for items dropped outside your visual range (f.ex. if you arrive later),
And it would mistakenly assume every dropper/dispenser/mob drop that appears near the player was also 'dropped' by them
In conclusion, such a feature does not exist, very likely won't exist in this mod, and is pretty unlikely to exist in a clientside mod at all
However, a serverside plugin to track something like that would probably be a lot easier - so depending on the reason you're asking for this, might be something to look into
0
First of all - props for the good analysis
You are correct that these "preprocessor directives" (iirc) are evaluated before the script is run, with no understanding of the surrounding context
There is an exception though - i'm not sure how it works, but the PROMPT command can be used to collect values during runtime
Signature: PROMPT(<&target>,<paramstring>,[prompt],[override],[default])
0
When your inventory isn't open, it doesn't exist - there is no slot 35 then
Some options:
Periodically open and close the inventory to check
Mine until hotbar is full - shift click into inventory - repeat
Use a hopper or similar to eliminate the need to pick up items in the first place
0
Are you running the script when your inventory is actually open?
0
1) Cobblestone does not have an item ID of 4, not since minecraft 1.7 (which was like 5 years ago now)
The id is now 'minecraft:cobblestone' or just 'cobblestone'
2) The lexer/parser in this mod is handmade and rather simplistic - it assumes you are giving it a simple sequence of commands, it doesn't build an AST.
So the command IF(GETSLOTITEM(35,&idvar) == cobblestone); is interpreted as a simple string comparison, which is never true
What you want instead is either
GETSLOTITEM(35,&idvar)
IF(&idvar == cobblestone)
or
&idvar = GETSLOTITEM(35); // new return-value syntax, available since
IF(&idvar == cobblestone)
addendum) A tip for any type of coding
When your program doesn't work, you need to forget / test ALL of your assumptions - the best way to do that is to work in small steps, implementing the simplest feature that gets you closer to the end goal.
For example, this is how i would build up the script
// Test Log first because having some visible output is always useful for debugging
Log(true) // works
// Test GetSlotItem
GetSlotItem(35,&id)
Log(&id) // Logs &id, how do i get the value?
GetSlotItem(35,&id)
Log(%&id%) // Logs cobblestone (oh, didn't expect that, okay, will keep it in mind)
// Test the IF statement
GetSlotItem(35,&id)
Log(%&id%)
IF(&id == cobblestone) // Seems to work so far, now let's try removing logs and simplifying
Log(true)
ELSE
Log(false)
ENDIF
// Test nesting
IF(GetSlotItem(35,&id) == cobblestone); // Only change was the indroduction of nesting - i guess nesting doesn't work, revert to previous
Log(true)
ELSE
Log(false)
ENDIF
0
Lots of good information here - i've only got two little things to add
Firstly, If you're unfamiliar with boolean operations (&&, ||, !=), you can test them right in your browser by opening the dev console (F12 on chrome, probably other browsers as well)
Note, however, that in the browser you MUST use lowercase 'true' and 'false'
Secondly - you mentioned variable assignment with a single equals sign.
This was actually included in the mod at one point, so now you can indeed write 'x = true' or '#foo = 12' - most commands also have a 'return value'
for example '#len = ARRAYSIZE(&names[])'
This is usable strictly only as the right hand side of a variable assignment, you still can't nest commands.
0
AFAIK that should open when you hold the 'macro override' key while editing - not sure how i could get stuck open though.. - double check your controls just in case
0
I'm not sure i understand what the problem is.., what do you want it to do?
SlotClick only clicks on the slot you specify, and only once...
GetSlotItem returns the number of items through the optional third variable
GetSlotItem(40,&id,#amount)
IF(%&id% != "iron_ingot"); Log("It's not iron"); Stop; ENDIF;
IF(#amount < 32); Log("It's iron, but there's not enough of it"); Stop; ENDIF
Log("Looks like a bit of iron there")
SlotClick(32);
Not really, since the only inputs you have are analog (movement key inputs), you have imperfect information (position rounded to a whole integer, or 1/10 if using the POS10 module, no information about speed), and there are hard-to.predict factors like friction/inertia, lag, and other external influences
Generally you can work around it, depending on what actual problem you're trying to solve
0
No built-in way, although for vanilla actions you can write a script that does both and bind it to a key, so kinda?
0
The Chat Filter 'event' is a blocking event - it doesn't allow you to use Wait() because that would prevent you from receiving any messages until your script has finished (or maybe even block your game entirely)
The purpose of blocking is to enable your script to modify or even cancel the message before it is displayed
If you only want to react to chat without touching it, use the onChat event instead instead
In any case, be careful that you don't accidentally create a feedback loop where your script accidentally replies to its' own messages
for example, what you've currently written will reply to any instance of hello in chat, regardless of context - so if someone's name is hello_kitty it will respond to all of their messages.
Likewise if someone mentions a hellovator or some other long word that contains 'hello' inside it
And, of course, if other people reply to the hello with a hello of their own, your script would reply to all of them
1
There is no stealth mode, and for good reason
If you suspect that the autokick is configured too agressively and the mod would otherwise be allowed, consider notifying an owner/admin and asking if they can add a whitelist entry for it.
0
What would be the purpose of launching a separate task if you're going to wait for it to finish anyway?
Did you mean to use a file include? $$<somefile.txt>
1
Not sure if that's supported, but two things you could try are:
Using different quotes (' around and " inside, or vice versa, f.ex. Echo("this is 'an' example"); Echo('and so is "this" now'))
Also it might be possible to escape quotes as in Echo("this is an \"escaped\" example")
Use a key state macro?
Key Down: $${KeyDown(jump); // Rest of the script }$$
Key held:
Key up: $${KeyUp(jump);}$$
0
Have you tried quoting the string?
Echo("this,is,a,test") vs Echo(this,is,a,test)
This only checks space once, so even if you don't hold it down, it'll still trigger after 250ms
you could also check after the wait, in which case you'd actually have to hold it (or press it again just before the wait finishes)
IF(SPACE);
Wait(delay)
IF(SPACE); Thing(); ENDIF;
ENDIF;
0
The messages appear separately, so what you need is at least two scripts
One that sends the commands
And another that runs for every message, checking if it's a name, checking if it's closer, and if it is - saving it
It would also have to detect when the server is done sending names...
Is there a specific message at the end of the list that could help with this?
--- Listing nearby players (3) ---
someplayer(10m)
someotherplayer(100m)
closestplayer(2m)
-- End of list --
0
No, and that is information that i don't believe even exists
When you pick up an item, the server only tells the client that their inventory has changed and which 'dropped item' entity to animate, it doesn't specify the 'last owner' because it's irrelevant - i doubt the server even remembers
The same applies even to the moment when the item is dropped - the server doesn't say "That player dropped X item in Y direction", rather it just says "There's a new dropped item entity at position Z moving in direction Y with speed Q"
So the only way for a mod to be able to tell you who dropped an item would be to painstakingly track every new entity that appears and check if it was near another player, and just assume it was dropped by them
This would be a bunch of code, and still wouldn't work for items dropped outside your visual range (f.ex. if you arrive later),
And it would mistakenly assume every dropper/dispenser/mob drop that appears near the player was also 'dropped' by them
In conclusion, such a feature does not exist, very likely won't exist in this mod, and is pretty unlikely to exist in a clientside mod at all
However, a serverside plugin to track something like that would probably be a lot easier - so depending on the reason you're asking for this, might be something to look into