#(JustinS) Prevent items from changing slots when inventory swapping
188 messages · Page 1 of 1 (latest)
(JustinS) Prevent items from changing slots when inventory swapping
Hi I'm AutoThreadBot! Don't mind me, I'll just be adding the helper team to this thread so they can see it. A human will get to you soon.
The solution is usually applying air
i.e if you set an inventory using a list, do like dirt|air|air|stone|air|stone
Im swapping inventories though
not setting
let me send the script
I dont think its possible with swap
- if !<player.has_flag[force_inv_open]>:
- ...
- else if <player.has_flag[force_inv_open]>:
- ...
a more straightforward and concise approach would be that
- if <player.has_flag[force_inv_open]>:
- ...
- else:
- ...
(tho note the conditions are inverted, i.e. what is now in the else block would be switched to the if block)
I can just keep the ! and change it to else so it doesnt get converted
- flag <player> force_inv_open:true you can easily replace with - flag <player> force_inv_open (when the flag is only toggled, never checked for a value, it's "cleaner")
(also true is the default value when setting a value-less flag)
It didnt get highlighted in the editor so I thought that might not work
but good to know
- ratelimit <player> 0.05s
that's just the complicated version of - ratelimit <player> 1t
(ticks are valid durations in denizen)
Ill keep forgetting how much 1 tick is lol
alr
it's also the "smallest relevant duration" in minecraft as it's the updating rate of the game
i.e. i'm not sure there is much things you can do at a sub-tick rate
take that with a grain of salt tho
Right, so now... how can I fix my inventory
oh boy...
Player
this event may in some cases double-fire, requiring usage of the 'ratelimit' command (like 'ratelimit <player> 1t') to prevent doubling actions.
player right clicks <entity>
with:<item> to only process the event when the player is holding a specified item.
type:<entity> to only run if the entity clicked matches the entity input.
when a player right clicks on an entity.
Always. - this adds switches flagged:<flag name> + permission:<node>, in addition to the <player> link.
<context.entity> returns the EntityTag the player is clicking on.
<context.item> returns the ItemTag the player is clicking with.
<context.hand> returns "offhand" or "mainhand" to indicate which hand was used to fire the event. ...
<context.click_position> returns a LocationTag of the click position (as a world-less vector, rela...
True - this adds switches in:<area> + location_flagged:<flag name>.
True - this adds <context.cancelled> and determines cancelled + cancelled:false.
!e clicks block
Player
this event may in some cases double-fire, requiring usage of the 'ratelimit' command (like 'ratelimit <player> 1t') to prevent doubling actions.
player (right|left) clicks <block>
with:<item> to only process the event if a specified item was held.
using:hand/off_hand/either_hand to only process the event if the specified hand was used to click.
type:<material> to only run if the block clicked matches the material input.
when a player clicks on a block or in the air.
Always. - this adds switches flagged:<flag name> + permission:<node>, in addition to the <player> link.
<context.item> returns the ItemTag the player is clicking with.
<context.location> returns the LocationTag the player is clicking on.
<context.relative> returns a LocationTag of the air block in front of the clicked block.
<context.click_type> returns an ElementTag of the Spigot API click type <@link url https://hub.spi...
<context.hand> returns an ElementTag of the used hand.
True - this adds switches in:<area> + location_flagged:<flag name>.
True - this adds <context.cancelled> and determines cancelled + cancelled:false.
which of the two do you want to run
the first one
you want the inventories to be swapped after any right click regardless of what the user is actually clicking ?
well
the only exception I dont want it to switch is when riding a camel or horse (right clicking it)
but I couldnt find a way to easily filter that
same for boats
but it should run when right clicking any other entity that doesnt cause any other event
!t vehicle
^
oh no i missread that
ye ok so you want to trigger the event only if it isn't actually used for something else
i'm assuming i.e. opening a chest or other clickable block wouldn't trigger it
yeah
Perhaps I can split it in two seperate events: 1 checks for entity and 1 for blocks
If the entity is a vehicle. don't do anything
If the block is a container don't do anything
just checked but couldn't find any particular preset list of entities and blocks that "do things"
so you have to perform some kind of check
the only time entities do anything when right clicked is when theyre vehicles right
yeah...
but its flagged with with:force_powers so....
it wont be run that often
points to consider: this will trigger both entity and block clicks
i also assume you're getting a warning after a reload mentionning your event being "possibly matched by multiple events"
what
Event forcepower_input_script.events.on player right clicks * with:force_powers is matched to multiple ScriptEvents: PlayerClicksBlock, PlayerRightClicksEntity
something like that
thats why I want to split into two seperate events
idk, why?
a /reload or /ex reload
ex reload
ye exactly
that's not an issue, that's for your information
it warns you that this script is likely to run with both entities and blocks, thus some logic might break
aha
this is indeed the fix
you replace the single event by two
on player right clicks block with:force_powers:
on player right clicks entity with:force_powers:
then, you can validate the block isn't a container in the first and a vehicle in the second
since i couldn't find any easy way to check whether the block is interactive, you might want to hard code a list of exluded blocks
!l matchable
Script events have a variety of matchable object inputs, and the range of inputs they accept may not always be obvious.
For example, an event might be "player clicks <block>"... what can "<block>" be filled with?
"<block>" usually indicates that a LocationTag and/or MaterialTag will be matched against.
This means you can specify any valid block material name, like "stone" or "air", like "on player clicks stone:" (will only run the event if the player is clicking stone)
You can also use a catch-all such as "block", like "on player clicks block:" (will always run the event when the player clicks anything/anywhere)
You can also use some more complicated matchables such as "vanilla_tagged:", like "on player clicks vanilla_tagged:mineable/axe:" (will run if the block is mineable with axes)
(Fo...
Object System
Script event lines often include specific 'matchable' keywords.
For example, while you can write "on player breaks block:" as a script event line,
you can also instead write "on player breaks stone:" to listen to a much more specific event.
This is general in-line matching.
This is made available to avoid needing to do things like "- if <context.material.name> == stone"
just to validate whether an event is even relevant to you.
Of course, there are times when you want to more than one specific thing to be handled by the event, so what do you do?
The Denizen script event system provides a few 'advanced' options to get more detailed matching.
One option is to use wildcards.
For example, there are several 'log' materials, such as 'oak_log', 'birch_log', and more for the rest of the tree typ...
Object System
Ill just only do containers. and harvestables. if they right click a noteblock or comparator or door, Ill just run it like normally
!t material.is_interac
Returns whether the material can be interacted with.
Some blocks such as piston heads and stairs are considered interactable.
Note that this will return true if at least one state of a material has interaction handling.
ElementTag(Boolean)
in the end you should just make a first iteration with a working script and tweak+improve from there
yo lessgo
Some blocks such as piston heads and stairs are considered interactable.
thats good bcs we'll probably have a sit plugin for stairs
Yea it be wonky
ex narrate <server.material_types.filter[is_interactable].parse[name]>
So I just gotta do:
- if <context.location.block.material.is_interactable>:
- stop```
oof thats a lot
it might or might not be what you need
maybe you'd be better off using matchers with a specific list of blocks
Theres like 10-20 items I dont want
Cant I just make a list with those and check if it's NOT that
the rest is all good
i mean you can do whatever you want
Can I do something like <list[A|B|*_C|D]>?
Because I dont want fences to count
so *_fence
if <[material].is_interactable> && !( stone|dirt contains <[material]> )
!l operator
An operator is a tool for comparing values, used by commands like !command if, !command while, !command waituntil, ... and tags like !tag ObjectTag.is.than
Available Operators include:
"Equals" is written as "==" or "equals".
"Does not equal" is written as "!=".
"Is more than" is written as ">" or "more".
"Is less than" is written as "<" or "less".
"Is more than or equal to" is written as ">=" or "or_more".
"Is less than or equal to" is written as "<=" or "or_less".
"does this list or map contain" is written as "contains". For example, "- if a|b|c contains b:" or "- if [a=1;b=2] contains b:"
"is this in the list or map" is written as "in". For example, "- if b in a|b|c:", or "- if [a=1;b=2] contains b:"
"does this object or text match an advanced matcher" is wr...
Comparables
would be stone|dirt not contains <[material]> instead of !( stone|dirt contains <[material]> ) then ? tias
what about stone|dirt|*_fence|pumpkin not contains <[material]>
The *_fence is what Im asking
^ matches
in that context you better off using matches than contains ye, so <[material]> matches stone|dirt|*_fence|pumpkin
👍 Ill give it a try
How do I check if an entity is a vehicle?
including boats, horses, camels
I cant find any tags for it
I found entitytag.vehicle but thats not it
any entity can be one
oh right
fuck
Ill just only check if they right click players
it should still work then
this feels unnatural on player right clicks player with:force_powers:
i mean you can always make a list of entities "vanilla ridable" and negate it
on player right clicks !horse|*_boat|cart|etc:
no bcs we'll have custom mobs
and idk if we might have ridable horses
so Ill just leave it out for now
can always change it
Right so I changed it to this
on player right clicks block with:force_powers:
- ratelimit <player> 1t
- if <context.location.block.material.is_interactable> && <context.location.block.material> matches pumpkin|*_fence|tnt|flower_pot|composter|beehive|bee_nest|*cauldron|:
- stop
- run switch_inventory_script```
Though Im getting errors that context.location is nul
!logs
Please post your full latest log file.
Background Info: One of the most helpful tools to identifying the source of a problem is your server logs file! Logs contain all sorts of important information like server and plugin versions, any error messages, and a lot more important information (More Info).
How To: Your log can be found in the logs folder within your server folder. The most recent log is a text file labeled latest.log. To get help using these logs, please open that file in a text editor and copy all of the text, then open https://paste.denizenscript.com/New/Log and paste the text into the box on the page. Then click "Submit" and copy the URL and paste that back into this channel.
Please do not upload the file to Discord or to other pastebin services, use the log pastebin linked above.
it's better to share a full log or debug next time
!debug
If you need help with a script issue, one of the most powerful tools Denizen has to offer is full debug output. This is displaying in your console whenever scripts are running until you turn debug off. To share a debug log quickly and easily with helpers, simply run the command /denizen debug -r in-game to begin recording, then run through the part of the script you need help with, then run the command /denizen submit. This will give you a link to a paste of the debug log, which you can then copy/paste back to us!
!tag locationtag.block
Returns the location of the block this location is on,
i.e. returns a location without decimals or direction.
Note that you almost never actually need this tag. This does not "get the block", this just rounds coordinates down.
If you have this in a script, it is more likely to be a mistake than actually needed.
Consider using !tag LocationTag.round_down instead.
math
LocationTag
!tag is_interactable
Returns whether the material can be interacted with.
Some blocks such as piston heads and stairs are considered interactable.
Note that this will return true if at least one state of a material has interaction handling.
ElementTag(Boolean)
Invalid context ID 'location'! this context tag failed
are you sure you didn't click out into the air?
thats a possibility but isnt air also a "block"
with a location?
otherwise Ill just filter it out
if you click into the sky, you could possibly be clicking nothing and the tag just fails, i'd check and see if that makes the difference
alright
https://github.com/mcmonkeyprojects/DenizenSampleScripts/blob/master/selector_tool.dsc#L243
take this script for example
this context can fail
wait but
how can I check if the block is air
if I cant even get the block, because its air
you could instead just check if it's truthy
air, void_air, cave_air, and invalid will return false
check what?
the location or the material
yeah but isnt that what's giving the error?
cant get the location because it's null?
ohh I can check if the location is null
yeah
let me try
I think that fixed it
Funny how like 5 things were fixed/changed but none were related to the original question lol
let me read the question again I forgot what the original question was
it looks like you had an issue with slot placement for items between inventories
i'd ask if you're excluding air somehow, but an updated script would help better first
I think this is all you need
https://paste.denizenscript.com/View/123008
Content of Denizen Script Paste #123008: Unnamed Denizen Script Paste... pasted 2024/05/24 07:24:10 UTC-07:00, Paste length: 1690 characters across 32 lines, Content: switch_inventory_script: type: task
!command inventory
item
inventory [open/close/copy/move/swap/set/keep/exclude/fill/clear/update/adjust <mechanism>:<value>/flag <name>(:<action>)[:<value>] (expire:<time>)] (destination:<inventory>) (origin:<inventory>/<item>|...) (slot:<slot>)
Edits the inventory of a player, NPC, or chest.
Use this command to edit the state of inventories.
By default, the destination inventory is the current attached player's inventory.
If you are copying, swapping, removing from (including via "keep" and "exclude"), adding to, moving, or filling inventories,
you'll need both destination and origin inventories.
Origin inventories may be specified as a list of ItemTags, but destinations must be actual InventoryTags.
Using "open", "clear", or "update" only require a destination.
"Update" also req...
an MCVE of the swap subcommand might be a quick check to look at;
can you create two inventories with air space between them, swap them, and then narrate their inventory_contents?
!mechanism contents
Did you mean to search for command quests?
i can't remember what the actual rough dirty mechanism is but something like this
/ex note as:test1 <inventory[generic[contents=stone|air|air|sand]]>
/ex note as:test2 <inventory[generic[contents=dirt|air|air|glass]]>
/ex inventory swap destination:test1 origin:test2
/ex narrate <inventory[test1].contents>
/ex narrate <inventory[test2].contents>
or in a task script ofc
MCVE?
!mcve
Please create a Minimal, Complete, and Verifiable Example of the problem you're reporting.
Minimal: contains nothing other than the part that's broken (and bare minimum structure).
Complete: contains everything needed to demonstrate the issue.
Verifiable: Anybody should be able to throw it on their own server and see the problem happen for themselves, without any needed tinkering.
goes along with my comment in #1243514046989471745 as well
Thanks for the help everyone, got this fixed (in a different thread)