Update corruption mechanics.

- Players no longer gain corruption from taking damage, but
 - But spells with the dark alignment now cause more corruption
and gaining corruption has side-effects not unlike the mild
effects of wearing an alicorn amulet.
 - Every time a side-effect manifests, the player's corruption goes
down.
 - Alicorn Amulet and Grogar's bell now cause more corruption

Corrupt influence now clones mobs when they are damaged
rather than just randomly.
This commit is contained in:
Sollace 2024-03-12 14:49:41 +00:00
parent e5f2f696ba
commit f06dad53fc
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
12 changed files with 180 additions and 37 deletions

View file

@ -12,7 +12,7 @@ import static net.minecraft.sound.SoundEvents.*;
public interface USounds { public interface USounds {
SoundEvent ENTITY_GENERIC_BUTTER_FINGERS = BLOCK_HONEY_BLOCK_SLIDE; SoundEvent ENTITY_GENERIC_BUTTER_FINGERS = BLOCK_HONEY_BLOCK_SLIDE;
SoundEvent ENTITY_PLAYER_CORRUPTION = PARTICLE_SOUL_ESCAPE; SoundEvent ENTITY_PLAYER_CORRUPTION = register("entity.player.corrupt");
SoundEvent ENTITY_PLAYER_BATPONY_SCREECH = register("entity.player.batpony.screech"); SoundEvent ENTITY_PLAYER_BATPONY_SCREECH = register("entity.player.batpony.screech");
SoundEvent ENTITY_PLAYER_HIPPOGRIFF_SCREECH = register("entity.player.hippogriff.screech"); SoundEvent ENTITY_PLAYER_HIPPOGRIFF_SCREECH = register("entity.player.hippogriff.screech");
SoundEvent ENTITY_PLAYER_HIPPOGRIFF_PECK = ENTITY_CHICKEN_STEP; SoundEvent ENTITY_PLAYER_HIPPOGRIFF_PECK = ENTITY_CHICKEN_STEP;

View file

@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic;
import java.util.UUID; import java.util.UUID;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.spell.*; import com.minelittlepony.unicopia.ability.magic.spell.*;
import com.minelittlepony.unicopia.ability.magic.spell.effect.MimicSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.MimicSpell;
import com.minelittlepony.unicopia.ability.magic.spell.effect.ShieldSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.ShieldSpell;
@ -21,6 +22,8 @@ public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
SpellPredicate<?> IS_NOT_PLACED = IS_PLACED.negate(); SpellPredicate<?> IS_NOT_PLACED = IS_PLACED.negate();
SpellPredicate<?> IS_VISIBLE = spell -> spell != null && !spell.isHidden(); SpellPredicate<?> IS_VISIBLE = spell -> spell != null && !spell.isHidden();
SpellPredicate<?> IS_CORRUPTING = spell -> spell.getAffinity() == Affinity.BAD;
default <Q extends Spell> SpellPredicate<Q> and(SpellPredicate<Q> predicate) { default <Q extends Spell> SpellPredicate<Q> and(SpellPredicate<Q> predicate) {
SpellPredicate<T> self = this; SpellPredicate<T> self = this;
return s -> self.test(s) && predicate.test(s); return s -> self.test(s) && predicate.test(s);

View file

@ -5,6 +5,7 @@ import java.util.List;
import com.minelittlepony.common.client.gui.IViewRoot; import com.minelittlepony.common.client.gui.IViewRoot;
import com.minelittlepony.common.client.gui.dimension.Bounds; import com.minelittlepony.common.client.gui.dimension.Bounds;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.client.gui.*; import com.minelittlepony.unicopia.client.gui.*;
import com.minelittlepony.unicopia.entity.player.*; import com.minelittlepony.unicopia.entity.player.*;
import com.minelittlepony.unicopia.util.ColorHelper; import com.minelittlepony.unicopia.util.ColorHelper;
@ -43,7 +44,7 @@ public class SpellbookProfilePageContent implements SpellbookChapterList.Content
.setTooltip(() -> List.of( .setTooltip(() -> List.of(
Text.literal(String.format("Level %d ", pony.getLevel().get() + 1)).append(pony.getSpecies().getDisplayName()).formatted(pony.getSpecies().getAffinity().getColor()), Text.literal(String.format("Level %d ", pony.getLevel().get() + 1)).append(pony.getSpecies().getDisplayName()).formatted(pony.getSpecies().getAffinity().getColor()),
Text.literal(String.format("Mana: %d%%", (int)(pony.getMagicalReserves().getMana().getPercentFill() * 100))), Text.literal(String.format("Mana: %d%%", (int)(pony.getMagicalReserves().getMana().getPercentFill() * 100))),
Text.literal(String.format("Corruption: %d%%", (int)(pony.getCorruption().getScaled(100)))), Text.literal(String.format("Corruption: %s%d%%", pony.getCorruptionhandler().hasCorruptingMagic() ? "^" : "", (int)(pony.getCorruption().getScaled(100)))),
Text.literal(String.format("Experience: %d", (int)(pony.getMagicalReserves().getXp().getPercentFill() * 100))), Text.literal(String.format("Experience: %d", (int)(pony.getMagicalReserves().getXp().getPercentFill() * 100))),
Text.literal(String.format("Next level in: %dxp", 100 - (int)(pony.getMagicalReserves().getXp().getPercentFill() * 100))) Text.literal(String.format("Next level in: %dxp", 100 - (int)(pony.getMagicalReserves().getXp().getPercentFill() * 100)))
)); ));
@ -108,7 +109,11 @@ public class SpellbookProfilePageContent implements SpellbookChapterList.Content
int alpha = (int)(alphaF * 0x10) & 0xFF; int alpha = (int)(alphaF * 0x10) & 0xFF;
int color = 0x10404000 | alpha; int color = 0x10404000 | alpha;
int xpColor = 0xAA0040FF | ((int)((0.3F + 0.7F * xpPercentage) * 0xFF) & 0xFF) << 16; int xpColor = 0xAA0040FF | ((int)((0.3F + 0.7F * xpPercentage) * 0xFF) & 0xFF) << 16;
int manaColor = 0xFF00F040 | (int)((0.3F + 0.7F * alphaF) * 0x40) << 16; int manaColor = 0xFF00F040;
if (pony.getSpellSlot().get(SpellPredicate.IS_CORRUPTING, false).isPresent()) {
manaColor = ColorHelper.lerp(Math.abs(MathHelper.sin(pony.asEntity().age / 15F)), manaColor, 0xFF0030F0);
}
manaColor |= (int)((0.3F + 0.7F * alphaF) * 0x40) << 16;
DrawableUtil.drawArc(matrices, 0, radius + 24, 0, DrawableUtil.TAU, color, false); DrawableUtil.drawArc(matrices, 0, radius + 24, 0, DrawableUtil.TAU, color, false);
DrawableUtil.drawArc(matrices, radius / 3, radius + 6, 0, DrawableUtil.TAU, color, false); DrawableUtil.drawArc(matrices, radius / 3, radius + 6, 0, DrawableUtil.TAU, color, false);

View file

@ -23,6 +23,7 @@ import com.minelittlepony.unicopia.entity.behaviour.Guest;
import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity; import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity;
import com.minelittlepony.unicopia.entity.damage.MagicalDamageSource; import com.minelittlepony.unicopia.entity.damage.MagicalDamageSource;
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
import com.minelittlepony.unicopia.entity.effect.CorruptInfluenceStatusEffect;
import com.minelittlepony.unicopia.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.effect.EffectUtils;
import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.effect.UEffects;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
@ -49,6 +50,7 @@ import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageTypes; import net.minecraft.entity.damage.DamageTypes;
import net.minecraft.entity.data.*; import net.minecraft.entity.data.*;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
@ -521,6 +523,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
} }
} }
if (entity instanceof HostileEntity mob && mob.hasStatusEffect(UEffects.CORRUPT_INFLUENCE) && mob.getRandom().nextInt(4) == 0) {
CorruptInfluenceStatusEffect.reproduce(mob);
}
return Optional.empty(); return Optional.empty();
} }

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.entity.effect; package com.minelittlepony.unicopia.entity.effect;
import java.util.UUID;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.Owned;
@ -13,6 +15,8 @@ import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory; import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.WorldEvents; import net.minecraft.world.WorldEvents;
@ -24,7 +28,6 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
addAttributeModifier(EntityAttributes.GENERIC_ATTACK_SPEED, "6D706448-6A60-4F59-BE8A-C23A6DD2C7A9", 10, EntityAttributeModifier.Operation.ADDITION); addAttributeModifier(EntityAttributes.GENERIC_ATTACK_SPEED, "6D706448-6A60-4F59-BE8A-C23A6DD2C7A9", 10, EntityAttributeModifier.Operation.ADDITION);
} }
@SuppressWarnings("unchecked")
@Override @Override
public void applyUpdateEffect(LivingEntity entity, int amplifier) { public void applyUpdateEffect(LivingEntity entity, int amplifier) {
@ -32,7 +35,7 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
return; return;
} }
if (entity instanceof HostileEntity) { if (entity instanceof HostileEntity mob) {
int nearby = entity.getWorld().getOtherEntities(entity, entity.getBoundingBox().expand(40), i -> i.getType() == entity.getType()).size(); int nearby = entity.getWorld().getOtherEntities(entity, entity.getBoundingBox().expand(40), i -> i.getType() == entity.getType()).size();
@ -48,25 +51,12 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
return; return;
} }
HostileEntity mob = (HostileEntity)entity; reproduce(mob);
HostileEntity clone = (HostileEntity)mob.getType().create(mob.getWorld());
clone.copyPositionAndRotation(entity);
Equine.of(clone).ifPresent(eq -> {
if (eq instanceof Owned.Mutable) {
((Owned.Mutable<Entity>)eq).setMaster(mob);
}
});
mob.getWorld().spawnEntity(clone);
if (!mob.isSilent()) {
mob.getWorld().syncWorldEvent((PlayerEntity)null, WorldEvents.ZOMBIE_INFECTS_VILLAGER, mob.getBlockPos(), 0);
}
} else if (entity.age % 2000 == 0) { } else if (entity.age % 2000 == 0) {
entity.damage(Living.living(entity).damageOf(UDamageTypes.ALICORN_AMULET), 2); entity.damage(Living.living(entity).damageOf(UDamageTypes.ALICORN_AMULET), 2);
} }
} }
@Override @Override
@ -78,4 +68,31 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
public boolean canApplyUpdateEffect(int duration, int amplifier) { public boolean canApplyUpdateEffect(int duration, int amplifier) {
return duration > 0; return duration > 0;
} }
public static void reproduce(HostileEntity mob) {
HostileEntity clone = (HostileEntity)mob.getType().create(mob.getWorld());
clone.copyPositionAndRotation(mob);
clone.takeKnockback(0.1, 0.5, 0.5);
mob.takeKnockback(0.1, -0.5, -0.5);
if (mob.getRandom().nextInt(4) != 0) {
mob.clearStatusEffects();
} else {
if (clone.getAttributes().hasAttribute(EntityAttributes.GENERIC_MAX_HEALTH)) {
float maxHealthDifference = mob.getMaxHealth() - clone.getMaxHealth();
clone.addStatusEffect(new StatusEffectInstance(StatusEffects.STRENGTH, 900000, 2));
clone.getAttributeInstance(EntityAttributes.GENERIC_MAX_HEALTH)
.addPersistentModifier(new EntityAttributeModifier(UUID.randomUUID(), "Corruption Strength Modifier", maxHealthDifference + 1, EntityAttributeModifier.Operation.ADDITION));
}
if (clone.getAttributes().hasAttribute(EntityAttributes.GENERIC_ATTACK_DAMAGE)) {
clone.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE)
.addPersistentModifier(new EntityAttributeModifier(UUID.randomUUID(), "Corruption Damage Modifier", mob.getAttributeValue(EntityAttributes.GENERIC_ATTACK_DAMAGE) + 1, EntityAttributeModifier.Operation.ADDITION));
}
}
mob.getWorld().spawnEntity(clone);
if (!mob.isSilent()) {
mob.getWorld().syncWorldEvent((PlayerEntity)null, WorldEvents.ZOMBIE_INFECTS_VILLAGER, mob.getBlockPos(), 0);
}
}
} }

View file

@ -10,8 +10,16 @@ import net.minecraft.registry.Registries;
public interface UEffects { public interface UEffects {
StatusEffect FOOD_POISONING = register("food_poisoning", new FoodPoisoningStatusEffect(3484199)); StatusEffect FOOD_POISONING = register("food_poisoning", new FoodPoisoningStatusEffect(3484199));
StatusEffect SUN_BLINDNESS = register("sun_blindness", new SunBlindnessStatusEffect(0x886F0F)); StatusEffect SUN_BLINDNESS = register("sun_blindness", new SunBlindnessStatusEffect(0x886F0F));
/**
* Status effect emitted by players with a high level of corruption.
* When affecting an entity, will give them a random chance to reproduce or duplicate themselves when they die.
*/
StatusEffect CORRUPT_INFLUENCE = register("corrupt_influence", new CorruptInfluenceStatusEffect(0x00FF00)); StatusEffect CORRUPT_INFLUENCE = register("corrupt_influence", new CorruptInfluenceStatusEffect(0x00FF00));
StatusEffect PARALYSIS = register("paralysis", new StatusEffect(StatusEffectCategory.HARMFUL, 0) {}); StatusEffect PARALYSIS = register("paralysis", new StatusEffect(StatusEffectCategory.HARMFUL, 0) {});
/**
* Side-effect of wearing the alicorn amulet.
* Causes the player to lose grip on whatever item they're holding.
*/
StatusEffect BUTTER_FINGERS = register("butter_fingers", new ButterfingersStatusEffect(0x888800)); StatusEffect BUTTER_FINGERS = register("butter_fingers", new ButterfingersStatusEffect(0x888800));
private static StatusEffect register(String name, StatusEffect effect) { private static StatusEffect register(String name, StatusEffect effect) {

View file

@ -0,0 +1,84 @@
package com.minelittlepony.unicopia.entity.player;
import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.entity.ItemTracker;
import com.minelittlepony.unicopia.entity.effect.UEffects;
import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.util.Tickable;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.math.random.Random;
public class CorruptionHandler implements Tickable {
private final Pony pony;
public CorruptionHandler(Pony pony) {
this.pony = pony;
}
public boolean hasCorruptingMagic() {
return pony.getSpellSlot().get(SpellPredicate.IS_CORRUPTING, false).isPresent() || UItems.ALICORN_AMULET.isApplicable(pony.asEntity());
}
@Override
public void tick() {
if (pony.isClient() || pony.asEntity().age % 5 != 0) {
return;
}
PlayerEntity entity = pony.asEntity();
Random random = pony.asEntity().getRandom();
if (!UItems.ALICORN_AMULET.isApplicable(entity)) {
if (entity.age % (10 * ItemTracker.SECONDS) == 0) {
if (random.nextInt(100) == 0) {
pony.getCorruption().add(-1);
pony.setDirty();
}
if (entity.getHealth() >= entity.getMaxHealth() - 1 && !entity.getHungerManager().isNotFull()) {
pony.getCorruption().add(-random.nextInt(4));
pony.setDirty();
}
}
}
if (pony.asEntity().age % 100 == 0 && hasCorruptingMagic()) {
pony.getCorruption().add(random.nextInt(4));
}
float corruptionPercentage = pony.getCorruption().getScaled(1);
if (corruptionPercentage > 0.5F && random.nextFloat() < corruptionPercentage - 0.25F) {
pony.findAllEntitiesInRange(10, e -> e instanceof LivingEntity && !((LivingEntity)e).hasStatusEffect(UEffects.CORRUPT_INFLUENCE)).forEach(e -> {
((LivingEntity)e).addStatusEffect(new StatusEffectInstance(UEffects.CORRUPT_INFLUENCE, 100, 1));
recover(10);
});
}
if (corruptionPercentage > 0.25F && random.nextInt(200) == 0) {
if (!pony.asEntity().hasStatusEffect(UEffects.BUTTER_FINGERS)) {
pony.asEntity().addStatusEffect(new StatusEffectInstance(UEffects.BUTTER_FINGERS, 2100, 1));
recover(25);
}
}
if (random.nextFloat() < corruptionPercentage) {
pony.spawnParticles(ParticleTypes.ASH, 10);
}
}
private void recover(float percentage) {
pony.getCorruption().set((int)(pony.getCorruption().get() * (1 - percentage)));
InteractionManager.INSTANCE.playLoopingSound(pony.asEntity(), InteractionManager.SOUND_HEART_BEAT, 0);
MagicReserves reserves = pony.getMagicalReserves();
reserves.getExertion().addPercent(10);
reserves.getEnergy().add(10);
pony.setDirty();
}
}

View file

@ -92,6 +92,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
private final PlayerCamera camera = new PlayerCamera(this); private final PlayerCamera camera = new PlayerCamera(this);
private final TraitDiscovery discoveries = new TraitDiscovery(this); private final TraitDiscovery discoveries = new TraitDiscovery(this);
private final Acrobatics acrobatics = new Acrobatics(this); private final Acrobatics acrobatics = new Acrobatics(this);
private final CorruptionHandler corruptionHandler = new CorruptionHandler(this);
private final Map<String, Integer> advancementProgress = new HashMap<>(); private final Map<String, Integer> advancementProgress = new HashMap<>();
@ -129,6 +130,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
addTicker(this::updateBatPonyAbilities); addTicker(this::updateBatPonyAbilities);
addTicker(this::updateCorruptionDecay); addTicker(this::updateCorruptionDecay);
addTicker(new PlayerAttributes(this)); addTicker(new PlayerAttributes(this));
addTicker(corruptionHandler);
} }
@Override @Override
@ -289,6 +291,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
return corruption; return corruption;
} }
public CorruptionHandler getCorruptionhandler() {
return corruptionHandler;
}
public boolean canUseSuperMove() { public boolean canUseSuperMove() {
return entity.isCreative() || getMagicalReserves().getCharge().get() >= getMagicalReserves().getCharge().getMax(); return entity.isCreative() || getMagicalReserves().getCharge().get() >= getMagicalReserves().getCharge().getMax();
} }
@ -572,19 +578,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
} }
private void updateCorruptionDecay() { private void updateCorruptionDecay() {
if (!isClient() && !UItems.ALICORN_AMULET.isApplicable(entity)) {
if (entity.age % (10 * ItemTracker.SECONDS) == 0) {
if (entity.getWorld().random.nextInt(100) == 0) {
corruption.add(-1);
setDirty();
}
if (entity.getHealth() >= entity.getMaxHealth() - 1 && !entity.getHungerManager().isNotFull()) {
corruption.add(-entity.getWorld().random.nextInt(4));
setDirty();
}
}
}
} }
@Override @Override
@ -784,6 +778,12 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
@Override @Override
public boolean subtractEnergyCost(double foodSubtract) { public boolean subtractEnergyCost(double foodSubtract) {
if (getSpellSlot().get(SpellPredicate.IS_CORRUPTING, false).isPresent()) {
int corruptionTaken = (int)(foodSubtract * (AmuletSelectors.ALICORN_AMULET.test(entity) ? 0.9F : 0.5F));
foodSubtract -= corruptionTaken;
getCorruption().add(corruptionTaken);
}
List<Pony> partyMembers = FriendshipBraceletItem.getPartyMembers(this, 10).toList(); List<Pony> partyMembers = FriendshipBraceletItem.getPartyMembers(this, 10).toList();
if (!partyMembers.isEmpty()) { if (!partyMembers.isEmpty()) {
@ -951,10 +951,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
@Override @Override
public void onSpellSet(@Nullable Spell spell) { public void onSpellSet(@Nullable Spell spell) {
if (spell != null) { if (spell != null) {
if (spell.getAffinity() == Affinity.BAD && entity.getWorld().random.nextInt(120) == 0) { if (spell.getAffinity() == Affinity.BAD && entity.getWorld().random.nextInt(20) == 0) {
getCorruption().add(1); getCorruption().add(entity.getRandom().nextBetween(1, 10));
} }
getCorruption().add((int)spell.getTraits().getCorruption()); getCorruption().add((int)spell.getTraits().getCorruption() * 10);
setDirty(); setDirty();
} }
} }

View file

@ -234,7 +234,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
// butterfingers effects // butterfingers effects
if (daysAttached >= 2) { if (daysAttached >= 2) {
if (pony.asWorld().random.nextInt(200) == 0 && !pony.asEntity().hasStatusEffect(UEffects.BUTTER_FINGERS)) { if (pony.asWorld().random.nextInt(200) == 0 && !pony.asEntity().hasStatusEffect(UEffects.BUTTER_FINGERS)) {
pony.asEntity().addStatusEffect(new StatusEffectInstance(UEffects.CORRUPT_INFLUENCE, 2100, 1)); pony.asEntity().addStatusEffect(new StatusEffectInstance(UEffects.BUTTER_FINGERS, 2100, 1));
} }
pony.findAllEntitiesInRange(10, e -> e instanceof LivingEntity && !((LivingEntity)e).hasStatusEffect(UEffects.CORRUPT_INFLUENCE)).forEach(e -> { pony.findAllEntitiesInRange(10, e -> e instanceof LivingEntity && !((LivingEntity)e).hasStatusEffect(UEffects.CORRUPT_INFLUENCE)).forEach(e -> {

View file

@ -57,7 +57,7 @@ public class BellItem extends Item implements ChargeableItem {
public ActionResult useOnEntity(ItemStack stack, PlayerEntity player, LivingEntity target, Hand hand) { public ActionResult useOnEntity(ItemStack stack, PlayerEntity player, LivingEntity target, Hand hand) {
player.setCurrentHand(hand); player.setCurrentHand(hand);
Pony pony = Pony.of(player); Pony pony = Pony.of(player);
pony.getCorruption().add(1); pony.getCorruption().add(1 + player.getRandom().nextBetween(1, 10));
pony.playSound(USounds.ITEM_GROGAR_BELL_USE, 0.4F, 0.2F); pony.playSound(USounds.ITEM_GROGAR_BELL_USE, 0.4F, 0.2F);
Living<?> targetLiving = target instanceof MobEntity || target instanceof PlayerEntity ? Living.getOrEmpty(target) Living<?> targetLiving = target instanceof MobEntity || target instanceof PlayerEntity ? Living.getOrEmpty(target)
.filter(living -> !(living instanceof Creature c && c.isDiscorded())) .filter(living -> !(living instanceof Creature c && c.isDiscorded()))
@ -79,7 +79,7 @@ public class BellItem extends Item implements ChargeableItem {
if (hasCharge(stack)) { if (hasCharge(stack)) {
pony.playSound(USounds.ITEM_GROGAR_BELL_CHARGE, 0.6F, 1); pony.playSound(USounds.ITEM_GROGAR_BELL_CHARGE, 0.6F, 1);
pony.getCorruption().add(1); pony.getCorruption().add(player.getRandom().nextBetween(1, 10));
if (offhandStack.getItem() instanceof ChargeableItem chargeable) { if (offhandStack.getItem() instanceof ChargeableItem chargeable) {
float maxChargeBy = chargeable.getMaxCharge() - ChargeableItem.getEnergy(offhandStack); float maxChargeBy = chargeable.getMaxCharge() - ChargeableItem.getEnergy(offhandStack);
float energyTransferred = Math.min(ChargeableItem.getEnergy(stack), maxChargeBy); float energyTransferred = Math.min(ChargeableItem.getEnergy(stack), maxChargeBy);

View file

@ -1547,6 +1547,7 @@
"unicopia.subtitle.pegasus.molt": "Pegasus loses feather", "unicopia.subtitle.pegasus.molt": "Pegasus loses feather",
"unicopia.subtitle.unicorn.teleport": "Magic pops", "unicopia.subtitle.unicorn.teleport": "Magic pops",
"unicopia.subtitle.player.wololo": "Wololo!", "unicopia.subtitle.player.wololo": "Wololo!",
"unicopia.subtitle.corrupt": "Magic Corrupts",
"unicopia.subtitle.entity.player.whistle": "Player whistles", "unicopia.subtitle.entity.player.whistle": "Player whistles",
"unicopia.subtitle.entity.player.kick": "Player kicks", "unicopia.subtitle.entity.player.kick": "Player kicks",
"unicopia.subtitle.magic_aura": "Magic humming", "unicopia.subtitle.magic_aura": "Magic humming",

View file

@ -108,6 +108,25 @@
"unicopia:heartbeat/heartbeat_1" "unicopia:heartbeat/heartbeat_1"
] ]
}, },
"entity.player.corrupt": {
"category": "ambient",
"subtitle": "unicopia.subtitle.corrupt",
"sounds": [
{ "name": "enchant/soulspeed/soulspeed1", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed2", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed3", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed4", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed5", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed6", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed7", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed8", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed9", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed10", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed11", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed12", "volume": 0.25 },
{ "name": "enchant/soulspeed/soulspeed13", "volume": 0.25 }
]
},
"ambient.wind.gust": { "ambient.wind.gust": {
"category": "ambient", "category": "ambient",
"subtitle": "unicopia.subtitle.wind_rush", "subtitle": "unicopia.subtitle.wind_rush",