Skip to content

Commit

Permalink
Performance tweaks and improvements to launch gel, cars no longer des…
Browse files Browse the repository at this point in the history
…troy decoration entities
  • Loading branch information
FoundationGames committed Jun 9, 2022
1 parent 7aeb33e commit 908dd39
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public void onEntityCollision(BlockState state, World world, BlockPos pos, Entit
super.onEntityCollision(state, world, pos, entity);

if (entity instanceof AutomobileEntity automobile && automobile.automobileOnGround()) {
automobile.setSpeed(Math.max(automobile.getHSpeed(), 0.08f), automobile.getVSpeed() + 0.5f);
automobile.boost(0.14f, 7);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.github.foundationgames.automobility.entity;

import com.google.common.util.concurrent.AtomicDouble;
import io.github.foundationgames.automobility.Automobility;
import io.github.foundationgames.automobility.automobile.AutomobileEngine;
import io.github.foundationgames.automobility.automobile.AutomobileFrame;
Expand All @@ -14,6 +13,7 @@
import io.github.foundationgames.automobility.automobile.render.RenderableAutomobile;
import io.github.foundationgames.automobility.automobile.screen.handler.AutomobileScreenHandlerContext;
import io.github.foundationgames.automobility.block.AutomobileAssemblerBlock;
import io.github.foundationgames.automobility.block.LaunchGelBlock;
import io.github.foundationgames.automobility.block.OffRoadBlock;
import io.github.foundationgames.automobility.item.AutomobileInteractable;
import io.github.foundationgames.automobility.item.AutomobilityItems;
Expand Down Expand Up @@ -57,7 +57,6 @@
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3f;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
Expand All @@ -67,7 +66,6 @@
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

public class AutomobileEntity extends Entity implements RenderableAutomobile, EntityWithInventory {
Expand Down Expand Up @@ -116,11 +114,11 @@ public class AutomobileEntity extends Entity implements RenderableAutomobile, En

private int boostTimer = 0;
private float boostPower = 0;
private int jumpCooldown = 0;

private float hSpeed = 0;
private float vSpeed = 0;

private float addedVSpeed = 0;
private Vec3d addedVelocity = getVelocity();

private float steering = 0;
Expand Down Expand Up @@ -471,22 +469,14 @@ public boolean hasSpaceForPassengers() {
}

public void setSpeed(float horizontal, float vertical) {
if (this.isLogicalSideForUpdatingMovement()) {
this.hSpeed = horizontal;
this.addedVSpeed = vertical;
} else if (this.getPrimaryPassenger() instanceof ServerPlayerEntity player) {
PayloadPackets.sendAutomobileSpeedSetPacket(this, horizontal, vertical, player);
}
this.hSpeed = horizontal;
this.vSpeed = vertical;
}

@Override
public void tick() {
boolean first = this.firstUpdate;

if (world.isClient()) {
clientTime++;
}

if (!this.hasPassengers() || !this.getFrontAttachment().canDrive(this.getFirstPassenger())) {
accelerating = false;
braking = false;
Expand All @@ -495,6 +485,10 @@ public void tick() {
holdingDrift = false;
}

if (this.jumpCooldown > 0) {
this.jumpCooldown--;
}

super.tick();
if (!this.rearAttachment.type.isEmpty()) this.rearAttachment.tick();
if (!this.frontAttachment.type.isEmpty()) this.frontAttachment.tick();
Expand Down Expand Up @@ -527,7 +521,7 @@ public void tick() {
var touchingEntities = this.world.getOtherEntities(this, this.getBoundingBox().expand(0.2, 0, 0.2), EntityPredicates.canBePushedBy(this));
for (Entity entity : touchingEntities) {
if (!entity.hasPassenger(this)) {
if (!entity.hasVehicle() && entity.getWidth() < this.getWidth() && entity instanceof MobEntity && !(entity instanceof WaterCreatureEntity)) {
if (!entity.hasVehicle() && entity.getWidth() <= this.getWidth() && entity instanceof MobEntity && !(entity instanceof WaterCreatureEntity)) {
entity.startRiding(this);
}
}
Expand All @@ -546,9 +540,16 @@ public void tick() {
this.destroyAutomobile(false, RemovalReason.DISCARDED);
}
}
} else {
clientTime++;

lastSusBounceTimer = suspensionBounceTimer;
if (suspensionBounceTimer > 0) {
suspensionBounceTimer--;
}
}

displacementTick(first || this.getPos().subtract(prevPos).length() > 0);
displacementTick(first || this.getPos().subtract(prevPos).length() > 0.01);
}

public void positionTrackingTick() {
Expand Down Expand Up @@ -666,15 +667,6 @@ public void provideMobDriverInputs(MobEntity driver) {

// witness me fighting against minecraft's collision/physics
public void movementTick() {
// Handle the small suspension bounce effect
if (lastSusBounceTimer != suspensionBounceTimer) markDirty();
lastSusBounceTimer = suspensionBounceTimer;
if (suspensionBounceTimer > 0) suspensionBounceTimer--;
if (!wasOnGround && automobileOnGround) {
suspensionBounceTimer = 3;
markDirty();
}

// Handles boosting
lastBoostSpeed = boostSpeed;
if (boostTimer > 0) {
Expand All @@ -692,6 +684,13 @@ public void movementTick() {
var blockBelow = new BlockPos(getX(), getY() - 0.05, getZ());
float grip = 1 - ((MathHelper.clamp((world.getBlockState(blockBelow).getBlock().getSlipperiness() - 0.6f) / 0.4f, 0, 1) * (1 - stats.getGrip() * 0.8f)));

// Bounce on gel
if (this.automobileOnGround && this.jumpCooldown <= 0 && world.getBlockState(this.getBlockPos()).getBlock() instanceof LaunchGelBlock) {
this.setSpeed(Math.max(this.getHSpeed(), 0.1f), Math.max(this.getVSpeed(), 0.9f));
this.jumpCooldown = 5;
this.automobileOnGround = false;
}

// Track the last position of the automobile
this.lastPosForDisplacement = getPos();

Expand Down Expand Up @@ -786,14 +785,21 @@ public void movementTick() {
lastVelocity = cumulative;

// Damage and launch entities that are hit by a moving automobile
if (hSpeed > 0.2) {
var frontBox = getBoundingBox().offset(cumulative.multiply(0.5));
var velAdd = cumulative.add(0, 0.1, 0).multiply(3);
for (var entity : world.getEntitiesByType(TypeFilter.instanceOf(Entity.class), frontBox, entity -> entity != this && entity != getFirstPassenger())) {
if (Math.abs(hSpeed) > 0.2) {
runOverEntities(cumulative);
}
}

public void runOverEntities(Vec3d velocity) {
var frontBox = getBoundingBox().offset(velocity.multiply(0.5));
var velAdd = velocity.add(0, 0.1, 0).multiply(3);
for (var entity : world.getEntitiesByType(TypeFilter.instanceOf(Entity.class), frontBox, entity -> entity != this && entity != getFirstPassenger())) {
if (!entity.isInvulnerable()) {
if (entity instanceof LivingEntity living && entity.getVehicle() != this) {
living.damage(AutomobilityEntities.AUTOMOBILE_DAMAGE_SOURCE, hSpeed * 10);

entity.addVelocity(velAdd.x, velAdd.y, velAdd.z);
}
entity.addVelocity(velAdd.x, velAdd.y, velAdd.z);
}
}
}
Expand Down Expand Up @@ -832,8 +838,7 @@ public void postMovementTick() {
}

// Handles gravity
vSpeed = Math.max(vSpeed - 0.08f, !automobileOnGround ? TERMINAL_VELOCITY : -0.01f) + addedVSpeed;
addedVSpeed = 0;
vSpeed = Math.max(vSpeed - 0.08f, !automobileOnGround ? TERMINAL_VELOCITY : -0.01f);

// Store previous y displacement to use when launching off slopes
prevYDisplacements.push(yDisp);
Expand Down Expand Up @@ -903,7 +908,7 @@ public void displacementTick(boolean tick) {
}

if (world.getBlockState(this.getBlockPos()).getBlock() instanceof AutomobileAssemblerBlock) {
this.displacement.verticalTarget = (-this.wheels.model().radius() / 16);
this.displacement.lastVertical = this.displacement.verticalTarget = (-this.wheels.model().radius() / 16);
}
}
}
Expand Down Expand Up @@ -1230,7 +1235,7 @@ public ActionResult interact(PlayerEntity player, Hand hand) {

@Override
public double getMountedHeightOffset() {
return ((wheels.model().radius() + frame.model().seatHeight() - 4) / 16) - (suspensionBounceTimer * 0.048f);
return ((wheels.model().radius() + frame.model().seatHeight() - 4) / 16);
}

@Override
Expand Down Expand Up @@ -1322,10 +1327,15 @@ public float getTrackedFrontAttachmentAnimation() {
return this.dataTracker.get(FRONT_ATTACHMENT_ANIMATION);
}

public void bounce() {
suspensionBounceTimer = 3;
}

public static final class Displacement {
private static final int SCAN_STEPS_PER_BLOCK = 20;
private static final double INV_SCAN_STEPS = 1d / SCAN_STEPS_PER_BLOCK;

private boolean wereAllOnGround = true;
private float lastVertical = 0;
private float lastAngularX = 0;
private float lastAngularZ = 0;
Expand All @@ -1350,8 +1360,9 @@ public void tick(World world, AutomobileEntity entity, Vec3d centerPos, double y
Vec3d lowestDisplacementPos = null;
Vec3d highestDisplacementPos = null;
var scannedPoints = new ArrayList<Vec3d>();
var collBoxes = new HashSet<VoxelShape>();
var anyOnGround = new AtomicBoolean(false);
var collBoxes = new HashSet<Box>();
boolean anyOnGround = false;
boolean allOnGround = true;
for (var scanPoint : scanPoints) {
scanPoint = scanPoint
.rotateY((float) Math.toRadians(yaw));
Expand All @@ -1369,38 +1380,50 @@ public void tick(World world, AutomobileEntity entity, Vec3d centerPos, double y
(int) Math.floor(centerPos.y) + heightOffset,
(int) Math.max(Math.floor(centerPos.z), Math.floor(pointPos.z))
);

var mpos = new BlockPos.Mutable();
while (iter.step()) {
mpos.set(iter.getX(), iter.getY(), iter.getZ());
var shape = world.getBlockState(mpos).getCollisionShape(world, mpos);
if (!shape.isEmpty()) {
collBoxes.add(shape.offset(mpos.getX(), mpos.getY(), mpos.getZ()));
if (shape == VoxelShapes.fullCube()) {
collBoxes.add(new Box(mpos.getX(), mpos.getY(), mpos.getZ(), mpos.getX() + 1, mpos.getY() + 1, mpos.getZ() + 1));
} else {
shape.offset(mpos.getX(), mpos.getY(), mpos.getZ()).forEachBox(((minX, minY, minZ, maxX, maxY, maxZ) ->
collBoxes.add(new Box(minX, minY, minZ, maxX, maxY, maxZ))));
}
}
}

var pointDir = new Vec3d(scanPoint.x, 0, scanPoint.z).normalize().multiply(INV_SCAN_STEPS);

AtomicDouble pointY = new AtomicDouble(centerPos.y);
double pointY = centerPos.y;
for (int i = 0; i < Math.ceil(scanDist * SCAN_STEPS_PER_BLOCK); i++) {
double pointX = centerPos.x + (i * pointDir.x);
double pointZ = centerPos.z + (i * pointDir.z);
pointY.set(pointY.get() - (INV_SCAN_STEPS * 1.5));
pointY -= INV_SCAN_STEPS * 1.5;

collBoxes.forEach(shape -> shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> {
if (pointX > minX && pointX < maxX &&
pointZ > minZ && pointZ < maxZ &&
pointY.get() >= (minY - (INV_SCAN_STEPS * 2)) && pointY.get() <= maxY
boolean ground = false;
for (var box : collBoxes) {
if (pointX > box.minX && pointX < box.maxX &&
pointZ > box.minZ && pointZ < box.maxZ &&
pointY >= (box.minY - (INV_SCAN_STEPS * 2)) && pointY <= box.maxY
) {
double diff = maxY - pointY.get();
if (diff < (entity.stepHeight + (INV_SCAN_STEPS * 1.5))) {
pointY.set(maxY);
anyOnGround.set(true);
double diff = box.maxY - pointY;
if (diff < (stepHeight + (INV_SCAN_STEPS * 1.5))) {
pointY = box.maxY;
ground = true;
}
}
}));
}
if (ground) {
anyOnGround = true;
} else {
allOnGround = false;
}
}

pointPos = new Vec3d(pointPos.x, pointY.get(), pointPos.z);
pointPos = new Vec3d(pointPos.x, pointY, pointPos.z);

if (lowestDisplacementPos == null || pointPos.y < lowestDisplacementPos.y) {
lowestDisplacementPos = pointPos;
Expand All @@ -1412,7 +1435,14 @@ public void tick(World world, AutomobileEntity entity, Vec3d centerPos, double y
scannedPoints.add(pointPos);
}

if (!anyOnGround.get()) return;
if (allOnGround && !wereAllOnGround) {
entity.bounce();
}
wereAllOnGround = allOnGround;

if (!anyOnGround) {
return;
}

angularXTarget = 0;
angularZTarget = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,6 @@ public static void sendSyncAutomobileAttachmentsPacket(AutomobileEntity entity,
ServerPlayNetworking.send(player, Automobility.id("sync_automobile_attachments"), buf);
}

public static void sendAutomobileSpeedSetPacket(AutomobileEntity entity, float hSpeed, float vSpeed, ServerPlayerEntity player) {
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
buf.writeInt(entity.getId());
buf.writeFloat(hSpeed);
buf.writeFloat(vSpeed);
ServerPlayNetworking.send(player, Automobility.id("send_automobile_speed"), buf);
}

public static void init() {
ServerPlayNetworking.registerGlobalReceiver(Automobility.id("sync_automobile_inputs"), (server, player, handler, buf, responseSender) -> {
boolean fwd = buf.readBoolean();
Expand Down Expand Up @@ -128,15 +120,5 @@ public static void initClient() {
}
});
});
ClientPlayNetworking.registerGlobalReceiver(Automobility.id("send_automobile_speed"), (client, handler, buf, responseSender) -> {
int entityId = buf.readInt();
float h = buf.readFloat();
float v = buf.readFloat();
client.execute(() -> {
if (client.player.world.getEntityById(entityId) instanceof AutomobileEntity automobile) {
automobile.setSpeed(h, v);
}
});
});
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 908dd39

Please sign in to comment.