Skip to content

Commit fb21f6b

Browse files
committed
Added death causes.
1 parent 9736380 commit fb21f6b

7 files changed

Lines changed: 182 additions & 0 deletions

File tree

src/main/java/turniplabs/halplibe/HalpLibe.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import org.jspecify.annotations.NonNull;
1010
import org.slf4j.Logger;
1111
import org.slf4j.LoggerFactory;
12+
import turniplabs.halplibe.helper.network.NetworkHandler;
1213
import turniplabs.halplibe.util.TomlConfigHandler;
14+
import turniplabs.halplibe.util.deathcause.DeathCauseNetworkMessage;
1315
import turniplabs.halplibe.util.toml.Toml;
1416

1517
import java.io.File;
@@ -66,6 +68,8 @@ public static String addModId(String modId, String name) {
6668
@Override
6769
public void onInitialize() {
6870
LOGGER.info("HalpLibe initialized.");
71+
72+
NetworkHandler.registerNetworkMessage(DeathCauseNetworkMessage::new);
6973
}
7074

7175
@Override
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package turniplabs.halplibe.mixin.deathcause;
2+
3+
import com.llamalad7.mixinextras.expression.Definition;
4+
import com.llamalad7.mixinextras.expression.Expression;
5+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
6+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
7+
8+
import net.minecraft.core.Global;
9+
import net.minecraft.core.entity.Mob;
10+
import net.minecraft.core.net.command.TextFormatting;
11+
import net.minecraft.core.world.World;
12+
import org.jetbrains.annotations.Nullable;
13+
import org.spongepowered.asm.mixin.Mixin;
14+
import org.spongepowered.asm.mixin.Unique;
15+
import org.spongepowered.asm.mixin.injection.At;
16+
import turniplabs.halplibe.helper.EnvironmentHelper;
17+
import turniplabs.halplibe.helper.network.NetworkHandler;
18+
import turniplabs.halplibe.util.deathcause.DeathCause;
19+
import turniplabs.halplibe.util.deathcause.DeathCauseMixinInterface;
20+
import turniplabs.halplibe.util.deathcause.DeathCauseNetworkMessage;
21+
22+
@Mixin(Mob.class)
23+
public class MobMixin implements DeathCauseMixinInterface {
24+
25+
@Unique
26+
@Nullable DeathCause deathCause = null;
27+
28+
@Definition(id = "world", field = "Lnet/minecraft/core/entity/Mob;world:Lnet/minecraft/core/world/World;")
29+
@Definition(id = "sendGlobalMessageTranslated", method = "Lnet/minecraft/core/world/World;sendGlobalMessageTranslated(Lnet/minecraft/core/net/command/TextFormatting$Base;Ljava/lang/String;[Ljava/lang/String;)V")
30+
@Expression("this.world.sendGlobalMessageTranslated(?, ?, ?)")
31+
@WrapOperation(method = "onDeath", at = @At("MIXINEXTRAS:EXPRESSION"))
32+
public void hijackDeathMessage(World world, TextFormatting.Base format, String key, String[] args, Operation<Void> original) {
33+
if (this.deathCause == null) {
34+
original.call(world, format, key, args);
35+
return;
36+
}
37+
38+
if (!EnvironmentHelper.isClientWorld()) {
39+
NetworkHandler.sendToAllPlayers(new DeathCauseNetworkMessage(this.deathCause));
40+
}
41+
}
42+
43+
@Override
44+
public void halplibe$setDeathCause(DeathCause deathCause) {
45+
this.deathCause = deathCause;
46+
}
47+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package turniplabs.halplibe.util.deathcause;
2+
3+
import com.mojang.nbt.tags.CompoundTag;
4+
import net.minecraft.core.entity.Mob;
5+
import net.minecraft.core.lang.I18n;
6+
7+
/**
8+
* <p><b>This Object represents a cause of death</b>. It is used to set custom death messages for players and entities.</p>
9+
*
10+
* <h3>The usage is as follows:</h3>
11+
* <ol>
12+
*
13+
* <li>
14+
* You create a custom constructor that acquires all fields from the entity you just attacked.
15+
* It is very important that all fields are serializable as they will be sent via the network by NBT.
16+
* </li>
17+
* <li>Write serialization and deserialization functions for the fields you just defined.</li>
18+
*
19+
* <li>You write a cute little function to output the translated death message using all fields previously acquired.</li>
20+
*
21+
* <li>Don't forget to register it to <code>DeathCauseRegistry</code>!</li>
22+
*
23+
* <li>To display the message: bind it to the victim entity via the <code>DeathCause.bind</code> method. </li>
24+
*
25+
* <li>Profit!</li>
26+
*
27+
* </ul>
28+
*
29+
* <h4>- Kheppo</h4>
30+
*/
31+
public abstract class DeathCause {
32+
public DeathCause() {};
33+
34+
public abstract String format(I18n i18n);
35+
public abstract void serialize(CompoundTag tag);
36+
public abstract void deserialize(CompoundTag tag);
37+
38+
public void bind(Mob victim) {
39+
((DeathCauseMixinInterface) victim).halplibe$setDeathCause(this);
40+
}
41+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package turniplabs.halplibe.util.deathcause;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
5+
@ApiStatus.Internal
6+
public interface DeathCauseMixinInterface {
7+
void halplibe$setDeathCause(DeathCause deathCause);
8+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package turniplabs.halplibe.util.deathcause;
2+
3+
import com.mojang.nbt.tags.CompoundTag;
4+
import net.minecraft.core.lang.I18n;
5+
import org.jspecify.annotations.NonNull;
6+
import turniplabs.halplibe.helper.network.NetworkMessage;
7+
import turniplabs.halplibe.helper.network.UniversalPacket;
8+
9+
import java.lang.reflect.InvocationTargetException;
10+
import java.util.Objects;
11+
12+
public class DeathCauseNetworkMessage implements NetworkMessage {
13+
14+
private CompoundTag deathCauseEncoded;
15+
private String deathCauseId;
16+
17+
public DeathCauseNetworkMessage() {}
18+
19+
public DeathCauseNetworkMessage(DeathCause deathCause) {
20+
this.deathCauseId = DeathCauseRegistry.getInstance().getKey(deathCause.getClass());
21+
this.deathCauseEncoded = new CompoundTag();
22+
deathCause.serialize(this.deathCauseEncoded);
23+
}
24+
25+
@Override
26+
public void encodeToUniversalPacket(@NonNull UniversalPacket packet) {
27+
packet.writeString(this.deathCauseId);
28+
packet.writeCompoundTag(this.deathCauseEncoded);
29+
}
30+
31+
@Override
32+
public void decodeFromUniversalPacket(@NonNull UniversalPacket packet) {
33+
this.deathCauseId = packet.readString();
34+
this.deathCauseEncoded = packet.readCompoundTag();
35+
}
36+
37+
@Override
38+
public void handleClientEnv(NetworkContext context) {
39+
final DeathCause deathCause;
40+
41+
try {
42+
deathCause = Objects.requireNonNull(DeathCauseRegistry.getInstance().getItem(this.deathCauseId)).getDeclaredConstructor().newInstance();
43+
}
44+
45+
catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
46+
throw new RuntimeException(e);
47+
}
48+
49+
deathCause.deserialize(this.deathCauseEncoded);
50+
51+
String deathMessage = deathCause.format(I18n.getInstance());
52+
context.player.world.sendGlobalMessage(deathMessage);
53+
}
54+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package turniplabs.halplibe.util.deathcause;
2+
3+
import net.minecraft.core.data.registry.Registry;
4+
import net.minecraft.core.util.HardIllegalArgumentException;
5+
import net.minecraft.core.util.collection.NamespaceID;
6+
7+
public class DeathCauseRegistry extends Registry<Class<? extends DeathCause>> {
8+
private DeathCauseRegistry(){};
9+
10+
private static final DeathCauseRegistry INSTANCE = new DeathCauseRegistry();
11+
12+
public static DeathCauseRegistry getInstance() {
13+
return INSTANCE;
14+
}
15+
16+
@Override
17+
public void register(String key, Class<? extends DeathCause> item) {
18+
try { NamespaceID.fromPool(key); }
19+
catch (HardIllegalArgumentException e) {
20+
throw new RuntimeException("Attempted to define invalid namespaced id for \"%s\"".formatted(item.getCanonicalName()));
21+
}
22+
super.register(key, item);
23+
}
24+
}

src/main/resources/halplibe.mixins.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"required": true,
3+
"mixinextras": {
4+
"minVersion": "0.5.0"
5+
},
36
"minVersion": "0.8",
47
"package": "turniplabs.halplibe.mixin",
58
"compatibilityLevel": "JAVA_${java}",
@@ -16,6 +19,7 @@
1619
"accessors.LanguageAccessor",
1720
"accessors.WeightedRandomBagAccessor",
1821
"accessors.WeightedRandomBagEntryAccessor",
22+
"deathcause.MobMixin",
1923
"recovery.WorldMixin"
2024
],
2125
"client": [

0 commit comments

Comments
 (0)