Skip to content

Commit 3dc9e8c

Browse files
Add traffic flow and a bunch of small random tweaks
- Autopilot vehicles will stop behind other vehicles - Auto mechanic table UI now shows tooltips for missing items in a recipe - You can extract items out of vehicles with hoppers - Invulnerable mobs will stay in the driver seat of a car even if another player gets on - More appropriate automobile frustum culling
1 parent f29b560 commit 3dc9e8c

17 files changed

Lines changed: 318 additions & 114 deletions

File tree

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
**Automobility is currently in BETA!** <br/>
55
The mod isn't feature-complete, and any feature requests would be greatly appreciated. Discuss features on the mod's GitHub Discussions page, or in the [Discord](https://discord.gg/7Aw3y4RtY9).
66

7-
## Available for Fabric/Quilt and Forge
8-
- Requires **[Fabric API](https://modrinth.com/mod/fabric-api)** (Fabric) or **[QSL](https://modrinth.com/mod/qsl)** (Quilt)
9-
- No additional mods required for Forge
7+
## Available for Fabric and NeoForge
8+
- Requires **[Fabric API](https://modrinth.com/mod/fabric-api)** (Fabric)
9+
- No additional mods required for NeoForge
1010

11-
**Currently maintained for version 1.19.2, older versions are retired.**
11+
**Currently maintained for version 1.21.1, older versions are retired.**
12+
13+
### Supports Data Packs and Resource Packs
14+
- Add your own custom vehicle types with data packs and resource packs!
15+
- Here is an [example](https://github.com/FoundationGames/City-Vehicles-Example-Addon) that you can use as a template.
1216

1317
## Getting Started
14-
- **Recipes:** Crafting recipes can be viewed using [**EMI**](https://www.curseforge.com/minecraft/mc-mods/emi) (Fabric/Quilt) or [**JEI**](https://www.curseforge.com/minecraft/mc-mods/jei) (Forge).
18+
- **Recipes:** Crafting table recipes can be viewed using [**EMI**](https://www.curseforge.com/minecraft/mc-mods/emi) or [**JEI**](https://www.curseforge.com/minecraft/mc-mods/jei). Automobile part recipes are viewed in the Auto Mechanic Table's GUI.
1519
- **Automobile Parts:** Craft an Auto Mechanic Table. Use the GUI to craft the frame, engine, and wheels for your automobile. You can optionally craft an attachment.
1620
- **Building your Automobile:** Craft an Automobile Assembler, as well as a Crowbar. Place parts on the assembler until the vehicle is complete. Use a crowbar to destroy the vehicle.
1721
- **Enhancing your Automobile:** Use your Auto Mechanic Table to craft attachments, which can be placed on your Automobile to add exciting functionality or utility.
@@ -26,7 +30,7 @@ The mod isn't feature-complete, and any feature requests would be greatly apprec
2630
- A/D - Steer left/right
2731
- Space - Drift/Deploy
2832

29-
**Controller Support (*Fabric and Quilt Exclusive*):** when using [MidnightControls](https://www.curseforge.com/minecraft/mc-mods/midnightcontrols), you will be able to control automobiles with the following default controls:
33+
**Controller Support (*Fabric Exclusive*):** when using [Controlify](https://modrinth.com/mod/controlify), you will be able to control automobiles with the following default controls:
3034
- A - Accelerate
3135
- B - Brake/Reverse
3236
- LStick - Steer left/right

common/src/main/java/io/github/foundationgames/automobility/automobile/attachment/front/AutopilotFrontAttachment.java

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
import io.github.foundationgames.automobility.automobile.attachment.FrontAttachmentType;
44
import io.github.foundationgames.automobility.block.AutopilotSignBlock;
55
import io.github.foundationgames.automobility.entity.AutomobileEntity;
6+
import io.github.foundationgames.automobility.entity.HitboxEntity;
7+
import io.github.foundationgames.automobility.item.AutopilotSignBlockItem;
68
import net.minecraft.core.HolderLookup;
79
import net.minecraft.nbt.CompoundTag;
810
import net.minecraft.util.Mth;
911
import net.minecraft.world.entity.Entity;
12+
import net.minecraft.world.entity.LivingEntity;
13+
import net.minecraft.world.phys.AABB;
1014
import net.minecraft.world.phys.Vec3;
1115
import org.jetbrains.annotations.Nullable;
1216
import org.joml.Vector3f;
@@ -15,7 +19,6 @@ public class AutopilotFrontAttachment extends FrontAttachment {
1519
public static final int MAX_HEADING_COMMAND_TIME = 6000;
1620

1721
private @Nullable AutopilotSignBlock.Heading currentHeading = null;
18-
private int playerStopTimer = 0;
1922
private int headingTimeLimit = 0;
2023
private int animationTimer = 0;
2124

@@ -38,28 +41,57 @@ public void provideAlternativeInputs(AutomobileEntity automobile, AutomobileEnti
3841
if (currentHeading == null) {
3942
input.clearInputs();
4043
} else {
44+
var dirHeading = automobile.getLookAngle();
45+
boolean somethingInTheWay = false;
46+
47+
double width = 0.8 * automobile.getBbWidth();
48+
var box = new AABB(-width, -2, -width, width, 4, width);
49+
box = box.move(pos().add(dirHeading.scale(1 + 1.75 * width)));
50+
51+
for (var e : world().getEntitiesOfClass(HitboxEntity.class, box)) {
52+
if (!automobile.isOneOfMyHitboxes(e) && (!automobile.isInvulnerable() || e.automobile().isInvulnerable())) {
53+
somethingInTheWay = true;
54+
break;
55+
}
56+
}
57+
58+
if (!somethingInTheWay) for (var e : world().getEntitiesOfClass(LivingEntity.class, box.inflate(1.25))) {
59+
if (e.isUsingItem() && e.getItemInHand(e.getUsedItemHand()).getItem() instanceof AutopilotSignBlockItem) {
60+
var eLooking = e.getLookAngle();
61+
var meToE = e.position().subtract(pos()).normalize();
62+
63+
if (eLooking.dot(meToE) < 0) {
64+
somethingInTheWay = true;
65+
break;
66+
}
67+
}
68+
}
69+
4170
var autoPos = autoPos();
4271
var autoMovement = automobile.getMeasuredMovement();
4372

4473
var dirAlongPath = currentHeading.dir();
45-
var dirHeading = automobile.getLookAngle();
74+
double offCosine = dirHeading.dot(dirAlongPath);
4675

4776
var pathToPath = currentHeading.pathToPath(autoPos);
4877
double distToPath = pathToPath.length();
4978

5079
var dirToPath = pathToPath.normalize();
51-
double autoSpeedIntoPath = currentHeading.stop() ? autoMovement.length() : Math.max(0, -autoMovement.dot(dirToPath));
80+
double autoSpeedIntoPath = currentHeading.stop() || somethingInTheWay ? autoMovement.length() : Math.max(0, -autoMovement.dot(dirToPath));
5281

5382
double favorDirToPath = Math.clamp(distToPath * 0.1, 0, 1);
5483

55-
if (this.playerStopTimer > 0 || (
56-
currentHeading.stop() && currentHeading.origin().distanceToSqr(autoPos) < 25 + 100 * autoMovement.lengthSqr())) {
57-
input.accelerating = false;
58-
input.braking = autoSpeedIntoPath > distToPath * 0.2;
84+
boolean burnout;
85+
if (somethingInTheWay || (
86+
currentHeading.stop() && currentHeading.origin().distanceToSqr(autoPos) < 25 + 49 * autoMovement.lengthSqr())) {
87+
burnout = offCosine > 0 && automobile.getTurboCharge() < AutomobileEntity.SMALL_TURBO_TIME - 5;
88+
input.accelerating = burnout;
89+
input.braking = burnout || autoSpeedIntoPath > 0.2;
5990
favorDirToPath = Math.sqrt(favorDirToPath);
6091
} else {
61-
input.accelerating = autoSpeedIntoPath * autoSpeedIntoPath * distToPath * distToPath < 6;
62-
input.braking = false;
92+
burnout = automobile.burningOut() ? offCosine > -0.8 : offCosine > 0.2;
93+
input.accelerating = burnout || autoSpeedIntoPath * autoSpeedIntoPath * distToPath * distToPath < 5 + (2 / automobile.getHandling());
94+
input.braking = burnout;
6395
}
6496

6597
var dirHeadingF = dirHeading.toVector3f().mul(1, 0, 1);
@@ -68,9 +100,11 @@ public void provideAlternativeInputs(AutomobileEntity automobile, AutomobileEnti
68100
double headingToPathDir = dirHeadingF.angleSigned(dirDesiredHeadingF, new Vector3f(0, 1, 0)) / Mth.HALF_PI;
69101
input.steering = (float) Math.clamp(headingToPathDir, -1, 1);
70102

71-
float offset = (float) dirAlongPath.cross(dirHeading).length();
72-
float damp = (float) Mth.clamp(Math.abs(distToPath * 0.2) + Math.sqrt(offset), 0, 1);
73-
input.steering *= damp * damp;
103+
if (!burnout) {
104+
float offset = (float) dirAlongPath.cross(dirHeading).length();
105+
float damp = (float) Mth.clamp(Math.abs(distToPath * 0.2) + Math.sqrt(offset), 0, 1);
106+
input.steering *= damp * damp;
107+
}
74108
}
75109
}
76110

@@ -92,10 +126,6 @@ public void notifyHeadingCommand(AutopilotSignBlock.Heading heading) {
92126
}
93127
}
94128

95-
public void notifyPlayerStop() {
96-
this.playerStopTimer = 8;
97-
}
98-
99129
@Override
100130
public void tick() {
101131
super.tick();
@@ -119,10 +149,6 @@ public void tick() {
119149
this.currentHeading = null;
120150
}
121151
}
122-
123-
if (this.playerStopTimer > 0) {
124-
this.playerStopTimer--;
125-
}
126152
}
127153

128154
this.animationTimer++;
@@ -141,7 +167,6 @@ public void writeNbt(CompoundTag nbt, HolderLookup.Provider registry) {
141167
}
142168

143169
nbt.putInt("timeout", this.headingTimeLimit);
144-
nbt.putInt("player_stop_time", this.playerStopTimer);
145170
}
146171

147172
@Override
@@ -155,7 +180,6 @@ public void readNbt(CompoundTag nbt, HolderLookup.Provider reg) {
155180
}
156181

157182
this.headingTimeLimit = nbt.getInt("timeout");
158-
this.playerStopTimer = nbt.getInt("player_stop_time");
159183
}
160184

161185
public int getAnimationTimer() {

common/src/main/java/io/github/foundationgames/automobility/block/AutomobilePressurePlateBlock.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.mojang.serialization.MapCodec;
44
import io.github.foundationgames.automobility.entity.AutomobileEntity;
5+
import io.github.foundationgames.automobility.entity.HitboxEntity;
56
import net.minecraft.core.BlockPos;
67
import net.minecraft.world.level.Level;
78
import net.minecraft.world.level.block.PressurePlateBlock;
@@ -16,6 +17,9 @@ public AutomobilePressurePlateBlock(Properties properties) {
1617

1718
@Override
1819
protected int getSignalStrength(Level level, BlockPos pos) {
19-
return getEntityCount(level, TOUCH_AABB.move(pos), AutomobileEntity.class) > 0 ? 15 : 0;
20+
var box = TOUCH_AABB.move(pos);
21+
return getEntityCount(level, box, AutomobileEntity.class) +
22+
getEntityCount(level, box, HitboxEntity.class)
23+
> 0 ? 15 : 0;
2024
}
2125
}

common/src/main/java/io/github/foundationgames/automobility/block/AutopilotSignBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public Heading getHeading(BlockState state, BlockPos pos) {
185185
}
186186

187187
public double getDetectBoxOffset(BlockState state) {
188-
return state.getValue(TYPE).standing() ? 6 : 1.5;
188+
return state.getValue(TYPE).standing() ? 7.5 : 2;
189189
}
190190

191191
@Override

common/src/main/java/io/github/foundationgames/automobility/block/entity/AutopilotSignBlockEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static void tick(Level level, BlockPos pos, BlockState state, AutopilotSi
2525
sign.broadcastDelay = BROADCAST_INTERVAL;
2626

2727
if (state.getBlock() instanceof AutopilotSignBlock block) {
28-
var box = new AABB(-16, -1.5, -16, 16, 1.5, 16);
28+
var box = new AABB(-16, -2, -16, 16, 2, 16);
2929
var heading = block.getHeading(state, pos);
3030

3131
var boxOrigin = heading.planeOrigin().add(heading.limitPlane().scale(block.getDetectBoxOffset(state)));

0 commit comments

Comments
 (0)