Added seapony's grace/seapony's ire status effects. Mining blocks in a monument will cause seaponies to lose their grace. Fixes #390

This commit is contained in:
Sollace 2024-06-23 16:59:02 +01:00
parent d4e3feacee
commit f6668eff72
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
11 changed files with 119 additions and 23 deletions

View file

@ -107,6 +107,7 @@ public interface UTags {
TagKey<Block> MIMIC_CHESTS = block("mimic_chests"); TagKey<Block> MIMIC_CHESTS = block("mimic_chests");
TagKey<Block> BUTTERFLIES_SPAWNABLE_ON = block("butterflies_spawn_on"); TagKey<Block> BUTTERFLIES_SPAWNABLE_ON = block("butterflies_spawn_on");
TagKey<Block> ANGERS_GUARDIANS = block("angers_guardians");
private static TagKey<Block> block(String name) { private static TagKey<Block> block(String name) {
return TagKey.of(RegistryKeys.BLOCK, Unicopia.id(name)); return TagKey.of(RegistryKeys.BLOCK, Unicopia.id(name));

View file

@ -2,6 +2,7 @@ package com.minelittlepony.unicopia;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.resource.ResourceType; import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -22,6 +23,7 @@ import com.minelittlepony.unicopia.container.UScreenHandlers;
import com.minelittlepony.unicopia.diet.DietsLoader; import com.minelittlepony.unicopia.diet.DietsLoader;
import com.minelittlepony.unicopia.diet.affliction.AfflictionType; import com.minelittlepony.unicopia.diet.affliction.AfflictionType;
import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.damage.UDamageTypes;
import com.minelittlepony.unicopia.entity.effect.SeaponyGraceStatusEffect;
import com.minelittlepony.unicopia.entity.effect.UPotions; import com.minelittlepony.unicopia.entity.effect.UPotions;
import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.entity.mob.UEntities;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
@ -76,6 +78,7 @@ public class Unicopia implements ModInitializer {
Debug.runTests(w); Debug.runTests(w);
} }
}); });
PlayerBlockBreakEvents.AFTER.register(SeaponyGraceStatusEffect::processBlockChange);
NocturnalSleepManager.bootstrap(); NocturnalSleepManager.bootstrap();
registerServerDataReloaders(ResourceManagerHelper.get(ResourceType.SERVER_DATA)); registerServerDataReloaders(ResourceManagerHelper.get(ResourceType.SERVER_DATA));

View file

@ -49,6 +49,12 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider {
Blocks.COMMAND_BLOCK, Blocks.CHAIN_COMMAND_BLOCK, Blocks.REPEATING_COMMAND_BLOCK, Blocks.COMMAND_BLOCK, Blocks.CHAIN_COMMAND_BLOCK, Blocks.REPEATING_COMMAND_BLOCK,
Blocks.LIGHT, Blocks.JIGSAW, Blocks.BARRIER, Blocks.BEDROCK Blocks.LIGHT, Blocks.JIGSAW, Blocks.BARRIER, Blocks.BEDROCK
).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS); ).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS);
getOrCreateTagBuilder(UTags.Blocks.ANGERS_GUARDIANS).add(
Blocks.PRISMARINE, Blocks.PRISMARINE_SLAB, Blocks.PRISMARINE_STAIRS, Blocks.PRISMARINE_WALL,
Blocks.PRISMARINE_BRICKS, Blocks.PRISMARINE_BRICK_SLAB, Blocks.PRISMARINE_BRICK_STAIRS,
Blocks.DARK_PRISMARINE, Blocks.DARK_PRISMARINE_SLAB, Blocks.DARK_PRISMARINE_STAIRS,
Blocks.SEA_LANTERN, Blocks.SPONGE
);
getOrCreateTagBuilder(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON).forceAddTag(BlockTags.ANIMALS_SPAWNABLE_ON).forceAddTag(BlockTags.LEAVES).forceAddTag(BlockTags.FLOWERS).forceAddTag(BlockTags.FLOWER_POTS); getOrCreateTagBuilder(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON).forceAddTag(BlockTags.ANIMALS_SPAWNABLE_ON).forceAddTag(BlockTags.LEAVES).forceAddTag(BlockTags.FLOWERS).forceAddTag(BlockTags.FLOWER_POTS);
getOrCreateTagBuilder(UTags.Blocks.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR); getOrCreateTagBuilder(UTags.Blocks.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR);
getOrCreateTagBuilder(BlockTags.CROPS).add(crops); getOrCreateTagBuilder(BlockTags.CROPS).add(crops);

View file

@ -0,0 +1,85 @@
package com.minelittlepony.unicopia.entity.effect;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.UTags;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.mob.GuardianEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.structure.StructureStart;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.StructureKeys;
public class SeaponyGraceStatusEffect {
public static void update(LivingEntity entity) {
if (entity.getWorld().isClient) {
return;
}
if (EquinePredicates.PLAYER_SEAPONY.test(entity)) {
if (!entity.hasStatusEffect(UEffects.SEAPONYS_GRACE) && !entity.hasStatusEffect(UEffects.SEAPONYS_IRE)) {
entity.addStatusEffect(new StatusEffectInstance(UEffects.SEAPONYS_GRACE, StatusEffectInstance.INFINITE, 0, false, true));
}
} else if (entity.hasStatusEffect(UEffects.SEAPONYS_GRACE)) {
entity.removeStatusEffect(UEffects.SEAPONYS_GRACE);
}
}
public static boolean hasIre(LivingEntity entity, MobEntity enemy) {
return enemy.getAttacker() == entity || hasIre(entity);
}
public static boolean hasGrace(LivingEntity entity) {
boolean isSeapony = EquinePredicates.PLAYER_SEAPONY.test(entity);
return isSeapony && entity.hasStatusEffect(UEffects.SEAPONYS_GRACE) && !entity.hasStatusEffect(UEffects.SEAPONYS_IRE);
}
public static boolean hasIre(LivingEntity entity) {
return !EquinePredicates.PLAYER_SEAPONY.test(entity) || entity.hasStatusEffect(UEffects.SEAPONYS_IRE);
}
public static void processBlockChange(World world, PlayerEntity player, BlockPos pos, BlockState stateBroken, @Nullable BlockEntity blockEntity) {
if (!(world instanceof ServerWorld sw)) {
return;
}
if (!hasGrace(player)) {
return;
}
if (!stateBroken.isIn(UTags.Blocks.ANGERS_GUARDIANS)) {
return;
}
StructureStart start = sw.getStructureAccessor().getStructureContaining(pos, StructureKeys.MONUMENT);
if (start.getStructure() == null) {
return;
}
List<GuardianEntity> guardians = sw.getEntitiesByClass(GuardianEntity.class, player.getBoundingBox().expand(10), EntityPredicates.VALID_LIVING_ENTITY);
if (guardians.size() > 0) {
guardians.forEach(guardian -> {
guardian.setTarget(player);
guardian.playAmbientSound();
});
player.removeStatusEffect(UEffects.SEAPONYS_GRACE);
player.addStatusEffect(new StatusEffectInstance(UEffects.SEAPONYS_IRE, 90000, 0, false, true));
world.playSound(null, pos, USounds.Vanilla.ENTITY_ELDER_GUARDIAN_CURSE, SoundCategory.PLAYERS, 1, 1);
}
}
}

View file

@ -24,6 +24,9 @@ public interface UEffects {
*/ */
StatusEffect BUTTER_FINGERS = register("butter_fingers", new ButterfingersStatusEffect(0x888800)); StatusEffect BUTTER_FINGERS = register("butter_fingers", new ButterfingersStatusEffect(0x888800));
StatusEffect SEAPONYS_GRACE = register("seaponys_grace", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0x0000EE, false));
StatusEffect SEAPONYS_IRE = register("seaponys_ire", new SimpleStatusEffect(StatusEffectCategory.HARMFUL, 0xEE00EE, false));
private static StatusEffect register(String name, StatusEffect effect) { private static StatusEffect register(String name, StatusEffect effect) {
return Registry.register(Registries.STATUS_EFFECT, Unicopia.id(name), effect); return Registry.register(Registries.STATUS_EFFECT, Unicopia.id(name), effect);
} }

View file

@ -24,6 +24,7 @@ import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
import com.minelittlepony.unicopia.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.effect.EffectUtils;
import com.minelittlepony.unicopia.entity.effect.MetamorphosisStatusEffect; import com.minelittlepony.unicopia.entity.effect.MetamorphosisStatusEffect;
import com.minelittlepony.unicopia.entity.effect.SeaponyGraceStatusEffect;
import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect; import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect;
import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.effect.UEffects;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
@ -414,6 +415,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
powers.tick(); powers.tick();
acrobatics.tick(); acrobatics.tick();
SeaponyGraceStatusEffect.update(entity);
if (getObservedSpecies() == Race.KIRIN) { if (getObservedSpecies() == Race.KIRIN) {
var charge = getMagicalReserves().getCharge(); var charge = getMagicalReserves().getCharge();
@ -484,9 +487,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
AmuletSelectors.PEARL_NECKLACE.test(entity) ? suppressedRace.or(Race.SEAPONY) : null AmuletSelectors.PEARL_NECKLACE.test(entity) ? suppressedRace.or(Race.SEAPONY) : null
); );
UCriteria.PLAYER_CHANGE_RACE.trigger(entity); UCriteria.PLAYER_CHANGE_RACE.trigger(entity);
var hasNecklace = AmuletSelectors.PEARL_NECKLACE.test(entity);
System.out.println(hasNecklace);
} }
@Override @Override

View file

@ -1,21 +1,23 @@
package com.minelittlepony.unicopia.mixin; package com.minelittlepony.unicopia.mixin;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.entity.effect.SeaponyGraceStatusEffect;
import com.minelittlepony.unicopia.EquinePredicates;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.GuardianEntity;
@Mixin(targets = "net.minecraft.entity.mob.GuardianEntity$GuardianTargetPredicate") @Mixin(targets = "net.minecraft.entity.mob.GuardianEntity$GuardianTargetPredicate")
abstract class MixinGuardianTargetPredicate { abstract class MixinGuardianTargetPredicate {
@Inject(method = "test", at = @At("HEAD"), cancellable = true) @Shadow
private void test(@Nullable LivingEntity livingEntity, CallbackInfoReturnable<Boolean> info) { private @Final GuardianEntity owner;
if (EquinePredicates.PLAYER_SEAPONY.test(livingEntity)) {
info.setReturnValue(false); @ModifyReturnValue(method = "test", at = @At("RETURN"))
} private boolean unicopia_excludeSeaponysGrace(boolean result, @Nullable LivingEntity target) {
return result && SeaponyGraceStatusEffect.hasIre(target, owner);
} }
} }

View file

@ -2,12 +2,8 @@ package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.entity.effect.SeaponyGraceStatusEffect;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.passive.FishEntity; import net.minecraft.entity.passive.FishEntity;
import net.minecraft.entity.passive.PufferfishEntity; import net.minecraft.entity.passive.PufferfishEntity;
@ -16,10 +12,8 @@ import net.minecraft.entity.passive.PufferfishEntity;
abstract class MixinPufferfishEntity extends FishEntity { abstract class MixinPufferfishEntity extends FishEntity {
MixinPufferfishEntity() { super(null, null); } MixinPufferfishEntity() { super(null, null); }
@Inject(method = "method_6591(Lnet/minecraft/entity/LivingEntity;)Z", at = @At("HEAD"), cancellable = true) @ModifyReturnValue(method = "method_6591(Lnet/minecraft/entity/LivingEntity;)Z", at = @At("RETURN"))
private static void onShouldTarget(LivingEntity entity, CallbackInfoReturnable<Boolean> info) { private static boolean unicopia_excludeSeaponysGrace(boolean result, LivingEntity entity) {
Pony.of(entity).filter(pony -> pony.getCompositeRace().includes(Race.SEAPONY)).ifPresent(pony -> { return result && !SeaponyGraceStatusEffect.hasGrace(entity);
info.setReturnValue(false);
});
} }
} }

View file

@ -408,6 +408,8 @@
"effect.unicopia.butter_fingers": "Butterfingers", "effect.unicopia.butter_fingers": "Butterfingers",
"effect.unicopia.fortification": "Fortification", "effect.unicopia.fortification": "Fortification",
"effect.unicopia.broken_wings": "Broken Wings", "effect.unicopia.broken_wings": "Broken Wings",
"effect.unicopia.seaponys_ire": "Seaponys Ire",
"effect.unicopia.seaponys_grace": "Seaponys Grace",
"effect.unicopia.change_race_earth": "Earth Pony Metamorphosis", "effect.unicopia.change_race_earth": "Earth Pony Metamorphosis",
"effect.unicopia.change_race_unicorn": "Unicorn Metamorphosis", "effect.unicopia.change_race_unicorn": "Unicorn Metamorphosis",

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB