Add: Scarpet functions to query and modify player's `abilities`
James103 opened this issue · 3 comments
Currently (as of Carpet mod 1.4.35 for Minecraft 1.16.5), there are abilities listed in the player data for each player which are used and modified by the game and some other mods, but for which (S)Carpet has no access to except via /data get entity
commands.
It would be great if there was a new section in query
and modify
called ability
, allowing Scarpet apps to view and perhaps modify the abilities of a player. These functions could be used to change a player's abilities without changing his/her game mode.
For example,
modify(p, 'ability', 'invulnerable', false)
allows you to take non-void damage when in Creative mode.
modify(p, 'ability', 'mayfly', true)
allows you to fly even in Survival mode.
modify(p, 'ability', 'instabuild', true)
gives you instant break powers as if you were in Creative mode.
modify(p, 'ability', 'walkSpeed', 1.0)
makes you walk 10x faster (stacks with attributes).
modify(p, 'ability', 'mayBuild', false)
disables placing and breaking blocks for you, even in Survival or Creative mode.
modify(p, 'ability', 'flying', false)
forces you to stop flying.
modify(p, 'ability', 'flySpeed', 0.4)
allows you to fly 8x faster than normal while in Spectator mode (2x faster than the 0.2
max speed achievable by scrolling the wheel)
query(p, 'abilities')
returns a list of all the player's abilities and their current states. (Optional to implement)
query(p, 'ability', 'flying')
checks whether you are flying or not, which could be used to drain extra (food) energy while in creative flight.
(and so on and so forth, see modify(p, 'ability', ...)
above for full list)
Practical example: Suppose that you want to allow creative flight when you have an elytra and 100 XP levels at the cost of massively increased food energy usage and XP usage.
In event handler for __on_tick()
:
if(player() == null, return());
player = player();
if(player~'gamemode' == 'creative' || player~'gamemode' == 'spectator',
modify(player, 'ability', 'mayfly', true);
return();
);
if(inventory_get(player, -3):0 == 'elytra' && player~'xp_level' >= 100,
modify(player, 'ability', 'mayfly', true);
, // else
modify(player, 'ability', 'mayfly', false);
);
if(query(player, 'ability', 'flying'),
modify(player, 'add_exhaustion', 0.2);
modify(player, 'add_xp', -1);
);
For a performance comparison, on my system, using Carpet mod 1.4.47 and Minecraft 1.17.1, assuming that all players have all recipes unlocked:
profile_expr(p~'nbt':'abilities':'flying')
returns values between270
and300
, or 165 to 185 μs per operation.- The proposed function is likely much faster. The difference gets more pronounced as players unlock more and more recipes.
In other words, even just running p~'nbt':'abilities':'flying'
once per player in __on_tick
, it adds 1 mspt for every 5-6 players online. Compared that to the proposed function query(p, 'ability', 'flying')
which would likely add 1 mspt for every couple of dozen players.