mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-12-03 17:37:59 +01:00
Added a gamerule to force players to select a new tribe after death
This commit is contained in:
parent
e052eb534f
commit
2b227eee1a
13 changed files with 91 additions and 49 deletions
10
src/main/java/com/minelittlepony/unicopia/UGameRules.java
Normal file
10
src/main/java/com/minelittlepony/unicopia/UGameRules.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.GameRules.BooleanRule;
|
||||
|
||||
public interface UGameRules {
|
||||
GameRules.Key<BooleanRule> SWAP_TRIBE_ON_DEATH = GameRules.register("swapTribeOnDeath", GameRules.Category.SPAWNING, BooleanRule.create(false));
|
||||
|
||||
static void bootstrap() { }
|
||||
}
|
|
@ -84,6 +84,7 @@ public class Unicopia implements ModInitializer {
|
|||
Abilities.bootstrap();
|
||||
UScreenHandlers.bootstrap();
|
||||
UTreeGen.bootstrap();
|
||||
UGameRules.bootstrap();
|
||||
}
|
||||
|
||||
public interface SidedAccess {
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgMarkTraitRead;
|
||||
import com.minelittlepony.unicopia.network.MsgUnlockTraits;
|
||||
import com.minelittlepony.unicopia.util.Copyable;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
@ -31,7 +32,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class TraitDiscovery implements NbtSerialisable {
|
||||
public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery> {
|
||||
private final Set<Trait> unreadTraits = new HashSet<>();
|
||||
|
||||
private final Set<Trait> traits = new HashSet<>();
|
||||
|
@ -152,7 +153,8 @@ public class TraitDiscovery implements NbtSerialisable {
|
|||
return SpellTraits.fromNbt(nbt);
|
||||
}
|
||||
|
||||
public void copyFrom(TraitDiscovery old) {
|
||||
@Override
|
||||
public void copyFrom(TraitDiscovery old, boolean alive) {
|
||||
clear();
|
||||
unreadTraits.addAll(old.unreadTraits);
|
||||
traits.addAll(old.traits);
|
||||
|
|
|
@ -151,8 +151,10 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
|
|||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(EntityPhysics<T> other) {
|
||||
setBaseGravityModifier(other.getBaseGravityModifier());
|
||||
public void copyFrom(EntityPhysics<T> other, boolean alive) {
|
||||
if (alive) {
|
||||
setBaseGravityModifier(other.getBaseGravityModifier());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -123,9 +123,11 @@ public class ItemTracker implements NbtSerialisable, Copyable<ItemTracker>, Tick
|
|||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(ItemTracker other) {
|
||||
public void copyFrom(ItemTracker other, boolean alive) {
|
||||
items.clear();
|
||||
items.putAll(other.items);
|
||||
if (alive) {
|
||||
items.putAll(other.items);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Trackable extends ItemConvertible {
|
||||
|
|
|
@ -70,6 +70,10 @@ public class RaceChangeStatusEffect extends StatusEffect {
|
|||
return;
|
||||
}
|
||||
|
||||
if (eq instanceof Pony pony) {
|
||||
pony.setRespawnRace(race);
|
||||
}
|
||||
|
||||
int ticks = Math.max(0, MAX_DURATION - state.getDuration());
|
||||
|
||||
Stage stage = Stage.forDuration(ticks / STAGE_DURATION);
|
||||
|
@ -80,23 +84,20 @@ public class RaceChangeStatusEffect extends StatusEffect {
|
|||
|
||||
int progression = ticks % (stage.ordinal() * STAGE_DURATION);
|
||||
|
||||
if ((eq instanceof Pony pony ? pony.getActualSpecies() : eq.getSpecies()) == race || !race.isPermitted(entity instanceof PlayerEntity ? (PlayerEntity)entity : null)) {
|
||||
if (progression == 0 && entity instanceof PlayerEntity && stage == Stage.CRAWLING) {
|
||||
((PlayerEntity)entity).sendMessage(Stage.INITIAL.getMessage(race), true);
|
||||
if ((eq instanceof Pony pony ? pony.getActualSpecies() : eq.getSpecies()) == race || !race.isPermitted(entity instanceof PlayerEntity player ? player : null)) {
|
||||
if (progression == 0 && entity instanceof PlayerEntity player && stage == Stage.CRAWLING) {
|
||||
player.sendMessage(Stage.INITIAL.getMessage(race), true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (progression == 0) {
|
||||
if (stage != Stage.DEATH && entity instanceof PlayerEntity) {
|
||||
((PlayerEntity)entity).sendMessage(stage.getMessage(race), true);
|
||||
}
|
||||
if (progression == 0 && stage != Stage.DEATH && entity instanceof PlayerEntity player) {
|
||||
player.sendMessage(stage.getMessage(race), true);
|
||||
}
|
||||
|
||||
entity.setHealth(1);
|
||||
|
||||
if (entity instanceof PlayerEntity) {
|
||||
Pony pony = (Pony)eq;
|
||||
if (eq instanceof Pony pony) {
|
||||
MagicReserves magic = pony.getMagicalReserves();
|
||||
magic.getExertion().add(50);
|
||||
magic.getEnergy().add(3);
|
||||
|
@ -108,8 +109,6 @@ public class RaceChangeStatusEffect extends StatusEffect {
|
|||
}
|
||||
|
||||
if (stage == Stage.DEATH) {
|
||||
|
||||
eq.setSpecies(race);
|
||||
if (eq instanceof Caster) {
|
||||
((Caster<?>)eq).getSpellSlot().clear();
|
||||
}
|
||||
|
@ -119,11 +118,10 @@ public class RaceChangeStatusEffect extends StatusEffect {
|
|||
magic.getEnergy().set(0.6F);
|
||||
magic.getExhaustion().set(0);
|
||||
magic.getExertion().set(0);
|
||||
pony.setDirty();
|
||||
entity.damage(MagicalDamageSource.TRIBE_SWAP, Float.MAX_VALUE);
|
||||
} else {
|
||||
eq.setSpecies(race);
|
||||
}
|
||||
|
||||
entity.damage(MagicalDamageSource.TRIBE_SWAP, Float.MAX_VALUE);
|
||||
entity.setHealth(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,8 @@ import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect;
|
|||
import com.minelittlepony.unicopia.entity.effect.UEffects;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerAnimationChange;
|
||||
import com.minelittlepony.unicopia.util.*;
|
||||
import com.minelittlepony.unicopia.network.*;
|
||||
import com.minelittlepony.unicopia.network.datasync.EffectSync.UpdateCallback;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
import com.minelittlepony.common.util.animation.LinearInterpolator;
|
||||
|
@ -82,6 +80,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
private final Interpolator interpolator = new LinearInterpolator();
|
||||
|
||||
private Race respawnRace = Race.UNSET;
|
||||
|
||||
private boolean dirty;
|
||||
|
||||
private int ticksHanging;
|
||||
|
@ -151,6 +151,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
return advancementProgress;
|
||||
}
|
||||
|
||||
public void setRespawnRace(Race race) {
|
||||
respawnRace = race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Race getSpecies() {
|
||||
if (AmuletSelectors.ALICORN_AMULET.test(entity)) {
|
||||
|
@ -621,21 +625,41 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(Pony oldPlayer) {
|
||||
if (!oldPlayer.asEntity().isRemoved()) {
|
||||
public void copyFrom(Pony oldPlayer, boolean alive) {
|
||||
|
||||
boolean forcedSwap = !alive
|
||||
&& entity instanceof ServerPlayerEntity
|
||||
&& entity.world.getGameRules().getBoolean(UGameRules.SWAP_TRIBE_ON_DEATH)
|
||||
&& oldPlayer.asEntity().getDamageTracker().getMostRecentDamage().getDamageSource() != MagicalDamageSource.TRIBE_SWAP;
|
||||
|
||||
if (alive) {
|
||||
oldPlayer.getSpellSlot().stream(true).forEach(getSpellSlot()::put);
|
||||
} else {
|
||||
oldPlayer.getSpellSlot().stream(true).filter(SpellPredicate.IS_PLACED).forEach(getSpellSlot()::put);
|
||||
if (forcedSwap) {
|
||||
Channel.SERVER_SELECT_TRIBE.sendToPlayer(new MsgTribeSelect(Race.allPermitted(entity), Text.translatable("gui.unicopia.tribe_selection.respawn")), (ServerPlayerEntity)entity);
|
||||
} else {
|
||||
oldPlayer.getSpellSlot().stream(true).filter(SpellPredicate.IS_PLACED).forEach(getSpellSlot()::put);
|
||||
}
|
||||
}
|
||||
|
||||
oldPlayer.getSpellSlot().put(null);
|
||||
getArmour().copyFrom(oldPlayer.getArmour());
|
||||
setSpecies(oldPlayer.getActualSpecies());
|
||||
getDiscoveries().copyFrom(oldPlayer.getDiscoveries());
|
||||
getCharms().equipSpell(Hand.MAIN_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.MAIN_HAND));
|
||||
getCharms().equipSpell(Hand.OFF_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.OFF_HAND));
|
||||
corruption.set(oldPlayer.getCorruption().get());
|
||||
levels.set(oldPlayer.getLevel().get());
|
||||
mana.getXp().set(oldPlayer.getMagicalReserves().getXp().get());
|
||||
setSpecies(oldPlayer.respawnRace != Race.UNSET && !alive ? oldPlayer.respawnRace : oldPlayer.getActualSpecies());
|
||||
getDiscoveries().copyFrom(oldPlayer.getDiscoveries(), alive);
|
||||
getPhysics().copyFrom(oldPlayer.getPhysics(), alive);
|
||||
if (!forcedSwap) {
|
||||
getArmour().copyFrom(oldPlayer.getArmour(), alive);
|
||||
getCharms().equipSpell(Hand.MAIN_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.MAIN_HAND));
|
||||
getCharms().equipSpell(Hand.OFF_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.OFF_HAND));
|
||||
corruption.set(oldPlayer.getCorruption().get());
|
||||
levels.set(oldPlayer.getLevel().get());
|
||||
mana.getXp().set(oldPlayer.getMagicalReserves().getXp().get());
|
||||
} else {
|
||||
mana.getEnergy().set(0.6F);
|
||||
mana.getExhaustion().set(0);
|
||||
mana.getExertion().set(0);
|
||||
}
|
||||
|
||||
|
||||
advancementProgress.putAll(oldPlayer.getAdvancementProgress());
|
||||
setDirty();
|
||||
onSpawn();
|
||||
|
|
|
@ -24,7 +24,7 @@ abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHan
|
|||
@SuppressWarnings("unchecked")
|
||||
@Inject(method = "copyFrom(Lnet/minecraft/server/network/ServerPlayerEntity;Z)V", at = @At("HEAD"))
|
||||
private void onCopyFrom(ServerPlayerEntity oldPlayer, boolean alive, CallbackInfo info) {
|
||||
get().copyFrom(((Equine.Container<Pony>)oldPlayer).get());
|
||||
get().copyFrom(((Equine.Container<Pony>)oldPlayer).get(), alive);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.sollace.fabwork.api.packets.*;
|
|||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public interface Channel {
|
||||
C2SPacketType<MsgPlayerAbility<?>> CLIENT_PLAYER_ABILITY = SimpleNetworking.clientToServer(Unicopia.id("player_ability"), MsgPlayerAbility::read);
|
||||
|
@ -39,7 +40,7 @@ public interface Channel {
|
|||
race = Race.UNSET;
|
||||
}
|
||||
if (race.isUnset()) {
|
||||
sender.sendPacket(SERVER_SELECT_TRIBE.id(), new MsgTribeSelect(Race.allPermitted(handler.player)).toBuffer());
|
||||
sender.sendPacket(SERVER_SELECT_TRIBE.id(), new MsgTribeSelect(Race.allPermitted(handler.player), Text.translatable("gui.unicopia.tribe_selection.journey")).toBuffer());
|
||||
} else {
|
||||
pony.setSpecies(race);
|
||||
Unicopia.LOGGER.info("Setting {}'s race to {} due to host setting", handler.player.getDisplayName().getString(), Race.REGISTRY.getId(race).toString());
|
||||
|
|
|
@ -8,19 +8,19 @@ import com.sollace.fabwork.api.packets.Packet;
|
|||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public record MsgTribeSelect (Set<Race> availableRaces) implements Packet<PlayerEntity> {
|
||||
public record MsgTribeSelect (Set<Race> availableRaces, Text serverMessage) implements Packet<PlayerEntity> {
|
||||
public MsgTribeSelect(PacketByteBuf buffer) {
|
||||
this(new HashSet<>());
|
||||
int len = buffer.readInt();
|
||||
while (len-- > 0) {
|
||||
availableRaces.add(buffer.readRegistryValue(Race.REGISTRY));
|
||||
}
|
||||
this(
|
||||
buffer.readCollection(HashSet::new, buf -> buf.readRegistryValue(Race.REGISTRY)),
|
||||
buffer.readText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeInt(availableRaces.size());
|
||||
availableRaces.forEach(race -> buffer.writeRegistryValue(Race.REGISTRY, race));
|
||||
buffer.writeCollection(availableRaces, (buf, race) -> buf.writeRegistryValue(Race.REGISTRY, race));
|
||||
buffer.writeText(serverMessage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package com.minelittlepony.unicopia.util;
|
||||
|
||||
public interface Copyable<T extends Copyable<T>> {
|
||||
void copyFrom(T other);
|
||||
void copyFrom(T other, boolean alive);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public class MagicalDamageSource extends EntityDamageSource {
|
|||
public static final DamageSource EXHAUSTION = new MagicalDamageSource("magical_exhaustion", null, true, true);
|
||||
public static final DamageSource ALICORN_AMULET = new MagicalDamageSource("alicorn_amulet", null, true, true);
|
||||
public static final DamageSource FOOD_POISONING = new DamageSource("food_poisoning");
|
||||
public static final DamageSource TRIBE_SWAP = new DamageSource("tribe_swap");
|
||||
public static final DamageSource TRIBE_SWAP = new DamageSource("tribe_swap").setOutOfWorld().setUnblockable();
|
||||
public static final DamageSource ZAP_APPLE = create("zap");
|
||||
public static final DamageSource KICK = create("kick");
|
||||
public static final DamageSource SUN = new DamageSource("sun").setBypassesArmor().setFire();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
accessWidener v1 named
|
||||
accessible class net/minecraft/client/render/RenderLayer$MultiPhaseParameters
|
||||
accessible method net/minecraft/client/render/RenderLayer of (Ljava/lang/String;Lnet/minecraft/client/render/VertexFormat;Lnet/minecraft/client/render/VertexFormat$DrawMode;IZZLnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase;
|
||||
accessible class net/minecraft/client/render/item/HeldItemRenderer$HandRenderType
|
||||
accessible method net/minecraft/client/render/RenderLayer of (Ljava/lang/String;Lnet/minecraft/client/render/VertexFormat;Lnet/minecraft/client/render/VertexFormat$DrawMode;IZZLnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase;
|
||||
accessible class net/minecraft/client/render/item/HeldItemRenderer$HandRenderType
|
||||
accessible method net/minecraft/world/GameRules register (Ljava/lang/String;Lnet/minecraft/world/GameRules$Category;Lnet/minecraft/world/GameRules$Type;)Lnet/minecraft/world/GameRules$Key;
|
||||
accessible method net/minecraft/world/GameRules$BooleanRule create (Z)Lnet/minecraft/world/GameRules$Type;
|
Loading…
Reference in a new issue