SkriptLang / skript-reflect

Powerful reflection utilities for Skript.
MIT License
56 stars 19 forks source link

[QoL] Easier handling of maps #62

Open UsainSrht opened 1 year ago

UsainSrht commented 1 year ago

Is your feature request related to a problem? Please describe. Quality of Life feature request for maps. Right now when you try to set a variable to a map. It just sets the first index to map. example:

set {_enchants::*} to tool.getItem().getEnchants()
send {_enchants::*}
#output: {Enchantment[minecraft:fire_aspect, FIRE_ASPECT]=2, Enchantment[minecraft:unbreaking, DURABILITY]=3}

Describe the solution you'd like When setting a variable to a map. skript-reflect would make the variable indexes to keys and their values to maps values.

set {_enchants::*} to tool.getItem().getEnchants()
send {_enchants::*}
#output: 2, 3
send indexes of {_enchants::*}
#output: fire_aspect, unbreaking

Describe alternatives you've considered Each key in the map could be added to a list normally. Like {_enchants::1} = {Enchantment[minecraft:fire_aspect, FIRE_ASPECT]=2} and 2 is durability.

TPGamesNL commented 1 year ago

This could be implemented when Skript adds a method like Expression#getMap(Event). This could then be integrated into EffChange, Variable and the changer methods as well.

However, one issue I foresee is that, in Skript lists, keys are always strings. Therefore having syntax for this (I'd probably add it to ExprSpread, like set {_l::*} to ...{_myMap}) would mean all keys need to be converted to strings. This could cause issues, say someone has a map with 2 entries, and the keys both have the same string form. In this case, information would be lost when converting it to a Skript list, as the list cannot store both items.

If anyone has suggestions to overcome this issue, feel free to comment

UsainSrht commented 1 year ago

I didn't think about keys' toString methods could be same.

Here's another suggestion: setting key and value to different indexes.

set {_i} to (netherite sword of unbreaking 3 and fire aspect 2)
set {_myMap} to (random item of {_i}).getEnchants()
set {_l::*} to ...{_myMap}
loop {_l::*}:
  send "%loop-index% %{_l::%loop-value%::key}% %{_l::%loop-value%::value}%"

output

1 unbreaking 3
2 fire_aspect 2

I'm not sure this could be done tho