Skip to content

Commit 1ce6971

Browse files
committed
Merge branch 'master' into feature/taskflow
2 parents 070c2b7 + 4de3b9b commit 1ce6971

File tree

7 files changed

+161
-51
lines changed

7 files changed

+161
-51
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.lambda.mixin.world;
2+
3+
import com.lambda.event.EventFlow;
4+
import com.lambda.event.events.WorldEvent;
5+
import net.minecraft.client.world.ClientChunkManager;
6+
import net.minecraft.client.world.ClientWorld;
7+
import net.minecraft.nbt.NbtCompound;
8+
import net.minecraft.network.PacketByteBuf;
9+
import net.minecraft.network.packet.s2c.play.ChunkData;
10+
import net.minecraft.util.math.ChunkPos;
11+
import net.minecraft.world.chunk.WorldChunk;
12+
import org.spongepowered.asm.mixin.Final;
13+
import org.spongepowered.asm.mixin.Mixin;
14+
import org.spongepowered.asm.mixin.Shadow;
15+
import org.spongepowered.asm.mixin.injection.At;
16+
import org.spongepowered.asm.mixin.injection.Inject;
17+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
18+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
19+
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
20+
21+
import java.util.function.Consumer;
22+
23+
@Mixin(ClientChunkManager.class)
24+
public class ClientChunkManagerMixin {
25+
@Final
26+
@Shadow
27+
ClientWorld world;
28+
29+
@Inject(method = "loadChunkFromPacket", at = @At("TAIL"))
30+
private void onChunkLoad(
31+
int x,
32+
int z,
33+
PacketByteBuf packetByteBuf,
34+
NbtCompound nbtCompound,
35+
Consumer<ChunkData.BlockEntityVisitor> consumer,
36+
CallbackInfoReturnable<WorldChunk> info
37+
) {
38+
EventFlow.post(new WorldEvent.ChunkEvent.Load(this.world, info.getReturnValue()));
39+
}
40+
41+
@Inject(method = "loadChunkFromPacket", at = @At(value = "NEW", target = "net/minecraft/world/chunk/WorldChunk", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD)
42+
private void onChunkUnload(
43+
int x,
44+
int z,
45+
PacketByteBuf buf,
46+
NbtCompound tag,
47+
Consumer<ChunkData.BlockEntityVisitor> consumer,
48+
CallbackInfoReturnable<WorldChunk> info,
49+
int index,
50+
WorldChunk chunk,
51+
ChunkPos chunkPos
52+
) {
53+
if (chunk != null) {
54+
EventFlow.post(new WorldEvent.ChunkEvent.Unload(this.world, chunk));
55+
}
56+
}
57+
58+
@Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;compareAndSet(ILnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/WorldChunk;)Lnet/minecraft/world/chunk/WorldChunk;"), locals = LocalCapture.CAPTURE_FAILHARD)
59+
private void onChunkUnload(ChunkPos pos, CallbackInfo ci, int i, WorldChunk chunk) {
60+
EventFlow.post(new WorldEvent.ChunkEvent.Unload(this.world, chunk));
61+
}
62+
63+
// @Inject(
64+
// method = "updateLoadDistance",
65+
// at = @At(
66+
// value = "INVOKE",
67+
// target = "net/minecraft/client/world/ClientChunkManager$ClientChunkMap.isInRadius(II)Z"
68+
// ),
69+
// locals = LocalCapture.CAPTURE_FAILHARD
70+
// )
71+
// private void onUpdateLoadDistance(
72+
// int loadDistance,
73+
// CallbackInfo ci,
74+
// int oldRadius,
75+
// int newRadius,
76+
// ClientChunkManager.ClientChunkMap clientChunkMap,
77+
// int k,
78+
// WorldChunk oldChunk,
79+
// ChunkPos chunkPos
80+
// ) {
81+
// if (!clientChunkMap.isInRadius(chunkPos.x, chunkPos.z)) {
82+
// EventFlow.post(new WorldEvent.ChunkEvent.Unload(this.world, oldChunk));
83+
// }
84+
// }
85+
}

common/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,26 @@
22

33
import com.lambda.event.EventFlow;
44
import com.lambda.event.events.WorldEvent;
5+
import net.minecraft.block.BlockState;
56
import net.minecraft.client.world.ClientWorld;
67
import net.minecraft.entity.Entity;
8+
import net.minecraft.util.math.BlockPos;
79
import org.spongepowered.asm.mixin.Mixin;
810
import org.spongepowered.asm.mixin.injection.At;
911
import org.spongepowered.asm.mixin.injection.Inject;
1012
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1113

1214
@Mixin(ClientWorld.class)
1315
public class ClientWorldMixin {
16+
@Inject(method = "handleBlockUpdate", at = @At("HEAD"), cancellable = true)
17+
private void handleBlockUpdateInject(BlockPos pos, BlockState state, int flags, CallbackInfo ci) {
18+
if (EventFlow.post(new WorldEvent.BlockUpdate(pos, state, flags)).isCanceled()) {
19+
ci.cancel();
20+
}
21+
}
22+
1423
@Inject(method = "addEntity", at = @At("HEAD"), cancellable = true)
1524
private void addEntity(Entity entity, CallbackInfo ci) {
1625
if (EventFlow.post(new WorldEvent.EntitySpawn(entity)).isCanceled()) ci.cancel();
1726
}
18-
}
27+
}

common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,34 @@ package com.lambda.event.events
33
import com.lambda.event.Event
44
import com.lambda.event.callback.Cancellable
55
import com.lambda.event.callback.ICancellable
6+
import net.minecraft.block.BlockState
7+
import net.minecraft.client.world.ClientWorld
68
import net.minecraft.entity.Entity
9+
import net.minecraft.util.math.BlockPos
10+
import net.minecraft.world.chunk.WorldChunk
711

812
abstract class WorldEvent : Event {
13+
abstract class ChunkEvent : WorldEvent() {
14+
abstract val world: ClientWorld
15+
abstract val chunk: WorldChunk
16+
17+
class Load(
18+
override val world: ClientWorld,
19+
override val chunk: WorldChunk
20+
) : ChunkEvent()
21+
22+
class Unload(
23+
override val world: ClientWorld,
24+
override val chunk: WorldChunk
25+
) : ChunkEvent()
26+
}
27+
28+
class BlockUpdate(
29+
val pos: BlockPos,
30+
val state: BlockState,
31+
val flags: Int
32+
) : WorldEvent(), ICancellable by Cancellable()
33+
934
class EntitySpawn(
1035
val entity: Entity
1136
) : WorldEvent(), ICancellable by Cancellable()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.lambda.module.modules.debug
2+
3+
import com.lambda.event.events.WorldEvent
4+
import com.lambda.event.listener.SafeListener.Companion.listener
5+
import com.lambda.module.Module
6+
import com.lambda.module.tag.ModuleTag
7+
import com.lambda.util.Communication.info
8+
9+
object UpdateTest : Module(
10+
name = "UpdateTest",
11+
description = "A module for testing updates",
12+
defaultTags = setOf(ModuleTag.DEBUG)
13+
) {
14+
init {
15+
listener<WorldEvent.BlockUpdate> {
16+
info("Block update at ${it.pos} with state ${it.state} and flags ${it.flags}")
17+
}
18+
19+
listener<WorldEvent.ChunkEvent.Load> {
20+
info("Chunk load at ${it.chunk.pos}")
21+
}
22+
23+
listener<WorldEvent.ChunkEvent.Unload> {
24+
info("Chunk unload at ${it.chunk.pos}")
25+
}
26+
}
27+
}

common/src/main/kotlin/com/lambda/util/combat/Explosion.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ object Explosion {
2020
* @param entity The entity to calculate the damage for.
2121
* @return The damage dealt by the explosion.
2222
*/
23-
fun SafeContext.damage(source: Explosion, entity: LivingEntity) =
24-
damage(source.position, entity, source.power.toDouble())
23+
fun SafeContext.explosionDamage(source: Explosion, entity: LivingEntity) =
24+
explosionDamage(source.position, entity, source.power.toDouble())
2525

2626
/**
2727
* Calculates the damage dealt by an explosion to a living entity.
@@ -30,7 +30,7 @@ object Explosion {
3030
* @param power The strength of the explosion above 0.
3131
* @return The damage dealt by the explosion.
3232
*/
33-
fun SafeContext.damage(position: Vec3d, entity: LivingEntity, power: Double): Double {
33+
fun SafeContext.explosionDamage(position: Vec3d, entity: LivingEntity, power: Double): Double {
3434
val distance = entity.pos.distanceTo(position)
3535

3636
val impact = (1.0 - distance / (power * 2.0)) *
@@ -49,10 +49,10 @@ object Explosion {
4949
* @param explosion The explosion to calculate the velocity for.
5050
* @return The velocity of the entities.
5151
*/
52-
fun SafeContext.velocity(explosion: Explosion): Map<LivingEntity, Vec3d> {
52+
fun SafeContext.explosionVelocity(explosion: Explosion): Map<LivingEntity, Vec3d> {
5353
val ref = ArrayList<LivingEntity>()
54-
getFastEntities<LivingEntity>(explosion.position, explosion.power * 2.0, ref)
55-
return ref.associateWith { entity -> velocity(entity, explosion) }
54+
getFastEntities(explosion.position, explosion.power * 2.0, ref)
55+
return ref.associateWith { entity -> explosionVelocity(entity, explosion) }
5656
}
5757

5858
/**
@@ -61,8 +61,8 @@ object Explosion {
6161
* @param explosion The explosion to calculate the velocity for.
6262
* @return The velocity of the entity.
6363
*/
64-
fun SafeContext.velocity(entity: LivingEntity, explosion: Explosion) =
65-
velocity(entity, explosion.position, explosion.power.toDouble())
64+
fun SafeContext.explosionVelocity(entity: LivingEntity, explosion: Explosion) =
65+
explosionVelocity(entity, explosion.position, explosion.power.toDouble())
6666

6767
/**
6868
* Calculates the velocity of a living entity affected by an explosion.
@@ -71,7 +71,7 @@ object Explosion {
7171
* @param power The strength of the explosion.
7272
* @return The velocity of the entity.
7373
*/
74-
fun SafeContext.velocity(entity: LivingEntity, position: Vec3d, power: Double): Vec3d {
74+
fun SafeContext.explosionVelocity(entity: LivingEntity, position: Vec3d, power: Double): Vec3d {
7575
val distance = entity.pos.distanceTo(position)
7676

7777
val size = power * 2.0
@@ -84,7 +84,7 @@ object Explosion {
8484
return diff.normalize() * vel
8585
}
8686

87-
fun SafeContext.destruction(source: Explosion): List<Vec3d> {
87+
fun SafeContext.explosionDestruction(source: Explosion): List<Vec3d> {
8888
val affected = mutableListOf<Vec3d>()
8989

9090
repeat(16) { x ->

common/src/main/kotlin/com/lambda/util/world/WorldUtils.kt

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,6 @@ import kotlin.math.ceil
4242
*
4343
*/
4444
object WorldUtils {
45-
/**
46-
* Gets the closest entity of type [T] within a specified range.
47-
*/
48-
inline fun <reified T : Entity> SafeContext.getClosestEntity(
49-
type: Class<out T>, // This is a class reference, not an instance of the class.
50-
pos: Vec3d,
51-
range: Double,
52-
predicate: (T) -> Boolean = { true },
53-
): T? {
54-
return getClosestEntity(pos, range, predicate)
55-
}
56-
5745
/**
5846
* Gets the closest entity of type [T] within a specified range.
5947
*
@@ -69,6 +57,7 @@ object WorldUtils {
6957
pos: Vec3d,
7058
range: Double,
7159
predicate: (T) -> Boolean = { true },
60+
type: Class<out T> = T::class.java,
7261
): T? {
7362
var closest: T? = null
7463
var closestDistance = Double.MAX_VALUE
@@ -86,20 +75,6 @@ object WorldUtils {
8675
return closest
8776
}
8877

89-
/**
90-
* Gets all entities of type [T] within a specified distance from a position.
91-
*/
92-
inline fun <T : Entity> SafeContext.getFastEntities(
93-
type: Class<out T>, // This is a class reference, not an instance of the class.
94-
pos: Vec3d,
95-
distance: Double,
96-
collector: MutableList<Entity>? = null,
97-
iterator: (Entity, Int) -> Unit = { _, _ -> },
98-
predicate: (Entity) -> Boolean = { true },
99-
) {
100-
return getFastEntities(pos, distance, collector, iterator, predicate)
101-
}
102-
10378
/**
10479
* Gets all entities of type [T] within a specified distance from a position.
10580
*
@@ -134,6 +109,7 @@ object WorldUtils {
134109
pointer: MutableList<T>? = null,
135110
iterator: (T, Int) -> Unit = { _, _ -> },
136111
predicate: (T) -> Boolean = { true },
112+
type: Class<out T> = T::class.java,
137113
) {
138114
val chunks = ceil(distance / 16).toInt()
139115
val sectionX = pos.x.toInt() shr 4
@@ -161,20 +137,6 @@ object WorldUtils {
161137
}
162138
}
163139

164-
/**
165-
* Gets all entities of type [T] within a specified distance from a position.
166-
*/
167-
inline fun <reified T : Entity> SafeContext.getEntities(
168-
type: Class<out T>, // This is a class reference, not an instance of the class.
169-
pos: Vec3d,
170-
distance: Double,
171-
pointer: MutableList<Entity>? = null,
172-
iterator: (Entity, Int) -> Unit = { _, _ -> },
173-
predicate: (Entity) -> Boolean = { true },
174-
) {
175-
return getEntities(pos, distance, pointer, iterator, predicate)
176-
}
177-
178140
/**
179141
* Gets all entities of type [T] within a specified distance from a position.
180142
*
@@ -191,6 +153,7 @@ object WorldUtils {
191153
pointer: MutableList<T>? = null,
192154
iterator: (T, Int) -> Unit = { _, _ -> },
193155
predicate: (T) -> Boolean = { true },
156+
type: Class<out T> = T::class.java,
194157
) {
195158
world.entities.filterPointer(pointer, iterator) { entity ->
196159
entity != player &&

common/src/main/resources/lambda.mixins.common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"render.ScreenHandlerMixin",
3535
"render.VertexBufferMixin",
3636
"render.WorldRendererMixin",
37+
"world.ClientChunkManagerMixin",
3738
"world.ClientWorldMixin"
3839
],
3940
"injectors": {

0 commit comments

Comments
 (0)