diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index efc638e8..5f5d5aac 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -2719,6 +2719,34 @@ and `true`. If no duration is specified, or it is null or 0, the effect is remov Sets AI to stay around the home position, within `distance` blocks from it. `distance` defaults to 16 blocks. `null` removes it. _May_ not work fully with mobs that have this AI built in, like Villagers. +### `modify(e, 'gamemode', gamemode?), modify(e, 'gamemode',gamemode_id?)` + +Modifies gamemode of player to whatever string (case-insensitive) or number you put in. + +* 0: survival +* 1: creative +* 2: adventure +* 3: spectator + +### `modify(e, 'jumping', true/false?)` + +Will make the entity constantly jump if set to true, and will stop the entity from jumping if set to false. + +### `modify(e, 'jump'))` + +Will make the entity jump once only + +### `modify(e, 'silent', true/false)` + +### `modify(e, 'gravity', true/false)` + +### `modify(e, 'fire', ticks)` + +Will set mob on fire for `ticks` ticks. Set to 0 to extinguish. + +### `modify(e, 'age', age)` + + ## Entity Events There is a number of events that happen to entities that you can attach your own code to in the form of event handlers. diff --git a/docs/scarpet/api/Entities.md b/docs/scarpet/api/Entities.md index 9b808752..4da5ddda 100644 --- a/docs/scarpet/api/Entities.md +++ b/docs/scarpet/api/Entities.md @@ -458,6 +458,33 @@ and `true`. If no duration is specified, or it is null or 0, the effect is remov Sets AI to stay around the home position, within `distance` blocks from it. `distance` defaults to 16 blocks. `null` removes it. _May_ not work fully with mobs that have this AI built in, like Villagers. +### `modify(e, 'gamemode', gamemode?), modify(e, 'gamemode',gamemode_id?)` + +Modifies gamemode of player to whatever string (case-insensitive) or number you put in. + +* 0: survival +* 1: creative +* 2: adventure +* 3: spectator + +### `modify(e, 'jumping', true/false)` + +Will make the entity constantly jump if set to true, and will stop the entity from jumping if set to false. + +### `modify(e, 'jump'))` + +Will make the entity jump once only + +### `modify(e, 'silent', true/false)` + +### `modify(e, 'gravity', true/false)` + +### `modify(e, 'fire', ticks)` + +Will set mob on fire for `ticks` ticks. Set to 0 to extinguish. + +### `modify(e, 'age', age)` + ## Entity Events There is a number of events that happen to entities that you can attach your own code to in the form of event handlers. diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index 3ec78696..9ef48a83 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -45,6 +45,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; +import net.minecraft.world.GameMode; import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; @@ -60,6 +61,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import static carpet.script.value.NBTSerializableValue.nameFromRegistryId; +import static carpet.utils.MobAI.jump; // TODO: decide whether copy(entity) should duplicate entity in the world. public class EntityValue extends Value @@ -876,7 +878,7 @@ public class EntityValue extends Value { le.removeStatusEffect(effect); return; - } + } int amplifier = 0; if (lv.size() > 2) amplifier = (int)NumericValue.asNumber(lv.get(2)).getLong(); @@ -893,21 +895,63 @@ public class EntityValue extends Value throw new InternalExpressionException("'effect' needs either no arguments (clear) or effect name, duration, and optional amplifier, show particles and show icon"); }); - // gamemode - // spectate - // "fire" - // "extinguish" - // "silent" - // "gravity" - // "invulnerable" - // "dimension" - // "item" - // "count", - // "age", - // "effect_"name - // "hold" - // "hold_offhand" - // "jump" + put("gamemode", (e,v)->{ + if(!(e instanceof ServerPlayerEntity)){ + return; + } + switch(v.getString().toLowerCase()){ + case "survival": case "0":((ServerPlayerEntity) e).setGameMode(GameMode.SURVIVAL);break; + case "creative": case "1":((ServerPlayerEntity) e).setGameMode(GameMode.CREATIVE);break; + case "adventure": case "2":((ServerPlayerEntity) e).setGameMode(GameMode.ADVENTURE);break; + case "spectator": case "3":((ServerPlayerEntity) e).setGameMode(GameMode.SPECTATOR);break; + } + }); + + put("jumping",(e,v)->{ + if(!(e instanceof LivingEntity)) return; + + ((LivingEntity) e).setJumping(v.getBoolean()); + }); + + put("jump",(e,v)->{ + jump((LivingEntity)e); + }); + + put("silent",(e,v)->{ + e.setSilent(v.getBoolean()); + }); + + put("gravity",(e,v)->{ + e.setNoGravity(!v.getBoolean()); + }); + + put("invulnerable",(e,v)->{ + e.setInvulnerable(v.getBoolean()); + }); + + put("fire",(e,v)->{ + e.setFireTicks((int)NumericValue.asNumber(v).getLong()); + }); + + put("age",(e,v)->{ + e.age=(int)NumericValue.asNumber(v).getLong(); + }); + + // gamemode [check] + // spectate [check] + // "fire" [check] + // "extinguish" [set fire ticks to 0] + // "silent" [check] + // "gravity" [check] + // "invulnerable" [check] + // "dimension" [] + // "item" [] + // "count", [] + // "age", [check] + // "effect_"name [] + // "hold" [inventory_set?] + // "hold_offhand" [inventory_set?] + // "jump" [check] // "nbt" <-big one, for now use run('data merge entity ... }}; diff --git a/src/main/java/carpet/utils/MobAI.java b/src/main/java/carpet/utils/MobAI.java index 0a202b16..77c4fd94 100644 --- a/src/main/java/carpet/utils/MobAI.java +++ b/src/main/java/carpet/utils/MobAI.java @@ -4,7 +4,12 @@ import carpet.CarpetServer; import com.google.common.collect.Sets; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffects; import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; import java.util.HashMap; @@ -93,4 +98,24 @@ public class MobAI } } + public static void jump(LivingEntity e){//Most *REDACTED* up code in the world + float m = e.world.getBlockState(new BlockPos(e)).getBlock().getJumpVelocityMultiplier(); + float g = e.world.getBlockState(new BlockPos(e.getX(), e.getBoundingBox().y1 - 0.5000001D, e.getZ())).getBlock().getJumpVelocityMultiplier(); + float JumpVelocityMultiplier= (double)m == 1.0D ? g : m; + + float f = (0.42F * JumpVelocityMultiplier); + if (e.hasStatusEffect(StatusEffects.JUMP_BOOST)) { + f += 0.1F * (float)(e.getStatusEffect(StatusEffects.JUMP_BOOST).getAmplifier() + 1); + } + + Vec3d vec3d = e.getVelocity(); + e.setVelocity(vec3d.x, f, vec3d.z); + if (e.isSprinting()) { + float u = e.yaw * 0.017453292F; + e.setVelocity(e.getVelocity().add((-MathHelper.sin(g) * 0.2F), 0.0D, (MathHelper.cos(u) * 0.2F))); + } + + e.velocityDirty = true; + } + }