mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Fixed certain race buffs and checks not accounting for worn amulets (or failing if wearing an amulet)
This commit is contained in:
parent
75a6912459
commit
76a7ecc3bb
32 changed files with 104 additions and 114 deletions
|
@ -5,7 +5,6 @@ import java.util.function.Predicate;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.entity.MagicImmune;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
|
@ -16,11 +15,13 @@ import net.minecraft.predicate.entity.EntityPredicates;
|
|||
|
||||
public interface EquinePredicates {
|
||||
Predicate<Entity> IS_PLAYER = e -> e instanceof PlayerEntity;
|
||||
Predicate<Entity> BAT = physicalRaceMatches(Race.BAT::equals);
|
||||
Predicate<Entity> CHANGELING = physicalRaceMatches(Race.CHANGELING::equals);
|
||||
|
||||
Predicate<Entity> RACE_INTERACT_WITH_CLOUDS = raceMatches(Race::canInteractWithClouds);
|
||||
|
||||
Predicate<Entity> PLAYER_EARTH = IS_PLAYER.and(ofRace(Race.EARTH));
|
||||
Predicate<Entity> PLAYER_BAT = IS_PLAYER.and(ofRace(Race.BAT)).or(physicalRaceMatches(Race.BAT::equals));
|
||||
Predicate<Entity> PLAYER_BAT = IS_PLAYER.and(BAT);
|
||||
Predicate<Entity> PLAYER_UNICORN = IS_PLAYER.and(raceMatches(Race::canCast));
|
||||
Predicate<Entity> PLAYER_CHANGELING = IS_PLAYER.and(ofRace(Race.CHANGELING));
|
||||
Predicate<Entity> PLAYER_PEGASUS = IS_PLAYER.and(e -> ((PlayerEntity)e).getAbilities().creativeMode || RACE_INTERACT_WITH_CLOUDS.test(e));
|
||||
|
@ -45,10 +46,10 @@ public interface EquinePredicates {
|
|||
}
|
||||
|
||||
static Predicate<Entity> raceMatches(Predicate<Race> predicate) {
|
||||
return e -> Equine.of(e).map(Equine::getSpecies).filter(predicate).isPresent();
|
||||
return e -> Equine.of(e).filter(pony -> pony.getCompositeRace().any(predicate)).isPresent();
|
||||
}
|
||||
|
||||
static Predicate<Entity> physicalRaceMatches(Predicate<Race> predicate) {
|
||||
return e -> Pony.of(e).map(Pony::getActualSpecies).filter(predicate).isPresent();
|
||||
return e -> Equine.of(e).filter(pony -> predicate.test(pony.getCompositeRace().physical())).isPresent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,6 +187,12 @@ public record Race (boolean canCast, FlightType flightType, boolean canUseEarth,
|
|||
}
|
||||
|
||||
public record Composite (Race physical, @Nullable Race pseudo) {
|
||||
public static Composite DEFAULT = new Composite(Race.HUMAN, null);
|
||||
|
||||
public Race collapsed() {
|
||||
return pseudo == null ? physical : pseudo;
|
||||
}
|
||||
|
||||
public boolean includes(Race race) {
|
||||
return physical == race || pseudo == race;
|
||||
}
|
||||
|
@ -194,6 +200,18 @@ public record Race (boolean canCast, FlightType flightType, boolean canUseEarth,
|
|||
public boolean any(Predicate<Race> test) {
|
||||
return test.test(physical) || (pseudo != null && test.test(pseudo));
|
||||
}
|
||||
|
||||
public boolean canUseEarth() {
|
||||
return any(Race::canUseEarth);
|
||||
}
|
||||
|
||||
public boolean canFly() {
|
||||
return any(Race::canFly);
|
||||
}
|
||||
|
||||
public boolean canCast() {
|
||||
return any(Race::canCast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@ public class Unicopia implements ModInitializer {
|
|||
public interface SidedAccess {
|
||||
Optional<Pony> getPony();
|
||||
|
||||
default Race getPlayerSpecies() {
|
||||
return getPony().map(Pony::getSpecies).orElse(Race.HUMAN);
|
||||
default Race.Composite getPlayerSpecies() {
|
||||
return getPony().map(Pony::getCompositeRace).orElse(Race.Composite.DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,8 +66,9 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
|
|||
}
|
||||
|
||||
public int getMaxPage() {
|
||||
if (maxPage < 0 || prevRace != player.getSpecies()) {
|
||||
prevRace = player.getSpecies();
|
||||
Race newRace = player.getCompositeRace().collapsed();
|
||||
if (maxPage < 0 || prevRace != newRace) {
|
||||
prevRace = newRace;
|
||||
maxPage = 0;
|
||||
for (AbilitySlot slot : AbilitySlot.values()) {
|
||||
maxPage = Math.max(maxPage, getStat(slot).getMaxPage() - 1);
|
||||
|
|
|
@ -127,7 +127,7 @@ public class EarthPonyStompAbility implements Ability<Hit> {
|
|||
double amount = (1.5F * player.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE).getValue() + heavyness * 0.4) / (float)(dist * 1.3F);
|
||||
|
||||
if (i instanceof PlayerEntity) {
|
||||
Race race = Pony.of((PlayerEntity)i).getSpecies();
|
||||
Race.Composite race = Pony.of((PlayerEntity)i).getCompositeRace();
|
||||
if (race.canUseEarth()) {
|
||||
amount /= 3;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class PegasusFlightToggleAbility implements Ability<Hit> {
|
|||
Identifier id = Abilities.REGISTRY.getId(this);
|
||||
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath()
|
||||
+ (player.getPhysics().isFlying() ? "_land" : "_takeoff")
|
||||
+ (player.getSpecies() == Race.CHANGELING ? "_changeling" : "")
|
||||
+ (player.getObservedSpecies() == Race.CHANGELING ? "_changeling" : "")
|
||||
+ ".png");
|
||||
}
|
||||
|
||||
|
|
|
@ -48,13 +48,13 @@ public interface AttractionUtils {
|
|||
return Pony.of(entity).map(pony -> {
|
||||
double force = 0.75;
|
||||
|
||||
if (pony.getSpecies().canUseEarth()) {
|
||||
if (pony.getCompositeRace().canUseEarth()) {
|
||||
force /= 2;
|
||||
|
||||
if (pony.asEntity().isSneaking()) {
|
||||
force /= 6;
|
||||
}
|
||||
} else if (pony.getSpecies().canFly()) {
|
||||
} else if (pony.getCompositeRace().canFly()) {
|
||||
force *= 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ public class SiphoningSpell extends AbstractAreaEffectSpell {
|
|||
if (e instanceof PlayerEntity) {
|
||||
Pony player = Pony.of((PlayerEntity)e);
|
||||
|
||||
Race race = player.getSpecies();
|
||||
Race.Composite race = player.getCompositeRace();
|
||||
|
||||
if (race.canCast()) {
|
||||
dealt /= 2;
|
||||
|
|
|
@ -83,7 +83,7 @@ public class CustomEventCriterion extends AbstractCriterion<CustomEventCriterion
|
|||
|
||||
public boolean test(String event, int count, ServerPlayerEntity player) {
|
||||
return this.event.equalsIgnoreCase(event)
|
||||
&& (races.isEmpty() || races.contains(Pony.of(player).getActualSpecies()))
|
||||
&& (races.isEmpty() || races.contains(Pony.of(player).getSpecies()))
|
||||
&& (flying == null || flying == Pony.of(player).getPhysics().isFlying())
|
||||
&& (repeatCount <= 0 || (count > 0 && count % repeatCount == 0));
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class RaceChangeCriterion extends AbstractCriterion<RaceChangeCriterion.C
|
|||
}
|
||||
|
||||
public boolean test(ServerPlayerEntity player) {
|
||||
return Pony.of(player).getActualSpecies() == race;
|
||||
return Pony.of(player).getSpecies() == race;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -77,7 +77,7 @@ public class BaseZapAppleLeavesBlock extends LeavesBlock implements TintedBlock
|
|||
|
||||
float delta = super.calcBlockBreakingDelta(state, player, world, pos);
|
||||
|
||||
if (Pony.of(player).getSpecies().canUseEarth()) {
|
||||
if (Pony.of(player).getCompositeRace().canUseEarth()) {
|
||||
delta *= 50;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class ZapAppleLogBlock extends PillarBlock {
|
|||
|
||||
float delta = super.calcBlockBreakingDelta(state, player, world, pos);
|
||||
|
||||
if (Pony.of(player).getSpecies().canUseEarth()) {
|
||||
if (Pony.of(player).getCompositeRace().canUseEarth()) {
|
||||
delta *= 50;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ZapBlock extends Block {
|
|||
|
||||
float delta = super.calcBlockBreakingDelta(state, player, world, pos);
|
||||
|
||||
if (Pony.of(player).getSpecies().canUseEarth()) {
|
||||
if (Pony.of(player).getCompositeRace().canUseEarth()) {
|
||||
delta *= 50;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package com.minelittlepony.unicopia.client.gui.spellbook;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.common.client.gui.Tooltip;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class ProfileTooltip {
|
||||
public static Tooltip get(Pony pony) {
|
||||
return () -> {
|
||||
return List.of(
|
||||
Text.literal(String.format("Level %d ", pony.getLevel().get() + 1)).append(pony.getActualSpecies().getDisplayName()).formatted(pony.getSpecies().getAffinity().getColor()),
|
||||
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("Experience: %d", (int)(pony.getMagicalReserves().getXp().getPercentFill() * 100))),
|
||||
Text.literal(String.format("Next level in: %dxp", 100 - (int)(pony.getMagicalReserves().getXp().getPercentFill() * 100)))
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
package com.minelittlepony.unicopia.client.gui.spellbook;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.common.client.gui.IViewRoot;
|
||||
import com.minelittlepony.common.client.gui.dimension.Bounds;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.client.gui.*;
|
||||
import com.minelittlepony.unicopia.entity.player.*;
|
||||
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||
|
@ -35,14 +38,21 @@ public class SpellbookProfilePageContent implements SpellbookChapterList.Content
|
|||
|
||||
screen.addDrawable(new SpellbookScreen.ImageButton(x, y, size, size))
|
||||
.getStyle()
|
||||
.setIcon(TribeButton.createSprite(pony.getActualSpecies(), 0, 0, size))
|
||||
.setTooltip(ProfileTooltip.get(pony));
|
||||
.setIcon(TribeButton.createSprite(pony.getSpecies(), 0, 0, size))
|
||||
.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("Mana: %d%%", (int)(pony.getMagicalReserves().getMana().getPercentFill() * 100))),
|
||||
Text.literal(String.format("Corruption: %d%%", (int)(pony.getCorruption().getScaled(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)))
|
||||
));
|
||||
|
||||
if (pony.getSpecies() != pony.getActualSpecies()) {
|
||||
Race inherited = pony.getCompositeRace().collapsed();
|
||||
if (inherited != pony.getSpecies()) {
|
||||
int halfSize = size / 2;
|
||||
screen.addDrawable(new SpellbookScreen.ImageButton(x + halfSize, y + halfSize, halfSize, halfSize))
|
||||
.getStyle()
|
||||
.setIcon(TribeButton.createSprite(pony.getSpecies(), 0, 0, halfSize));
|
||||
.setIcon(TribeButton.createSprite(inherited, 0, 0, halfSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ class SpeciesCommand {
|
|||
}
|
||||
|
||||
static int get(ServerCommandSource source, PlayerEntity player, boolean isSelf) {
|
||||
Race spec = Pony.of(player).getActualSpecies();
|
||||
Race spec = Pony.of(player).getSpecies();
|
||||
|
||||
String name = "commands.race.tell.";
|
||||
name += isSelf ? "self" : "other";
|
||||
|
|
|
@ -20,6 +20,10 @@ public interface Equine<T extends Entity> extends NbtSerialisable, Tickable, Pro
|
|||
|
||||
void setSpecies(Race race);
|
||||
|
||||
default Race.Composite getCompositeRace() {
|
||||
return new Race.Composite(getSpecies(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the beginning of an update cycle.
|
||||
*/
|
||||
|
|
|
@ -81,7 +81,7 @@ 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 player ? player : null)) {
|
||||
if (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);
|
||||
}
|
||||
|
|
|
@ -95,13 +95,13 @@ class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyabl
|
|||
energy.addPercent(-1);
|
||||
}
|
||||
|
||||
if (pony.getSpecies().canFly() && !pony.getPhysics().isFlying()) {
|
||||
if (pony.getCompositeRace().canFly() && !pony.getPhysics().isFlying()) {
|
||||
exhaustion.multiply(0.8F);
|
||||
} else {
|
||||
exhaustion.addPercent(-1);
|
||||
}
|
||||
|
||||
if (!pony.getSpecies().canFly() || !pony.getPhysics().isFlying()) {
|
||||
if (!pony.getCompositeRace().canFly() || !pony.getPhysics().isFlying()) {
|
||||
if (mana.getPercentFill() < 1 && mana.getShadowFill(1) <= mana.getPercentFill(1)) {
|
||||
mana.addPercent(MathHelper.clamp(1 + pony.getLevel().get(), 1, 50) / 4F);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ public class PlayerAttributes implements Tickable {
|
|||
private static final EntityAttributeModifier EARTH_PONY_STRENGTH =
|
||||
new EntityAttributeModifier(UUID.fromString("777a5505-521e-480b-b9d5-6ea54f259564"), "Earth Pony Strength", 0.6, Operation.MULTIPLY_TOTAL);
|
||||
private static final EntityAttributeModifier EARTH_PONY_MINING_SPEED =
|
||||
new EntityAttributeModifier(UUID.fromString("9fc9e269-152e-0b48-9bd5-564a546e59f2"), "Earth Pony Mining Speed", 0.4, Operation.MULTIPLY_TOTAL);
|
||||
new EntityAttributeModifier(UUID.fromString("9fc9e269-152e-0b48-9bd5-564a546e59f2"), "Earth Pony Mining Speed", 0.5, Operation.MULTIPLY_TOTAL);
|
||||
private static final EntityAttributeModifier EARTH_PONY_KNOCKBACK_RESISTANCE =
|
||||
new EntityAttributeModifier(UUID.fromString("79e269a8-03e8-b9d5-5853-e25fdcf6706d"), "Earth Pony Knockback Resistance", 2, Operation.ADDITION);
|
||||
new EntityAttributeModifier(UUID.fromString("79e269a8-03e8-b9d5-5853-e25fdcf6706d"), "Earth Pony Knockback Resistance", 6, Operation.ADDITION);
|
||||
|
||||
private static final EntityAttributeModifier PEGASUS_SPEED =
|
||||
new EntityAttributeModifier(UUID.fromString("9e2699fc-3b8d-4f71-9d2d-fb92ee19b4f7"), "Pegasus Speed", 0.2, Operation.MULTIPLY_TOTAL);
|
||||
|
@ -41,15 +41,18 @@ public class PlayerAttributes implements Tickable {
|
|||
@Override
|
||||
public void tick() {
|
||||
PlayerEntity entity = pony.asEntity();
|
||||
Race race = pony.getSpecies();
|
||||
Race.Composite race = pony.getCompositeRace();
|
||||
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, EARTH_PONY_KNOCKBACK_RESISTANCE, race.canUseEarth() && entity.isSneaking());
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_MOVEMENT_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_ATTACK_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
toggleAttribute(entity, UEntityAttributes.EXTENDED_REACH_DISTANCE, PEGASUS_REACH, race.canFly());
|
||||
toggleAttribute(entity, UEntityAttributes.EXTRA_MINING_SPEED, EARTH_PONY_MINING_SPEED, race.canUseEarth());
|
||||
boolean earth = race.canUseEarth();
|
||||
boolean flight = race.canFly();
|
||||
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_ATTACK_DAMAGE, EARTH_PONY_STRENGTH, earth);
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, earth);
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, EARTH_PONY_KNOCKBACK_RESISTANCE, earth && entity.isSneaking());
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_MOVEMENT_SPEED, PEGASUS_SPEED, flight);
|
||||
toggleAttribute(entity, EntityAttributes.GENERIC_ATTACK_SPEED, PEGASUS_SPEED, flight);
|
||||
toggleAttribute(entity, UEntityAttributes.EXTENDED_REACH_DISTANCE, PEGASUS_REACH, flight);
|
||||
toggleAttribute(entity, UEntityAttributes.EXTRA_MINING_SPEED, EARTH_PONY_MINING_SPEED, earth);
|
||||
}
|
||||
|
||||
private void toggleAttribute(PlayerEntity entity, EntityAttribute attribute, EntityAttributeModifier modifier, boolean enable) {
|
||||
|
|
|
@ -353,7 +353,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
descentRate = 0;
|
||||
ticksDiving = 0;
|
||||
|
||||
if (Abilities.RAINBOOM.canUse(pony.getActualSpecies()) && entity.isOnGround()) {
|
||||
if (Abilities.RAINBOOM.canUse(pony.getSpecies()) && entity.isOnGround()) {
|
||||
pony.getMagicalReserves().getCharge().set(0);
|
||||
}
|
||||
|
||||
|
@ -683,7 +683,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
SoundEmitter.playSoundAt(entity, USounds.AMBIENT_WIND_GUST, SoundCategory.AMBIENT, 3, 1);
|
||||
}
|
||||
|
||||
float weight = 1 + (EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, entity) * 0.8F) + (pony.getActualSpecies().canUseEarth() ? 1 : 0);
|
||||
float weight = 1 + (EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, entity) * 0.8F) + (pony.getCompositeRace().canUseEarth() ? 1 : 0);
|
||||
|
||||
velocity.add(WeatherConditions.getAirflow(entity.getBlockPos(), entity.getWorld()), 0.04F * effectStrength);
|
||||
velocity.add(Vec3d.fromPolar(
|
||||
|
|
|
@ -190,23 +190,11 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets this player's species as it appears when interacting physically with other players or the world.
|
||||
* This includes temporary race swaps due to illusions/shape shifting as well as artifacts that merely
|
||||
* grant the abilities of a race, such as the alicorn amulet.
|
||||
*
|
||||
* @deprecated Use {@link Pony#getCompositeRace()} or {@link Pony#getObservedSpecies()}
|
||||
* Gets this player's inherent species.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public Race getSpecies() {
|
||||
if (AmuletSelectors.ALICORN_AMULET.test(entity)) {
|
||||
return Race.ALICORN;
|
||||
}
|
||||
if (AmuletSelectors.UNICORN_AMULET.test(entity)) {
|
||||
return Race.UNICORN;
|
||||
}
|
||||
|
||||
return getObservedSpecies();
|
||||
return Race.fromName(entity.getDataTracker().get(RACE), Race.HUMAN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,30 +207,23 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
.map(AbstractDisguiseSpell::getDisguise)
|
||||
.map(EntityAppearance::getAppearance)
|
||||
.flatMap(Pony::of)
|
||||
.map(Pony::getActualSpecies)
|
||||
.orElseGet(this::getActualSpecies);
|
||||
.map(Pony::getSpecies)
|
||||
.orElseGet(this::getSpecies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the composite race that represents what this player is capable of.
|
||||
* Physical is the race they appear to have, whilst pseudo is the race who's abilities they have been granted by magical means.
|
||||
*/
|
||||
@Override
|
||||
public Race.Composite getCompositeRace() {
|
||||
Race observed = getObservedSpecies();
|
||||
return new Race.Composite(observed,
|
||||
return new Race.Composite(getObservedSpecies(),
|
||||
AmuletSelectors.UNICORN_AMULET.test(entity) ? Race.UNICORN
|
||||
: AmuletSelectors.ALICORN_AMULET.test(entity) ? Race.ALICORN
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin species of the player. This excludes any shapeshifting, illusions, or magic.
|
||||
*/
|
||||
public Race getActualSpecies() {
|
||||
return Race.fromName(entity.getDataTracker().get(RACE), Race.HUMAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpecies(Race race) {
|
||||
race = race.validate(entity);
|
||||
|
@ -575,7 +556,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
}
|
||||
|
||||
if (entity.hurtTime == 1 && getSpecies().canCast()) {
|
||||
if (entity.hurtTime == 1 && getCompositeRace().physical().canCast()) {
|
||||
corruption.add(1);
|
||||
setDirty();
|
||||
}
|
||||
|
@ -586,7 +567,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
Race currentRace = getActualSpecies();
|
||||
Race currentRace = getSpecies();
|
||||
if (!currentRace.isUnset()) {
|
||||
Race newRace = currentRace.validate(entity);
|
||||
|
||||
|
@ -596,16 +577,12 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
sendCapabilities();
|
||||
|
||||
//if (!isClient()) {
|
||||
// CrystalShardsEntity.infestBlock((ServerWorld)asWorld(), entity.getBlockPos().down());
|
||||
//}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeSeenBy(Entity entity) {
|
||||
if (entity instanceof HostileEntity hostile
|
||||
&& getActualSpecies() == Race.BAT
|
||||
&& getSpecies() == Race.BAT
|
||||
&& hostile.getTarget() != this.entity
|
||||
&& hostile.getAttacker() != this.entity
|
||||
&& entity.distanceTo(this.entity) > entity.getWidth()) {
|
||||
|
@ -659,7 +636,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
&& !cause.isOf(DamageTypes.THORNS)
|
||||
&& !cause.isOf(DamageTypes.FREEZE)) {
|
||||
|
||||
if (getSpecies().canUseEarth() && entity.isSneaking()) {
|
||||
if (getCompositeRace().canUseEarth() && entity.isSneaking()) {
|
||||
amount /= (cause.isOf(DamageTypes.MOB_PROJECTILE) ? 3 : 2) * (entity.getHealth() < 5 ? 3 : 1);
|
||||
|
||||
return Optional.of(amount);
|
||||
|
@ -692,7 +669,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
}
|
||||
|
||||
if (getSpecies().canFly() || (getSpecies().canUseEarth() && entity.isSneaking())) {
|
||||
if (getCompositeRace().canFly() || (getCompositeRace().canUseEarth() && entity.isSneaking())) {
|
||||
distance -= 5;
|
||||
}
|
||||
distance = Math.max(0, distance);
|
||||
|
@ -710,7 +687,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
protected void handleFall(float distance, float damageMultiplier, DamageSource cause) {
|
||||
super.handleFall(distance, damageMultiplier, cause);
|
||||
|
||||
if (getSpecies().canUseEarth() && entity.isSneaking()) {
|
||||
if (getCompositeRace().canUseEarth() && entity.isSneaking()) {
|
||||
double radius = distance / 10;
|
||||
if (radius > 0) {
|
||||
EarthPonyStompAbility.spawnEffectAround(entity, entity.getLandingPos(), radius, radius);
|
||||
|
@ -775,7 +752,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
public ActionResult canSleepNow() {
|
||||
if (asWorld().getGameRules().getBoolean(UGameRules.DO_NOCTURNAL_BAT_PONIES) && getActualSpecies().isNocturnal()) {
|
||||
if (asWorld().getGameRules().getBoolean(UGameRules.DO_NOCTURNAL_BAT_PONIES) && getSpecies().isNocturnal()) {
|
||||
return asWorld().isDay() ? ActionResult.SUCCESS : ActionResult.FAIL;
|
||||
}
|
||||
|
||||
|
@ -790,7 +767,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
@Override
|
||||
public void toSyncronisedNbt(NbtCompound compound) {
|
||||
super.toSyncronisedNbt(compound);
|
||||
compound.putString("playerSpecies", Race.REGISTRY.getId(getActualSpecies()).toString());
|
||||
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
|
||||
compound.putFloat("magicExhaustion", magicExhaustion);
|
||||
compound.putInt("ticksHanging", ticksHanging);
|
||||
BLOCK_POS.writeOptional("hangingPosition", compound, getHangingPosition());
|
||||
|
@ -843,7 +820,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
&& entity instanceof ServerPlayerEntity
|
||||
&& entity.getWorld().getGameRules().getBoolean(UGameRules.SWAP_TRIBE_ON_DEATH)
|
||||
&& oldPlayer.respawnRace.isUnset())
|
||||
|| oldPlayer.getActualSpecies().isUnset();
|
||||
|| oldPlayer.getSpecies().isUnset();
|
||||
|
||||
if (alive) {
|
||||
oldPlayer.getSpellSlot().stream(true).forEach(getSpellSlot()::put);
|
||||
|
@ -866,7 +843,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
}
|
||||
|
||||
setSpecies(oldPlayer.respawnRace != Race.UNSET && !alive ? oldPlayer.respawnRace : oldPlayer.getActualSpecies());
|
||||
setSpecies(oldPlayer.respawnRace != Race.UNSET && !alive ? oldPlayer.respawnRace : oldPlayer.getSpecies());
|
||||
getDiscoveries().copyFrom(oldPlayer.getDiscoveries(), alive);
|
||||
getPhysics().copyFrom(oldPlayer.getPhysics(), alive);
|
||||
if (!forcedSwap) {
|
||||
|
|
|
@ -138,7 +138,7 @@ public class BellItem extends Item implements ChargeableItem {
|
|||
if (living instanceof Pony pony) {
|
||||
amountDrawn = pony.getMagicalReserves().getMana().get() * 0.2F;
|
||||
pony.getMagicalReserves().getMana().multiply(0.8F);
|
||||
if (pony.getActualSpecies() == Race.CHANGELING) {
|
||||
if (pony.getSpecies() == Race.CHANGELING) {
|
||||
particleType = ParticleTypes.HEART;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -130,7 +130,7 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
|
|||
}
|
||||
});
|
||||
VecHelper.findInRange(entity, entity.getWorld(), entity.getPos(), 20, i -> {
|
||||
return i instanceof ItemEntity ie && isFillable(ie.getStack()) && Equine.of(i).filter(p -> p.getSpecies() == Race.CHANGELING).isPresent();
|
||||
return i instanceof ItemEntity ie && isFillable(ie.getStack()) && EquinePredicates.CHANGELING.test(i);
|
||||
}).forEach(i -> containers.add((ItemEntity)i));
|
||||
|
||||
int demand = outputs.size() + containers.stream().mapToInt(i -> i.getStack().getCount()).sum();
|
||||
|
|
|
@ -41,7 +41,7 @@ public interface EnchantmentUtil {
|
|||
}
|
||||
|
||||
static int getLuck(int baseline, LivingEntity entity) {
|
||||
boolean naturallyLucky = Living.getOrEmpty(entity).filter(c -> c.getSpecies().canUseEarth()).isPresent();
|
||||
boolean naturallyLucky = Living.getOrEmpty(entity).filter(c -> c.getCompositeRace().canUseEarth()).isPresent();
|
||||
if (naturallyLucky) {
|
||||
baseline += 15;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ abstract class MixinDamageSource {
|
|||
});
|
||||
|
||||
|
||||
Pony.of(entity).filter(e -> e.getSpecies().canFly()).ifPresent(pony -> {
|
||||
Pony.of(entity).filter(e -> e.getCompositeRace().canFly()).ifPresent(pony -> {
|
||||
if (pony.getPhysics().isFlying()) {
|
||||
info.setReturnValue(Text.translatable("death.attack.unicopia.generic.whilst_flying", info.getReturnValue()));
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ abstract class MixinFallLocation {
|
|||
return;
|
||||
}
|
||||
Pony.of(entity).ifPresent(pony -> {
|
||||
if (pony.getSpecies().canFly()) {
|
||||
if (pony.getCompositeRace().canFly()) {
|
||||
info.setReturnValue(new FallLocation(location.id() + ".pegasus"));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.block.PowderSnowBlock;
|
||||
|
@ -15,7 +14,7 @@ import net.minecraft.entity.Entity;
|
|||
abstract class MixinPowderSnowBlock {
|
||||
@Inject(method = "canWalkOnPowderSnow", at = @At("HEAD"), cancellable = true)
|
||||
private static void onCanWalkOnPowderSnow(Entity entity, CallbackInfoReturnable<Boolean> info) {
|
||||
if (Pony.of(entity).map(Pony::getSpecies).filter(Race::canFly).isPresent()) {
|
||||
if (Pony.of(entity).filter(pony -> pony.getCompositeRace().canFly()).isPresent()) {
|
||||
info.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHan
|
|||
at = @At(value = "FIELD", target = "net/minecraft/entity/player/PlayerEntity$SleepFailureReason.NOT_POSSIBLE_NOW:Lnet/minecraft/entity/player/PlayerEntity$SleepFailureReason;"),
|
||||
cancellable = true)
|
||||
private void onTrySleep(BlockPos pos, CallbackInfoReturnable<Either<PlayerEntity.SleepFailureReason, Unit>> info) {
|
||||
if (get().getActualSpecies().isNocturnal() && get().asWorld().getGameRules().getBoolean(UGameRules.DO_NOCTURNAL_BAT_PONIES)) {
|
||||
if (get().getSpecies().isNocturnal() && get().asWorld().getGameRules().getBoolean(UGameRules.DO_NOCTURNAL_BAT_PONIES)) {
|
||||
((PlayerEntity)this).sendMessage(Text.translatable("block.unicopia.bed.no_sleep.nocturnal"), true);
|
||||
|
||||
info.setReturnValue(Either.left(PlayerEntity.SleepFailureReason.OTHER_PROBLEM));
|
||||
|
|
|
@ -35,7 +35,7 @@ public interface Channel {
|
|||
static void bootstrap() {
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
Pony pony = Pony.of(handler.player);
|
||||
if (pony.getActualSpecies() == Race.UNSET) {
|
||||
if (pony.getSpecies() == Race.UNSET) {
|
||||
Race race = UnicopiaWorldProperties.forWorld(handler.player.getServerWorld()).getDefaultRace();
|
||||
if (!race.isPermitted(handler.player)) {
|
||||
race = Race.UNSET;
|
||||
|
|
|
@ -35,14 +35,14 @@ public record MsgRequestSpeciesChange (
|
|||
public void handle(ServerPlayerEntity sender) {
|
||||
Pony player = Pony.of(sender);
|
||||
|
||||
if (force || player.getActualSpecies().isUnset()) {
|
||||
if (force || player.getSpecies().isUnset()) {
|
||||
player.setSpecies(newRace.isPermitted(sender) ? newRace : UnicopiaWorldProperties.forWorld((ServerWorld)player.asWorld()).getDefaultRace());
|
||||
|
||||
if (force) {
|
||||
if (sender.getWorld().getGameRules().getBoolean(UGameRules.ANNOUNCE_TRIBE_JOINS)) {
|
||||
Text message = Text.translatable("respawn.reason.joined_new_tribe",
|
||||
sender.getDisplayName(),
|
||||
player.getActualSpecies().getDisplayName(), player.getActualSpecies().getAltDisplayName());
|
||||
player.getSpecies().getDisplayName(), player.getSpecies().getAltDisplayName());
|
||||
sender.getWorld().getPlayers().forEach(p -> {
|
||||
((ServerPlayerEntity)p).sendMessageToClient(message, false);
|
||||
});
|
||||
|
|
|
@ -33,7 +33,7 @@ public class NocturnalSleepManager extends SleepManager {
|
|||
if (world.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE) && world.getPlayers().stream()
|
||||
.filter(LivingEntity::isSleeping)
|
||||
.map(Pony::of)
|
||||
.map(Pony::getActualSpecies)
|
||||
.map(Pony::getSpecies)
|
||||
.noneMatch(Race::isDayurnal)) {
|
||||
world.setTimeOfDay(world.getLevelProperties().getTimeOfDay() - DAY_LENGTH + 13500);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class NocturnalSleepManager extends SleepManager {
|
|||
|
||||
return players.stream().filter(player -> {
|
||||
Pony pony = Pony.of(player);
|
||||
return (pony.getActualSpecies().isNocturnal() == world.isDay());
|
||||
return (pony.getSpecies().isNocturnal() == world.isDay());
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,8 +74,7 @@ public class MagicalDamageSource extends DamageSource {
|
|||
}
|
||||
|
||||
Text message = Text.translatable(basic, params.toArray());
|
||||
return Pony.of(target).filter(e -> e.getSpecies().canFly()).map(pony -> {
|
||||
|
||||
return Pony.of(target).filter(e -> e.getCompositeRace().canFly()).map(pony -> {
|
||||
if (pony.getPhysics().isFlying()) {
|
||||
return Text.translatable("death.attack.unicopia.generic.whilst_flying", message);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue