adding a shape that can display a item or a block (#1365)
added 'polygon', 'item' and 'block' to scarpet rendered shapes
This commit is contained in:
1 parent
c528695d1a
commit
179f5a6006
5 files changed
+868
-6
No files matched your search
@@ -0,0 +1,11 @@
|
||||
package carpet.mixins;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.ShulkerModel;
|
||||
|
||||
@Mixin(net.minecraft.client.renderer.blockentity.ShulkerBoxRenderer.class)
|
||||
public interface ShulkerBoxAccessMixin {
|
||||
@Accessor("model")
|
||||
ShulkerModel getModel();
|
||||
}
|
||||
@@ -6,18 +6,26 @@ import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.ThrowStatement;
|
||||
import carpet.script.exception.Throwables;
|
||||
import carpet.script.language.Sys;
|
||||
import carpet.script.value.AbstractListValue;
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.BooleanValue;
|
||||
import carpet.script.value.EntityValue;
|
||||
import carpet.script.value.FormattedTextValue;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.MapValue;
|
||||
import carpet.script.value.NBTSerializableValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat.Mode;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
|
||||
import net.minecraft.commands.arguments.ParticleArgument;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -29,8 +37,11 @@ import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.nbt.NumericTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -40,12 +51,16 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -249,6 +264,9 @@ public class ShapeDispatcher
|
||||
put("sphere", creator(Sphere::new));
|
||||
put("cylinder", creator(Cylinder::new));
|
||||
put("label", creator(DisplayedText::new));
|
||||
put("polygon",creator(Polyface::new));
|
||||
put("block",creator(()->new DisplayedSprite(false)));
|
||||
put("item",creator(()->new DisplayedSprite(true)));
|
||||
}};
|
||||
private static Function<Map<String, Value>,ExpiringShape> creator(Supplier<ExpiringShape> shapeFactory)
|
||||
{
|
||||
@@ -271,6 +289,7 @@ public class ShapeDispatcher
|
||||
protected boolean snapX, snapY, snapZ;
|
||||
protected boolean discreteX, discreteY, discreteZ;
|
||||
protected ResourceKey<Level> shapeDimension;
|
||||
protected boolean needf3b;
|
||||
|
||||
|
||||
protected ExpiringShape() { }
|
||||
@@ -322,6 +341,11 @@ public class ShapeDispatcher
|
||||
this.b = (float)(color >> 8 & 0xFF) / 255.0F;
|
||||
this.a = (float)(color & 0xFF) / 255.0F;
|
||||
|
||||
needf3b = false;
|
||||
if (options.containsKey("toggleable")) {
|
||||
needf3b = options.get("toggleable").getBoolean();
|
||||
}
|
||||
|
||||
key = 0;
|
||||
followEntity = -1;
|
||||
shapeDimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(options.get("dim").getString()));
|
||||
@@ -386,6 +410,7 @@ public class ShapeDispatcher
|
||||
hash ^= shapeDimension.hashCode(); hash *= 1099511628211L;
|
||||
hash ^= color; hash *= 1099511628211L;
|
||||
hash ^= followEntity; hash *= 1099511628211L;
|
||||
hash ^= Boolean.hashCode(needf3b); hash *= 1099511628211L;
|
||||
if (followEntity >= 0)
|
||||
{
|
||||
hash ^= snapTo.hashCode(); hash *= 1099511628211L;
|
||||
@@ -408,6 +433,7 @@ public class ShapeDispatcher
|
||||
"color", new NumericValue(-1),
|
||||
"follow", new NumericValue(-1),
|
||||
"line", new NumericValue(2.0),
|
||||
"toggleable", Value.FALSE,
|
||||
"fill", new NumericValue(0xffffff00),
|
||||
"snap", new StringValue("xyz")
|
||||
);
|
||||
@@ -546,6 +572,140 @@ public class ShapeDispatcher
|
||||
}
|
||||
}
|
||||
|
||||
public static class DisplayedSprite extends ExpiringShape {
|
||||
private final Set<String> required = Set.of("pos");
|
||||
private final Map<String, Value> optional = Map.ofEntries(
|
||||
entry("facing", new StringValue("north")),
|
||||
entry("tilt", new NumericValue(0)),
|
||||
entry("lean", new NumericValue(0)),
|
||||
entry("turn", new NumericValue(0)),
|
||||
entry("scale", ListValue.fromTriple(1,1,1)),
|
||||
entry("blocklight", new NumericValue(-1)),
|
||||
entry("skylight", new NumericValue(-1)));
|
||||
private boolean isitem;
|
||||
|
||||
@Override
|
||||
protected Set<String> requiredParams() {
|
||||
return Sets.union(Sets.union(super.requiredParams(), required), Set.of(isitem ? "item" : "block"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> optionalParams() {
|
||||
return Sets.union(Sets.union(super.optionalParams(), optional.keySet()),isitem ? Set.of("variant") : Set.of());
|
||||
}
|
||||
|
||||
public DisplayedSprite(boolean i) {
|
||||
isitem = i;
|
||||
}
|
||||
|
||||
Vec3 pos;
|
||||
|
||||
Direction facing;
|
||||
|
||||
float tilt;
|
||||
float lean;
|
||||
float turn;
|
||||
float scale_z = 1.0f;
|
||||
int light_fromblock;
|
||||
int light_fromsky;
|
||||
|
||||
float scale_y = 1.0f;
|
||||
float scale_x = 1.0f;
|
||||
CompoundTag blockEntity;
|
||||
BlockState blockState;
|
||||
ItemStack item = null;
|
||||
TransformType item_transform_type;
|
||||
|
||||
@Override
|
||||
protected void init(Map<String, Value> options) {
|
||||
super.init(options);
|
||||
pos = vecFromValue(options.get("pos"));
|
||||
if(!this.isitem){
|
||||
blockState = ((BlockValue) options.get("block")).getBlockState();
|
||||
blockEntity = ((BlockValue) options.get("block")).getData();
|
||||
}else{
|
||||
this.item = ItemStack.of(((NBTSerializableValue) options.get("item")).getCompoundTag());
|
||||
}
|
||||
light_fromblock = NumericValue
|
||||
.asNumber(options.getOrDefault("blocklight", optional.get("blocklight"))).getInt();
|
||||
if (light_fromblock > 15)
|
||||
light_fromblock = 15;
|
||||
light_fromsky = NumericValue.asNumber(options.getOrDefault("skylight", optional.get("skylight")))
|
||||
.getInt();
|
||||
if (light_fromsky > 15)
|
||||
light_fromsky = 15;
|
||||
|
||||
item_transform_type = TransformType.NONE;
|
||||
if(options.containsKey("variant")){
|
||||
item_transform_type = TransformType.valueOf(options.get("variant").getString());
|
||||
}
|
||||
|
||||
String dir = options.getOrDefault("facing", optional.get("facing")).getString();
|
||||
facing = null;
|
||||
switch (dir)
|
||||
{
|
||||
case "north": facing = Direction.NORTH; break;
|
||||
case "south": facing = Direction.SOUTH; break;
|
||||
case "east": facing = Direction.EAST; break;
|
||||
case "west": facing = Direction.WEST; break;
|
||||
case "up": facing = Direction.UP; break;
|
||||
case "down": facing = Direction.DOWN; break;
|
||||
}
|
||||
|
||||
|
||||
tilt = NumericValue.asNumber(options.getOrDefault("tilt", optional.get("tilt"))).getFloat();
|
||||
lean = NumericValue.asNumber(options.getOrDefault("lean", optional.get("lean"))).getFloat();
|
||||
turn = NumericValue.asNumber(options.getOrDefault("turn", optional.get("turn"))).getFloat();
|
||||
List<Value> scale = ((ListValue) options.getOrDefault("scale", optional.get("scale"))).unpack();
|
||||
scale_y = NumericValue.asNumber(scale.get(1)).getFloat();
|
||||
scale_x = NumericValue.asNumber(scale.get(0)).getFloat();
|
||||
scale_z = NumericValue.asNumber(scale.get(2)).getFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consumer<ServerPlayer> alternative() {
|
||||
ParticleOptions locparticledata;
|
||||
if(this.isitem){
|
||||
if(Block.byItem(this.item.getItem()).defaultBlockState().isAir())
|
||||
return p->{};
|
||||
locparticledata = getParticleData("block_marker "+Registry.BLOCK.getKey(Block.byItem(this.item.getItem())));
|
||||
}else{
|
||||
locparticledata = getParticleData("block_marker "+Registry.BLOCK.getKey(this.blockState.getBlock()));
|
||||
}
|
||||
|
||||
|
||||
return p -> {
|
||||
Vec3 v=relativiseRender(p.level, this.pos, 0);
|
||||
p.getLevel().sendParticles(p,locparticledata , true,
|
||||
v.x, v.y, v.z, 1,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public long calcKey() {
|
||||
long hash = super.calcKey();
|
||||
hash ^= 7; hash *= 1099511628211L;
|
||||
hash ^= vec3dhash(pos); hash *= 1099511628211L;
|
||||
if (facing!= null) hash ^= facing.hashCode(); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(tilt); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(lean); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(turn); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(scale_y); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(scale_z); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(scale_x); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(light_fromsky); hash *= 1099511628211L;
|
||||
hash ^= Float.hashCode(light_fromblock); hash *= 1099511628211L;
|
||||
if (blockEntity!= null) hash ^= blockEntity.toString().hashCode(); hash *= 1099511628211L;
|
||||
if (blockState!= null) hash ^= blockState.hashCode(); hash *= 1099511628211L;
|
||||
hash ^= ValueConversions.of(item).getString().hashCode(); hash *= 1099511628211L;
|
||||
//hash ^= Boolean.hashCode(needf3b); hash *= 1099511628211L;
|
||||
hash ^= item_transform_type.hashCode(); hash *= 1099511628211L;
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Box extends ExpiringShape
|
||||
{
|
||||
@@ -625,6 +785,192 @@ public class ShapeDispatcher
|
||||
}
|
||||
}
|
||||
|
||||
public static class Polyface extends ExpiringShape
|
||||
{
|
||||
@Override
|
||||
public long calcKey(){
|
||||
long hash = super.calcKey();
|
||||
hash ^= 6; hash *= 1099511628211L;
|
||||
hash ^= mode.hashCode(); hash *= 1099511628211L;
|
||||
hash ^= relative.hashCode(); hash *= 1099511628211L;
|
||||
for (Vec3 i :vertex_list){
|
||||
hash ^= vec3dhash(i);
|
||||
hash *= 1099511628211L;
|
||||
}
|
||||
hash ^= Boolean.hashCode(doublesided); hash *= 1099511628211L;
|
||||
hash ^= Integer.hashCode(vertex_list.size()); hash *= 1099511628211L;
|
||||
hash ^= Boolean.hashCode(inneredges); hash *= 1099511628211L;
|
||||
//hash ^= Boolean.hashCode(needf3b); hash *= 1099511628211L;
|
||||
return hash;
|
||||
}
|
||||
ArrayList<Vec3> alter_point=null;
|
||||
final Random random=new Random();
|
||||
boolean doublesided;
|
||||
|
||||
ArrayList<Vec3> alter_point(ServerPlayer p){
|
||||
if (alter_point!=null){
|
||||
return alter_point;
|
||||
}
|
||||
alter_point=new ArrayList<>();
|
||||
switch (mode) {
|
||||
case TRIANGLES:
|
||||
for (int i=0;i<vertex_list.size();i++){
|
||||
Vec3 vecA=vertex_list.get(i);
|
||||
if(relative.get(i)){
|
||||
vecA=relativiseRender(p.level, vecA, 0);
|
||||
}
|
||||
i++;
|
||||
Vec3 vecB=vertex_list.get(i);
|
||||
if(relative.get(i)){
|
||||
vecB=relativiseRender(p.level, vecB, 0);
|
||||
}
|
||||
i++;
|
||||
Vec3 vecC=vertex_list.get(i);
|
||||
if(relative.get(i)){
|
||||
vecC=relativiseRender(p.level, vecC, 0);
|
||||
}
|
||||
alter_draw_triangles(vecA, vecB, vecC);
|
||||
}
|
||||
break;
|
||||
case TRIANGLE_FAN:
|
||||
Vec3 vec0=vertex_list.get(0);
|
||||
if(relative.get(0)){
|
||||
vec0=relativiseRender(p.level, vec0, 0);
|
||||
}
|
||||
Vec3 vec1=vertex_list.get(1);
|
||||
if(relative.get(1)){
|
||||
vec1=relativiseRender(p.level, vec1, 0);
|
||||
}
|
||||
for(int i=2;i<vertex_list.size();i++){
|
||||
Vec3 vec=vertex_list.get(i);
|
||||
if(relative.get(i)){
|
||||
vec=relativiseRender(p.level, vec, 0);
|
||||
}
|
||||
alter_draw_triangles(vec0,vec1,vec);
|
||||
vec1=vec;
|
||||
}
|
||||
break;
|
||||
case TRIANGLE_STRIP:
|
||||
Vec3 vecA=vertex_list.get(0);
|
||||
if(relative.get(0)){
|
||||
vecA=relativiseRender(p.level, vecA, 0);
|
||||
}
|
||||
Vec3 vecB=vertex_list.get(1);
|
||||
if(relative.get(1)){
|
||||
vecB=relativiseRender(p.level, vecB, 0);
|
||||
}
|
||||
//ArrayList<Vec3> last = new ArrayList<Vec3>();
|
||||
//last.add(vecA);last.add(vecB);
|
||||
for(int i=2;i<vertex_list.size();i++){
|
||||
Vec3 vec=vertex_list.get(i);
|
||||
if(relative.get(i)){
|
||||
vec=relativiseRender(p.level, vec, 0);
|
||||
}
|
||||
//alter_draw_triangles(last.get(0),last.get(1),vec);
|
||||
//last.remove(0);last.add(vec);
|
||||
alter_draw_triangles(vecA,vecB,vec);
|
||||
vecA=vecB;vecB=vec;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return alter_point;
|
||||
}
|
||||
void alter_draw_triangles(Vec3 a,Vec3 b,Vec3 c){
|
||||
|
||||
|
||||
Vec3 B = b.subtract(a);Vec3 C = c.subtract(a);
|
||||
for(int i=0;i/8<B.cross(C).length();i++){
|
||||
double x = random.nextDouble();double y = random.nextDouble();
|
||||
alter_point.add(a.add(B.scale(x/2)).add(C.scale(y/2)));
|
||||
if(x+y<1){
|
||||
alter_point.add(a.add(B.scale((x+1)/2)).add(C.scale(y/2)));
|
||||
}else{
|
||||
x=1-x;y=1-y;
|
||||
alter_point.add(a.add(B.scale(x/2)).add(C.scale((y+1)/2)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public Consumer<ServerPlayer> alternative() {
|
||||
final ParticleOptions locparticledata = getParticleData(String.format(Locale.ROOT ,"dust %.1f %.1f %.1f %.1f", fr, fg, fb, fa));
|
||||
return p->{
|
||||
if(p.level.dimension() != this.shapeDimension){return;}
|
||||
if(!(fa>0.0f)){return;}
|
||||
for(Vec3 v : alter_point(p)){
|
||||
p.getLevel().sendParticles(p,locparticledata , true,
|
||||
v.x, v.y, v.z, 1,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
};
|
||||
}
|
||||
private final Set<String> required = Set.of("points");
|
||||
private final Map<String, Value> optional = Map.ofEntries(
|
||||
entry("relative",Value.NULL),
|
||||
entry("mode", new StringValue("polygon")),
|
||||
entry("inner", Value.TRUE),
|
||||
entry("doublesided", Value.TRUE)
|
||||
);
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
protected Set<String> optionalParams() { return Sets.union(super.optionalParams(), optional.keySet()); }
|
||||
ArrayList<Vec3> vertex_list=new ArrayList<>();
|
||||
Mode mode;
|
||||
ArrayList<Boolean> relative=new ArrayList<>();
|
||||
boolean inneredges;
|
||||
@Override
|
||||
protected void init(Map<String, Value> options)
|
||||
{
|
||||
super.init(options);
|
||||
|
||||
|
||||
|
||||
doublesided=options.getOrDefault("doublesided",optional.get("doublesided")).getBoolean();
|
||||
|
||||
if (options.get("points") instanceof AbstractListValue abl){
|
||||
abl.forEach(x->vertex_list.add(vecFromValue(x)));
|
||||
}
|
||||
String _mode = options.getOrDefault("mode",optional.get("mode")).getString();
|
||||
inneredges = options.getOrDefault("inner",optional.get("inner")).getBoolean();
|
||||
if(vertex_list.size()<3){
|
||||
throw new IllegalArgumentException("Unexpected vertex list size: " + vertex_list.size());
|
||||
}else if(vertex_list.size()<4){
|
||||
inneredges=false;
|
||||
}
|
||||
if("polygon".equals(_mode)){
|
||||
mode=VertexFormat.Mode.TRIANGLE_FAN;
|
||||
}else if("strip".equals(_mode)){
|
||||
mode=VertexFormat.Mode.TRIANGLE_STRIP;
|
||||
}else if("triangles".equals(_mode)){
|
||||
mode=VertexFormat.Mode.TRIANGLES;
|
||||
if(vertex_list.size()%3!=0){
|
||||
throw new IllegalArgumentException("Unexpected vertex list size: " + vertex_list.size());
|
||||
}
|
||||
}
|
||||
if (options.getOrDefault("relative",optional.get("relative")) instanceof AbstractListValue abl){
|
||||
Iterator<Value> it = abl.iterator();
|
||||
for(long i=0L;i<vertex_list.size();i++){
|
||||
relative.add(it.hasNext()?it.next().getBoolean():false);//if part of it got defined.
|
||||
}
|
||||
}
|
||||
else if(options.getOrDefault("relative",optional.get("relative")) instanceof BooleanValue boolv){
|
||||
for(long i=0L;i<vertex_list.size();i++){
|
||||
relative.add(boolv.getBoolean());//if it is a boolean.
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(long i=0L;i<vertex_list.size();i++){
|
||||
relative.add(true);//if there is nothing defined at all.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class Line extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = Set.of("from", "to");
|
||||
@@ -858,11 +1204,30 @@ public class ShapeDispatcher
|
||||
public static abstract class Param
|
||||
{
|
||||
public static Map<String, Param> of = new HashMap<String, Param>(){{
|
||||
put("mode",new StringChoiceParam("mode","polygon","strip","triangles"));
|
||||
put("relative",new OptionalBoolListParam("relative"));
|
||||
put("inner", new BoolParam("inner"));
|
||||
put("shape", new ShapeParam());
|
||||
put("dim", new DimensionParam());
|
||||
put("duration", new NonNegativeIntParam("duration"));
|
||||
put("color", new ColorParam("color"));
|
||||
put("follow", new EntityParam("follow"));
|
||||
put("variant",new StringChoiceParam("variant",
|
||||
"NONE",
|
||||
"THIRD_PERSON_LEFT_HAND",
|
||||
"THIRD_PERSON_RIGHT_HAND",
|
||||
"FIRST_PERSON_LEFT_HAND",
|
||||
"FIRST_PERSON_RIGHT_HAND",
|
||||
"HEAD",
|
||||
"GUI",
|
||||
"GROUND",
|
||||
"FIXED")
|
||||
{
|
||||
public Value validate(Map o, MinecraftServer s, Value v)
|
||||
{
|
||||
return super.validate(o, s ,new StringValue(v.getString().toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
});
|
||||
put("snap", new StringChoiceParam("snap",
|
||||
"xyz", "xz", "yz", "xy", "x", "y", "z",
|
||||
"dxdydz", "dxdz", "dydz", "dxdy", "dx", "dy", "dz",
|
||||
@@ -879,6 +1244,15 @@ public class ShapeDispatcher
|
||||
put("radius", new PositiveFloatParam("radius"));
|
||||
put("level", new PositiveIntParam("level"));
|
||||
put("height", new FloatParam("height"));
|
||||
put("width", new FloatParam("width"));
|
||||
put("scale", new Vec3Param("scale", false){
|
||||
public Value validate(java.util.Map<String,Value> options, MinecraftServer server, Value value) {
|
||||
if (value instanceof NumericValue vn){
|
||||
value = ListValue.of(vn,vn,vn);
|
||||
}
|
||||
return super.validate(options, server, value);
|
||||
};
|
||||
});
|
||||
put("axis", new StringChoiceParam("axis", "x", "y", "z"));
|
||||
put("points", new PointsParam("points"));
|
||||
put("text", new FormattedTextParam("text"));
|
||||
@@ -886,11 +1260,18 @@ public class ShapeDispatcher
|
||||
put("size", new PositiveIntParam("size"));
|
||||
put("align", new StringChoiceParam("align", "center", "left", "right"));
|
||||
|
||||
put("block", new BlockParam("block"));
|
||||
put("item", new ItemParam("item"));
|
||||
put("blocklight", new NonNegativeIntParam("blocklight"));
|
||||
put("skylight", new NonNegativeIntParam("skylight"));
|
||||
put("indent", new FloatParam("indent"));
|
||||
put("raise", new FloatParam("raise"));
|
||||
put("tilt", new FloatParam("tilt"));
|
||||
put("lean", new FloatParam("lean"));
|
||||
put("turn", new FloatParam("turn"));
|
||||
put("facing", new StringChoiceParam("axis", "player", "north", "south", "east", "west", "up", "down"));
|
||||
put("doublesided", new BoolParam("doublesided"));
|
||||
put("toggleable", new BoolParam("toggleable"));
|
||||
|
||||
}};
|
||||
protected String id;
|
||||
@@ -903,7 +1284,34 @@ public class ShapeDispatcher
|
||||
public abstract Value validate(Map<String, Value> options, MinecraftServer server, Value value); // makes sure the value is proper
|
||||
public abstract Value decode(Tag tag);
|
||||
}
|
||||
public static class OptionalBoolListParam extends Param
|
||||
{
|
||||
public OptionalBoolListParam(String id) { super(id); }
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value) { return value.toTag(true);}
|
||||
@Override
|
||||
public Value decode(Tag tag) {
|
||||
if(tag instanceof ListTag){
|
||||
return ListValue.wrap(((ListTag)tag).stream().map(x->BooleanValue.of(((NumericTag)x).getAsNumber().doubleValue()!=0)));
|
||||
}
|
||||
if(tag instanceof ByteTag booltag){
|
||||
return BooleanValue.of(booltag.getAsByte()!=0);
|
||||
}
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value validate(Map<String, Value> options, MinecraftServer server, Value value) {
|
||||
if(value instanceof AbstractListValue lv){
|
||||
return ListValue.wrap(lv.unpack().stream().map(Value::getBoolean).map(BooleanValue::of));
|
||||
}
|
||||
if(value instanceof BooleanValue || value.isNull()){
|
||||
return value;
|
||||
}
|
||||
return BooleanValue.of(value.getBoolean());
|
||||
}
|
||||
}
|
||||
public abstract static class StringParam extends Param
|
||||
{
|
||||
protected StringParam(String id) { super(id); }
|
||||
@@ -913,6 +1321,65 @@ public class ShapeDispatcher
|
||||
@Override
|
||||
public Value decode(Tag tag) { return new StringValue(tag.getAsString()); }
|
||||
}
|
||||
public static class BlockParam extends Param
|
||||
{
|
||||
|
||||
protected BlockParam(String id) {
|
||||
super(id);
|
||||
}
|
||||
@Override
|
||||
public Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
||||
{
|
||||
if(value instanceof BlockValue blv){
|
||||
return value;
|
||||
}
|
||||
return BlockValue.fromString(value.getString());
|
||||
}
|
||||
@Override
|
||||
public Tag toTag(Value value) {
|
||||
if(value instanceof BlockValue blv){
|
||||
CompoundTag com = NbtUtils.writeBlockState(blv.getBlockState());
|
||||
CompoundTag dataTag = blv.getData();
|
||||
if (dataTag != null)
|
||||
{
|
||||
com.put("TileEntityData", dataTag);
|
||||
}
|
||||
return com;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value decode(Tag tag) {
|
||||
BlockState bs = NbtUtils.readBlockState((CompoundTag) tag);
|
||||
CompoundTag compoundTag2 = null;
|
||||
if (((CompoundTag) tag).contains("TileEntityData", 10)) {
|
||||
compoundTag2 = ((CompoundTag) tag).getCompound("TileEntityData");
|
||||
}
|
||||
return new BlockValue(bs, null, null, compoundTag2);
|
||||
}
|
||||
}
|
||||
public static class ItemParam extends Param
|
||||
{
|
||||
|
||||
protected ItemParam(String id) {
|
||||
super(id);
|
||||
}
|
||||
@Override
|
||||
public Value validate(Map<String, Value> options, MinecraftServer server, Value value)
|
||||
{
|
||||
ItemStack item=ValueConversions.getItemStackFromValue(value, true);
|
||||
return new NBTSerializableValue(item.save(new CompoundTag()));
|
||||
}
|
||||
@Override
|
||||
public Tag toTag(Value value) {
|
||||
return ((NBTSerializableValue)value).getTag();
|
||||
}
|
||||
@Override
|
||||
public Value decode(Tag tag) {
|
||||
return new NBTSerializableValue(tag);
|
||||
}
|
||||
}
|
||||
public static class TextParam extends StringParam
|
||||
{
|
||||
protected TextParam(String id)
|
||||
@@ -1211,9 +1678,9 @@ public class ShapeDispatcher
|
||||
{
|
||||
List<Value> coords = ((ListValue)value).getItems();
|
||||
ListTag tag = new ListTag();
|
||||
tag.add(DoubleTag.valueOf(NumericValue.asNumber(lv.get(0), "x").getDouble()));
|
||||
tag.add(DoubleTag.valueOf(NumericValue.asNumber(lv.get(1), "y").getDouble()));
|
||||
tag.add(DoubleTag.valueOf(NumericValue.asNumber(lv.get(2), "z").getDouble()));
|
||||
tag.add(DoubleTag.valueOf(NumericValue.asNumber(coords.get(0), "x").getDouble()));
|
||||
tag.add(DoubleTag.valueOf(NumericValue.asNumber(coords.get(1), "y").getDouble()));
|
||||
tag.add(DoubleTag.valueOf(NumericValue.asNumber(coords.get(2), "z").getDouble()));
|
||||
ltag.add(tag);
|
||||
}
|
||||
return ltag;
|
||||
|
||||
@@ -2,30 +2,81 @@ package carpet.script.utils;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.utils.CarpetProfiler;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat.Mode;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.math.Vector3f;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.Sheets;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkSource;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import net.minecraft.world.ticks.LevelTickAccess;
|
||||
|
||||
public class ShapesRenderer
|
||||
{
|
||||
@@ -41,6 +92,9 @@ public class ShapesRenderer
|
||||
put("sphere", RenderedSphere::new);
|
||||
put("cylinder", RenderedCylinder::new);
|
||||
put("label", RenderedText::new);
|
||||
put("polygon",RenderedPolyface::new);
|
||||
put("block",(c,s)->new RenderedSprite(c,s).set_isitem(false));
|
||||
put("item",(c,s)->new RenderedSprite(c,s).set_isitem(true));
|
||||
}};
|
||||
|
||||
public ShapesRenderer(Minecraft minecraftClient)
|
||||
@@ -82,6 +136,7 @@ public class ShapesRenderer
|
||||
double cameraX = camera.getPosition().x;
|
||||
double cameraY = camera.getPosition().y;
|
||||
double cameraZ = camera.getPosition().z;
|
||||
boolean hasf3b = client.getEntityRenderDispatcher().shouldRenderHitBoxes();
|
||||
|
||||
if (shapes.size() != 0) { synchronized (shapes) {
|
||||
shapes.get(dimensionType).long2ObjectEntrySet().removeIf(
|
||||
@@ -95,12 +150,12 @@ public class ShapesRenderer
|
||||
// lines
|
||||
RenderSystem.lineWidth(0.5F);
|
||||
shapes.get(dimensionType).values().forEach( s -> {
|
||||
if (s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
|
||||
if ( (!s.shape.needf3b ||hasf3b ) && s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
|
||||
});
|
||||
// faces
|
||||
RenderSystem.lineWidth(0.1F);
|
||||
shapes.get(dimensionType).values().forEach(s -> {
|
||||
if (s.shouldRender(dimensionType)) s.renderFaces(tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
|
||||
if ( (!s.shape.needf3b ||hasf3b ) && s.shouldRender(dimensionType)) s.renderFaces(tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
|
||||
});
|
||||
RenderSystem.lineWidth(1.0F);
|
||||
matrixStack.popPose();
|
||||
@@ -113,7 +168,7 @@ public class ShapesRenderer
|
||||
entry -> entry.getValue().isExpired(currentTime)
|
||||
);
|
||||
labels.get(dimensionType).values().forEach(s -> {
|
||||
if (s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
|
||||
if ( (!s.shape.needf3b || hasf3b) && s.shouldRender(dimensionType)) s.renderLines(matrices, tessellator, bufferBuilder, cameraX, cameraY, cameraZ, partialTick);
|
||||
});
|
||||
}}
|
||||
RenderSystem.enableCull();
|
||||
@@ -233,6 +288,175 @@ public class ShapesRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public static class RenderedSprite extends RenderedShape<ShapeDispatcher.DisplayedSprite> {
|
||||
|
||||
private boolean isitem;
|
||||
|
||||
public RenderedSprite set_isitem(boolean isitem) {
|
||||
this.isitem = isitem;
|
||||
return this;
|
||||
}
|
||||
|
||||
private BlockPos blockPos;
|
||||
private BlockState blockState;
|
||||
private BlockEntity BlockEntity = null;
|
||||
|
||||
protected RenderedSprite(Minecraft client, ShapeDispatcher.ExpiringShape shape) {
|
||||
super(client, (ShapeDispatcher.DisplayedSprite) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
|
||||
double cz, float partialTick) {
|
||||
if (shape.a == 0.0)
|
||||
return;
|
||||
|
||||
Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||
Camera camera1 = client.gameRenderer.getMainCamera();
|
||||
|
||||
matrices.pushPose();
|
||||
if (!isitem)// blocks should use its center as the origin
|
||||
matrices.translate(0.5, 0.5, 0.5);
|
||||
matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz);
|
||||
if (shape.facing == null) {
|
||||
matrices.mulPose(camera1.rotation());
|
||||
matrices.mulPose(Vector3f.YP.rotationDegrees(180));
|
||||
} else {
|
||||
switch (shape.facing) {
|
||||
case NORTH:
|
||||
break;
|
||||
case SOUTH:
|
||||
matrices.mulPose(Vector3f.YP.rotationDegrees(180));
|
||||
break;
|
||||
case EAST:
|
||||
matrices.mulPose(Vector3f.YP.rotationDegrees(270));
|
||||
break;
|
||||
case WEST:
|
||||
matrices.mulPose(Vector3f.YP.rotationDegrees(90));
|
||||
break;
|
||||
case UP:
|
||||
matrices.mulPose(Vector3f.XP.rotationDegrees(90));
|
||||
break;
|
||||
case DOWN:
|
||||
matrices.mulPose(Vector3f.XP.rotationDegrees(-90));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape.tilt != 0.0f)
|
||||
matrices.mulPose(Vector3f.ZP.rotationDegrees(shape.tilt));
|
||||
if (shape.lean != 0.0f)
|
||||
matrices.mulPose(Vector3f.XP.rotationDegrees(shape.lean));
|
||||
if (shape.turn != 0.0f)
|
||||
matrices.mulPose(Vector3f.YP.rotationDegrees(shape.turn));
|
||||
matrices.scale(shape.scale_x, shape.scale_y, shape.scale_z);
|
||||
|
||||
if (!isitem)// blocks should use its center as the origin
|
||||
matrices.translate(-0.5, -0.5, -0.5);
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
|
||||
|
||||
blockPos = new BlockPos(v1);
|
||||
int light;
|
||||
light = LightTexture.pack(
|
||||
shape.light_fromblock < 0 ? client.level.getBrightness(LightLayer.BLOCK, blockPos)
|
||||
: shape.light_fromblock,
|
||||
shape.light_fromsky < 0 ? client.level.getBrightness(LightLayer.SKY, blockPos)
|
||||
: shape.light_fromsky);
|
||||
|
||||
blockState = shape.blockState;
|
||||
|
||||
MultiBufferSource.BufferSource immediate = client.renderBuffers().bufferSource();
|
||||
if (!isitem) {
|
||||
// draw the block itself
|
||||
if (blockState.getRenderShape() == RenderShape.MODEL) {
|
||||
|
||||
var bakedModel = client.getBlockRenderer().getBlockModel(blockState);
|
||||
int color = client.getBlockColors().getColor(blockState,client.level,blockPos,0);
|
||||
//dont know why there is a 0.
|
||||
//see https://github.com/senseiwells/EssentialClient/blob/4db1f291936f502304791ee323f369c206b3021d/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java#L464
|
||||
float red = (color >> 16 & 0xFF) / 255.0F;
|
||||
float green = (color >> 8 & 0xFF) / 255.0F;
|
||||
float blue = (color & 0xFF) / 255.0F;
|
||||
client.getBlockRenderer().getModelRenderer().renderModel(matrices.last(), immediate.getBuffer(ItemBlockRenderTypes.getRenderType(blockState, false)), blockState, bakedModel, red, green, blue, light, OverlayTexture.NO_OVERLAY);
|
||||
}
|
||||
|
||||
// draw the block`s entity part
|
||||
if (BlockEntity == null) {
|
||||
if (blockState.getBlock() instanceof EntityBlock eb) {
|
||||
BlockEntity = eb.newBlockEntity(blockPos, blockState);
|
||||
if (BlockEntity != null) {
|
||||
BlockEntity.setLevel(client.level);
|
||||
if (shape.blockEntity != null)
|
||||
BlockEntity.load(shape.blockEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (BlockEntity instanceof ShulkerBoxBlockEntity sbBlockEntity){
|
||||
sbrender(sbBlockEntity, partialTick,
|
||||
matrices, immediate, light, OverlayTexture.NO_OVERLAY);
|
||||
}else
|
||||
if (BlockEntity != null && client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity) != null) {
|
||||
client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity).render(BlockEntity, partialTick,
|
||||
matrices, immediate, light, OverlayTexture.NO_OVERLAY);
|
||||
}
|
||||
} else {
|
||||
// draw item
|
||||
if (shape.item != null)
|
||||
client.getItemRenderer().renderStatic(shape.item, shape.item_transform_type, light,
|
||||
OverlayTexture.NO_OVERLAY, matrices, immediate, (int) shape.key());
|
||||
}
|
||||
matrices.popPose();
|
||||
immediate.endBatch();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stageDeux() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// copy and modifiy a bit from net.minecraft.client.renderer.blockentity.ShulkerBoxRenderer.render
|
||||
public void sbrender(ShulkerBoxBlockEntity shulkerBoxBlockEntity, float f, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int j) {
|
||||
Direction direction = Direction.UP;
|
||||
if (shulkerBoxBlockEntity.hasLevel()) {
|
||||
BlockState blockState = shulkerBoxBlockEntity.getBlockState();
|
||||
if (blockState.getBlock() instanceof ShulkerBoxBlock) {
|
||||
direction = blockState.getValue(ShulkerBoxBlock.FACING);
|
||||
}
|
||||
}
|
||||
DyeColor dyeColor = shulkerBoxBlockEntity.getColor();
|
||||
Material material;
|
||||
if (dyeColor == null) {
|
||||
material = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION;
|
||||
} else {
|
||||
material = (Material)Sheets.SHULKER_TEXTURE_LOCATION.get(dyeColor.getId());
|
||||
}
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(0.5, 0.5, 0.5);
|
||||
float g = 0.9995F;
|
||||
poseStack.scale(0.9995F, 0.9995F, 0.9995F);
|
||||
poseStack.mulPose(direction.getRotation());
|
||||
poseStack.scale(1.0F, -1.0F, -1.0F);
|
||||
poseStack.translate(0.0, -1.0, 0.0);
|
||||
ModelPart modelPart = ((carpet.mixins.ShulkerBoxAccessMixin)(Object)(client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity))).getModel().getLid();
|
||||
modelPart.setPos(0.0F, 24.0F - shulkerBoxBlockEntity.getProgress(f) * 0.5F * 16.0F, 0.0F);
|
||||
modelPart.yRot = 270.0F * shulkerBoxBlockEntity.getProgress(f) * (float) (Math.PI / 180.0);
|
||||
VertexConsumer vertexConsumer = material.buffer(multiBufferSource, RenderType::entityCutoutNoCull);
|
||||
((carpet.mixins.ShulkerBoxAccessMixin)(Object)(client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity))).getModel().renderToBuffer(poseStack, vertexConsumer, i, j, 1.0F, 1.0F, 1.0F, 1.0F);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class RenderedText extends RenderedShape<ShapeDispatcher.DisplayedText>
|
||||
{
|
||||
|
||||
@@ -386,7 +610,140 @@ public class ShapesRenderer
|
||||
);
|
||||
}
|
||||
}
|
||||
public static class RenderedPolyface extends RenderedShape<ShapeDispatcher.Polyface>
|
||||
{
|
||||
public RenderedPolyface(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.Polyface)shape);
|
||||
}
|
||||
@Override
|
||||
public void renderFaces(Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if(shape.fa==0){return;}
|
||||
|
||||
if (shape.doublesided)
|
||||
RenderSystem.disableCull();
|
||||
else
|
||||
RenderSystem.enableCull();
|
||||
|
||||
bufferBuilder.begin(shape.mode, DefaultVertexFormat.POSITION_COLOR);
|
||||
for(int i=0;i<shape.vertex_list.size();i++){
|
||||
Vec3 vec=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
bufferBuilder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.fr, shape.fg, shape.fb, shape.fa).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.depthMask(false);
|
||||
//RenderSystem.enableDepthTest();
|
||||
|
||||
|
||||
|
||||
}
|
||||
@Override
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
|
||||
double cz, float partialTick) {
|
||||
if(shape.a==0){return;}
|
||||
|
||||
if (shape.mode==Mode.TRIANGLE_FAN){
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||
Vec3 vec0=null;
|
||||
for(int i=0;i<shape.vertex_list.size();i++){
|
||||
Vec3 vec=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
if(i==0)vec0=vec;
|
||||
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
builder.vertex(vec0.x()-cx, vec0.y()-cy, vec0.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
tessellator.end();
|
||||
if(shape.inneredges){
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for(int i=1;i<shape.vertex_list.size()-1;i++){
|
||||
Vec3 vec = shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
|
||||
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
builder.vertex(vec0.x()-cx, vec0.y()-cy, vec0.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (shape.mode==Mode.TRIANGLE_STRIP){
|
||||
//02468
|
||||
//1357*
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||
Vec3 vec=shape.vertex_list.get(1);
|
||||
if(shape.relative.get(1)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
int i;
|
||||
for(i=0;i<shape.vertex_list.size();i+=2){
|
||||
vec=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
i=shape.vertex_list.size()-1;
|
||||
for(i-=1-i%2;i>0;i-=2){
|
||||
vec=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
if(shape.inneredges){
|
||||
for(i=2;i<shape.vertex_list.size()-1;i++){
|
||||
vec=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vec=shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
builder.vertex(vec.x()-cx, vec.y()-cy, vec.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
}
|
||||
tessellator.end();
|
||||
return;
|
||||
}
|
||||
if (shape.mode==Mode.TRIANGLES){
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i=0;i<shape.vertex_list.size();i++){
|
||||
Vec3 vecA=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vecA=shape.relativiseRender(client.level, vecA, partialTick);
|
||||
}
|
||||
i++;
|
||||
Vec3 vecB=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vecB=shape.relativiseRender(client.level, vecB, partialTick);
|
||||
}
|
||||
i++;
|
||||
Vec3 vecC=shape.vertex_list.get(i);
|
||||
if(shape.relative.get(i)){
|
||||
vecC=shape.relativiseRender(client.level, vecC, partialTick);
|
||||
}
|
||||
builder.vertex(vecA.x()-cx, vecA.y()-cy, vecA.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
builder.vertex(vecB.x()-cx, vecB.y()-cy, vecB.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
|
||||
builder.vertex(vecB.x()-cx, vecB.y()-cy, vecB.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
builder.vertex(vecC.x()-cx, vecC.y()-cy, vecC.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
|
||||
builder.vertex(vecC.x()-cx, vecC.y()-cy, vecC.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
builder.vertex(vecA.x()-cx, vecA.y()-cy, vecA.z()-cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static class RenderedSphere extends RenderedShape<ShapeDispatcher.Sphere>
|
||||
{
|
||||
public RenderedSphere(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
|
||||
Reference in new issue
Block a user