mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Added some enchantments suggested by kerplamp
This commit is contained in:
parent
ec50aadda3
commit
c61801b507
27 changed files with 880 additions and 19 deletions
|
@ -12,6 +12,8 @@ public interface USounds {
|
|||
SoundEvent BATPONY_EEEE = register("batpony_eeee");
|
||||
SoundEvent CHANGELING_BUZZ = register("changeling_buzz");
|
||||
|
||||
SoundEvent AURA = register("aura");
|
||||
|
||||
SoundEvent RECORD_CRUSADE = register("record.crusade");
|
||||
SoundEvent RECORD_PET = register("record.pet");
|
||||
SoundEvent RECORD_POPULAR = register("record.popular");
|
||||
|
|
|
@ -7,18 +7,23 @@ import net.minecraft.tag.Tag;
|
|||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface UTags {
|
||||
Tag<Item> APPLES = register("apples");
|
||||
Tag<Item> FESH_APPLES = register("fresh_apples");
|
||||
Tag<Item> APPLES = item("apples");
|
||||
Tag<Item> FESH_APPLES = item("fresh_apples");
|
||||
|
||||
Tag<Item> NON_TOXIC = register("non_toxic");
|
||||
Tag<Item> FAIRLY_TOXIC = register("fairly_toxic");
|
||||
Tag<Item> SEVERELY_TOXIC = register("severely_toxic");
|
||||
Tag<Item> NON_TOXIC = item("non_toxic");
|
||||
Tag<Item> FAIRLY_TOXIC = item("fairly_toxic");
|
||||
Tag<Item> SEVERELY_TOXIC = item("severely_toxic");
|
||||
|
||||
Tag<Block> FRAGILE = TagRegistry.block(new Identifier("unicopia", "fragile"));
|
||||
Tag<Block> FRAGILE = block("fragile");
|
||||
Tag<Block> INTERESTING = block("interesting");
|
||||
|
||||
static Tag<Item> register(String name) {
|
||||
static Tag<Item> item(String name) {
|
||||
return TagRegistry.item(new Identifier("unicopia", name));
|
||||
}
|
||||
|
||||
static Tag<Block> block(String name) {
|
||||
return TagRegistry.block(new Identifier("unicopia", name));
|
||||
}
|
||||
|
||||
static void bootstrap() { }
|
||||
}
|
||||
|
|
|
@ -6,12 +6,15 @@ import com.minelittlepony.unicopia.BlockDestructionManager;
|
|||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||
import com.minelittlepony.unicopia.util.PosHelper;
|
||||
import com.minelittlepony.unicopia.util.WorldEvent;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -80,19 +83,27 @@ public class EarthPonyStompAbility implements Ability<Hit> {
|
|||
iplayer.waitForFall(() -> {
|
||||
BlockPos center = PosHelper.findSolidGroundAt(player.getEntityWorld(), player.getBlockPos());
|
||||
|
||||
float heavyness = 1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, player);
|
||||
|
||||
iplayer.getWorld().getOtherEntities(player, areaOfEffect.offset(iplayer.getOriginVector())).forEach(i -> {
|
||||
double dist = Math.sqrt(center.getSquaredDistance(i.getBlockPos()));
|
||||
|
||||
if (dist <= rad + 3) {
|
||||
double force = dist / 5;
|
||||
double inertia = dist / 5;
|
||||
|
||||
if (i instanceof LivingEntity) {
|
||||
inertia *= 1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, (LivingEntity)i);
|
||||
}
|
||||
inertia /= heavyness;
|
||||
|
||||
i.addVelocity(
|
||||
-(player.getX() - i.getX()) / force,
|
||||
-(player.getY() - i.getY() - 2) / force + (dist < 1 ? dist : 0),
|
||||
-(player.getZ() - i.getZ()) / force);
|
||||
-(player.getX() - i.getX()) / inertia,
|
||||
-(player.getY() - i.getY() - 2) / inertia + (dist < 1 ? dist : 0),
|
||||
-(player.getZ() - i.getZ()) / inertia);
|
||||
|
||||
DamageSource damage = MagicalDamageSource.create("smash", player);
|
||||
|
||||
double amount = (4 * player.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE).getValue()) / (float)dist;
|
||||
double amount = (4 * player.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE).getValue() + heavyness * 0.4) / (float)dist;
|
||||
|
||||
if (i instanceof PlayerEntity) {
|
||||
Race race = Pony.of((PlayerEntity)i).getSpecies();
|
||||
|
@ -109,10 +120,12 @@ public class EarthPonyStompAbility implements Ability<Hit> {
|
|||
}
|
||||
});
|
||||
|
||||
BlockPos.iterate(center.add(-rad, -rad, -rad), center.add(rad, rad, rad)).forEach(i -> {
|
||||
double radius = rad + heavyness * 0.3;
|
||||
|
||||
BlockPos.iterate(center.add(-radius, -radius, -radius), center.add(radius, radius, radius)).forEach(i -> {
|
||||
double dist = Math.sqrt(i.getSquaredDistance(player.getX(), player.getY(), player.getZ(), true));
|
||||
|
||||
if (dist <= rad) {
|
||||
if (dist <= radius) {
|
||||
spawnEffect(player.world, i, dist);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -13,12 +13,14 @@ import com.minelittlepony.unicopia.ability.magic.Attached;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EyeOfEnderEntity;
|
||||
import net.minecraft.entity.FallingBlockEntity;
|
||||
|
@ -182,6 +184,10 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached {
|
|||
protected void applyForce(Vec3d pos, Entity target, double force, double distance) {
|
||||
pos = target.getPos().subtract(pos).normalize().multiply(force);
|
||||
|
||||
if (target instanceof LivingEntity) {
|
||||
pos = pos.multiply(1 / (1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, (LivingEntity)target)));
|
||||
}
|
||||
|
||||
target.addVelocity(
|
||||
pos.x,
|
||||
pos.y + (distance < 1 ? distance : 0),
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package com.minelittlepony.unicopia.client.sound;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.item.enchantment.SimpleEnchantment;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
|
||||
import net.minecraft.client.sound.MovingSoundInstance;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class MagicAuraSoundInstance extends MovingSoundInstance {
|
||||
|
||||
private final Living<?> living;
|
||||
|
||||
private float sourceVolume;
|
||||
private float targetVolume;
|
||||
private float interpolate;
|
||||
|
||||
private boolean fadingOut;
|
||||
|
||||
public MagicAuraSoundInstance(SoundCategory category, Living<?> living) {
|
||||
super(USounds.AURA, category);
|
||||
this.looping = true;
|
||||
this.repeat = true;
|
||||
this.living = living;
|
||||
this.volume = 0;
|
||||
setTargetVolume(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAlwaysPlay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
Optional<SimpleEnchantment.Data> data = living.getEnchants().getOrEmpty(UEnchantments.GEM_LOCATION);
|
||||
|
||||
Vec3d pos = living.getOriginVector();
|
||||
x = pos.x;
|
||||
y = pos.y;
|
||||
z = pos.z;
|
||||
|
||||
if (!living.getEntity().removed && data.isPresent()) {
|
||||
float level = data.get().level;
|
||||
if (level != targetVolume) {
|
||||
setTargetVolume(level);
|
||||
}
|
||||
} else {
|
||||
fadingOut = true;
|
||||
setTargetVolume(0);
|
||||
}
|
||||
|
||||
if (interpolate < 1) {
|
||||
interpolate = Math.min(interpolate + 0.4F, 1);
|
||||
volume = MathHelper.lerp(interpolate, sourceVolume, targetVolume);
|
||||
}
|
||||
|
||||
if (fadingOut && volume < 0.01F) {
|
||||
setDone();
|
||||
}
|
||||
}
|
||||
|
||||
private void setTargetVolume(float target) {
|
||||
sourceVolume = volume;
|
||||
targetVolume = target;
|
||||
interpolate = 0;
|
||||
}
|
||||
}
|
|
@ -6,10 +6,17 @@ import com.minelittlepony.unicopia.ability.magic.Affine;
|
|||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
|
||||
import com.minelittlepony.unicopia.entity.ai.WantItNeedItTargetGoal;
|
||||
import com.minelittlepony.unicopia.entity.ai.WantItTakeItGoal;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.goal.GoalSelector;
|
||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class Creature extends Living<LivingEntity> {
|
||||
|
@ -26,6 +33,16 @@ public class Creature extends Living<LivingEntity> {
|
|||
super(entity, EFFECT);
|
||||
}
|
||||
|
||||
public void initAi(GoalSelector goals, GoalSelector targets) {
|
||||
targets.add(1, new WantItNeedItTargetGoal((MobEntity)entity));
|
||||
goals.add(1, new WantItTakeItGoal((MobEntity)entity));
|
||||
}
|
||||
|
||||
public static void registerAttributes(DefaultAttributeContainer.Builder builder) {
|
||||
builder.add(EntityAttributes.GENERIC_ATTACK_DAMAGE);
|
||||
builder.add(EntityAttributes.GENERIC_ATTACK_KNOCKBACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Race getSpecies() {
|
||||
return Race.HUMAN;
|
||||
|
@ -55,6 +72,7 @@ public class Creature extends Living<LivingEntity> {
|
|||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
super.toNBT(compound);
|
||||
Spell effect = getSpell(true);
|
||||
|
||||
if (effect != null) {
|
||||
|
@ -65,6 +83,7 @@ public class Creature extends Living<LivingEntity> {
|
|||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
super.fromNBT(compound);
|
||||
if (compound.contains("effect")) {
|
||||
setSpell(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect")));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.item.enchantment.SimpleEnchantment;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Tickable;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class Enchantments implements NbtSerialisable, Tickable {
|
||||
|
||||
private final Living<?> entity;
|
||||
|
||||
private final Set<Enchantment> equippedEnchantments = new HashSet<>();
|
||||
|
||||
private final Map<Enchantment, SimpleEnchantment.Data> data = new HashMap<>();
|
||||
|
||||
Enchantments(Living<?> entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends SimpleEnchantment.Data> Optional<T> getOrEmpty(Enchantment enchantment) {
|
||||
return Optional.ofNullable((T)data.get(enchantment));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends SimpleEnchantment.Data> T computeIfAbsent(Enchantment enchantment, Supplier<T> factory) {
|
||||
return (T)data.computeIfAbsent(enchantment, e -> factory.get());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends SimpleEnchantment.Data> T remove(Enchantment enchantment) {
|
||||
return (T)data.remove(enchantment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
UEnchantments.REGISTRY.forEach(ench -> {
|
||||
int level = EnchantmentHelper.getEquipmentLevel(ench, entity.getMaster());
|
||||
|
||||
boolean active = level > 0;
|
||||
|
||||
if (active != equippedEnchantments.contains(ench)) {
|
||||
if (active) {
|
||||
equippedEnchantments.add(ench);
|
||||
ench.onEquipped(entity);
|
||||
} else {
|
||||
equippedEnchantments.remove(ench);
|
||||
ench.onUnequipped(entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (active) {
|
||||
ench.onUserTick(entity, level);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
ListTag list = new ListTag();
|
||||
equippedEnchantments.forEach(enchant -> {
|
||||
Identifier id = Registry.ENCHANTMENT.getId(enchant);
|
||||
if (id != null) {
|
||||
list.add(StringTag.of(id.toString()));
|
||||
}
|
||||
});
|
||||
compound.put("enchants", list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
equippedEnchantments.clear();
|
||||
if (compound.contains("enchants")) {
|
||||
compound.getList("enchants", 8).forEach(tag -> {
|
||||
Registry.ENCHANTMENT.getOrEmpty(new Identifier(tag.asString())).ifPresent(equippedEnchantments::add);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,6 +34,8 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
|
||||
private int invinsibilityTicks;
|
||||
|
||||
private final Enchantments enchants = new Enchantments(this);
|
||||
|
||||
protected Living(T entity, TrackedData<CompoundTag> effect) {
|
||||
this.entity = entity;
|
||||
this.effectDelegate = new EffectSync(this, effect);
|
||||
|
@ -58,6 +60,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
return effectDelegate;
|
||||
}
|
||||
|
||||
public Enchantments getEnchants() {
|
||||
return enchants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaster(T owner) {
|
||||
}
|
||||
|
@ -93,6 +99,8 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
if (getPhysics().isGravityNegative() && entity.getY() > entity.world.getHeight() + 64) {
|
||||
entity.damage(DamageSource.OUT_OF_WORLD, 4.0F);
|
||||
}
|
||||
|
||||
enchants.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,4 +160,14 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
spell.getDisguise().onImpact(this, distance, damageMultiplier);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
enchants.toNBT(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
enchants.fromNBT(compound);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.minelittlepony.unicopia.entity.ai;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.brain.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.sensor.Sensor;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
public class WantItNeedItSensor extends Sensor<LivingEntity> {
|
||||
|
||||
@Override
|
||||
public Set<MemoryModuleType<?>> getOutputMemoryModules() {
|
||||
return ImmutableSet.of(MemoryModuleType.ATTACK_TARGET, MemoryModuleType.VISIBLE_MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sense(ServerWorld world, LivingEntity entity) {
|
||||
entity.getBrain().getOptionalMemory(MemoryModuleType.VISIBLE_MOBS).ifPresent(targets -> {
|
||||
|
||||
Optional<LivingEntity> target = targets.stream()
|
||||
.filter(e -> (EnchantmentHelper.getEquipmentLevel(UEnchantments.DESIRED, e) * 10) >= entity.distanceTo(e))
|
||||
.findFirst();
|
||||
|
||||
entity.getBrain().remember(MemoryModuleType.ATTACK_TARGET, target);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.minelittlepony.unicopia.entity.ai;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.TargetPredicate;
|
||||
import net.minecraft.entity.ai.goal.Goal;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
|
||||
public class WantItNeedItTargetGoal extends Goal {
|
||||
|
||||
private final TargetPredicate predicate;
|
||||
|
||||
private final MobEntity mob;
|
||||
|
||||
private int interval;
|
||||
|
||||
public WantItNeedItTargetGoal(MobEntity mob) {
|
||||
this.predicate = new TargetPredicate()
|
||||
.setBaseMaxDistance(64)
|
||||
.setPredicate(WantItNeedItTargetGoal::canTarget);
|
||||
this.mob = mob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart() {
|
||||
if (interval-- <= 0) {
|
||||
interval = 20;
|
||||
Optional<LivingEntity> target = mob.world.getOtherEntities(mob, mob.getBoundingBox().expand(16, 16, 16),
|
||||
e -> e instanceof LivingEntity && predicate.test(mob, (LivingEntity)e))
|
||||
.stream()
|
||||
.map(e -> (LivingEntity)e)
|
||||
.sorted(Comparator.comparing((Entity e) -> mob.distanceTo(e)))
|
||||
.findFirst();
|
||||
|
||||
if (target.isPresent()) {
|
||||
mob.setTarget(target.get());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldContinue() {
|
||||
LivingEntity target = mob.getTarget();
|
||||
return target != null && mob.isTarget(target, TargetPredicate.DEFAULT);
|
||||
}
|
||||
|
||||
static boolean canTarget(LivingEntity e) {
|
||||
return EnchantmentHelper.getEquipmentLevel(UEnchantments.DESIRED, e) > 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package com.minelittlepony.unicopia.entity.ai;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.AwaitTickQueue;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.util.VecHelper;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.goal.Goal;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class WantItTakeItGoal extends Goal {
|
||||
|
||||
private final MobEntity mob;
|
||||
|
||||
@Nullable
|
||||
private LivingEntity target;
|
||||
@Nullable
|
||||
private ItemEntity item;
|
||||
|
||||
private int cooldown;
|
||||
|
||||
public WantItTakeItGoal(MobEntity mob) {
|
||||
this.mob = mob;
|
||||
this.setControls(EnumSet.of(Goal.Control.MOVE, Goal.Control.LOOK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart() {
|
||||
LivingEntity target = mob.getTarget();
|
||||
if (target == null || !WantItNeedItTargetGoal.canTarget(target)) {
|
||||
|
||||
Optional<ItemEntity> item = VecHelper.findInRange(mob, mob.world, mob.getPos(), 16,
|
||||
e -> !e.removed && e instanceof ItemEntity && EnchantmentHelper.getLevel(UEnchantments.DESIRED, ((ItemEntity)e).getStack()) > 0)
|
||||
.stream()
|
||||
.map(e -> (ItemEntity)e)
|
||||
.sorted(Comparator.comparing((Entity e) -> mob.distanceTo(e)))
|
||||
.findFirst();
|
||||
|
||||
if (item.isPresent()) {
|
||||
this.item = item.get();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.target = target;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldContinue() {
|
||||
return (target == null || (
|
||||
target.isAlive()
|
||||
&& WantItNeedItTargetGoal.canTarget(target)
|
||||
&& mob.squaredDistanceTo(target) <= 225))
|
||||
&& (item == null || item.isAlive())
|
||||
&& (!mob.getNavigation().isIdle() || canStart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
target = null;
|
||||
item = null;
|
||||
mob.getNavigation().stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (target == null && (item == null || item.removed)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity targetEntity = target == null ? item : target;
|
||||
|
||||
mob.getLookControl().lookAt(targetEntity, 30, 30);
|
||||
|
||||
double reach = mob.getWidth() * 2 * mob.getWidth() * 2;
|
||||
double distance = mob.squaredDistanceTo(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ());
|
||||
|
||||
double speed = 0.8D;
|
||||
|
||||
if (distance > reach && distance < 16) {
|
||||
speed = 1.33;
|
||||
} else if (distance < 225) {
|
||||
speed = 0.6;
|
||||
}
|
||||
speed *= 2;
|
||||
|
||||
ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, mob, 0.2F), mob, 1);
|
||||
|
||||
mob.getNavigation().startMovingTo(targetEntity, speed);
|
||||
|
||||
cooldown = Math.max(this.cooldown - 1, 0);
|
||||
if (distance <= reach) {
|
||||
if (target != null) {
|
||||
if (cooldown <= 0) {
|
||||
cooldown = 20;
|
||||
mob.tryAttack(target);
|
||||
|
||||
if (mob.world.random.nextInt(20) == 0) {
|
||||
for (EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
ItemStack stack = target.getEquippedStack(slot);
|
||||
if (EnchantmentHelper.getLevel(UEnchantments.DESIRED, stack) > 0) {
|
||||
target.equipStack(slot, ItemStack.EMPTY);
|
||||
AwaitTickQueue.scheduleTask(mob.world, w -> {
|
||||
mob.tryEquip(stack);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ItemStack stack = item.getStack();
|
||||
AwaitTickQueue.scheduleTask(mob.world, w -> {
|
||||
if (!item.removed) {
|
||||
mob.tryEquip(stack);
|
||||
mob.method_29499(item);
|
||||
mob.sendPickup(item, stack.getCount());
|
||||
item.remove();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,11 +6,13 @@ import com.minelittlepony.unicopia.USounds;
|
|||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
import com.minelittlepony.unicopia.util.MutableVector;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
import net.minecraft.entity.attribute.EntityAttributeInstance;
|
||||
|
@ -196,6 +198,12 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
|
||||
lastPos = new Vec3d(entity.getX(), 0, entity.getZ());
|
||||
|
||||
if (!entity.isOnGround()) {
|
||||
float heavyness = 1 - EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, entity) * 0.015F;
|
||||
velocity.x *= heavyness;
|
||||
velocity.z *= heavyness;
|
||||
}
|
||||
|
||||
entity.setVelocity(velocity.toImmutable());
|
||||
}
|
||||
|
||||
|
@ -245,12 +253,17 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
thrustScale *= 0.1889F;
|
||||
}
|
||||
|
||||
float heavyness = EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, player) / 6F;
|
||||
float thrustStrength = 0.135F * thrustScale;
|
||||
if (heavyness > 0) {
|
||||
thrustStrength /= heavyness;
|
||||
}
|
||||
|
||||
Vec3d direction = player.getRotationVec(1).normalize().multiply(thrustStrength);
|
||||
|
||||
velocity.x += direction.x;
|
||||
velocity.z += direction.z;
|
||||
velocity.y += (direction.y * 2.45 + Math.abs(direction.y) * 10) * getGravitySignum();
|
||||
velocity.y += (direction.y * 2.45 + Math.abs(direction.y) * 10) * getGravitySignum() - heavyness / 5F;
|
||||
|
||||
if (player.isSneaking()) {
|
||||
if (!isGravityNegative()) {
|
||||
|
@ -264,7 +277,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
}
|
||||
}
|
||||
|
||||
protected void applyTurbulance(Entity player, MutableVector velocity) {
|
||||
protected void applyTurbulance(PlayerEntity player, MutableVector velocity) {
|
||||
float glance = 360 * player.world.random.nextFloat();
|
||||
float forward = 0.015F * player.world.random.nextFloat() * player.world.getRainGradient(1);
|
||||
|
||||
|
@ -287,6 +300,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
}
|
||||
|
||||
forward = Math.min(forward, 7);
|
||||
forward /= 1 + (EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, player) * 0.8F);
|
||||
|
||||
velocity.x += - forward * MathHelper.sin((player.yaw + glance) * 0.017453292F);
|
||||
velocity.z += forward * MathHelper.cos((player.yaw + glance) * 0.017453292F);
|
||||
|
|
|
@ -276,10 +276,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
ticksHanging = 0;
|
||||
}
|
||||
|
||||
super.tick();
|
||||
|
||||
tickers.forEach(Tickable::tick);
|
||||
|
||||
super.tick();
|
||||
|
||||
if (dirty) {
|
||||
sendCapabilities(true);
|
||||
}
|
||||
|
@ -376,6 +376,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
super.toNBT(compound);
|
||||
compound.putString("playerSpecies", getSpecies().name());
|
||||
|
||||
compound.putFloat("magicExhaustion", magicExhaustion);
|
||||
|
@ -392,6 +393,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
super.fromNBT(compound);
|
||||
speciesPersisted = true;
|
||||
setSpecies(Race.fromName(compound.getString("playerSpecies")));
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.item.toxin.ToxicHolder;
|
||||
import com.minelittlepony.unicopia.item.toxin.Toxics;
|
||||
import com.minelittlepony.unicopia.item.toxin.UFoodComponents;
|
||||
|
@ -72,6 +73,7 @@ public interface UItems {
|
|||
|
||||
static void bootstrap() {
|
||||
Toxics.bootstrap();
|
||||
UEnchantments.bootstrap();
|
||||
URecipes.bootstrap();
|
||||
|
||||
FabricItemGroupBuilder.create(new Identifier("unicopia", "items")).appendItems(list -> {
|
||||
|
@ -81,7 +83,7 @@ public interface UItems {
|
|||
.map(Item::getDefaultStack)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}).icon(ZAP_APPLE::getDefaultStack).build();
|
||||
}).icon(EMPTY_JAR::getDefaultStack).build();
|
||||
|
||||
FabricItemGroupBuilder.create(new Identifier("unicopia", "horsefeed")).appendItems(list -> {
|
||||
list.addAll(Registry.ITEM.stream()
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package com.minelittlepony.unicopia.item.enchantment;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentTarget;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.attribute.EntityAttribute;
|
||||
import net.minecraft.entity.attribute.EntityAttributeInstance;
|
||||
import net.minecraft.entity.attribute.EntityAttributeModifier;
|
||||
|
||||
public class AttributedEnchantment extends SimpleEnchantment {
|
||||
|
||||
private final Map<EntityAttribute, IntFunction<EntityAttributeModifier>> modifiers = new HashMap<>();
|
||||
|
||||
protected AttributedEnchantment(Rarity rarity, EnchantmentTarget target, boolean cursed, int maxLevel, EquipmentSlot... slots) {
|
||||
super(rarity, target, cursed, maxLevel, slots);
|
||||
}
|
||||
|
||||
protected AttributedEnchantment(Rarity rarity, boolean cursed, int maxLevel, EquipmentSlot... slots) {
|
||||
super(rarity, cursed, maxLevel, slots);
|
||||
}
|
||||
|
||||
public AttributedEnchantment addModifier(EntityAttribute attribute, IntFunction<EntityAttributeModifier> modifierSupplier) {
|
||||
modifiers.put(attribute, modifierSupplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserTick(Living<?> user, int level) {
|
||||
if (shouldChangeModifiers(user, level)) {
|
||||
LivingEntity entity = user.getMaster();
|
||||
modifiers.forEach((attr, modifierSupplier) -> {
|
||||
EntityAttributeInstance instance = entity.getAttributeInstance(attr);
|
||||
|
||||
EntityAttributeModifier modifier = modifierSupplier.apply(level);
|
||||
|
||||
instance.removeModifier(modifier.getId());
|
||||
instance.addPersistentModifier(modifier);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnequipped(Living<?> user) {
|
||||
LivingEntity entity = user.getMaster();
|
||||
modifiers.forEach((attr, modifierSupplier) -> {
|
||||
EntityAttributeInstance instance = entity.getAttributeInstance(attr);
|
||||
|
||||
instance.tryRemoveModifier(modifierSupplier.apply(1).getId());
|
||||
});
|
||||
user.getEnchants().remove(this);
|
||||
}
|
||||
|
||||
protected boolean shouldChangeModifiers(Living<?> user, int level) {
|
||||
return user.getEnchants().computeIfAbsent(this, Data::new).update(level);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.minelittlepony.unicopia.item.enchantment;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.client.sound.MagicAuraSoundInstance;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.enchantment.EnchantmentTarget;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class GemFindingEnchantment extends SimpleEnchantment {
|
||||
|
||||
protected GemFindingEnchantment() {
|
||||
super(Rarity.RARE, EnchantmentTarget.DIGGER, false, 3, EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserTick(Living<?> user, int level) {
|
||||
int radius = 2 + (level * 2);
|
||||
|
||||
BlockPos origin = user.getOrigin();
|
||||
|
||||
float volume = BlockPos.findClosest(origin, radius, radius, pos -> user.getWorld().getBlockState(pos).isIn(UTags.INTERESTING))
|
||||
.map(p -> user.getOriginVector().squaredDistanceTo(p.getX(), p.getY(), p.getZ()))
|
||||
.map(find -> (1 - (MathHelper.sqrt(find) / radius)))
|
||||
.orElse(-1F);
|
||||
|
||||
volume = Math.max(volume, 0.04F);
|
||||
|
||||
user.getEnchants().computeIfAbsent(this, Data::new).level = volume * (1.3F + level * 0.3F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEquipped(Living<?> user) {
|
||||
if (user.isClient()) {
|
||||
MinecraftClient.getInstance().getSoundManager().play(new MagicAuraSoundInstance(user.getEntity().getSoundCategory(), user));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnequipped(Living<?> user) {
|
||||
user.getEnchants().remove(this).level = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.minelittlepony.unicopia.item.enchantment;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentTarget;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class SimpleEnchantment extends Enchantment {
|
||||
|
||||
private final boolean cursed;
|
||||
|
||||
private final boolean allItems;
|
||||
|
||||
private final int maxLevel;
|
||||
|
||||
protected SimpleEnchantment(Rarity rarity, EnchantmentTarget target, boolean cursed, int maxLevel, EquipmentSlot... slots) {
|
||||
super(rarity, target, slots);
|
||||
this.cursed = cursed;
|
||||
this.allItems = false;
|
||||
this.maxLevel = maxLevel;
|
||||
}
|
||||
|
||||
protected SimpleEnchantment(Rarity rarity, boolean cursed, int maxLevel, EquipmentSlot... slots) {
|
||||
super(rarity, EnchantmentTarget.VANISHABLE, slots); // vanishable includes breakable. It's the one that accepts the widest variety of items
|
||||
this.cursed = cursed;
|
||||
this.allItems = true;
|
||||
this.maxLevel = maxLevel;
|
||||
}
|
||||
|
||||
public void onUserTick(Living<?> user, int level) {
|
||||
|
||||
}
|
||||
|
||||
public void onEquipped(Living<?> user) {
|
||||
|
||||
}
|
||||
|
||||
public void onUnequipped(Living<?> user) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptableItem(ItemStack itemStack) {
|
||||
return allItems || super.isAcceptableItem(itemStack);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return maxLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursed() {
|
||||
return cursed;
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
public float level;
|
||||
|
||||
public boolean update(int level) {
|
||||
if (level == this.level) {
|
||||
return false;
|
||||
}
|
||||
this.level = level;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.minelittlepony.unicopia.item.enchantment;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
|
||||
public class StressfulEnchantment extends SimpleEnchantment {
|
||||
|
||||
protected StressfulEnchantment() {
|
||||
super(Rarity.COMMON, true, 3, EquipmentSlot.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserTick(Living<?> user, int level) {
|
||||
if (user instanceof Pony) {
|
||||
Bar bar = ((Pony)user).getMagicalReserves().getEnergy();
|
||||
float targetPercent = (level / (float)getMaxLevel()) * 0.5F;
|
||||
if (bar.getPercentFill() < targetPercent) {
|
||||
bar.add(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.minelittlepony.unicopia.item.enchantment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.Enchantment.Rarity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.attribute.EntityAttributeModifier;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
|
||||
import net.minecraft.enchantment.EnchantmentTarget;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public interface UEnchantments {
|
||||
|
||||
List<SimpleEnchantment> REGISTRY = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Makes a sound when there are interesting blocks in your area.
|
||||
*/
|
||||
Enchantment GEM_LOCATION = register("gem_location", new GemFindingEnchantment());
|
||||
|
||||
/**
|
||||
* Protects against wall collisions and earth pony attacks!
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
Enchantment PADDED = register("padded", new SimpleEnchantment(Rarity.COMMON, EnchantmentTarget.ARMOR, false, 3, EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET));
|
||||
|
||||
/**
|
||||
* Heavy players move more slowly but are less likely to be flung around wildly.
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
Enchantment HEAVY = register("heavy", new AttributedEnchantment(Rarity.COMMON, EnchantmentTarget.ARMOR_FEET, false, 4, EquipmentSlot.FEET))
|
||||
.addModifier(EntityAttributes.GENERIC_MOVEMENT_SPEED, level -> {
|
||||
// 1 -> 0.9
|
||||
// 2 -> 0.8
|
||||
// 3 -> 0.7
|
||||
return new EntityAttributeModifier(UUID.fromString("a3d5a94f-4c40-48f6-a343-558502a13e10"), "Heavyness", (1 - level/(float)10) - 1, Operation.MULTIPLY_TOTAL);
|
||||
});
|
||||
|
||||
/**
|
||||
* It's dangerous to go alone, take this!
|
||||
*
|
||||
* Weapons will become stronger the more allies you have around.
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
Enchantment COLLABORATOR = register("collaborator", new SimpleEnchantment(Rarity.COMMON, EnchantmentTarget.WEAPON, false, 1, EquipmentSlot.MAINHAND));
|
||||
|
||||
/**
|
||||
* I want it, I neeeed it!
|
||||
*
|
||||
* Mobs really want your candy. You'd better give it to them.
|
||||
*/
|
||||
Enchantment DESIRED = register("desired", new WantItNeedItEnchantment());
|
||||
|
||||
/**
|
||||
* Hahaha geddit?
|
||||
*
|
||||
* Random things happen.
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
Enchantment POISON_JOKE = register("poison_joke", new SimpleEnchantment(Rarity.COMMON, true, 3, EquipmentSlot.values()));
|
||||
|
||||
/**
|
||||
* Who doesn't like a good freakout?
|
||||
*/
|
||||
Enchantment STRESS = register("stress", new StressfulEnchantment());
|
||||
|
||||
static void bootstrap() { }
|
||||
|
||||
static <T extends SimpleEnchantment> T register(String name, T enchantment) {
|
||||
REGISTRY.add(enchantment);
|
||||
return Registry.register(Registry.ENCHANTMENT, new Identifier("unicopia", name), enchantment);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.minelittlepony.unicopia.item.enchantment;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
|
||||
public class WantItNeedItEnchantment extends SimpleEnchantment {
|
||||
|
||||
protected WantItNeedItEnchantment() {
|
||||
super(Rarity.VERY_RARE, true, 1, EquipmentSlot.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserTick(Living<?> user, int level) {
|
||||
if (user instanceof Creature && user.getWorld().random.nextInt(10) == 0) {
|
||||
ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, user.getEntity(), 0.2F), user.getEntity(), 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import com.minelittlepony.unicopia.entity.ItemWielder;
|
|||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -58,6 +59,11 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
|||
return caster;
|
||||
}
|
||||
|
||||
@Inject(method = "createLivingAttributes()Lnet/minecraft/entity/attribute/DefaultAttributeContainer$Builder;", at = @At("RETURN"))
|
||||
private static void onCreateAttributes(CallbackInfoReturnable<DefaultAttributeContainer.Builder> info) {
|
||||
Creature.registerAttributes(info.getReturnValue());
|
||||
}
|
||||
|
||||
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
||||
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
||||
if (get() instanceof Pony && horizontalCollision) {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.minelittlepony.unicopia.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.goal.GoalSelector;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
|
||||
@Mixin(MobEntity.class)
|
||||
abstract class MixinMobEntity extends LivingEntity implements PonyContainer<Equine<?>> {
|
||||
private MixinMobEntity() { super(null, null); }
|
||||
|
||||
@Shadow
|
||||
protected @Final GoalSelector goalSelector;
|
||||
@Shadow
|
||||
protected @Final GoalSelector targetSelector;
|
||||
|
||||
@Inject(method = "<init>()V", at = @At("RETURN"), remap = false)
|
||||
private void init(CallbackInfo info) {
|
||||
((Creature)get()).initAi(goalSelector, targetSelector);
|
||||
}
|
||||
}
|
|
@ -164,6 +164,14 @@
|
|||
"key.unicopia.hud_page_dn": "Hud Previous Page",
|
||||
"key.unicopia.hud_page_up": "Hud Next Page",
|
||||
|
||||
"enchantment.unicopia.gem_location": "Gem Locator",
|
||||
"enchantment.unicopia.padded": "Padded",
|
||||
"enchantment.unicopia.heavy": "Heavy",
|
||||
"enchantment.unicopia.collaborator": "Collaborator",
|
||||
"enchantment.unicopia.desired": "Want It Need It",
|
||||
"enchantment.unicopia.poison_joke": "Poisoned Joke",
|
||||
"enchantment.unicopia.stress": "Stressful",
|
||||
|
||||
"commands.race.success.self": "Your race has been updated",
|
||||
"commands.race.success.otherself": "%1$s changed race to %2$s",
|
||||
"commands.race.success.other": "Changed %1$s's race to %2$s",
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
"unicopia:wing/wing3"
|
||||
]
|
||||
},
|
||||
"aura": {
|
||||
"category": "player",
|
||||
"sounds": [
|
||||
"unicopia:aura/aura0"
|
||||
]
|
||||
},
|
||||
"batpony_eeee": {
|
||||
"category": "player",
|
||||
"subtitle": "unicopia.subtitle.batpony_eeee",
|
||||
|
|
BIN
src/main/resources/assets/unicopia/sounds/aura/aura0.ogg
Normal file
BIN
src/main/resources/assets/unicopia/sounds/aura/aura0.ogg
Normal file
Binary file not shown.
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"minecraft:coal_ore",
|
||||
"minecraft:iron_ore",
|
||||
"minecraft:gold_ore",
|
||||
"minecraft:emerald_ore",
|
||||
"minecraft:lapis_ore",
|
||||
"minecraft:diamond_ore",
|
||||
"minecraft:nether_gold_ore",
|
||||
"minecraft:nether_quartz_ore",
|
||||
"minecraft:sea_lantern",
|
||||
"minecraft:ender_chest",
|
||||
"minecraft:end_portal_frame",
|
||||
"minecraft:jukebox",
|
||||
"minecraft:spawner"
|
||||
]
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
"MixinItems",
|
||||
"MixinLivingEntity",
|
||||
"MixinMilkBucketItem",
|
||||
"MixinMobEntity",
|
||||
"MixinPersistentProjectileEntity",
|
||||
"MixinPlayerEntity",
|
||||
"MixinProjectileEntity",
|
||||
|
|
Loading…
Reference in a new issue