diff --git a/docs/scarpet/api/Scoreboard.md b/docs/scarpet/api/Scoreboard.md index 36903292..826c5328 100644 --- a/docs/scarpet/api/Scoreboard.md +++ b/docs/scarpet/api/Scoreboard.md @@ -10,8 +10,9 @@ With specified `objective` and ### `scoreboard_add(objective, criterion?)` -Adds a new objective to scoreboard. If `criterion` is not specified, assumes `'dummy'`. Returns `false` if objective -already existed, `true` otherwise. +Adds a new objective to scoreboard. If `criterion` is not specified, assumes `'dummy'`. +If the objective already exists, changes the criterion of that objective and returns `false`. If the criterion was not specified but the objective already exists, returns the current criterion. +If the objective was added, returns `true`. If nothing is affected, returns `null`
 scoreboard_add('counter')
@@ -162,4 +163,3 @@ for(bossbar(),bossbar(_,'remove'))  -> remove all bossbars
 
 
 
-
diff --git a/src/main/java/carpet/mixins/ScoreboardObjective_scarpetMixin.java b/src/main/java/carpet/mixins/ScoreboardObjective_scarpetMixin.java
new file mode 100644
index 00000000..a7506dde
--- /dev/null
+++ b/src/main/java/carpet/mixins/ScoreboardObjective_scarpetMixin.java
@@ -0,0 +1,12 @@
+package carpet.mixins;
+
+import net.minecraft.scoreboard.ScoreboardCriterion;
+import net.minecraft.scoreboard.ScoreboardObjective;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(ScoreboardObjective.class)
+public interface ScoreboardObjective_scarpetMixin {
+    @Accessor("criterion")
+    void setCriterion(ScoreboardCriterion criterion);
+}
diff --git a/src/main/java/carpet/mixins/Scoreboard_scarpetMixin.java b/src/main/java/carpet/mixins/Scoreboard_scarpetMixin.java
new file mode 100644
index 00000000..646e2ee7
--- /dev/null
+++ b/src/main/java/carpet/mixins/Scoreboard_scarpetMixin.java
@@ -0,0 +1,16 @@
+package carpet.mixins;
+
+import net.minecraft.scoreboard.Scoreboard;
+import net.minecraft.scoreboard.ScoreboardCriterion;
+import net.minecraft.scoreboard.ScoreboardObjective;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.List;
+import java.util.Map;
+
+@Mixin(Scoreboard.class)
+public interface Scoreboard_scarpetMixin {
+    @Accessor("objectivesByCriterion")
+    Map> getObjectivesByCriterion();
+}
diff --git a/src/main/java/carpet/script/api/Scoreboards.java b/src/main/java/carpet/script/api/Scoreboards.java
index cf1c2859..d7cdf1e8 100644
--- a/src/main/java/carpet/script/api/Scoreboards.java
+++ b/src/main/java/carpet/script/api/Scoreboards.java
@@ -1,5 +1,7 @@
 package carpet.script.api;
 
+import carpet.mixins.ScoreboardObjective_scarpetMixin;
+import carpet.mixins.Scoreboard_scarpetMixin;
 import carpet.script.CarpetContext;
 import carpet.script.Expression;
 import carpet.script.LazyValue;
@@ -11,6 +13,7 @@ import carpet.script.value.NumericValue;
 import carpet.script.value.StringValue;
 import carpet.script.value.FormattedTextValue;
 import carpet.script.value.Value;
+import com.google.common.collect.Lists;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.boss.BossBar;
 import net.minecraft.entity.boss.BossBarManager;
@@ -133,8 +136,15 @@ public class Scoreboards {
             }
 
             ScoreboardObjective objective = scoreboard.getObjective(objectiveName);
-            if (objective != null)
+            if (objective != null) {
+                if(lv.size() == 1) return (_c, _t) -> StringValue.of(objective.getCriterion().getName());
+                if(objective.getCriterion().equals(criterion) || lv.size() == 1) return LazyValue.NULL;
+                ((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().get(objective.getCriterion()).remove(objective);
+                ((ScoreboardObjective_scarpetMixin) objective).setCriterion(criterion);
+                (((Scoreboard_scarpetMixin)scoreboard).getObjectivesByCriterion().computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
+                scoreboard.updateObjective(objective);
                 return LazyValue.FALSE;
+            }
 
             scoreboard.addObjective(objectiveName, criterion, new LiteralText(objectiveName), criterion.getCriterionType());
             return LazyValue.TRUE;
diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json
index 1551b661..2df590c4 100644
--- a/src/main/resources/carpet.mixins.json
+++ b/src/main/resources/carpet.mixins.json
@@ -164,6 +164,8 @@
     "BlockItem_scarpetEventMixin",
     "PlayerManager_scarpetEventsMixin",
     "PlayerInventory_scarpetEventMixin",
+    "ScoreboardObjective_scarpetMixin",
+    "Scoreboard_scarpetMixin",
     "TradeOutputSlot_scarpetEventMixin",
 
     "ChunkTicketManager_scarpetMixin",