From 3a2edb9ed227a1be9fc90815f7902d2ecbeccab1 Mon Sep 17 00:00:00 2001 From: replaceitem <40722305+replaceitem@users.noreply.github.com> Date: Mon, 30 Nov 2020 16:12:04 +0100 Subject: [PATCH] Added scarpet bossbar function (#585) --- docs/scarpet/api/Scoreboard.md | 59 ++++++++ docs/scarpet/resources/editors/idea/2.txt | 5 +- .../scarpet/resources/editors/npp/scarpet.xml | 2 + .../java/carpet/script/api/Scoreboards.java | 131 ++++++++++++++++++ 4 files changed, 195 insertions(+), 2 deletions(-) diff --git a/docs/scarpet/api/Scoreboard.md b/docs/scarpet/api/Scoreboard.md index 98e9c9b7..36903292 100644 --- a/docs/scarpet/api/Scoreboard.md +++ b/docs/scarpet/api/Scoreboard.md @@ -104,3 +104,62 @@ team_property('admin','seeFriendlyInvisibles',true) Make all players in 'a team_property('admin','deathMessageVisibility','hideForOtherTeams') Make all players in 'admin' see other admins even when invisible ``` +## `bossbar()`, `bossbar(id)`, `bossbar(id,property,value?)` + +Manage bossbars just like with the `/bossbar` command. + +Without any arguments, returns a list of all bossbars. + +When an id is specified, creates a bossbar with that `id` and returns the id of the created bossbar. +Bossbar ids need a namespace and a name. If no namespace is specified, it will automatically use `minecraft:`. +In that case you should keep track of the bossbar with the id that `bossbar(id)` returns, because a namespace may be added automatically. +If the id was invalid (for example by having more than one colon), returns `null`. +If the bossbar already exists, returns `false`. + +`bossbar('timer') => 'minecraft:timer'` (Adds the namespace `minecraft:` because none is specified) + +`bossbar('scarpet:test') => 'scarpet:test'` In this case there is already a namespace specified + +`bossbar('foo:bar:baz') => null` Invalid identifier + +`bossbar(id,property)` is used to query the `property` of a bossbar. + +`bossbar(id,property,value)` can modify the `property` of the bossbar to a specified `value`. + +Available properties are: + +* color: can be `'pink'`, `'blue'`, `'red'`, `'green'`, `'yellow'`, `'purple'` or `'white'` + +* style: can be `'progress'`, `'notched_6'`, `'notched_10'`, `'notched_12'` or `'notched_20'` + +* value: value of the bossbar progress + +* max: maximum value of the bossbar progress, by default 100 + +* name: Text to display above the bossbar, supports formatted text + +* visible: whether the bossbar is visible or not + +* players: List of players that can see the bossbar + +* add_player: add a player to the players that can see this bossbar, this can only be used for modifying (`value` must be present) + +* remove: remove this bossbar, no `value` required + +``` +bossbar('script:test','style','notched_12') +bossbar('script:test','value',74) +bossbar('script:test','name',format('rb Test')) -> Change text +bossbar('script:test','visible',false) -> removes visibility, but keeps players +bossbar('script:test','players',player('all')) -> Visible for all players +bossbar('script:test','players',player('Steve')) -> Visible for Steve only +bossbar('script:test','players',null) -> Invalid player, removing all players +bossbar('script:test','add_player',player('Alex')) -> Add Alex to the list of players that can see the bossbar +bossbar('script:test','remove') -> remove bossbar 'script:test' +for(bossbar(),bossbar(_,'remove')) -> remove all bossbars +``` + + + + + diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt index 642a8bc5..8f826f39 100644 --- a/docs/scarpet/resources/editors/idea/2.txt +++ b/docs/scarpet/resources/editors/idea/2.txt @@ -12,6 +12,7 @@ block_tick block_tags blocks_daylight blocks_movement +bossbar brightness chunk_tickets crafting_remaining_item @@ -92,10 +93,10 @@ scoreboard_remove scoreboard_display tag_matches team_add -team_list -team_remove team_leave +team_list team_property +team_remove read_file see_sky set diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml index 65a7800d..5dba63e7 100644 --- a/docs/scarpet/resources/editors/npp/scarpet.xml +++ b/docs/scarpet/resources/editors/npp/scarpet.xml @@ -64,6 +64,8 @@ team_add team_list team_remove team_leave team_property + bossbar + player spawn entity_id entity_list entity_area entity_selector query modify entity_event entity_load_handler entity_types stack_limit item_category recipe_data crafting_remaining_item diff --git a/src/main/java/carpet/script/api/Scoreboards.java b/src/main/java/carpet/script/api/Scoreboards.java index 0ba8d9e5..cf1c2859 100644 --- a/src/main/java/carpet/script/api/Scoreboards.java +++ b/src/main/java/carpet/script/api/Scoreboards.java @@ -12,6 +12,9 @@ import carpet.script.value.StringValue; import carpet.script.value.FormattedTextValue; import carpet.script.value.Value; import net.minecraft.entity.Entity; +import net.minecraft.entity.boss.BossBar; +import net.minecraft.entity.boss.BossBarManager; +import net.minecraft.entity.boss.CommandBossBar; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.ServerScoreboard; @@ -20,9 +23,12 @@ import net.minecraft.scoreboard.ScoreboardObjective; import net.minecraft.scoreboard.ScoreboardPlayerScore; import net.minecraft.scoreboard.Team; import net.minecraft.scoreboard.AbstractTeam; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; +import net.minecraft.util.InvalidIdentifierException; import java.util.stream.Collectors; @@ -396,6 +402,131 @@ public class Scoreboards { } return LazyValue.TRUE; }); + + expression.addLazyFunction("bossbar", -1, (c, t, lv) -> + { + BossBarManager bossBarManager = ((CarpetContext)c).s.getMinecraftServer().getBossBarManager(); + if(lv.size() > 3) throw new InternalExpressionException("'bossbar' accepts max three arguments"); + + if(lv.size() == 0) { + Value ret = ListValue.wrap(bossBarManager.getAll().stream().map(CommandBossBar::getId).map(Identifier::toString).map(StringValue::of).collect(Collectors.toList())); + return (_c, _t) -> ret; + } + + String id = lv.get(0).evalValue(c).getString(); + Identifier identifier; + try { + identifier = new Identifier(id); + } catch (InvalidIdentifierException invalidIdentifierException) { + return LazyValue.NULL; + } + + if(lv.size() == 1) { + if(bossBarManager.get(identifier) != null) return LazyValue.FALSE; + Value ret = StringValue.of(bossBarManager.add(identifier,new LiteralText(id)).getId().toString()); + return (_c, _t) -> ret; + } + + String property = lv.get(1).evalValue(c).getString(); + + CommandBossBar bossBar = bossBarManager.get(identifier); + if(bossBar == null) return LazyValue.NULL; + + Value propertyValue = (lv.size() == 3)?lv.get(2).evalValue(c):null; + + switch (property) { + case "color": + if(propertyValue == null) { + BossBar.Color color = (bossBar).getColor(); + if(color == null) return LazyValue.NULL; + return (_c, _t) -> StringValue.of(color.getName()); + } + + BossBar.Color color = BossBar.Color.byName(propertyValue.getString()); + if(color == null) return LazyValue.NULL; + bossBar.setColor(BossBar.Color.byName(propertyValue.getString())); + return LazyValue.TRUE; + case "max": + if(propertyValue == null) return (_c, _t) -> NumericValue.of(bossBar.getMaxValue()); + + if(!(propertyValue instanceof NumericValue)) throw new InternalExpressionException("'bossbar' requires a number as the value for the property " + property); + bossBar.setMaxValue(((NumericValue) propertyValue).getInt()); + return LazyValue.TRUE; + case "name": + if(propertyValue == null) return (_c, _t) -> new FormattedTextValue(bossBar.getName()); + + if(propertyValue instanceof FormattedTextValue) { + bossBar.setName(((FormattedTextValue) propertyValue).getText()); + } else { + bossBar.setName(new LiteralText(propertyValue.getString())); + } + return LazyValue.TRUE; + case "add_player": + if(propertyValue == null) throw new InternalExpressionException("Bossbar property " + property + " can't be queried, add a third parameter"); + + if(propertyValue instanceof ListValue) { + ((ListValue) propertyValue).getItems().forEach((v)->{ + ServerPlayerEntity player = EntityValue.getPlayerByValue(((CarpetContext)c).s.getMinecraftServer(),propertyValue); + if(player != null) bossBar.addPlayer(player); + }); + return LazyValue.TRUE; + } + + ServerPlayerEntity player = EntityValue.getPlayerByValue(((CarpetContext) c).s.getMinecraftServer(), propertyValue); + if(player != null) { + bossBar.addPlayer(player); + return LazyValue.TRUE; + } + return LazyValue.FALSE; + case "players": + if(propertyValue == null) { + return (_c, _t) -> ListValue.wrap(bossBar.getPlayers().stream().map(EntityValue::new).collect(Collectors.toList())); + } + + if(propertyValue instanceof ListValue) { + bossBar.clearPlayers(); + ((ListValue) propertyValue).getItems().forEach((v) -> { + ServerPlayerEntity p = EntityValue.getPlayerByValue(((CarpetContext) c).s.getMinecraftServer(), v); + if (p != null) bossBar.addPlayer(p); + }); + return LazyValue.TRUE; + } + + + ServerPlayerEntity p = EntityValue.getPlayerByValue(((CarpetContext) c).s.getMinecraftServer(), propertyValue); + bossBar.clearPlayers(); + if (p != null) { + bossBar.addPlayer(p); + return LazyValue.TRUE; + } + return LazyValue.FALSE; + case "style": + if(propertyValue == null) { + return (_c, _t) -> StringValue.of(bossBar.getOverlay().getName()); + } + + BossBar.Style style = BossBar.Style.byName(propertyValue.getString()); + if(style == null) throw new InternalExpressionException("'" + propertyValue.getString() + "' is not a valid value for property " + property); + bossBar.setOverlay(style); + return LazyValue.TRUE; + case "value": + if(propertyValue == null) return (_c, _t) -> NumericValue.of(bossBar.getValue()); + + if(!(propertyValue instanceof NumericValue)) throw new InternalExpressionException("'bossbar' requires a number as the value for the property " + property); + bossBar.setValue(((NumericValue) propertyValue).getInt()); + return LazyValue.TRUE; + case "visible": + if(propertyValue == null) return (_c, _t) -> new NumericValue(bossBar.isVisible()); + + bossBar.setVisible(propertyValue.getBoolean()); + return LazyValue.TRUE; + case "remove": + bossBarManager.remove(bossBar); + return LazyValue.TRUE; + default: + throw new InternalExpressionException("Unknown bossbar property " + property); + } + }); } }