diff --git a/docs/scarpet/api/Entities.md b/docs/scarpet/api/Entities.md index 1d053fbf..8ecb1af0 100644 --- a/docs/scarpet/api/Entities.md +++ b/docs/scarpet/api/Entities.md @@ -405,8 +405,8 @@ Gets the absorption of the player (yellow hearts, e.g when having a golden apple ### `query(e,'xp_progress')` ### `query(e,'score')` -Numbers related to player's xp. `xp` is the overall xp in the bar, `xp_level` is the levels seen in the hotbar, -`xp_points` is a float between 0 and 1 indicating the percentage of the xp bar filled, and `score` is the score displayed upon death +Numbers related to player's xp. `xp` is the overall xp player has, `xp_level` is the levels seen in the hotbar, +`xp_progress` is a float between 0 and 1 indicating the percentage of the xp bar filled, and `score` is the number displayed upon death ### `query(e, 'air')` @@ -724,10 +724,13 @@ Sets the absorption value for the player. Each point is half a yellow heart. ### `modify(e, 'add_xp', value)` ### `modify(e, 'xp_level', value)` +### `modify(e, 'xp_progress', value)` ### `modify(e, 'xp_score', value)` -Manipulates player xp values - that's the method you probably want to use -to manipulate how much 'xp' an action should give. +Manipulates player xp values - `'add_xp'` the method you probably want to use +to manipulate how much 'xp' an action should give. `'xp_score'` only affects the number you see when you die, and +`'xp_progress'` controls the xp progressbar above the hotbar, should take values from 0 to 1, but you can set it to any value, +maybe you will get a double, who knows. ### `modify(e, 'air', ticks)` diff --git a/src/main/java/carpet/fakes/HungerManagerInterface.java b/src/main/java/carpet/fakes/HungerManagerInterface.java index b4df2334..f6a2787c 100644 --- a/src/main/java/carpet/fakes/HungerManagerInterface.java +++ b/src/main/java/carpet/fakes/HungerManagerInterface.java @@ -3,4 +3,5 @@ package carpet.fakes; public interface HungerManagerInterface { float getExhaustionCM(); void setExhaustionCM(float exhaust); + void setSaturationCM(float saturn); } diff --git a/src/main/java/carpet/mixins/HungerManagerMixin_scarpetEventsMixin.java b/src/main/java/carpet/mixins/HungerManagerMixin_scarpetEventsMixin.java index 3e6fcdc2..2f841f1c 100644 --- a/src/main/java/carpet/mixins/HungerManagerMixin_scarpetEventsMixin.java +++ b/src/main/java/carpet/mixins/HungerManagerMixin_scarpetEventsMixin.java @@ -8,13 +8,11 @@ import org.spongepowered.asm.mixin.Shadow; @Mixin(HungerManager.class) public class HungerManagerMixin_scarpetEventsMixin implements HungerManagerInterface { @Shadow private float exhaustion; - public float getExhaustionCM(){ - return exhaustion; - } - + @Shadow private float foodSaturationLevel; @Override - public void setExhaustionCM(float exhaust) - { - exhaustion = exhaust; - } + public float getExhaustionCM(){ return exhaustion; } + @Override + public void setExhaustionCM(float exhaust) { exhaustion = exhaust; } + @Override + public void setSaturationCM(float saturn) { foodSaturationLevel = saturn; } } diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index f1888417..a9f8e780 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -420,16 +420,17 @@ public class WorldAccess { ServerWorld world = ((CarpetContext) c).s.getWorld(); if(lv.size()==0)//cos it can thunder when raining or when clear. - return (_c,_t)->new StringValue( world.isThundering()? "thunder" : (world.isRaining()? "rain":"clear")); - + { + Value ret = new StringValue(world.isThundering() ? "thunder" : (world.isRaining() ? "rain" : "clear")); + return (_c, _t) -> ret; + } Value weather = lv.get(0).evalValue(c); ServerWorldProperties worldProperties = ((ServerWorldInterface) world).getWorldPropertiesCM(); - - if(lv.size()==1) { + if(lv.size()==1) + { int ticks; - - switch (weather.getString()) { + switch (weather.getString().toLowerCase(Locale.ROOT)) { case "clear": ticks = worldProperties.getClearWeatherTime(); break; @@ -442,11 +443,14 @@ public class WorldAccess { default: throw new InternalExpressionException("Weather can only be 'clear', 'rain' or 'thunder'"); } - return (_c,_t) -> new NumericValue(ticks); - } else if(lv.size()==2){ - int ticks = ((NumericValue)lv.get(1).evalValue(c)).getInt(); - - switch (weather.getString()){ + Value ret = new NumericValue(ticks); + return (_c,_t) -> ret; + } + if(lv.size()==2) + { + int ticks = NumericValue.asNumber(lv.get(1).evalValue(c), "tick_time in 'weather'").getInt(); + switch (weather.getString().toLowerCase(Locale.ROOT)) + { case "clear": world.setWeather(ticks,0,false,false); break; @@ -467,10 +471,10 @@ public class WorldAccess { default: throw new InternalExpressionException("Weather can only be 'clear', 'rain' or 'thunder'"); } - - return LazyValue.TRUE; - } else - throw new InternalExpressionException("'weather' between 0 and 2 arguments"); + Value ret = NumericValue.of(ticks); + return (_c, _t) -> ret; + } + throw new InternalExpressionException("'weather' requires 0, 1 or 2 arguments"); }); expression.addLazyFunction("pos", 1, (c, t, lv) -> diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index ff863165..c30ff0aa 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -30,6 +30,7 @@ import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket; +import net.minecraft.network.packet.s2c.play.ExperienceBarUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket; import net.minecraft.command.EntitySelector; import net.minecraft.command.EntitySelectorReader; @@ -1354,26 +1355,35 @@ public class EntityValue extends Value }); put("absorption", (e, v) -> { - if (e instanceof PlayerEntity) ((PlayerEntity) e).setAbsorptionAmount((float) NumericValue.asNumber(v).getLong()); + if (e instanceof PlayerEntity) ((PlayerEntity) e).setAbsorptionAmount((float) NumericValue.asNumber(v, "absorbtion").getLong()); }); put("add_xp", (e, v) -> { - if (e instanceof PlayerEntity) ((PlayerEntity) e).addExperience(NumericValue.asNumber(v).getInt()); + if (e instanceof PlayerEntity) ((PlayerEntity) e).addExperience(NumericValue.asNumber(v, "add_xp").getInt()); }); put("xp_level", (e, v) -> { - if (e instanceof PlayerEntity) ((PlayerEntity) e).addExperienceLevels(NumericValue.asNumber(v).getInt()-((PlayerEntity) e).experienceLevel); + if (e instanceof PlayerEntity) ((PlayerEntity) e).addExperienceLevels(NumericValue.asNumber(v, "xp_level").getInt()-((PlayerEntity) e).experienceLevel); + }); + + put("xp_progress", (e, v) -> { + if (e instanceof ServerPlayerEntity) + { + ServerPlayerEntity p = (ServerPlayerEntity) e; + p.experienceProgress = NumericValue.asNumber(v, "xp_progress").getFloat(); + p.networkHandler.sendPacket(new ExperienceBarUpdateS2CPacket(p.experienceProgress, p.totalExperience, p.experienceLevel)); + } }); put("xp_score", (e, v) -> { - if (e instanceof PlayerEntity) ((PlayerEntity) e).setScore(NumericValue.asNumber(v).getInt()); + if (e instanceof PlayerEntity) ((PlayerEntity) e).setScore(NumericValue.asNumber(v, "xp_score").getInt()); }); put("saturation", (e, v)-> { - if(e instanceof PlayerEntity) ((PlayerEntity) e).getHungerManager().setSaturationLevelClient(NumericValue.asNumber(v).getFloat()); + if(e instanceof PlayerEntity) ((HungerManagerInterface) ((PlayerEntity) e).getHungerManager()).setSaturationCM(NumericValue.asNumber(v, "saturation").getFloat()); }); - put("air", (e, v) -> e.setAir(NumericValue.asNumber(v).getInt())); + put("air", (e, v) -> e.setAir(NumericValue.asNumber(v, "air").getInt())); put("breaking_progress", (e, a) -> { if (e instanceof ServerPlayerEntity)