Skip to content

Commit

Permalink
Implement better hitboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
iam4722202468 committed Jul 6, 2023
1 parent 2828cbe commit b33fc9f
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 34 deletions.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ publishing {
publications.create<MavenPublication>("maven") {
groupId = "net.worldseed.multipart"
artifactId = "WorldSeedEntityEngine"
version = "7.0.0"
version = "7.0.4"

from(components["java"])
}
Expand All @@ -38,7 +38,7 @@ publishing {
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
compileOnly("dev.hollowcube:minestom-ce:438338381e")
implementation("dev.hollowcube:minestom-ce:438338381e")
implementation("commons-io:commons-io:2.11.0")
implementation("org.zeroturnaround:zt-zip:1.8")

Expand Down
21 changes: 19 additions & 2 deletions src/main/java/net/worldseed/multipart/GenericModelImpl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.worldseed.multipart;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minestom.server.MinecraftServer;
Expand All @@ -13,8 +14,8 @@
import net.worldseed.multipart.animations.AnimationHandlerImpl;
import net.worldseed.multipart.events.AnimationCompleteEvent;
import net.worldseed.multipart.model_bones.ModelBone;
import net.worldseed.multipart.model_bones.ModelBoneImpl;
import net.worldseed.multipart.model_bones.ModelBoneHead;
import net.worldseed.multipart.model_bones.ModelBoneImpl;
import net.worldseed.multipart.model_bones.ModelBoneViewable;
import net.worldseed.multipart.model_bones.armour_stand.ModelBoneHeadArmourStand;
import net.worldseed.multipart.model_bones.armour_stand.ModelBoneHeadArmourStandHand;
Expand Down Expand Up @@ -119,7 +120,7 @@ protected void loadBones(JsonObject loadedModel, LivingEntity masterEntity) {
this.nametag = new ModelBoneNametag(pivotPos, name, boneRotation, this, null);
modelBonePart = nametag;
} else if (name.contains("hitbox")) {
modelBonePart = new ModelBoneHitbox(pivotPos, name, boneRotation, this, masterEntity);
addHitboxParts(pivotPos, name, boneRotation, this, masterEntity, bone.getAsJsonObject().getAsJsonArray("cubes"), this.parts);
} else if (name.contains("globalloader")) {
if (config.modelType() == ModelConfig.ModelType.ZOMBIE) {
globalLoader = new ModelBoneLoaderGlobal(pivotPos, name, boneRotation, this, masterEntity);
Expand Down Expand Up @@ -200,6 +201,22 @@ protected void loadBones(JsonObject loadedModel, LivingEntity masterEntity) {
}
}

private void addHitboxParts(Point pivotPos, String name, Point boneRotation, GenericModelImpl genericModel, LivingEntity masterEntity, JsonArray cubes, LinkedHashMap<String, ModelBone> parts) {
if (cubes.size() < 1) return;

var cube = cubes.get(0);
JsonArray sizeArray = cube.getAsJsonObject().get("size").getAsJsonArray();
JsonArray p = cube.getAsJsonObject().get("pivot").getAsJsonArray();

Point sizePoint = new Vec(sizeArray.get(0).getAsFloat(), sizeArray.get(1).getAsFloat(), sizeArray.get(2).getAsFloat());
Point pivotPoint = new Vec(p.get(0).getAsFloat(), p.get(1).getAsFloat(), p.get(2).getAsFloat());

var newOffset = pivotPoint.mul(-1, 1, 1);

ModelBone created = new ModelBoneHitbox(pivotPos, name, boneRotation, genericModel, masterEntity, newOffset, sizePoint.x(), sizePoint.y(), cubes, true);
parts.put(name, created);
}

public void setNametagEntity(LivingEntity entity) {
if (this.nametag != null) this.nametag.linkEntity(entity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ public CompletableFuture<Void> spawn(Instance instance, Point position) {
if (this.offset != null && this.stand != null) {
this.stand.setNoGravity(true);
this.stand.setSilent(true);
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> this.stand.setInvisible(true));

return this.stand.setInstance(instance, position);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void tick(long time) {}
};

ArmorStandMeta meta = (ArmorStandMeta) this.stand.getEntityMeta();
stand.setInvisible(true);

if (modelConfig.size() == ModelConfig.Size.SMALL)
meta.setSmall(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void tick(long time) {}
};

ArmorStandMeta meta = (ArmorStandMeta) this.stand.getEntityMeta();
stand.setInvisible(true);

if (config.size() == ModelConfig.Size.SMALL)
meta.setSmall(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,122 @@
package net.worldseed.multipart.model_bones.misc;

import com.google.gson.JsonArray;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.metadata.other.SlimeMeta;
import net.minestom.server.entity.metadata.other.InteractionMeta;
import net.minestom.server.instance.Instance;
import net.minestom.server.tag.Tag;
import net.worldseed.multipart.GenericModel;
import net.worldseed.multipart.ModelConfig;
import net.worldseed.multipart.animations.ModelAnimation;
import net.worldseed.multipart.model_bones.ModelBone;
import net.worldseed.multipart.model_bones.ModelBoneImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public class ModelBoneHitbox extends ModelBoneImpl {
public ModelBoneHitbox(Point pivot, String name, Point rotation, GenericModel model, LivingEntity forwardTo) {
Pos actualPosition = Pos.ZERO;
List<ModelBone> illegitimateChildren = new ArrayList<>();

public ModelBoneHitbox(Point pivot, String name, Point rotation, GenericModel model, LivingEntity forwardTo, Point newOffset, double sizeX, double sizeY, JsonArray cubes, boolean parent) {
super(pivot, name, rotation, model);

String[] spl = name.split("_");
int size = spl.length > 1 ? Integer.parseInt(spl[1]) : 1;
if (parent) {
generateStands(cubes, pivot, name, rotation, model, forwardTo);
this.offset = null;
}
else {
if (this.offset != null) {
this.stand = new LivingEntity(EntityType.INTERACTION) {
@Override
public void tick(long time) {
}
};

this.stand.setTag(Tag.String("WSEE"), "hitbox");
this.offset = newOffset;

InteractionMeta meta = (InteractionMeta) this.stand.getEntityMeta();
meta.setHeight((float) (sizeY / 4f));
meta.setWidth((float) (sizeX / 4f));

ModelBoneImpl.hookPart(this, forwardTo);
}
}
}

public void generateStands(JsonArray cubes, Point pivotPos, String name, Point boneRotation, GenericModel genericModel, LivingEntity masterEntity) {
for (var cube : cubes) {
JsonArray sizeArray = cube.getAsJsonObject().get("size").getAsJsonArray();
JsonArray p = cube.getAsJsonObject().get("pivot").getAsJsonArray();

Point sizePoint = new Vec(sizeArray.get(0).getAsFloat(), sizeArray.get(1).getAsFloat(), sizeArray.get(2).getAsFloat());
Point pivotPoint = new Vec(p.get(0).getAsFloat(), p.get(1).getAsFloat(), p.get(2).getAsFloat());

int maxSize = (int) Math.min(Math.min(sizePoint.x(), sizePoint.y()), sizePoint.z());

if (this.offset != null) {
this.stand = new LivingEntity(EntityType.SLIME) {
@Override
public void tick(long time) {}
};
// Convert sizePoint in to smaller squares
for (int x = 0; x < sizePoint.x() / maxSize; ++x) {
for (int y = 0; y < sizePoint.y() / maxSize; ++y) {
for (int z = 0; z < sizePoint.z() / maxSize; ++z) {
var relativeSize = new Vec(maxSize, maxSize, maxSize);
var relativePivotPoint = new Vec(x * maxSize, y * maxSize, z * maxSize);

SlimeMeta meta = (SlimeMeta) this.stand.getEntityMeta();
meta.setSize(size);
var newOffset = pivotPoint.mul(-1, 1, 1).sub(sizePoint.x() / 2, sizePoint.y() / 2, sizePoint.z() / 2);
newOffset = newOffset.add(relativePivotPoint).add(relativeSize.x() / 2, 0, relativeSize.z() / 2);

ModelBoneImpl.hookPart(this, forwardTo);
this.stand.setTag(Tag.String("WSEE"), "hitbox");
ModelBone created = new ModelBoneHitbox(pivotPos, name, boneRotation, genericModel, masterEntity, newOffset, relativeSize.x(), relativeSize.y(), cubes, false);
illegitimateChildren.add(created);
}
}
}
}
}

@Override
public void setParent(ModelBone parent) {
super.setParent(parent);
this.illegitimateChildren.forEach(modelBone -> modelBone.setParent(parent));
}

@Override
public CompletableFuture<Void> spawn(Instance instance, Point position) {
this.illegitimateChildren.forEach(modelBone -> modelBone.spawn(instance, position));
return super.spawn(instance, position);
}

@Override
public void addAnimation(ModelAnimation animation) {
super.addAnimation(animation);
this.illegitimateChildren.forEach(modelBone -> modelBone.addAnimation(animation));
}

@Override
public void setState(String state) {}

@Override
public Pos calculatePosition() {
if (this.offset == null) return Pos.ZERO;

Point p = this.offset;

p = applyTransform(p);
p = calculateGlobalRotation(p);

Pos endPos = Pos.fromPoint(p);
var lp = actualPosition;
var newPoint = Pos.fromPoint(p).div(4);
actualPosition = Pos.fromPoint(lp.asVec().lerp(Vec.fromPoint(newPoint), 0.25));

double divisor;
if (model.config().itemSlot() == ModelConfig.ItemSlot.HEAD) {
divisor = model.config().size() == ModelConfig.Size.SMALL ? 1.426 : 1;
} else {
divisor = model.config().size() == ModelConfig.Size.SMALL ? 1.25 : 0.624;
}
return lp;
}

return endPos
.div(6.4, 6.4, 6.4)
.div(divisor)
.add(model.getPosition())
.add(model.getGlobalOffset());
@Override
public void destroy() {
super.destroy();
illegitimateChildren.forEach(ModelBone::destroy);
}

@Override
Expand All @@ -66,8 +125,12 @@ public Point calculateRotation() {
}

public void draw() {
this.children.forEach(ModelBone::draw);
if (this.illegitimateChildren.size() > 0) {
this.children.forEach(ModelBone::draw);
this.illegitimateChildren.forEach(ModelBone::draw);
}
if (this.offset == null) return;
stand.teleport(calculatePosition());

stand.teleport(calculatePosition().add(model.getPosition()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public ModelBoneSeat(Point pivot, String name, Point rotation, GenericModel mode
public void tick(long time) {}
};
this.stand.setTag(Tag.String("WSEE"), "seat");
stand.setInvisible(true);

ModelBoneImpl.hookPart(this, forwardTo);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public void tick(long time) {}
meta.setBaby(true);
}

stand.setInvisible(true);
ModelBoneImpl.hookPart(this, forwardTo);
}
}
Expand Down

0 comments on commit b33fc9f

Please sign in to comment.