mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 07:17:58 +01:00
Merge branch '1.20.1' into 1.20.2
This commit is contained in:
commit
c608a33aea
1296 changed files with 3436 additions and 16506 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
|||
bin/
|
||||
build/
|
||||
run/
|
||||
generated/
|
||||
.classpath
|
||||
.project
|
||||
*.launch
|
||||
|
|
19
build.gradle
19
build.gradle
|
@ -27,7 +27,18 @@ archivesBaseName = project.name
|
|||
loom {
|
||||
mixin.defaultRefmapName = 'unicopia.mixin.refmap.json'
|
||||
accessWidenerPath = file('src/main/resources/unicopia.aw')
|
||||
runs {
|
||||
datagen {
|
||||
server()
|
||||
name "Data Generation"
|
||||
vmArg "-Dfabric-api.datagen"
|
||||
vmArg "-Dfabric-api.datagen.modid=unicopia"
|
||||
vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}"
|
||||
runDir "build/datagen"
|
||||
}
|
||||
}
|
||||
}
|
||||
//assemble.dependsOn(runDatagen)
|
||||
|
||||
reckon {
|
||||
scopeFromProp()
|
||||
|
@ -98,6 +109,14 @@ dependencies {
|
|||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
resources {
|
||||
srcDirs += [ "src/main/generated" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version.toString()
|
||||
|
||||
|
|
|
@ -35,11 +35,13 @@ public interface EquinePredicates {
|
|||
Predicate<Entity> IS_CASTER = e -> !e.isRemoved() && (e instanceof Caster || IS_PLAYER.test(e));
|
||||
Predicate<Entity> IS_PLACED_SPELL = e -> e instanceof Caster && !e.isRemoved();
|
||||
|
||||
Predicate<Entity> IS_MAGIC_IMMUNE = e -> (e instanceof MagicImmune || !(e instanceof LivingEntity))
|
||||
Predicate<Entity> IS_MAGIC_IMMUNE = EntityPredicates.VALID_ENTITY.negate()
|
||||
.or(EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.negate()
|
||||
.or(e -> (e instanceof MagicImmune || !(e instanceof LivingEntity))
|
||||
&& !(e instanceof ItemEntity)
|
||||
&& !(e instanceof ExperienceOrbEntity)
|
||||
&& !(e instanceof BoatEntity)
|
||||
&& !(e instanceof ProjectileEntity);
|
||||
&& !(e instanceof ProjectileEntity)));
|
||||
Predicate<Entity> EXCEPT_MAGIC_IMMUNE = IS_MAGIC_IMMUNE.negate();
|
||||
Predicate<Entity> VALID_LIVING_AND_NOT_MAGIC_IMMUNE = EntityPredicates.VALID_LIVING_ENTITY.and(EXCEPT_MAGIC_IMMUNE);
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface UConventionalTags {
|
||||
TagKey<Item> APPLES = item("apples");
|
||||
TagKey<Item> ACORNS = item("acorns");
|
||||
TagKey<Item> PINECONES = item("pinecones");
|
||||
TagKey<Item> PINEAPPLES = item("pineapples");
|
||||
TagKey<Item> BANANAS = item("bananas");
|
||||
TagKey<Item> STICKS = item("sticks");
|
||||
TagKey<Item> SEEDS = item("seeds");
|
||||
TagKey<Item> GRAIN = item("grain");
|
||||
TagKey<Item> NUTS = item("nuts");
|
||||
TagKey<Item> MUSHROOMS = item("mushrooms");
|
||||
TagKey<Item> MUFFINS = item("muffins");
|
||||
TagKey<Item> MANGOES = item("mangoes");
|
||||
TagKey<Item> OEATMEALS = item("oatmeals");
|
||||
|
||||
TagKey<Item> FRUITS = item("fruits");
|
||||
|
||||
TagKey<Item> COOKED_FISH = item("cooked_fish");
|
||||
|
||||
TagKey<Item> CROPS_PEANUTS = item("crops/peanuts");
|
||||
TagKey<Item> TOOL_KNIVES = item("tools/knives");
|
||||
|
||||
static TagKey<Item> item(String name) {
|
||||
return TagKey.of(RegistryKeys.ITEM, new Identifier("c", name));
|
||||
}
|
||||
|
||||
static TagKey<Block> block(String name) {
|
||||
return TagKey.of(RegistryKeys.BLOCK, new Identifier("c", name));
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import static net.minecraft.sound.SoundEvents.*;
|
|||
public interface USounds {
|
||||
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_HIPPOGRIFF_SCREECH = register("entity.player.hippogriff.screech");
|
||||
SoundEvent ENTITY_PLAYER_HIPPOGRIFF_PECK = ENTITY_CHICKEN_STEP;
|
||||
|
|
|
@ -11,7 +11,6 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
public interface UTags {
|
||||
TagKey<Item> APPLES = item("apples");
|
||||
TagKey<Item> FRESH_APPLES = item("fresh_apples");
|
||||
|
||||
TagKey<Item> FALLS_SLOWLY = item("falls_slowly");
|
||||
|
@ -27,16 +26,19 @@ public interface UTags {
|
|||
TagKey<Item> IS_DELIVERED_AGGRESSIVELY = item("is_delivered_aggressively");
|
||||
TagKey<Item> FLOATS_ON_CLOUDS = item("floats_on_clouds");
|
||||
TagKey<Item> COOLS_OFF_KIRINS = item("cools_off_kirins");
|
||||
TagKey<Item> LOOT_BUG_HIGH_VALUE_DROPS = item("loot_bug_high_value_drops");
|
||||
|
||||
TagKey<Item> SHELLS = item("food_types/shells");
|
||||
|
||||
TagKey<Item> POLEARMS = item("polearms");
|
||||
TagKey<Item> HORSE_SHOES = item("horse_shoes");
|
||||
TagKey<Item> APPLE_SEEDS = item("apple_seeds");
|
||||
|
||||
TagKey<Item> ACORNS = item("acorns");
|
||||
TagKey<Item> BASKETS = item("baskets");
|
||||
TagKey<Item> BADGES = item("badges");
|
||||
TagKey<Item> BED_SHEETS = item("bed_sheets");
|
||||
TagKey<Item> CLOUD_JARS = item("cloud_jars");
|
||||
|
||||
TagKey<Block> GLASS_PANES = block("glass_panes");
|
||||
TagKey<Block> GLASS_BLOCKS = block("glass_blocks");
|
||||
TagKey<Block> FRAGILE = block("fragile");
|
||||
TagKey<Block> INTERESTING = block("interesting");
|
||||
TagKey<Block> CATAPULT_IMMUNE = block("catapult_immune");
|
||||
|
@ -57,6 +59,28 @@ public interface UTags {
|
|||
|
||||
TagKey<DimensionType> HAS_NO_ATMOSPHERE = dimension("has_no_atmosphere");
|
||||
|
||||
interface Items {
|
||||
TagKey<Item> ZAP_LOGS = item("zap_logs");
|
||||
TagKey<Item> WAXED_ZAP_LOGS = item("waxed_zap_logs");
|
||||
TagKey<Item> PALM_LOGS = item("palm_logs");
|
||||
TagKey<Item> CLOUD_BEDS = item("cloud_beds");
|
||||
TagKey<Item> CLOUD_SLABS = item("cloud_slabs");
|
||||
TagKey<Item> CLOUD_STAIRS = item("cloud_stairs");
|
||||
TagKey<Item> CLOUD_BLOCKS = item("cloud_blocks");
|
||||
TagKey<Item> CHITIN_BLOCKS = item("chitin_blocks");
|
||||
}
|
||||
|
||||
interface Blocks {
|
||||
TagKey<Block> ZAP_LOGS = block("zap_logs");
|
||||
TagKey<Block> WAXED_ZAP_LOGS = block("waxed_zap_logs");
|
||||
TagKey<Block> PALM_LOGS = block("palm_logs");
|
||||
TagKey<Block> CLOUD_BEDS = block("cloud_beds");
|
||||
TagKey<Block> CLOUD_SLABS = block("cloud_slabs");
|
||||
TagKey<Block> CLOUD_STAIRS = block("cloud_stairs");
|
||||
TagKey<Block> CLOUD_BLOCKS = block("cloud_blocks");
|
||||
TagKey<Block> CHITIN_BLOCKS = block("chitin_blocks");
|
||||
}
|
||||
|
||||
static TagKey<Item> item(String name) {
|
||||
return TagKey.of(RegistryKeys.ITEM, Unicopia.id(name));
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ public class TimeChangeAbility implements Ability<Rot> {
|
|||
|
||||
@Override
|
||||
public boolean canUse(Race.Composite race) {
|
||||
return Ability.super.canUse(race) || race.pseudo() == Race.UNICORN;
|
||||
return canUse(race.physical()) || race.pseudo() == Race.UNICORN;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,7 +37,7 @@ public class UnicornCastingAbility extends AbstractSpellCastingAbility {
|
|||
|
||||
@Override
|
||||
public int getWarmupTime(Pony player) {
|
||||
return 20;
|
||||
return (int)(20 - Math.min(17F, player.getLevel().get() * 0.75F));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,9 @@ import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
|||
import com.minelittlepony.unicopia.util.Trace;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.LeavesBlock;
|
||||
import net.minecraft.block.PowderSnowBlock;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -48,12 +51,12 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
|||
|
||||
@Override
|
||||
public int getWarmupTime(Pony player) {
|
||||
return 20;
|
||||
return (int)(20 - Math.min(17F, player.getLevel().get() * 0.75F));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldownTime(Pony player) {
|
||||
return 50;
|
||||
return (int)(50 - Math.min(45F, player.getLevel().get() * 0.75F));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,8 +81,7 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
int maxDistance = player.asEntity().isCreative() ? 1000 : 100;
|
||||
|
||||
int maxDistance = (int)((player.asEntity().isCreative() ? 1000 : 100) + (player.getLevel().get() * 0.25F));
|
||||
|
||||
World w = player.asWorld();
|
||||
|
||||
|
@ -87,10 +89,16 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
|||
return trace.getBlockOrEntityPos().map(pos -> {
|
||||
final BlockPos originalPos = pos;
|
||||
|
||||
boolean airAbove = enterable(w, pos.up()) && enterable(w, pos.up(2));
|
||||
boolean originalPosHasSupport = exception(w, pos, player.asEntity());
|
||||
boolean originalPosValid = enterable(w, pos.up()) && enterable(w, pos.up(2));
|
||||
|
||||
if (exception(w, pos, player.asEntity())) {
|
||||
if (w.getBlockState(pos).isOf(Blocks.POWDER_SNOW) && !PowderSnowBlock.canWalkOnPowderSnow(player.asEntity())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (originalPosHasSupport) {
|
||||
final BlockPos p = pos;
|
||||
// offset to adjacent
|
||||
pos = trace.getSide().map(sideHit -> {
|
||||
if (player.asEntity().isSneaking()) {
|
||||
sideHit = sideHit.getOpposite();
|
||||
|
@ -100,15 +108,19 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
|||
}).orElse(pos);
|
||||
}
|
||||
|
||||
if (enterable(w, pos.down())) {
|
||||
pos = pos.down();
|
||||
|
||||
if (enterable(w, pos.down())) {
|
||||
if (!airAbove) {
|
||||
return null;
|
||||
if (pos.getX() != originalPos.getX() || pos.getZ() != originalPos.getZ()) {
|
||||
// check support
|
||||
int steps = 0;
|
||||
while (enterable(w, pos.down())) {
|
||||
pos = pos.down();
|
||||
if (++steps > 2) {
|
||||
if (originalPosValid) {
|
||||
pos = originalPos.up();
|
||||
break;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
pos = originalPos.up(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,11 +174,17 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
|||
participant.getZ() - Math.floor(participant.getZ())
|
||||
);
|
||||
|
||||
Vec3d dest = destination.vec().add(offset);
|
||||
|
||||
dest = new Vec3d(dest.x, getTargetYPosition(participant.getEntityWorld(), BlockPos.ofFloored(dest), ShapeContext.of(participant)), dest.z);
|
||||
|
||||
double yPos = getTargetYPosition(participant.getEntityWorld(), destination.pos(), ShapeContext.of(participant));
|
||||
Vec3d dest = new Vec3d(
|
||||
destination.x() + offset.getX(),
|
||||
yPos,
|
||||
destination.z() + offset.getZ()
|
||||
);
|
||||
participant.teleport(dest.x, dest.y, dest.z);
|
||||
if (participant.getWorld().getBlockCollisions(participant, participant.getBoundingBox()).iterator().hasNext()) {
|
||||
dest = destination.vec();
|
||||
participant.teleport(dest.x, participant.getY(), dest.z);
|
||||
}
|
||||
teleporter.subtractEnergyCost(distance);
|
||||
|
||||
participant.fallDistance /= distance;
|
||||
|
@ -183,7 +201,10 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
|||
|
||||
private boolean enterable(World w, BlockPos pos) {
|
||||
BlockState state = w.getBlockState(pos);
|
||||
return w.isAir(pos) || !state.isOpaque();
|
||||
if (StatePredicate.isFluid(state) || state.getBlock() instanceof LeavesBlock) {
|
||||
return false;
|
||||
}
|
||||
return w.isAir(pos) || !state.isOpaque() || !state.shouldSuffocate(w, pos);
|
||||
}
|
||||
|
||||
private boolean exception(World w, BlockPos pos, PlayerEntity player) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic;
|
|||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.MimicSpell;
|
||||
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_VISIBLE = spell -> spell != null && !spell.isHidden();
|
||||
|
||||
SpellPredicate<?> IS_CORRUPTING = spell -> spell.getAffinity() == Affinity.BAD;
|
||||
|
||||
default <Q extends Spell> SpellPredicate<Q> and(SpellPredicate<Q> predicate) {
|
||||
SpellPredicate<T> self = this;
|
||||
return s -> self.test(s) && predicate.test(s);
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.effect.*;
|
||||
import com.minelittlepony.unicopia.entity.damage.UDamageTypes;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleSpawner;
|
||||
import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect;
|
||||
|
@ -60,9 +59,7 @@ public class RainboomAbilitySpell extends AbstractSpell {
|
|||
}
|
||||
}
|
||||
|
||||
source.findAllEntitiesInRange(RADIUS)
|
||||
.filter(e -> !FriendshipBraceletItem.isComrade(source, e))
|
||||
.forEach(e -> {
|
||||
source.findAllEntitiesInRange(RADIUS, e -> !source.isOwnerOrFriend(e)).forEach(e -> {
|
||||
e.damage(source.damageOf(UDamageTypes.RAINBOOM, source), 6);
|
||||
});
|
||||
EFFECT_RANGE.translate(source.getOrigin()).getBlockPositions().forEach(pos -> {
|
||||
|
|
|
@ -7,11 +7,7 @@ import java.util.Optional;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -43,7 +39,7 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
|
|||
*
|
||||
* Returns the resulting projectile entity for customization (or null if on the client).
|
||||
*/
|
||||
public Optional<MagicProjectileEntity> throwProjectile(Caster<?> caster) {
|
||||
public Optional<MagicBeamEntity> throwProjectile(Caster<?> caster) {
|
||||
return throwProjectile(caster, 1);
|
||||
}
|
||||
|
||||
|
@ -52,33 +48,23 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
|
|||
*
|
||||
* Returns the resulting projectile entity for customization (or null if on the client).
|
||||
*/
|
||||
public Optional<MagicProjectileEntity> throwProjectile(Caster<?> caster, float divergance) {
|
||||
public Optional<MagicBeamEntity> throwProjectile(Caster<?> caster, float divergance) {
|
||||
World world = caster.asWorld();
|
||||
|
||||
Entity entity = caster.asEntity();
|
||||
|
||||
caster.playSound(USounds.SPELL_CAST_SHOOT, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
if (caster.isClient()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Spell s = spell.get().prepareForCast(caster, CastingMethod.STORED);
|
||||
if (s == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.ofNullable(spell.get().prepareForCast(caster, CastingMethod.STORED)).map(s -> {
|
||||
MagicBeamEntity projectile = new MagicBeamEntity(world, caster.asEntity(), divergance, s);
|
||||
|
||||
MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world);
|
||||
projectile.setPosition(entity.getX(), entity.getEyeY() - 0.1F, entity.getZ());
|
||||
projectile.setOwner(entity);
|
||||
projectile.setItem(UItems.GEMSTONE.getDefaultStack(spell.get().getType()));
|
||||
s.apply(projectile);
|
||||
projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, divergance);
|
||||
projectile.setNoGravity(true);
|
||||
configureProjectile(projectile, caster);
|
||||
world.spawnEntity(projectile);
|
||||
configureProjectile(projectile, caster);
|
||||
world.spawnEntity(projectile);
|
||||
|
||||
return Optional.of(projectile);
|
||||
return projectile;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
|
@ -42,15 +43,15 @@ public class CatapultSpell extends AbstractSpell implements ProjectileDelegate.B
|
|||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockHitResult hit) {
|
||||
if (!projectile.isClient() && projectile.canModifyAt(hit.getBlockPos())) {
|
||||
createBlockEntity(projectile.getWorld(), hit.getBlockPos(), e -> apply(projectile, e));
|
||||
if (!projectile.isClient() && projectile instanceof MagicBeamEntity source && source.canModifyAt(hit.getBlockPos())) {
|
||||
createBlockEntity(projectile.getWorld(), hit.getBlockPos(), e -> apply(source, e));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) {
|
||||
if (!projectile.isClient()) {
|
||||
apply(projectile, hit.getEntity());
|
||||
if (!projectile.isClient() && projectile instanceof MagicBeamEntity source) {
|
||||
apply(source, hit.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
|||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
@ -55,10 +56,10 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
|||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockHitResult hit) {
|
||||
if (!projectile.isClient()) {
|
||||
if (!projectile.isClient() && projectile instanceof MagicBeamEntity source) {
|
||||
BlockPos pos = hit.getBlockPos();
|
||||
projectile.getWorld().createExplosion(projectile, pos.getX(), pos.getY(), pos.getZ(), 3, ExplosionSourceType.NONE);
|
||||
toPlaceable().tick(projectile, Situation.BODY);
|
||||
toPlaceable().tick(source, Situation.BODY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.*;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
|
@ -48,6 +49,8 @@ public class DispellEvilSpell extends AbstractSpell implements ProjectileDelegat
|
|||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile) {
|
||||
tick(projectile, Situation.GROUND);
|
||||
if (projectile instanceof MagicBeamEntity source) {
|
||||
tick(source, Situation.GROUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,13 +45,11 @@ public class FireBoltSpell extends AbstractSpell implements HomingSpell,
|
|||
@Override
|
||||
public boolean tick(Caster<?> caster, Situation situation) {
|
||||
if (situation == Situation.PROJECTILE) {
|
||||
if (caster instanceof MagicProjectileEntity && getTraits().get(Trait.FOCUS) >= 50) {
|
||||
if (caster instanceof MagicProjectileEntity projectile && getTraits().get(Trait.FOCUS) >= 50) {
|
||||
caster.findAllEntitiesInRange(
|
||||
getTraits().get(Trait.FOCUS) - 49,
|
||||
EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.validTarget(this, caster))
|
||||
).findFirst().ifPresent(target -> {
|
||||
((MagicProjectileEntity)caster).setHomingTarget(target);
|
||||
});
|
||||
).findFirst().ifPresent(target -> projectile.setHomingTarget(target));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
|||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
import com.minelittlepony.unicopia.util.Weighted;
|
||||
|
@ -231,9 +232,10 @@ public class NecromancySpell extends AbstractAreaEffectSpell implements Projecti
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity source, BlockHitResult hit) {
|
||||
|
||||
// source.asWorld().createExplosion(source, hit.getPos().x, hit.getPos().y, hit.getPos().z, 3, ExplosionSourceType.MOB);
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockHitResult hit) {
|
||||
if (!(projectile instanceof MagicBeamEntity source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Shape affectRegion = new Sphere(false, 3);
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.minelittlepony.unicopia.ability.magic.Affine;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
|
||||
public class TargetSelecter {
|
||||
private final Map<UUID, Target> targets = new TreeMap<>();
|
||||
|
@ -46,7 +45,6 @@ public class TargetSelecter {
|
|||
public Stream<Entity> getEntities(Caster<?> source, double radius) {
|
||||
targets.values().removeIf(Target::tick);
|
||||
return source.findAllEntitiesInRange(radius)
|
||||
.filter(EntityPredicates.VALID_ENTITY)
|
||||
.filter(EquinePredicates.EXCEPT_MAGIC_IMMUNE)
|
||||
.filter(entity -> entity != source.asEntity() && checkAlliegance(spell, source, entity) && filter.test(source, entity))
|
||||
.map(i -> {
|
||||
|
|
|
@ -50,7 +50,7 @@ public class EdibleBlock extends HayBlock {
|
|||
static final BooleanProperty BOTTOM_SOUTH_WEST = BooleanProperty.of("bottom_south_west");
|
||||
|
||||
// [up/down][north/south][west/east]
|
||||
private static final BooleanProperty[] SEGMENTS = {
|
||||
public static final BooleanProperty[] SEGMENTS = {
|
||||
BOTTOM_NORTH_WEST,
|
||||
BOTTOM_NORTH_EAST,
|
||||
BOTTOM_SOUTH_WEST,
|
||||
|
|
|
@ -24,9 +24,9 @@ import net.minecraft.util.math.random.Random;
|
|||
import net.minecraft.world.*;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
|
||||
public class FruitBearingBlock extends LeavesBlock implements TintedBlock, Buckable {
|
||||
public class FruitBearingBlock extends LeavesBlock implements TintedBlock, Buckable, Fertilizable {
|
||||
public static final IntProperty AGE = Properties.AGE_25;
|
||||
public static final int WITHER_AGE = 15;
|
||||
public static final int MAX_AGE = 25;
|
||||
public static final EnumProperty<Stage> STAGE = EnumProperty.of("stage", Stage.class);
|
||||
|
||||
private final Supplier<Block> fruit;
|
||||
|
@ -41,7 +41,7 @@ public class FruitBearingBlock extends LeavesBlock implements TintedBlock, Bucka
|
|||
.allowsSpawning(BlockConstructionUtils::canSpawnOnLeaves)
|
||||
.suffocates(BlockConstructionUtils::never)
|
||||
.blockVision(BlockConstructionUtils::never));
|
||||
setDefaultState(getDefaultState().with(STAGE, Stage.IDLE));
|
||||
setDefaultState(getDefaultState().with(AGE, 0).with(STAGE, Stage.IDLE));
|
||||
this.overlay = overlay;
|
||||
this.fruit = fruit;
|
||||
this.rottenFruitSupplier = rottenFruitSupplier;
|
||||
|
@ -76,51 +76,81 @@ public class FruitBearingBlock extends LeavesBlock implements TintedBlock, Bucka
|
|||
}
|
||||
|
||||
if (world.getBaseLightLevel(pos, 0) > 8) {
|
||||
BlockSoundGroup group = getSoundGroup(state);
|
||||
int steps = FertilizableUtil.getGrowthSteps(world, pos, state, random);
|
||||
while (steps-- > 0) {
|
||||
if (!shouldAdvance(random)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state.get(STAGE) == Stage.FRUITING) {
|
||||
state = state.cycle(AGE);
|
||||
if (state.get(AGE) > 20) {
|
||||
state = state.with(AGE, 0).cycle(STAGE);
|
||||
}
|
||||
} else {
|
||||
state = state.with(AGE, 0).cycle(STAGE);
|
||||
}
|
||||
world.setBlockState(pos, state, Block.NOTIFY_ALL);
|
||||
state = cycleStage(state);
|
||||
BlockPos fruitPosition = pos.down();
|
||||
|
||||
Stage stage = state.get(STAGE);
|
||||
|
||||
if (stage == Stage.FRUITING && isPositionValidForFruit(state, pos)) {
|
||||
if (world.isAir(fruitPosition)) {
|
||||
world.setBlockState(fruitPosition, getPlacedFruitState(random), Block.NOTIFY_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
BlockState fruitState = world.getBlockState(fruitPosition);
|
||||
|
||||
if (stage == Stage.WITHERING && fruitState.isOf(fruit.get())) {
|
||||
if (world.random.nextInt(2) == 0) {
|
||||
Block.dropStack(world, fruitPosition, rottenFruitSupplier.get());
|
||||
} else {
|
||||
Block.dropStacks(fruitState, world, fruitPosition, fruitState.hasBlockEntity() ? world.getBlockEntity(fruitPosition) : null, null, ItemStack.EMPTY);
|
||||
switch (state.get(STAGE)) {
|
||||
case WITHERING:
|
||||
wither(state, world, pos, fruitPosition, world.getBlockState(fruitPosition));
|
||||
case BEARING:
|
||||
if (!fruitState.isOf(fruit.get())) {
|
||||
state = withStage(state, Stage.IDLE);
|
||||
}
|
||||
break;
|
||||
case FRUITING: {
|
||||
if (!isPositionValidForFruit(state, pos)) {
|
||||
state = withStage(state, Stage.IDLE);
|
||||
} else {
|
||||
state = grow(state, world, pos, fruitPosition, fruitState, random);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (world.removeBlock(fruitPosition, false)) {
|
||||
world.emitGameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Emitter.of(fruitState));
|
||||
}
|
||||
|
||||
world.playSound(null, pos, USounds.ITEM_APPLE_ROT, SoundCategory.BLOCKS, group.getVolume(), group.getPitch());
|
||||
default:
|
||||
}
|
||||
|
||||
world.setBlockState(pos, state, Block.NOTIFY_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected BlockState withStage(BlockState state, Stage stage) {
|
||||
return state.with(AGE, 0).with(STAGE, stage);
|
||||
}
|
||||
|
||||
private BlockState cycleStage(BlockState state) {
|
||||
state = state.cycle(AGE);
|
||||
if (state.get(AGE) == 0) {
|
||||
state = state.cycle(STAGE);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
protected BlockState grow(BlockState state, World world, BlockPos pos, BlockPos fruitPosition, BlockState fruitState, Random random) {
|
||||
if (world.isAir(fruitPosition)) {
|
||||
world.setBlockState(fruitPosition, getPlacedFruitState(random), Block.NOTIFY_ALL);
|
||||
return withStage(state, Stage.BEARING);
|
||||
}
|
||||
|
||||
if (!fruitState.isOf(fruit.get())) {
|
||||
return withStage(state, Stage.IDLE);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
protected void wither(BlockState state, World world, BlockPos pos, BlockPos fruitPosition, BlockState fruitState) {
|
||||
if (!fruitState.isOf(fruit.get())) {
|
||||
if (world.random.nextInt(2) == 0) {
|
||||
Block.dropStack(world, fruitPosition, rottenFruitSupplier.get());
|
||||
} else {
|
||||
Block.dropStacks(fruitState, world, fruitPosition, fruitState.hasBlockEntity() ? world.getBlockEntity(fruitPosition) : null, null, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
if (world.removeBlock(fruitPosition, false)) {
|
||||
world.emitGameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Emitter.of(fruitState));
|
||||
}
|
||||
|
||||
BlockSoundGroup group = getSoundGroup(state);
|
||||
world.playSound(null, pos, USounds.ITEM_APPLE_ROT, SoundCategory.BLOCKS, group.getVolume(), group.getPitch());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> onBucked(ServerWorld world, BlockState state, BlockPos pos) {
|
||||
world.setBlockState(pos, state.with(STAGE, Stage.IDLE).with(AGE, 0));
|
||||
|
@ -142,18 +172,42 @@ public class FruitBearingBlock extends LeavesBlock implements TintedBlock, Bucka
|
|||
return state.getRenderingSeed(pos) % 3 == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state) {
|
||||
return switch (state.get(STAGE)) {
|
||||
case FLOWERING -> world.isAir(pos.down());
|
||||
default -> !world.getBlockState(pos.down()).isOf(fruit.get());
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
||||
return isFertilizable(world, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
|
||||
state = state.cycle(AGE);
|
||||
if (state.get(AGE) == 0) {
|
||||
state = state.with(STAGE, switch (state.get(STAGE)) {
|
||||
case IDLE -> Stage.FLOWERING;
|
||||
case FLOWERING -> Stage.FRUITING;
|
||||
default -> Stage.FLOWERING;
|
||||
});
|
||||
}
|
||||
if (state.get(STAGE) == Stage.FRUITING && state.get(AGE) == 0) {
|
||||
state = grow(state, world, pos, pos.down(), world.getBlockState(pos.down()), random);
|
||||
}
|
||||
world.setBlockState(pos, state);
|
||||
}
|
||||
|
||||
public enum Stage implements StringIdentifiable {
|
||||
IDLE,
|
||||
FLOWERING,
|
||||
FRUITING,
|
||||
BEARING,
|
||||
WITHERING;
|
||||
|
||||
private static final Stage[] VALUES = values();
|
||||
|
||||
public Stage getNext() {
|
||||
return VALUES[(ordinal() + 1) % VALUES.length];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
|
|
|
@ -74,6 +74,18 @@ public class FruitBlock extends Block implements Buckable {
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
if (!newState.isOf(state.getBlock())) {
|
||||
BlockState leaves = world.getBlockState(pos.up());
|
||||
if (leaves.contains(FruitBearingBlock.STAGE)) {
|
||||
world.setBlockState(pos.up(), leaves.withIfExists(FruitBearingBlock.AGE, 0).with(FruitBearingBlock.STAGE, FruitBearingBlock.Stage.IDLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canAttachTo(BlockState state) {
|
||||
return state.isOf(stem);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
|
|||
this.progressionAge = progressionAge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntProperty getAgeProperty() {
|
||||
return super.getAgeProperty();
|
||||
}
|
||||
|
||||
public SegmentedCropBlock createNext(int progressionAge) {
|
||||
SegmentedCropBlock next = create(getMaxAge() - this.progressionAge, progressionAge, Settings.copy(this), seeds, () -> this, null);
|
||||
nextSegmentSupplier = () -> next;
|
||||
|
|
|
@ -40,7 +40,7 @@ import net.minecraft.world.WorldAccess;
|
|||
import net.minecraft.world.WorldView;
|
||||
|
||||
public class SlimePustuleBlock extends Block {
|
||||
private static final EnumProperty<Shape> SHAPE = EnumProperty.of("shape", Shape.class);
|
||||
public static final EnumProperty<Shape> SHAPE = EnumProperty.of("shape", Shape.class);
|
||||
private static final BooleanProperty POWERED = Properties.POWERED;
|
||||
private static final Direction[] DIRECTIONS = Arrays.stream(Direction.values())
|
||||
.filter(direction -> direction != Direction.UP)
|
||||
|
|
|
@ -32,9 +32,9 @@ public class ThornBlock extends ConnectingBlock implements EarthPonyGrowAbility.
|
|||
static final Collection<BooleanProperty> PROPERTIES = FACING_PROPERTIES.values();
|
||||
static final DirectionProperty FACING = Properties.FACING;
|
||||
static final int MAX_DISTANCE = 25;
|
||||
static final int MAX_AGE = 4;
|
||||
static final int MAX_AGE = Properties.AGE_4_MAX;
|
||||
static final IntProperty DISTANCE = IntProperty.of("distance", 0, MAX_DISTANCE);
|
||||
static final IntProperty AGE = IntProperty.of("age", 0, MAX_AGE);
|
||||
static final IntProperty AGE = Properties.AGE_4;
|
||||
|
||||
private final Supplier<Block> bud;
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ public interface UBlocks {
|
|||
SegmentedCropBlock OATS_CROWN = register("oats_crown", OATS_STEM.createNext(5));
|
||||
|
||||
Block PLUNDER_VINE = register("plunder_vine", new ThornBlock(Settings.create().mapColor(MapColor.DARK_CRIMSON).hardness(1).ticksRandomly().sounds(BlockSoundGroup.WOOD).pistonBehavior(PistonBehavior.DESTROY), () -> UBlocks.PLUNDER_VINE_BUD));
|
||||
Block PLUNDER_VINE_BUD = register("plunder_vine_bud", new ThornBudBlock(Settings.create().mapColor(MapColor.DARK_CRIMSON).hardness(1).nonOpaque().ticksRandomly().sounds(BlockSoundGroup.GRASS).pistonBehavior(PistonBehavior.DESTROY), PLUNDER_VINE.getDefaultState()));
|
||||
Block PLUNDER_VINE_BUD = register("plunder_vine_bud", new ThornBudBlock(Settings.create().mapColor(MapColor.DARK_CRIMSON).hardness(1).nonOpaque().ticksRandomly().noCollision().sounds(BlockSoundGroup.GRASS).pistonBehavior(PistonBehavior.DESTROY), PLUNDER_VINE.getDefaultState()));
|
||||
CuringJokeBlock CURING_JOKE = register("curing_joke", new CuringJokeBlock(UEffects.BUTTER_FINGERS, 7, AbstractBlock.Settings.create().mapColor(MapColor.PALE_PURPLE).noCollision().breakInstantly().sounds(BlockSoundGroup.GRASS).offset(AbstractBlock.OffsetType.XZ).pistonBehavior(PistonBehavior.DESTROY)));
|
||||
Block GOLD_ROOT = register("gold_root", new CarrotsBlock(AbstractBlock.Settings.create().mapColor(MapColor.GOLD).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP).pistonBehavior(PistonBehavior.DESTROY)) {
|
||||
@Override
|
||||
|
|
|
@ -12,6 +12,7 @@ import net.minecraft.block.ShapeContext;
|
|||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
|
@ -20,8 +21,8 @@ import net.minecraft.world.BlockView;
|
|||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
public class CloudPillarBlock extends CloudBlock {
|
||||
private static final BooleanProperty NORTH = BooleanProperty.of("north");
|
||||
private static final BooleanProperty SOUTH = BooleanProperty.of("south");
|
||||
private static final BooleanProperty NORTH = Properties.NORTH;
|
||||
private static final BooleanProperty SOUTH = Properties.SOUTH;
|
||||
private static final Map<Direction, BooleanProperty> DIRECTION_PROPERTIES = Map.of(
|
||||
Direction.UP, NORTH,
|
||||
Direction.DOWN, SOUTH
|
||||
|
|
|
@ -52,6 +52,7 @@ import net.minecraft.client.item.ModelPredicateProviderRegistry;
|
|||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
|
||||
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
|
@ -210,7 +211,6 @@ public interface URenderers {
|
|||
matrices.translate(0, 0.06, 0);
|
||||
}
|
||||
// GUI, FIXED, NONE - translate(0, 0, 0)
|
||||
//matrices.scale(0.5F, 0.5F, 0.5F);
|
||||
|
||||
float scale = 0.5F;
|
||||
matrices.scale(scale, scale, scale);
|
||||
|
@ -219,11 +219,16 @@ public interface URenderers {
|
|||
renderer.renderItem(appearance, mode, light, overlay, matrices, immediate, world, 0);
|
||||
matrices.pop();
|
||||
}
|
||||
renderer.renderItem(item.createAppearanceStack(stack, UItems.EMPTY_JAR), mode, light, OverlayTexture.DEFAULT_UV, matrices, vertices, world, 0);
|
||||
renderer.renderItem(UItems.EMPTY_JAR.getDefaultStack(), mode, light, overlay, matrices, vertices, world, 0);
|
||||
|
||||
if (mode == ModelTransformationMode.GUI) {
|
||||
if (vertices instanceof Immediate i) {
|
||||
i.draw();
|
||||
}
|
||||
|
||||
DiffuseLighting.enableGuiDepthLighting();
|
||||
}
|
||||
|
||||
matrices.push();
|
||||
}
|
||||
|
||||
|
|
|
@ -163,15 +163,15 @@ public class DismissSpellScreen extends GameGui {
|
|||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
copy.set(x, y, z, w);
|
||||
copy.mul(matrices.peek().getPositionMatrix());
|
||||
|
||||
var type = actualSpell.getType().withTraits(actualSpell.getTraits());
|
||||
|
||||
DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, 0xFFAAFF99);
|
||||
copy.set(mouseX - width * 0.5F - x * 0.5F, mouseY - height * 0.5F - y * 0.5F, 0, 0);
|
||||
|
||||
DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, actualSpell.getAffinity().getColor().getColorValue());
|
||||
DrawableUtil.renderItemIcon(context, actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(),
|
||||
copy.x - 8 + copy.z / 20F,
|
||||
copy.y - 8 + copy.z / 20F,
|
||||
x - 8 - copy.x * 0.2F,
|
||||
y - 8 - copy.y * 0.2F,
|
||||
1
|
||||
);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ 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.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.client.gui.*;
|
||||
import com.minelittlepony.unicopia.entity.player.*;
|
||||
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||
|
@ -43,7 +44,7 @@ public class SpellbookProfilePageContent implements SpellbookChapterList.Content
|
|||
.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("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("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 color = 0x10404000 | alpha;
|
||||
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, radius / 3, radius + 6, 0, DrawableUtil.TAU, color, false);
|
||||
|
|
|
@ -1,14 +1,38 @@
|
|||
package com.minelittlepony.unicopia.client.render;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface RenderLayerUtil {
|
||||
Identifier SHADOW_TEXTURE = new Identifier("textures/misc/shadow.png");
|
||||
|
||||
static Optional<Identifier> getTexture(RenderLayer layer) {
|
||||
if (layer instanceof RenderLayer.MultiPhase multiphase) {
|
||||
return multiphase.getPhases().texture.getId();
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
static void createUnionBuffer(Consumer<VertexConsumerProvider> action, VertexConsumerProvider vertices, Function<Identifier, RenderLayer> overlayFunction) {
|
||||
Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEffectVertexConsumers();
|
||||
action.accept(layer -> {
|
||||
Identifier texture = RenderLayerUtil.getTexture(layer).orElse(null);
|
||||
|
||||
if (texture == null || texture.equals(SHADOW_TEXTURE) || texture.equals(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE)) {
|
||||
return vertices.getBuffer(layer);
|
||||
}
|
||||
return VertexConsumers.union(
|
||||
vertices.getBuffer(layer),
|
||||
immediate.getBuffer(overlayFunction.apply(texture))
|
||||
);
|
||||
});
|
||||
immediate.draw();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package com.minelittlepony.unicopia.client.render;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.client.util.render.RenderLayerUtil;
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
|
@ -14,6 +12,7 @@ import com.minelittlepony.unicopia.entity.ItemImpl;
|
|||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.duck.LavaAffine;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -24,14 +23,13 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.vehicle.BoatEntity;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class WorldRenderDelegate {
|
||||
public static final WorldRenderDelegate INSTANCE = new WorldRenderDelegate();
|
||||
private static final Optional<Vec3d> RED_SKY_COLOR = Optional.of(new Vec3d(1, 0, 0));
|
||||
private static final Identifier SHADOW_TEXTURE = new Identifier("textures/misc/shadow.png");
|
||||
|
||||
private final EntityReplacementManager disguiseLookup = new EntityReplacementManager();
|
||||
private final EntityDisguiseRenderer disguiseRenderer = new EntityDisguiseRenderer(this);
|
||||
|
@ -72,23 +70,10 @@ public class WorldRenderDelegate {
|
|||
|
||||
if (MinecraftClient.getInstance().getResourceManager().getResource(frostingTexture).isPresent()) {
|
||||
recurseFrosting = true;
|
||||
|
||||
Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEffectVertexConsumers();
|
||||
|
||||
client.getEntityRenderDispatcher().render(entity, x, y, z, yaw, tickDelta, matrices, layer -> {
|
||||
|
||||
Identifier texture = RenderLayerUtil.getTexture(layer).orElse(null);
|
||||
|
||||
if (texture == null || texture.equals(SHADOW_TEXTURE)) {
|
||||
return vertices.getBuffer(layer);
|
||||
}
|
||||
return VertexConsumers.union(
|
||||
vertices.getBuffer(layer),
|
||||
immediate.getBuffer(RenderLayers.getEntityTranslucent(frostingTexture))
|
||||
);
|
||||
}, light);
|
||||
RenderLayerUtil.createUnionBuffer(c -> {
|
||||
client.getEntityRenderDispatcher().render(entity, x, y, z, yaw, tickDelta, matrices, c, light);
|
||||
}, vertices, texture -> RenderLayers.getEntityTranslucent(frostingTexture));
|
||||
recurseFrosting = false;
|
||||
immediate.draw();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -146,16 +131,9 @@ public class WorldRenderDelegate {
|
|||
if (!recurseMinion && pony instanceof Creature creature && creature.isMinion()) {
|
||||
try {
|
||||
recurseMinion = true;
|
||||
client.getEntityRenderDispatcher().render(creature.asEntity(), x, y, z, yaw, tickDelta, matrices, layer -> {
|
||||
return RenderLayerUtil.getTexture(layer)
|
||||
.filter(texture -> texture != PlayerScreenHandler.BLOCK_ATLAS_TEXTURE)
|
||||
.map(texture -> {
|
||||
return VertexConsumers.union(
|
||||
vertices.getBuffer(layer),
|
||||
vertices.getBuffer(RenderLayers.getMagicColored(texture, creature.isDiscorded() ? 0xCCFF0000 : 0xCC0000FF))
|
||||
);
|
||||
}).orElseGet(() -> vertices.getBuffer(layer));
|
||||
}, light);
|
||||
RenderLayerUtil.createUnionBuffer(c -> {
|
||||
client.getEntityRenderDispatcher().render(creature.asEntity(), x, y, z, yaw, tickDelta, matrices, c, light);
|
||||
}, vertices, texture -> RenderLayers.getMagicColored(texture, creature.isDiscorded() ? 0x33FF0000 : ColorHelper.getRainbowColor(creature.asEntity(), 25, 1) )); // 0x8800AA00
|
||||
return true;
|
||||
} catch (Throwable t) {
|
||||
Unicopia.LOGGER.error("Error whilst rendering minion", t);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.minelittlepony.unicopia.client.render.entity;
|
||||
|
||||
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import net.minecraft.client.model.Dilation;
|
||||
import net.minecraft.client.model.ModelData;
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
|
@ -23,7 +22,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class MagicBeamEntityRenderer extends EntityRenderer<MagicProjectileEntity> {
|
||||
public class MagicBeamEntityRenderer extends EntityRenderer<MagicBeamEntity> {
|
||||
private final Model model;
|
||||
|
||||
public MagicBeamEntityRenderer(EntityRendererFactory.Context ctx) {
|
||||
|
@ -32,17 +31,17 @@ public class MagicBeamEntityRenderer extends EntityRenderer<MagicProjectileEntit
|
|||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(MagicProjectileEntity entity) {
|
||||
public Identifier getTexture(MagicBeamEntity entity) {
|
||||
return PlayerScreenHandler.BLOCK_ATLAS_TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getBlockLight(MagicProjectileEntity entity, BlockPos pos) {
|
||||
protected int getBlockLight(MagicBeamEntity entity, BlockPos pos) {
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MagicProjectileEntity entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
|
||||
public void render(MagicBeamEntity entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
|
||||
if (entity.age < 2 && dispatcher.camera.getFocusedEntity().squaredDistanceTo(entity) < 8) {
|
||||
return;
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ public class MagicBeamEntityRenderer extends EntityRenderer<MagicProjectileEntit
|
|||
super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light);
|
||||
}
|
||||
|
||||
public class Model extends EntityModel<MagicProjectileEntity> {
|
||||
public class Model extends EntityModel<MagicBeamEntity> {
|
||||
|
||||
private final ModelPart part;
|
||||
|
||||
|
@ -89,7 +88,7 @@ public class MagicBeamEntityRenderer extends EntityRenderer<MagicProjectileEntit
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setAngles(MagicProjectileEntity entity, float limbAngle, float limbDistance, float customAngle, float headYaw, float headPitch) {
|
||||
public void setAngles(MagicBeamEntity entity, float limbAngle, float limbDistance, float customAngle, float headYaw, float headPitch) {
|
||||
part.pitch = headPitch;
|
||||
part.yaw = headYaw;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
package com.minelittlepony.unicopia.compat.ad_astra;
|
||||
|
||||
import com.minelittlepony.unicopia.mixin.ad_astra.MixinOxygenUtils;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.world.World;
|
||||
public final class OxygenUtils {
|
||||
public static OxygenApi API = entity -> false;
|
||||
|
||||
public interface OxygenUtils {
|
||||
boolean MOD_LOADED = FabricLoader.getInstance().isModLoaded("ad_astra");
|
||||
|
||||
static boolean entityHasOxygen(World world, LivingEntity entity) {
|
||||
if (MOD_LOADED) {
|
||||
return MixinOxygenUtils.entityHasOxygen(world, entity);
|
||||
}
|
||||
return false;
|
||||
public interface OxygenApi {
|
||||
boolean hasOxygen(Entity entity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public interface TrinketsDelegate {
|
|||
TrinketsDelegate EMPTY = new TrinketsDelegate() {};
|
||||
|
||||
static TrinketsDelegate getInstance(@Nullable LivingEntity entity) {
|
||||
if (!(entity instanceof PlayerEntity && hasTrinkets())) {
|
||||
if (!hasTrinkets() || (entity != null && !(entity instanceof PlayerEntity))) {
|
||||
return EMPTY;
|
||||
}
|
||||
return TrinketsDelegateImpl.INSTANCE;
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.minelittlepony.unicopia.compat.trinkets;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.minelittlepony.unicopia.entity.ItemTracker;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.item.WearableItem;
|
||||
|
||||
|
@ -30,6 +32,17 @@ public class UnicopiaTrinket implements Trinket {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(stack.getItem() instanceof ItemTracker.Trackable) && stack.getItem() instanceof Equipment q) {
|
||||
entity.playSound(q.getEquipSound(), 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnequip(ItemStack stack, SlotReference slot, LivingEntity entity) {
|
||||
if (stack.getItem() instanceof ItemTracker.Trackable t) {
|
||||
Living<?> l = Living.living(entity);
|
||||
t.onUnequipped(l, l.getArmour().forceRemove(t));
|
||||
}
|
||||
if (stack.getItem() instanceof Equipment q) {
|
||||
entity.playSound(q.getEquipSound(), 1, 1);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.minelittlepony.unicopia.datagen;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import net.minecraft.data.DataOutput.PathResolver;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.DataWriter;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class DataCollector {
|
||||
private final HashMap<Identifier, Supplier<JsonElement>> values = new HashMap<>();
|
||||
|
||||
private final PathResolver resolver;
|
||||
|
||||
public DataCollector(PathResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public BiConsumer<Identifier, Supplier<JsonElement>> prime() {
|
||||
values.clear();
|
||||
return (Identifier id, Supplier<JsonElement> value) ->
|
||||
Preconditions.checkState(values.put(id, value) == null, "Duplicate model definition for " + id);
|
||||
}
|
||||
|
||||
public CompletableFuture<?> upload(DataWriter cache) {
|
||||
return CompletableFuture.allOf(values.entrySet()
|
||||
.stream()
|
||||
.map(entry -> DataProvider.writeToPath(cache, entry.getValue().get(), resolver.resolveJson(entry.getKey())))
|
||||
.toArray(CompletableFuture[]::new)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.minelittlepony.unicopia.datagen;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.UBlockTagProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.UItemTagProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.UModelProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.URecipeProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider;
|
||||
import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider;
|
||||
import com.minelittlepony.unicopia.server.world.UWorldGen;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.minecraft.registry.RegistryBuilder;
|
||||
import net.minecraft.registry.RegistryEntryLookup;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.world.biome.OverworldBiomeCreator;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
|
||||
public class Datagen implements DataGeneratorEntrypoint {
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
|
||||
final FabricDataGenerator.Pack pack = fabricDataGenerator.createPack();
|
||||
|
||||
UBlockTagProvider blockTags = pack.addProvider(UBlockTagProvider::new);
|
||||
pack.addProvider((output, registries) -> new UItemTagProvider(output, registries, blockTags));
|
||||
|
||||
pack.addProvider(UModelProvider::new);
|
||||
pack.addProvider(URecipeProvider::new);
|
||||
pack.addProvider(UBlockLootTableProvider::new);
|
||||
pack.addProvider(UBlockAdditionsLootTableProvider::new);
|
||||
pack.addProvider(UChestAdditionsLootTableProvider::new);
|
||||
pack.addProvider(SeasonsGrowthRatesProvider::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildRegistry(RegistryBuilder builder) {
|
||||
builder.addRegistry(RegistryKeys.BIOME, registerable -> {
|
||||
RegistryEntryLookup<PlacedFeature> placedFeatureLookup = registerable.getRegistryLookup(RegistryKeys.PLACED_FEATURE);
|
||||
RegistryEntryLookup<ConfiguredCarver<?>> carverLookup = registerable.getRegistryLookup(RegistryKeys.CONFIGURED_CARVER);
|
||||
registerable.register(UWorldGen.SWEET_APPLE_ORCHARD, OverworldBiomeCreator.createNormalForest(placedFeatureLookup, carverLookup, false, false, false));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.minelittlepony.unicopia.datagen;
|
||||
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
public interface ItemFamilies {
|
||||
Item[] MUSIC_DISCS = {
|
||||
UItems.MUSIC_DISC_CRUSADE, UItems.MUSIC_DISC_FUNK, UItems.MUSIC_DISC_PET, UItems.MUSIC_DISC_POPULAR
|
||||
};
|
||||
Item[] POLEARMS = {
|
||||
UItems.WOODEN_POLEARM, UItems.STONE_POLEARM, UItems.IRON_POLEARM, UItems.GOLDEN_POLEARM, UItems.DIAMOND_POLEARM, UItems.NETHERITE_POLEARM
|
||||
};
|
||||
Item[] HORSE_SHOES = {
|
||||
UItems.IRON_HORSE_SHOE, UItems.GOLDEN_HORSE_SHOE, UItems.COPPER_HORSE_SHOE, UItems.NETHERITE_HORSE_SHOE
|
||||
};
|
||||
Item[] BASKETS = {
|
||||
UItems.ACACIA_BASKET, UItems.BAMBOO_BASKET, UItems.BIRCH_BASKET, UItems.CHERRY_BASKET, UItems.DARK_OAK_BASKET,
|
||||
UItems.JUNGLE_BASKET, UItems.MANGROVE_BASKET, UItems.OAK_BASKET, UItems.PALM_BASKET, UItems.SPRUCE_BASKET
|
||||
};
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.minelittlepony.unicopia.datagen;
|
||||
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
|
||||
import net.minecraft.data.family.BlockFamily;
|
||||
|
||||
public interface UBlockFamilies {
|
||||
BlockFamily PALM = new BlockFamily.Builder(UBlocks.PALM_PLANKS)
|
||||
.slab(UBlocks.PALM_SLAB).stairs(UBlocks.PALM_STAIRS).fence(UBlocks.PALM_FENCE).fenceGate(UBlocks.PALM_FENCE_GATE)
|
||||
.button(UBlocks.PALM_BUTTON).pressurePlate(UBlocks.PALM_PRESSURE_PLATE).sign(UBlocks.PALM_SIGN, UBlocks.PALM_WALL_SIGN)
|
||||
.door(UBlocks.PALM_DOOR).trapdoor(UBlocks.PALM_TRAPDOOR)
|
||||
.group("wooden").unlockCriterionName("has_planks")
|
||||
.build();
|
||||
BlockFamily ZAP = new BlockFamily.Builder(UBlocks.ZAP_PLANKS)
|
||||
.slab(UBlocks.ZAP_SLAB).stairs(UBlocks.ZAP_STAIRS).fence(UBlocks.ZAP_FENCE).fenceGate(UBlocks.ZAP_FENCE_GATE)
|
||||
.group("wooden").unlockCriterionName("has_planks")
|
||||
.build();
|
||||
BlockFamily WAXED_ZAP = new BlockFamily.Builder(UBlocks.WAXED_ZAP_PLANKS)
|
||||
.slab(UBlocks.WAXED_ZAP_SLAB).stairs(UBlocks.WAXED_ZAP_STAIRS).fence(UBlocks.WAXED_ZAP_FENCE).fenceGate(UBlocks.WAXED_ZAP_FENCE_GATE)
|
||||
.group("wooden").unlockCriterionName("has_planks")
|
||||
.build();
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.client.Model;
|
||||
import net.minecraft.data.client.ModelIds;
|
||||
import net.minecraft.data.client.Models;
|
||||
import net.minecraft.data.client.TextureKey;
|
||||
import net.minecraft.data.client.TextureMap;
|
||||
import net.minecraft.data.client.TexturedModel;
|
||||
import net.minecraft.data.client.VariantSettings;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
|
||||
public interface BlockModels {
|
||||
TextureKey SHELL = TextureKey.of("shell");
|
||||
TextureKey STEP = TextureKey.of("step");
|
||||
|
||||
Model FRUIT = block("fruit", TextureKey.CROSS);
|
||||
Model STRAIGHT_STAIRS = block("seethrough_stairs", TextureKey.BOTTOM, TextureKey.TOP, TextureKey.SIDE, STEP);
|
||||
Model INNER_STAIRS = block("inner_seethrough_stairs", "_inner", TextureKey.BOTTOM, TextureKey.TOP, TextureKey.SIDE, STEP);
|
||||
Model OUTER_STAIRS = block("outer_seethrough_stairs", "_outer", TextureKey.BOTTOM, TextureKey.TOP, TextureKey.SIDE, STEP);
|
||||
Model DOOR_LEFT = block("door_left", TextureKey.BOTTOM, TextureKey.TOP);
|
||||
Model DOOR_RIGHT = block("door_right", TextureKey.BOTTOM, TextureKey.TOP);
|
||||
Model TEMPLATE_PILLAR = block("template_pillar", TextureKey.SIDE);
|
||||
Model TEMPLATE_PILLAR_END = block("template_pillar_end", "_end", TextureKey.BOTTOM, TextureKey.TOP, TextureKey.END);
|
||||
|
||||
Factory CROP = Factory.of(TextureMap::crop, Models.CROP);
|
||||
Factory CUBE_ALL = Factory.of(TextureMap::all, Models.CUBE_ALL);
|
||||
TexturedModel.Factory SPIKES = TexturedModel.makeFactory(b -> TextureMap.crop(ModelIds.getBlockModelId(b)), Models.CROP);
|
||||
|
||||
String[] FLATTENED_MODEL_SUFFEXES = {"xyz", "yz", "xy", "y", "xz", "z", "x", "full"};
|
||||
String[] FLATTENED_MODEL_SUFFEXES_ROT = {"xyz", "xy", "yz", "y", "xz", "x", "z", "full"};
|
||||
VariantSettings.Rotation[] FLATTENED_MODEL_ROTATIONS = {
|
||||
VariantSettings.Rotation.R0, VariantSettings.Rotation.R270, VariantSettings.Rotation.R90, VariantSettings.Rotation.R180,
|
||||
VariantSettings.Rotation.R270, VariantSettings.Rotation.R180, VariantSettings.Rotation.R0, VariantSettings.Rotation.R90
|
||||
};
|
||||
|
||||
Model[] FLATTENED_MODELS = Arrays.stream(FLATTENED_MODEL_SUFFEXES)
|
||||
.map(variant -> block("flattened_corner_" + variant, "_corner_" + variant, TextureKey.ALL))
|
||||
.toArray(Model[]::new);
|
||||
Model[] SHELL_MODELS = IntStream.range(1, 5)
|
||||
.mapToObj(i -> block("template_shell_" + i, "_" + i, SHELL))
|
||||
.toArray(Model[]::new);
|
||||
Model[] PIE_MODELS = Stream.of("_full", "_elbow", "_straight", "_corner")
|
||||
.map(variant -> block("pie" + variant, variant, TextureKey.TOP, TextureKey.BOTTOM, TextureKey.SIDE, TextureKey.INSIDE))
|
||||
.toArray(Model[]::new);
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<Model, String>[] BALE_MODELS = Stream.of("bnw", "bne", "bsw", "bse", "tnw", "tne", "tsw", "tse")
|
||||
.map(suffex -> new Pair<>(block("template_bale_" + suffex, "_" + suffex, TextureKey.TOP, TextureKey.SIDE), "_" + suffex))
|
||||
.toArray(Pair[]::new);
|
||||
|
||||
static Model block(String parent, TextureKey ... requiredTextureKeys) {
|
||||
return new Model(Optional.of(Unicopia.id("block/" + parent)), Optional.empty(), requiredTextureKeys);
|
||||
}
|
||||
|
||||
static Model block(String parent, String variant, TextureKey ... requiredTextureKeys) {
|
||||
return new Model(Optional.of(Unicopia.id("block/" + parent)), Optional.of(variant), requiredTextureKeys);
|
||||
}
|
||||
|
||||
static Model block(Identifier parent, TextureKey ... requiredTextureKeys) {
|
||||
return new Model(Optional.of(parent.withPrefixedPath("block/")), Optional.empty(), requiredTextureKeys);
|
||||
}
|
||||
|
||||
static Model block(Identifier parent, String variant, TextureKey ... requiredTextureKeys) {
|
||||
return new Model(Optional.of(parent.withPrefixedPath("block/")), Optional.of(variant), requiredTextureKeys);
|
||||
}
|
||||
|
||||
public interface Factory {
|
||||
static Factory of(Function<Identifier, TextureMap> textureFunc, Model model) {
|
||||
return (block, suffix) -> TexturedModel.makeFactory(b -> textureFunc.apply(ModelIds.getBlockSubModelId(b, suffix)), model).get(block);
|
||||
}
|
||||
|
||||
TexturedModel get(Block block, String suffix);
|
||||
|
||||
default Identifier upload(Block block, String suffix, BiConsumer<Identifier, Supplier<JsonElement>> writer) {
|
||||
return get(block, suffix).upload(block, suffix, writer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import net.minecraft.data.client.VariantSettings;
|
||||
import net.minecraft.data.client.VariantSettings.Rotation;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import static net.minecraft.util.math.Direction.*;
|
||||
|
||||
public class BlockRotation {
|
||||
private static final Rotation[] ROTATIONS = Rotation.values();
|
||||
public static final Direction[] DIRECTIONS = { EAST, SOUTH, WEST, NORTH };
|
||||
|
||||
public static VariantSettings.Rotation cycle(Rotation rotation, int steps) {
|
||||
int index = rotation.ordinal() + steps;
|
||||
while (index < 0) {
|
||||
index += ROTATIONS.length;
|
||||
}
|
||||
return ROTATIONS[index % ROTATIONS.length];
|
||||
}
|
||||
|
||||
public static Rotation next(Rotation rotation) {
|
||||
return cycle(rotation, 1);
|
||||
}
|
||||
|
||||
public static Rotation previous(Rotation rotation) {
|
||||
return cycle(rotation, -1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.client.BlockStateModelGenerator;
|
||||
import net.minecraft.data.client.ModelIds;
|
||||
import net.minecraft.data.client.MultipartBlockStateSupplier;
|
||||
import net.minecraft.data.client.VariantSettings;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
final class FireModels {
|
||||
static void registerSoulFire(BlockStateModelGenerator modelGenerator, Block fire, Block texture) {
|
||||
List<Identifier> floorModels = getFireModels(modelGenerator, texture, "_floor").toList();
|
||||
List<Identifier> sideModels = Stream.concat(
|
||||
getFireModels(modelGenerator, texture, "_side"),
|
||||
getFireModels(modelGenerator, texture, "_side_alt")
|
||||
).toList();
|
||||
modelGenerator.blockStateCollector.accept(MultipartBlockStateSupplier.create(fire)
|
||||
.with(BlockStateModelGenerator.buildBlockStateVariants(floorModels, UnaryOperator.identity()))
|
||||
.with(BlockStateModelGenerator.buildBlockStateVariants(sideModels, UnaryOperator.identity()))
|
||||
.with(BlockStateModelGenerator.buildBlockStateVariants(sideModels, blockStateVariant -> blockStateVariant.put(VariantSettings.Y, VariantSettings.Rotation.R90)))
|
||||
.with(BlockStateModelGenerator.buildBlockStateVariants(sideModels, blockStateVariant -> blockStateVariant.put(VariantSettings.Y, VariantSettings.Rotation.R180)))
|
||||
.with(BlockStateModelGenerator.buildBlockStateVariants(sideModels, blockStateVariant -> blockStateVariant.put(VariantSettings.Y, VariantSettings.Rotation.R270))));
|
||||
}
|
||||
|
||||
private static Stream<Identifier> getFireModels(BlockStateModelGenerator modelGenerator, Block texture, String midfix) {
|
||||
return IntStream.range(0, 2).mapToObj(i -> ModelIds.getBlockSubModelId(texture, midfix + i));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
||||
import net.minecraft.data.client.ItemModelGenerator;
|
||||
import net.minecraft.data.client.Model;
|
||||
import net.minecraft.data.client.ModelIds;
|
||||
import net.minecraft.data.client.TextureKey;
|
||||
import net.minecraft.data.client.TextureMap;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
interface ItemModels {
|
||||
Model GENERATED = net.minecraft.data.client.Models.GENERATED;
|
||||
Model CHEST = item(new Identifier("chest"), TextureKey.PARTICLE);
|
||||
Model BUILTIN_ENTITY = new Model(Optional.of(new Identifier("builtin/entity")), Optional.empty());
|
||||
Model TEMPLATE_AMULET = item("template_amulet", TextureKey.LAYER0);
|
||||
Model TEMPLATE_EYEWEAR = item("template_eyewear", TextureKey.LAYER0);
|
||||
Model TEMPLATE_SPAWN_EGG = item(new Identifier("template_spawn_egg"));
|
||||
Model TEMPLATE_MUG = item("template_mug", TextureKey.LAYER0);
|
||||
Model TEMPLATE_PILLAR = item("template_pillar", TextureKey.TOP, TextureKey.BOTTOM, TextureKey.SIDE, TextureKey.END);
|
||||
Model HANDHELD_STAFF = item("handheld_staff", TextureKey.LAYER0);
|
||||
Model TRIDENT_THROWING = item(new Identifier("trident_throwing"), TextureKey.LAYER0);
|
||||
Model TRIDENT_IN_HAND = item(new Identifier("trident_in_hand"), TextureKey.LAYER0);
|
||||
|
||||
static Model item(String parent, TextureKey ... requiredTextureKeys) {
|
||||
return new Model(Optional.of(Unicopia.id("item/" + parent)), Optional.empty(), requiredTextureKeys);
|
||||
}
|
||||
|
||||
static Model item(Identifier parent, TextureKey ... requiredTextureKeys) {
|
||||
return new Model(Optional.of(parent.withPrefixedPath("item/")), Optional.empty(), requiredTextureKeys);
|
||||
}
|
||||
|
||||
static void register(ItemModelGenerator itemModelGenerator, Item... items) {
|
||||
register(itemModelGenerator, GENERATED, items);
|
||||
}
|
||||
|
||||
static void register(ItemModelGenerator itemModelGenerator, Model model, Item... items) {
|
||||
for (Item item : items) {
|
||||
itemModelGenerator.register(item, model);
|
||||
}
|
||||
}
|
||||
|
||||
static void registerPolearm(ItemModelGenerator itemModelGenerator, Item item) {
|
||||
TextureMap textures = TextureMap.layer0(TextureMap.getId(item));
|
||||
GENERATED.upload(ModelIds.getItemSubModelId(item, "_in_inventory"), textures, itemModelGenerator.writer);
|
||||
ModelOverrides.of(TRIDENT_IN_HAND)
|
||||
.addOverride("throwing", 1, generator -> TRIDENT_THROWING.upload(ModelIds.getItemSubModelId(item, "_throwing"), textures, itemModelGenerator.writer))
|
||||
.upload(ModelIds.getItemModelId(item), textures, itemModelGenerator);
|
||||
}
|
||||
|
||||
static void registerButterfly(ItemModelGenerator itemModelGenerator, Item item) {
|
||||
float step = 1F / ButterflyEntity.Variant.VALUES.length;
|
||||
ModelOverrides.of(GENERATED).addUniform("variant", step, 1 - step, step, (i, value) -> {
|
||||
String name = ButterflyEntity.Variant.byId(i + 1).name().toLowerCase(Locale.ROOT);
|
||||
Identifier subModelId = Registries.ITEM.getId(item).withPath(p -> "item/" + name + "_" + p);
|
||||
return GENERATED.upload(subModelId, TextureMap.layer0(subModelId), itemModelGenerator.writer);
|
||||
}).upload(item, itemModelGenerator);
|
||||
}
|
||||
|
||||
static void registerSpectralBlock(ItemModelGenerator itemModelGenerator, Item item) {
|
||||
final float step = 0.025F;
|
||||
String[] suffexes = { "", "_greening", "_flowering", "_fruiting", "_ripe", "" };
|
||||
ModelOverrides.of(GENERATED).addUniform("unicopia:zap_cycle", 0, 1, step, (index, value) -> {
|
||||
if (value < 0.0001 || value > 0.999F) {
|
||||
return ModelIds.getItemModelId(item);
|
||||
}
|
||||
Identifier subModelId = ModelIds.getItemSubModelId(item, suffexes[index / 8] + "_" + Strings.padStart((index % 8) * 5 + "", 2, '0'));
|
||||
return GENERATED.upload(subModelId, TextureMap.layer0(subModelId), itemModelGenerator.writer);
|
||||
}).upload(item, "_00", itemModelGenerator);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.data.client.ItemModelGenerator;
|
||||
import net.minecraft.data.client.Model;
|
||||
import net.minecraft.data.client.ModelIds;
|
||||
import net.minecraft.data.client.TextureMap;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public final class ModelOverrides {
|
||||
private final Model model;
|
||||
private final List<Override> overrides = new ArrayList<>();
|
||||
|
||||
public static ModelOverrides of(Model model) {
|
||||
return new ModelOverrides(model);
|
||||
}
|
||||
|
||||
private ModelOverrides(Model model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public ModelOverrides addUniform(String key, int from, int to, Identifier model) {
|
||||
float step = 1F / to;
|
||||
for (int index = from; index <= to; index++) {
|
||||
addOverride(model.withSuffixedPath("_" + index), key, index * step);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelOverrides addUniform(String key, float from, float to, float step, ModelVariantSupplier childModelSupplier) {
|
||||
int index = 0;
|
||||
for (float value = from; value <= to; value += step) {
|
||||
final int capture = index++;
|
||||
final float capture2 = value;
|
||||
addOverride(key, value, generator -> {
|
||||
return childModelSupplier.upload(capture, capture2);
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelOverrides addOverride(Identifier modelId, String key, float value) {
|
||||
return addOverride(modelId, TextureMap.layer0(modelId), key, value);
|
||||
}
|
||||
|
||||
public ModelOverrides addOverride(Identifier modelId, TextureMap textures, String key, float value) {
|
||||
return addOverride(key, value, generator -> model.upload(modelId, textures, generator.writer));
|
||||
}
|
||||
|
||||
public ModelOverrides addOverride(String key, float value, Function<ItemModelGenerator, Identifier> generator) {
|
||||
return addOverride(Map.of(key, value), generator);
|
||||
}
|
||||
|
||||
public ModelOverrides addOverride(Map<String, Float> predicate, Function<ItemModelGenerator, Identifier> generator) {
|
||||
overrides.add(new Override(predicate, generator));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Identifier upload(Item item, ItemModelGenerator generator) {
|
||||
return upload(item, "", generator);
|
||||
}
|
||||
|
||||
public Identifier upload(Item item, String suffex, ItemModelGenerator generator) {
|
||||
return upload(ModelIds.getItemModelId(item), TextureMap.layer0(ModelIds.getItemSubModelId(item, suffex)), generator);
|
||||
}
|
||||
|
||||
public Identifier upload(Identifier id, TextureMap textures, ItemModelGenerator generator) {
|
||||
List<Pair<Identifier, Map<String, Float>>> overrides = this.overrides.stream()
|
||||
.map(override -> new Pair<>(override.model().apply(generator), override.predicate()))
|
||||
.toList();
|
||||
|
||||
return model.upload(id, textures, (a, jsonSupplier) -> {
|
||||
generator.writer.accept(a, () -> Util.make(jsonSupplier.get(), json -> {
|
||||
json.getAsJsonObject().add("overrides", Util.make(new JsonArray(), array -> {
|
||||
overrides.forEach(override -> {
|
||||
array.add(writeOverride(override.getLeft(), override.getRight(), new JsonObject()));
|
||||
});
|
||||
}));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private JsonObject writeOverride(Identifier model, Map<String, Float> predicate, JsonObject json) {
|
||||
json.addProperty("model", model.toString());
|
||||
json.add("predicate", Util.make(new JsonObject(), output -> {
|
||||
predicate.forEach(output::addProperty);
|
||||
}));
|
||||
return json;
|
||||
}
|
||||
|
||||
private record Override(Map<String, Float> predicate, Function<ItemModelGenerator, Identifier> model) {
|
||||
|
||||
}
|
||||
|
||||
public interface ModelVariantSupplier {
|
||||
Identifier upload(int index, float value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.datagen.DataCollector;
|
||||
import com.minelittlepony.unicopia.server.world.UTreeGen;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.DataOutput;
|
||||
import net.minecraft.data.DataOutput.PathResolver;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.DataWriter;
|
||||
|
||||
public class SeasonsGrowthRatesProvider implements DataProvider {
|
||||
|
||||
private final PathResolver pathResolver;
|
||||
|
||||
public SeasonsGrowthRatesProvider(FabricDataOutput output) {
|
||||
this.pathResolver = output.getResolver(DataOutput.OutputType.DATA_PACK, "seasons/crop");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Seasons Growth Rates";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(DataWriter writer) {
|
||||
DataCollector collectedData = new DataCollector(pathResolver);
|
||||
var exporter = collectedData.prime();
|
||||
generate((block, crop) -> {
|
||||
exporter.accept(Registries.BLOCK.getId(block), crop::toJson);
|
||||
});
|
||||
return collectedData.upload(writer);
|
||||
}
|
||||
|
||||
private void generate(BiConsumer<Block, Crop> exporter) {
|
||||
Crop greenApple = new Crop(0.5F, 0.6F, 1, 0);
|
||||
exporter.accept(UBlocks.GREEN_APPLE_LEAVES, greenApple);
|
||||
exporter.accept(UBlocks.GREEN_APPLE_SPROUT, greenApple);
|
||||
exporter.accept(UTreeGen.GREEN_APPLE_TREE.sapling().get(), greenApple);
|
||||
|
||||
Crop sourApple = new Crop(0.25F, 0.5F, 1, 0.5F);
|
||||
exporter.accept(UBlocks.SOUR_APPLE_LEAVES, sourApple);
|
||||
exporter.accept(UBlocks.SOUR_APPLE_SPROUT, sourApple);
|
||||
exporter.accept(UTreeGen.SOUR_APPLE_TREE.sapling().get(), sourApple);
|
||||
|
||||
Crop sweetApple = new Crop(1, 1, 0.6F, 0);
|
||||
exporter.accept(UBlocks.SWEET_APPLE_LEAVES, sweetApple);
|
||||
exporter.accept(UBlocks.SWEET_APPLE_SPROUT, sweetApple);
|
||||
exporter.accept(UTreeGen.SWEET_APPLE_TREE.sapling().get(), sweetApple);
|
||||
|
||||
Crop goldenOak = new Crop(1.5F, 1.4F, 0.6F, 0);
|
||||
exporter.accept(UBlocks.GOLDEN_OAK_LEAVES, goldenOak);
|
||||
exporter.accept(UBlocks.GOLDEN_OAK_SPROUT, goldenOak);
|
||||
exporter.accept(UTreeGen.GOLDEN_APPLE_TREE.sapling().get(), goldenOak);
|
||||
|
||||
Crop palm = new Crop(1.1F, 0.9F, 0.2F, 0);
|
||||
exporter.accept(UBlocks.PALM_LEAVES, palm);
|
||||
exporter.accept(UBlocks.BANANAS, palm);
|
||||
exporter.accept(UTreeGen.BANANA_TREE.sapling().get(), palm);
|
||||
|
||||
Crop mango = new Crop(1, 1.6F, 0.5F, 0);
|
||||
exporter.accept(UBlocks.MANGO_LEAVES, mango);
|
||||
exporter.accept(UTreeGen.MANGO_TREE.sapling().get(), mango);
|
||||
|
||||
Crop oats = new Crop(0.6F, 1, 1, 0);
|
||||
exporter.accept(UBlocks.OATS_CROWN, oats);
|
||||
exporter.accept(UBlocks.OATS_STEM, oats);
|
||||
exporter.accept(UBlocks.OATS, oats);
|
||||
|
||||
exporter.accept(UBlocks.ROCKS, new Crop(1, 1, 1, 1));
|
||||
exporter.accept(UBlocks.PINEAPPLE, palm);
|
||||
}
|
||||
|
||||
record Crop(float spring, float summer, float fall, float winter) {
|
||||
|
||||
JsonElement toJson() {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("spring", spring);
|
||||
json.addProperty("summer", summer);
|
||||
json.addProperty("winter", winter);
|
||||
json.addProperty("fall", fall);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
||||
import net.minecraft.data.client.BlockStateModelGenerator;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class SeasonsModelGenerator extends UBlockStateModelGenerator {
|
||||
|
||||
private static final String[] SEASONS = { "fall", "summer", "winter" };
|
||||
|
||||
public SeasonsModelGenerator(BlockStateModelGenerator modelGenerator, BiConsumer<Identifier, Supplier<JsonElement>> seasonsModelConsumer) {
|
||||
super(modelGenerator.blockStateCollector, (id, jsonSupplier) -> {
|
||||
modelGenerator.modelCollector.accept(id, jsonSupplier);
|
||||
seasonsModelConsumer.accept(id, () -> {
|
||||
JsonObject textures = jsonSupplier.get().getAsJsonObject().getAsJsonObject("textures");
|
||||
JsonObject seasonTextures = new JsonObject();
|
||||
for (String season : SEASONS) {
|
||||
seasonTextures.add(season, createTextures(season, textures));
|
||||
}
|
||||
JsonObject model = new JsonObject();
|
||||
model.add("textures", seasonTextures);
|
||||
return model;
|
||||
});
|
||||
}, modelGenerator::excludeFromSimpleItemModelGeneration);
|
||||
}
|
||||
|
||||
private static JsonObject createTextures(String season, JsonObject input) {
|
||||
JsonObject textures = new JsonObject();
|
||||
input.entrySet().forEach(entry -> {
|
||||
textures.addProperty(entry.getKey(), new Identifier(entry.getValue().getAsString()).withPath(path -> path.replace("/", "/seasons/" + season + "/")).toString());
|
||||
});
|
||||
return textures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
registerWithStages(UBlocks.OATS, UBlocks.OATS.getAgeProperty(), BlockModels.CROP, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
|
||||
registerWithStages(UBlocks.OATS_STEM, UBlocks.OATS_STEM.getAgeProperty(), BlockModels.CROP, 0, 1, 2, 3, 4, 5, 6);
|
||||
registerWithStages(UBlocks.OATS_CROWN, UBlocks.OATS_CROWN.getAgeProperty(), BlockModels.CROP, 0, 1);
|
||||
|
||||
registerItemModel(UItems.OATS);
|
||||
registerItemModel(UItems.OAT_SEEDS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,524 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.block.EdibleBlock;
|
||||
import com.minelittlepony.unicopia.block.FruitBearingBlock;
|
||||
import com.minelittlepony.unicopia.block.PieBlock;
|
||||
import com.minelittlepony.unicopia.block.PileBlock;
|
||||
import com.minelittlepony.unicopia.block.ShellsBlock;
|
||||
import com.minelittlepony.unicopia.block.SlimePustuleBlock;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.block.zap.ZapAppleLeavesBlock;
|
||||
import com.minelittlepony.unicopia.datagen.UBlockFamilies;
|
||||
import com.minelittlepony.unicopia.server.world.Tree;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.ConnectingBlock;
|
||||
import net.minecraft.block.enums.DoorHinge;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.data.client.BlockStateModelGenerator;
|
||||
import net.minecraft.data.client.BlockStateSupplier;
|
||||
import net.minecraft.data.client.BlockStateVariant;
|
||||
import net.minecraft.data.client.BlockStateVariantMap;
|
||||
import net.minecraft.data.client.Model;
|
||||
import net.minecraft.data.client.ModelIds;
|
||||
import net.minecraft.data.client.Models;
|
||||
import net.minecraft.data.client.MultipartBlockStateSupplier;
|
||||
import net.minecraft.data.client.TextureMap;
|
||||
import net.minecraft.data.client.TexturedModel;
|
||||
import net.minecraft.data.client.VariantsBlockStateSupplier;
|
||||
import net.minecraft.data.client.When;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.state.property.EnumProperty;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.StringIdentifiable;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import static net.minecraft.data.client.TextureKey.*;
|
||||
import static net.minecraft.data.client.VariantSettings.*;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
|
||||
public class UBlockStateModelGenerator extends BlockStateModelGenerator {
|
||||
static final Identifier AIR_BLOCK_ID = new Identifier("block/air");
|
||||
static final Identifier AIR_ITEM_ID = new Identifier("item/air");
|
||||
|
||||
static UBlockStateModelGenerator create(BlockStateModelGenerator modelGenerator) {
|
||||
return new UBlockStateModelGenerator(modelGenerator.blockStateCollector, modelGenerator.modelCollector, modelGenerator::excludeFromSimpleItemModelGeneration);
|
||||
}
|
||||
|
||||
protected UBlockStateModelGenerator(BlockStateModelGenerator modelGenerator) {
|
||||
this(modelGenerator.blockStateCollector, modelGenerator.modelCollector, modelGenerator::excludeFromSimpleItemModelGeneration);
|
||||
}
|
||||
|
||||
public UBlockStateModelGenerator(
|
||||
Consumer<BlockStateSupplier> blockStateCollector,
|
||||
BiConsumer<Identifier, Supplier<JsonElement>> modelCollector,
|
||||
Consumer<Block> simpleItemModelExemptionCollector) {
|
||||
super(blockStateCollector, (id, jsonSupplier) -> {
|
||||
if (AIR_BLOCK_ID.equals(id) || AIR_ITEM_ID.equals(id)) {
|
||||
throw new IllegalStateException("Registered air id for block model: " + jsonSupplier.get().toString());
|
||||
}
|
||||
modelCollector.accept(id, jsonSupplier);
|
||||
}, item -> simpleItemModelExemptionCollector.accept(Block.getBlockFromItem(item)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
for (int i = 0; i < Models.STEM_GROWTH_STAGES.length; i++) {
|
||||
Models.STEM_GROWTH_STAGES[i].upload(Unicopia.id("block/apple_sprout_stage" + i), TextureMap.stem(Blocks.MELON_STEM), modelCollector);
|
||||
}
|
||||
|
||||
// handmade
|
||||
registerAll((g, block) -> g.registerParentedItemModel(block, ModelIds.getBlockModelId(block)), UBlocks.SHAPING_BENCH, UBlocks.SURFACE_CHITIN);
|
||||
registerAll(UBlockStateModelGenerator::registerSimpleState, UBlocks.SHAPING_BENCH, UBlocks.BANANAS);
|
||||
// doors
|
||||
registerAll(UBlockStateModelGenerator::registerStableDoor, UBlocks.STABLE_DOOR, UBlocks.DARK_OAK_DOOR, UBlocks.CRYSTAL_DOOR, UBlocks.CLOUD_DOOR);
|
||||
|
||||
// cloud blocks
|
||||
createCustomTexturePool(UBlocks.CLOUD, TexturedModel.CUBE_ALL).same(UBlocks.UNSTABLE_CLOUD).slab(UBlocks.CLOUD_SLAB).stairs(UBlocks.CLOUD_STAIRS);
|
||||
createCustomTexturePool(UBlocks.ETCHED_CLOUD, TexturedModel.CUBE_ALL).slab(UBlocks.ETCHED_CLOUD_SLAB).stairs(UBlocks.ETCHED_CLOUD_STAIRS);
|
||||
createCustomTexturePool(UBlocks.DENSE_CLOUD, TexturedModel.CUBE_ALL).slab(UBlocks.DENSE_CLOUD_SLAB).stairs(UBlocks.DENSE_CLOUD_STAIRS);
|
||||
createCustomTexturePool(UBlocks.CLOUD_PLANKS, TexturedModel.CUBE_ALL).slab(UBlocks.CLOUD_PLANK_SLAB).stairs(UBlocks.CLOUD_PLANK_STAIRS);
|
||||
createCustomTexturePool(UBlocks.CLOUD_BRICKS, TexturedModel.CUBE_ALL).slab(UBlocks.CLOUD_BRICK_SLAB).stairs(UBlocks.CLOUD_BRICK_STAIRS);
|
||||
createTwoStepTexturePool(UBlocks.SOGGY_CLOUD, TexturedModel.CUBE_BOTTOM_TOP.andThen(textures -> textures.put(BOTTOM, ModelIds.getBlockModelId(UBlocks.CLOUD)))).slab(UBlocks.SOGGY_CLOUD_SLAB).stairs(UBlocks.SOGGY_CLOUD_STAIRS);
|
||||
registerRotated(UBlocks.CARVED_CLOUD, TexturedModel.CUBE_COLUMN);
|
||||
registerPillar(UBlocks.CLOUD_PILLAR);
|
||||
|
||||
registerAll(UBlockStateModelGenerator::registerCompactedBlock, UBlocks.COMPACTED_CLOUD, UBlocks.COMPACTED_CLOUD_BRICKS, UBlocks.COMPACTED_CLOUD_PLANKS, UBlocks.COMPACTED_DENSE_CLOUD, UBlocks.COMPACTED_ETCHED_CLOUD);
|
||||
registerChest(UBlocks.CLOUD_CHEST, UBlocks.CLOUD);
|
||||
registerFancyBed(UBlocks.CLOUD_BED, UBlocks.CLOUD);
|
||||
registerFancyBed(UBlocks.CLOTH_BED, Blocks.SPRUCE_PLANKS);
|
||||
|
||||
// chitin blocks
|
||||
registerTopsoil(UBlocks.SURFACE_CHITIN, UBlocks.CHITIN);
|
||||
registerHollow(UBlocks.CHITIN);
|
||||
registerCubeAllModelTexturePool(UBlocks.CHISELLED_CHITIN).stairs(UBlocks.CHISELLED_CHITIN_STAIRS).slab(UBlocks.CHISELLED_CHITIN_SLAB);
|
||||
registerHiveBlock(UBlocks.HIVE);
|
||||
registerRotated(UBlocks.CHITIN_SPIKES, BlockModels.SPIKES);
|
||||
registerHull(UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHITIN, UBlocks.CHISELLED_CHITIN);
|
||||
registerParentedItemModel(UBlocks.SLIME_PUSTULE, ModelIds.getBlockSubModelId(UBlocks.SLIME_PUSTULE, "_pod"));
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(UBlocks.SLIME_PUSTULE)
|
||||
.coordinate(BlockStateVariantMap.create(SlimePustuleBlock.SHAPE)
|
||||
.register(state -> BlockStateVariant.create().put(MODEL, ModelIds.getBlockSubModelId(UBlocks.SLIME_PUSTULE, "_" + state.asString())))));
|
||||
registerPie(UBlocks.APPLE_PIE);
|
||||
|
||||
// palm wood
|
||||
registerLog(UBlocks.PALM_LOG).log(UBlocks.PALM_LOG).wood(UBlocks.PALM_WOOD);
|
||||
registerLog(UBlocks.STRIPPED_PALM_LOG).log(UBlocks.STRIPPED_PALM_LOG).wood(UBlocks.STRIPPED_PALM_WOOD);
|
||||
registerCubeAllModelTexturePool(UBlocks.PALM_PLANKS).family(UBlockFamilies.PALM);
|
||||
registerHangingSign(UBlocks.STRIPPED_PALM_LOG, UBlocks.PALM_HANGING_SIGN, UBlocks.PALM_WALL_HANGING_SIGN);
|
||||
registerSimpleCubeAll(UBlocks.PALM_LEAVES);
|
||||
|
||||
// zap wood
|
||||
registerLog(UBlocks.ZAP_LOG)
|
||||
.log(UBlocks.ZAP_LOG).wood(UBlocks.ZAP_WOOD)
|
||||
.log(UBlocks.WAXED_ZAP_LOG).wood(UBlocks.WAXED_ZAP_WOOD);
|
||||
registerLog(UBlocks.STRIPPED_ZAP_LOG)
|
||||
.log(UBlocks.STRIPPED_ZAP_LOG).wood(UBlocks.STRIPPED_ZAP_WOOD)
|
||||
.log(UBlocks.WAXED_STRIPPED_ZAP_LOG).wood(UBlocks.WAXED_STRIPPED_ZAP_WOOD);
|
||||
registerCubeAllModelTexturePool(UBlocks.ZAP_PLANKS).family(UBlockFamilies.ZAP).same(UBlocks.WAXED_ZAP_PLANKS).family(UBlockFamilies.WAXED_ZAP);
|
||||
registerZapLeaves(UBlocks.ZAP_LEAVES);
|
||||
registerSingleton(UBlocks.FLOWERING_ZAP_LEAVES, TexturedModel.LEAVES);
|
||||
registerStateWithModelReference(UBlocks.ZAP_LEAVES_PLACEHOLDER, Blocks.AIR);
|
||||
|
||||
// golden oak wood
|
||||
registerSimpleCubeAll(UBlocks.GOLDEN_OAK_LEAVES);
|
||||
registerLog(UBlocks.GOLDEN_OAK_LOG).log(UBlocks.GOLDEN_OAK_LOG);
|
||||
|
||||
// plants
|
||||
Tree.REGISTRY.stream().filter(tree -> tree.sapling().isPresent()).forEach(tree -> registerFlowerPotPlant(tree.sapling().get(), tree.pot().get(), TintType.NOT_TINTED));
|
||||
registerTintableCross(UBlocks.CURING_JOKE, TintType.NOT_TINTED);
|
||||
registerWithStages(UBlocks.GOLD_ROOT, Properties.AGE_7, BlockModels.CROP, 0, 0, 1, 1, 2, 2, 2, 3);
|
||||
|
||||
registerTallCrop(UBlocks.PINEAPPLE, Properties.AGE_7, Properties.BLOCK_HALF,
|
||||
new int[] { 0, 1, 2, 3, 4, 5, 5, 6 },
|
||||
new int[] { 0, 0, 1, 2, 3, 4, 5, 6 }
|
||||
);
|
||||
registerPlunderVine(UBlocks.PLUNDER_VINE, UBlocks.PLUNDER_VINE_BUD);
|
||||
|
||||
// leaves
|
||||
registerAll(UBlockStateModelGenerator::registerFloweringLeaves, UBlocks.GREEN_APPLE_LEAVES, UBlocks.SOUR_APPLE_LEAVES, UBlocks.SWEET_APPLE_LEAVES);
|
||||
registerAll(UBlockStateModelGenerator::registerSprout, UBlocks.GREEN_APPLE_SPROUT, UBlocks.SOUR_APPLE_SPROUT, UBlocks.SWEET_APPLE_SPROUT, UBlocks.GOLDEN_OAK_SPROUT);
|
||||
registerStateWithModelReference(UBlocks.MANGO_LEAVES, Blocks.JUNGLE_LEAVES);
|
||||
registerParentedItemModel(UBlocks.MANGO_LEAVES, ModelIds.getBlockModelId(Blocks.JUNGLE_LEAVES));
|
||||
|
||||
// fruit
|
||||
UModelProvider.FRUITS.forEach((block, item) -> registerSingleton(block, TextureMap.cross(ModelIds.getItemModelId(item)), BlockModels.FRUIT));
|
||||
|
||||
// bales
|
||||
registerAll((g, block) -> g.registerBale(Unicopia.id(block.getLeft().getPath().replace("bale", "block")), block.getLeft(), block.getRight()),
|
||||
new Pair<>(new Identifier("hay_block"), "_top"),
|
||||
new Pair<>(new Identifier("farmersdelight", "rice_bale"), "_top"),
|
||||
new Pair<>(new Identifier("farmersdelight", "straw_bale"), "_end")
|
||||
);
|
||||
// shells
|
||||
registerAll(UBlockStateModelGenerator::registerShell, UBlocks.CLAM_SHELL, UBlocks.TURRET_SHELL, UBlocks.SCALLOP_SHELL);
|
||||
// other
|
||||
registerBuiltinWithParticle(UBlocks.WEATHER_VANE, UBlocks.WEATHER_VANE.asItem());
|
||||
registerWithStages(UBlocks.FROSTED_OBSIDIAN, Properties.AGE_3, BlockModels.CUBE_ALL, 0, 1, 2, 3);
|
||||
registerWithStagesBuiltinModels(UBlocks.ROCKS, Properties.AGE_7, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
registerWithStagesBuiltinModels(UBlocks.MYSTERIOUS_EGG, PileBlock.COUNT, 1, 2, 3);
|
||||
excludeFromSimpleItemModelGeneration(UBlocks.MYSTERIOUS_EGG);
|
||||
FireModels.registerSoulFire(this, UBlocks.SPECTRAL_FIRE, Blocks.SOUL_FIRE);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final <T> UBlockStateModelGenerator registerAll(BiConsumer<? super UBlockStateModelGenerator, T> register, T... blocks) {
|
||||
for (T block : blocks) {
|
||||
register.accept(this, block);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerParentedItemModel(Block block, Identifier parentModelId) {
|
||||
Item item = block.asItem();
|
||||
if (item != Items.AIR) {
|
||||
registerParentedItemModel(item, parentModelId);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockTexturePool createCustomTexturePool(Block block, TexturedModel.Factory modelFactory) {
|
||||
final TexturedModel texturedModel = modelFactory.get(block);
|
||||
final TextureMap textures = texturedModel.getTextures();
|
||||
return (new BlockTexturePool(textures) {
|
||||
@Override
|
||||
public BlockTexturePool stairs(Block block) {
|
||||
TextureMap textMap = textures.copyAndAdd(BlockModels.STEP, textures.getTexture(SIDE));
|
||||
Identifier inner = BlockModels.INNER_STAIRS.upload(block, textMap, modelCollector);
|
||||
Identifier straight = BlockModels.STRAIGHT_STAIRS.upload(block, textMap, modelCollector);
|
||||
Identifier outer = BlockModels.OUTER_STAIRS.upload(block, textMap, modelCollector);
|
||||
blockStateCollector.accept(BlockStateModelGenerator.createStairsBlockState(block, inner, straight, outer));
|
||||
registerParentedItemModel(block, straight);
|
||||
return this;
|
||||
}
|
||||
}).base(block, texturedModel.getModel());
|
||||
}
|
||||
|
||||
public BlockTexturePool createTwoStepTexturePool(Block block, TexturedModel.Factory modelFactory) {
|
||||
final TexturedModel texturedModel = modelFactory.get(block);
|
||||
final TextureMap textures = texturedModel.getTextures();
|
||||
final Identifier baseModelId = ModelIds.getBlockModelId(block);
|
||||
final Identifier twoStepTexture = ModelIds.getBlockSubModelId(block, "_slab_side");
|
||||
return (new BlockTexturePool(textures) {
|
||||
@Override
|
||||
public BlockTexturePool stairs(Block block) {
|
||||
TextureMap textMap = textures.copyAndAdd(BlockModels.STEP, twoStepTexture);
|
||||
Identifier inner = BlockModels.INNER_STAIRS.upload(block, textMap, modelCollector);
|
||||
Identifier straight = BlockModels.STRAIGHT_STAIRS.upload(block, textMap, modelCollector);
|
||||
Identifier outer = BlockModels.OUTER_STAIRS.upload(block, textMap, modelCollector);
|
||||
blockStateCollector.accept(BlockStateModelGenerator.createStairsBlockState(block, inner, straight, outer));
|
||||
registerParentedItemModel(block, straight);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTexturePool slab(Block block) {
|
||||
TextureMap textMap = textures.copyAndAdd(SIDE, twoStepTexture);
|
||||
Identifier lower = Models.SLAB.upload(block, textMap, modelCollector);
|
||||
Identifier upper = Models.SLAB_TOP.upload(block, textMap, modelCollector);
|
||||
blockStateCollector.accept(BlockStateModelGenerator.createSlabBlockState(block, lower, upper, baseModelId));
|
||||
registerParentedItemModel(block, lower);
|
||||
return this;
|
||||
}
|
||||
}).base(block, texturedModel.getModel());
|
||||
}
|
||||
|
||||
public void registerTopsoil(Block block, Block dirt) {
|
||||
TexturedModel model = TexturedModel.CUBE_BOTTOM_TOP.get(dirt);
|
||||
registerTopSoil(block,
|
||||
model.upload(block, modelCollector),
|
||||
BlockStateVariant.create().put(MODEL, Models.CUBE_BOTTOM_TOP.upload(dirt, "_snow", model.getTextures()
|
||||
.copyAndAdd(SIDE, ModelIds.getBlockSubModelId(dirt, "_side_snow_covered")
|
||||
), modelCollector))
|
||||
);
|
||||
}
|
||||
|
||||
public void registerHollow(Block block) {
|
||||
Identifier outside = ModelIds.getBlockModelId(UBlocks.CHITIN);
|
||||
Identifier inside = ModelIds.getBlockSubModelId(UBlocks.CHITIN, "_bottom");
|
||||
registerSingleton(UBlocks.CHITIN, new TextureMap()
|
||||
.put(SIDE, outside)
|
||||
.put(TOP, outside)
|
||||
.put(BOTTOM, inside), Models.CUBE_BOTTOM_TOP);
|
||||
}
|
||||
|
||||
public void registerRotated(Block block, TexturedModel.Factory modelFactory) {
|
||||
Identifier modelId = modelFactory.get(block).upload(block, modelCollector);
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(block, BlockStateVariant.create()
|
||||
.put(MODEL, modelId))
|
||||
.coordinate(createUpDefaultFacingVariantMap()));
|
||||
}
|
||||
|
||||
public void registerPlunderVine(Block plant, Block bud) {
|
||||
var rotationVariants = BlockStateVariantMap.create(Properties.FACING);
|
||||
createDownDefaultFacingVariantMap(rotationVariants::register);
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(bud, BlockStateVariant.create()
|
||||
.put(MODEL, ModelIds.getBlockModelId(bud)))
|
||||
.coordinate(rotationVariants));
|
||||
|
||||
var supplier = MultipartBlockStateSupplier.create(plant);
|
||||
String[] stages = { "", "_2", "_3", "_4", "_4"};
|
||||
Properties.AGE_4.getValues().forEach(age -> {
|
||||
Identifier modelId = ModelIds.getBlockSubModelId(plant, "_branch" + stages[age]);
|
||||
createDownDefaultFacingVariantMap((direction, variant) -> {
|
||||
supplier.with(When.create().set(Properties.AGE_4, age).set(ConnectingBlock.FACING_PROPERTIES.get(direction), true), variant.put(MODEL, modelId));
|
||||
});
|
||||
});
|
||||
|
||||
blockStateCollector.accept(supplier);
|
||||
registerParentedItemModel(bud, ModelIds.getBlockModelId(bud));
|
||||
}
|
||||
|
||||
public final void createDownDefaultFacingVariantMap(BiConsumer<Direction, BlockStateVariant> builder) {
|
||||
builder.accept(Direction.DOWN, BlockStateVariant.create());
|
||||
builder.accept(Direction.UP, BlockStateVariant.create().put(X, R180));
|
||||
builder.accept(Direction.SOUTH, BlockStateVariant.create().put(X, R90));
|
||||
builder.accept(Direction.NORTH, BlockStateVariant.create().put(X, R90).put(Y, R180));
|
||||
builder.accept(Direction.EAST, BlockStateVariant.create().put(X, R90).put(Y, R270));
|
||||
builder.accept(Direction.WEST, BlockStateVariant.create().put(X, R90).put(Y, R90));
|
||||
}
|
||||
|
||||
public void registerCompactedBlock(Block block) {
|
||||
for (Model model : BlockModels.FLATTENED_MODELS) {
|
||||
model.upload(block, TextureMap.all(ModelIds.getBlockModelId(block).withPath(p -> p.replace("compacted_", ""))), modelCollector);
|
||||
}
|
||||
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
|
||||
for (byte i = 0; i < BlockModels.FLATTENED_MODEL_ROTATIONS.length; i++) {
|
||||
final BooleanProperty yAxis = (i & 0b100) == 0 ? Properties.DOWN : Properties.UP;
|
||||
final BooleanProperty xAxis = (i & 0b010) == 0 ? Properties.NORTH: Properties.SOUTH;
|
||||
final BooleanProperty zAxis = (i & 0b001) == 0 ? Properties.EAST : Properties.WEST;
|
||||
final Rotation xRot = yAxis == Properties.DOWN ? R0 : R180;
|
||||
final Rotation yRot = BlockModels.FLATTENED_MODEL_ROTATIONS[i];
|
||||
final String[] suffexes = yRot.ordinal() % 2 == 0 ? BlockModels.FLATTENED_MODEL_SUFFEXES : BlockModels.FLATTENED_MODEL_SUFFEXES_ROT;
|
||||
for (byte v = 0; v < suffexes.length; v++) {
|
||||
supplier.with(When.create()
|
||||
.set(yAxis, (v & 0b100) != 0)
|
||||
.set(xAxis, (v & 0b010) != 0)
|
||||
.set(zAxis, (v & 0b001) != 0), BlockStateVariant.create()
|
||||
.put(MODEL, ModelIds.getBlockSubModelId(block, "_corner_" + suffexes[v]))
|
||||
.put(UVLOCK, true)
|
||||
.put(X, xRot)
|
||||
.put(Y, yRot)
|
||||
);
|
||||
}
|
||||
}
|
||||
blockStateCollector.accept(supplier);
|
||||
}
|
||||
|
||||
public void registerChest(Block chest, Block particleSource) {
|
||||
registerBuiltin(ModelIds.getBlockModelId(chest), particleSource).includeWithoutItem(chest);
|
||||
ItemModels.CHEST.upload(ModelIds.getItemModelId(chest.asItem()), TextureMap.particle(particleSource), modelCollector);
|
||||
}
|
||||
|
||||
public void registerFancyBed(Block bed, Block particleSource) {
|
||||
registerBuiltinWithParticle(bed, ModelIds.getBlockModelId(particleSource));
|
||||
super.registerBed(bed, particleSource);
|
||||
}
|
||||
|
||||
public void registerStableDoor(Block door) {
|
||||
TextureMap topTextures = TextureMap.topBottom(door);
|
||||
TextureMap bottomTextures = topTextures.copyAndAdd(TOP, topTextures.getTexture(BOTTOM));
|
||||
registerItemModel(door.asItem());
|
||||
var variants = BlockStateVariantMap.create(Properties.HORIZONTAL_FACING, Properties.DOUBLE_BLOCK_HALF, Properties.DOOR_HINGE, Properties.OPEN);
|
||||
fillStableDoorVariantMap(variants, DoubleBlockHalf.LOWER,
|
||||
BlockModels.DOOR_LEFT.upload(door, "_bottom_left", bottomTextures, modelCollector),
|
||||
BlockModels.DOOR_RIGHT.upload(door, "_bottom_right", bottomTextures, modelCollector)
|
||||
);
|
||||
fillStableDoorVariantMap(variants, DoubleBlockHalf.UPPER,
|
||||
BlockModels.DOOR_LEFT.upload(door, "_top_left", topTextures, modelCollector),
|
||||
BlockModels.DOOR_RIGHT.upload(door, "_top_right", topTextures, modelCollector)
|
||||
);
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(door).coordinate(variants));
|
||||
}
|
||||
|
||||
public static void fillStableDoorVariantMap(
|
||||
BlockStateVariantMap.QuadrupleProperty<Direction, DoubleBlockHalf, DoorHinge, Boolean> variantMap,
|
||||
DoubleBlockHalf targetHalf, Identifier leftModelId, Identifier rightModelId) {
|
||||
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.LEFT, false, R0, leftModelId);
|
||||
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.RIGHT, false, R0, rightModelId);
|
||||
|
||||
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.LEFT, true, R90, rightModelId);
|
||||
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.RIGHT, true, R270, leftModelId);
|
||||
}
|
||||
|
||||
public static void fillStableDoorVariantMap(
|
||||
BlockStateVariantMap.QuadrupleProperty<Direction, DoubleBlockHalf, DoorHinge, Boolean> variantMap,
|
||||
DoubleBlockHalf targetHalf,
|
||||
DoorHinge hinge, boolean open, Rotation rotation,
|
||||
Identifier modelId) {
|
||||
|
||||
for (int i = 0; i < BlockRotation.DIRECTIONS.length; i++) {
|
||||
variantMap.register(BlockRotation.DIRECTIONS[i], targetHalf, hinge, open, BlockStateVariant.create()
|
||||
.put(MODEL, modelId)
|
||||
.put(Y, BlockRotation.cycle(rotation, i))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerPillar(Block pillar) {
|
||||
TextureMap textures = new TextureMap()
|
||||
.put(SIDE, ModelIds.getBlockSubModelId(pillar, "_side"))
|
||||
.put(TOP, ModelIds.getBlockSubModelId(pillar, "_lip"))
|
||||
.put(BOTTOM, ModelIds.getBlockSubModelId(pillar, "_end"))
|
||||
.put(END, ModelIds.getBlockSubModelId(pillar, "_side_end"));
|
||||
Identifier middle = BlockModels.TEMPLATE_PILLAR.upload(pillar, textures, modelCollector);
|
||||
Identifier end = BlockModels.TEMPLATE_PILLAR_END.upload(pillar, textures, modelCollector);
|
||||
blockStateCollector.accept(MultipartBlockStateSupplier.create(pillar)
|
||||
.with(BlockStateVariant.create().put(MODEL, middle))
|
||||
.with(When.create().set(Properties.NORTH, false), BlockStateVariant.create().put(MODEL, end).put(UVLOCK, true).put(X, R180))
|
||||
.with(When.create().set(Properties.SOUTH, false), BlockStateVariant.create().put(MODEL, end))
|
||||
);
|
||||
ItemModels.TEMPLATE_PILLAR.upload(ModelIds.getItemModelId(pillar.asItem()), textures, modelCollector);
|
||||
}
|
||||
|
||||
public void registerHiveBlock(Block hive) {
|
||||
Identifier core = ModelIds.getBlockSubModelId(hive, "_core");
|
||||
Identifier side = ModelIds.getBlockSubModelId(hive, "_side");
|
||||
blockStateCollector.accept(MultipartBlockStateSupplier.create(hive)
|
||||
.with(BlockStateVariant.create().put(MODEL, core))
|
||||
.with(When.create().set(Properties.NORTH, true), BlockStateVariant.create().put(MODEL, side).put(UVLOCK, true))
|
||||
.with(When.create().set(Properties.EAST, true), BlockStateVariant.create().put(MODEL, side).put(UVLOCK, true).put(Y, R90))
|
||||
.with(When.create().set(Properties.SOUTH, true), BlockStateVariant.create().put(MODEL, side).put(UVLOCK, true).put(Y, R180))
|
||||
.with(When.create().set(Properties.WEST, true), BlockStateVariant.create().put(MODEL, side).put(UVLOCK, true).put(Y, R270))
|
||||
.with(When.create().set(Properties.DOWN, true), BlockStateVariant.create().put(MODEL, side).put(UVLOCK, true).put(X, R90))
|
||||
.with(When.create().set(Properties.UP, true), BlockStateVariant.create().put(MODEL, side).put(UVLOCK, true).put(X, R270)));
|
||||
Models.CUBE_ALL.upload(ModelIds.getItemModelId(hive.asItem()), TextureMap.all(ModelIds.getBlockSubModelId(hive, "_side")), modelCollector);
|
||||
}
|
||||
|
||||
public void registerBale(Identifier blockId, Identifier baseBlockId, String endSuffex) {
|
||||
Identifier top = baseBlockId.withPath(p -> "block/" + p + endSuffex);
|
||||
Identifier side = baseBlockId.withPath(p -> "block/" + p + "_side");
|
||||
TextureMap textures = new TextureMap().put(TOP, top).put(SIDE, side);
|
||||
|
||||
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(Registries.BLOCK.getOrEmpty(blockId).orElseGet(() -> {
|
||||
return Registry.register(Registries.BLOCK, blockId, new EdibleBlock(blockId, blockId, false));
|
||||
}));
|
||||
Map<Integer, Identifier> uploadedModels = new HashMap<>();
|
||||
|
||||
for (Direction.Axis axis : Direction.Axis.VALUES) {
|
||||
for (int i = 0; i < EdibleBlock.SEGMENTS.length; i++) {
|
||||
BooleanProperty segment = EdibleBlock.SEGMENTS[i];
|
||||
segment.getName();
|
||||
supplier.with(When.create().set(EdibleBlock.AXIS, axis).set(segment, true), BlockStateVariant.create()
|
||||
.put(MODEL, uploadedModels.computeIfAbsent(i, ii -> {
|
||||
return BlockModels.BALE_MODELS[ii].getLeft().upload(blockId.withPath(p -> "block/" + p + BlockModels.BALE_MODELS[ii].getRight()), textures, modelCollector);
|
||||
}))
|
||||
.put(X, axis == Direction.Axis.Y ? R0 : R90)
|
||||
.put(Y, axis == Direction.Axis.X ? R90 : R0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
blockStateCollector.accept(supplier);
|
||||
}
|
||||
|
||||
public void registerWithStages(Block crop, Property<Integer> ageProperty, BlockModels.Factory modelFactory, int ... stages) {
|
||||
if (ageProperty.getValues().size() != stages.length) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int offset = ageProperty.getValues().iterator().next();
|
||||
Int2ObjectOpenHashMap<Identifier> uploadedModels = new Int2ObjectOpenHashMap<>();
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(crop)
|
||||
.coordinate(BlockStateVariantMap.create(ageProperty)
|
||||
.register(age -> BlockStateVariant.create().put(MODEL, uploadedModels.computeIfAbsent(stages[age - offset], stage -> {
|
||||
return modelFactory.upload(crop, "_stage" + stage, modelCollector);
|
||||
})))));
|
||||
}
|
||||
|
||||
public void registerWithStagesBuiltinModels(Block crop, Property<Integer> ageProperty, int ... stages) {
|
||||
if (ageProperty.getValues().size() != stages.length) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int offset = ageProperty.getValues().iterator().next();
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(crop)
|
||||
.coordinate(BlockStateVariantMap.create(ageProperty)
|
||||
.register(age -> BlockStateVariant.create().put(MODEL, ModelIds.getBlockSubModelId(crop, "_stage" + stages[age - offset])))));
|
||||
}
|
||||
|
||||
public <T extends Enum<T> & StringIdentifiable> void registerTallCrop(Block crop,
|
||||
Property<Integer> ageProperty,
|
||||
EnumProperty<T> partProperty,
|
||||
int[] ... ageTextureIndices) {
|
||||
Map<String, Identifier> uploadedModels = new HashMap<>();
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(crop).coordinate(BlockStateVariantMap.create(partProperty, ageProperty).register((part, age) -> {
|
||||
int i = ageTextureIndices[part.ordinal()][age];
|
||||
Identifier identifier = uploadedModels.computeIfAbsent("_" + part.asString() + "_stage" + i, variant -> createSubModel(crop, variant, Models.CROSS, TextureMap::cross));
|
||||
return BlockStateVariant.create().put(MODEL, identifier);
|
||||
})));
|
||||
}
|
||||
|
||||
public void registerPie(Block pie) {
|
||||
TextureMap textures = new TextureMap()
|
||||
.put(TOP, ModelIds.getBlockSubModelId(pie, "_top"))
|
||||
.put(BOTTOM, ModelIds.getBlockSubModelId(pie, "_bottom"))
|
||||
.put(SIDE, ModelIds.getBlockSubModelId(pie, "_side"))
|
||||
.put(INSIDE, ModelIds.getBlockSubModelId(pie, "_inside"));
|
||||
TextureMap stompedTextures = textures.copyAndAdd(TOP, ModelIds.getBlockSubModelId(pie, "_top_stomped"));
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(pie).coordinate(BlockStateVariantMap.create(PieBlock.BITES, PieBlock.STOMPED).register((bites, stomped) -> {
|
||||
return BlockStateVariant.create().put(MODEL, BlockModels.PIE_MODELS[bites].upload(pie, (stomped ? "_stomped" : ""), stomped ? stompedTextures : textures, modelCollector));
|
||||
})));
|
||||
}
|
||||
|
||||
public void registerFloweringLeaves(Block block) {
|
||||
Identifier baseModel = TexturedModel.LEAVES.upload(block, modelCollector);
|
||||
Identifier floweringModel = Models.CUBE_ALL.upload(block, "_flowering", TextureMap.of(ALL, ModelIds.getBlockSubModelId(block, "_flowering")), modelCollector);
|
||||
blockStateCollector.accept(MultipartBlockStateSupplier.create(block)
|
||||
.with(BlockStateVariant.create().put(MODEL, baseModel))
|
||||
.with(When.create().set(FruitBearingBlock.STAGE, FruitBearingBlock.Stage.FLOWERING), BlockStateVariant.create().put(MODEL, floweringModel)));
|
||||
}
|
||||
|
||||
public void registerZapLeaves(Block block) {
|
||||
Identifier baseModel = TexturedModel.LEAVES.upload(block, modelCollector);
|
||||
Identifier floweringModel = Registries.BLOCK.getId(block).withPrefixedPath("block/flowering_");
|
||||
Identifier airModel = ModelIds.getBlockModelId(Blocks.AIR);
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(block)
|
||||
.coordinate(BlockStateVariantMap.create(ZapAppleLeavesBlock.STAGE)
|
||||
.register(stage -> BlockStateVariant.create()
|
||||
.put(MODEL, switch (stage) {
|
||||
case HIBERNATING -> airModel;
|
||||
case FLOWERING -> floweringModel;
|
||||
default -> baseModel;
|
||||
}))));
|
||||
}
|
||||
|
||||
public void registerSprout(Block sprout) {
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(sprout)
|
||||
.coordinate(BlockStateVariantMap.create(Properties.AGE_7)
|
||||
.register(age -> BlockStateVariant.create()
|
||||
.put(MODEL, Unicopia.id("block/apple_sprout_stage" + age)))));
|
||||
}
|
||||
|
||||
public void registerShell(Block shell) {
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(shell)
|
||||
.coordinate(BlockStateVariantMap.create(ShellsBlock.COUNT)
|
||||
.register(count -> BlockStateVariant.create()
|
||||
.put(MODEL, BlockModels.SHELL_MODELS[count - 1].upload(shell, TextureMap.of(BlockModels.SHELL, Registries.BLOCK.getId(shell).withPrefixedPath("item/")), modelCollector)))));
|
||||
}
|
||||
|
||||
public void registerHull(Block block, Block core, Block shell) {
|
||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(
|
||||
block,
|
||||
BlockStateVariant.create().put(MODEL, Models.CUBE_BOTTOM_TOP.upload(block, new TextureMap()
|
||||
.put(BOTTOM, ModelIds.getBlockModelId(core))
|
||||
.put(TOP, ModelIds.getBlockModelId(shell))
|
||||
.put(SIDE, ModelIds.getBlockSubModelId(shell, "_half")), modelCollector))
|
||||
).coordinate(createUpDefaultFacingVariantMap()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.server.world.Tree;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.RegistryWrapper;
|
||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||
import net.minecraft.registry.tag.BlockTags;
|
||||
import net.minecraft.registry.tag.TagBuilder;
|
||||
import net.minecraft.registry.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider {
|
||||
public UBlockTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TagBuilder getTagBuilder(TagKey<Block> tag) {
|
||||
return super.getTagBuilder(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(WrapperLookup registries) {
|
||||
Block[] crops = {
|
||||
UBlocks.OATS, UBlocks.OATS_STEM, UBlocks.OATS_CROWN,
|
||||
UBlocks.ROCKS, UBlocks.PINEAPPLE,
|
||||
UBlocks.SWEET_APPLE_SPROUT, UBlocks.GREEN_APPLE_SPROUT, UBlocks.SWEET_APPLE_SPROUT,
|
||||
UBlocks.GOLDEN_OAK_SPROUT
|
||||
};
|
||||
|
||||
getOrCreateTagBuilder(UTags.CATAPULT_IMMUNE).add(Blocks.BEDROCK).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS);
|
||||
getOrCreateTagBuilder(BlockTags.CROPS).add(crops);
|
||||
getOrCreateTagBuilder(BlockTags.BEE_GROWABLES).add(crops);
|
||||
getOrCreateTagBuilder(BlockTags.MAINTAINS_FARMLAND).add(crops);
|
||||
getOrCreateTagBuilder(BlockTags.NEEDS_DIAMOND_TOOL).add(UBlocks.FROSTED_OBSIDIAN);
|
||||
getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE);
|
||||
getOrCreateTagBuilder(BlockTags.DRAGON_IMMUNE).add(UBlocks.FROSTED_OBSIDIAN, UBlocks.GOLDEN_OAK_LOG, UBlocks.GOLDEN_OAK_LEAVES);
|
||||
getOrCreateTagBuilder(BlockTags.FIRE).add(UBlocks.SPECTRAL_FIRE);
|
||||
getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(UBlocks.HAY_BLOCK).addOptional(Unicopia.id("rice_block")).addOptional(Unicopia.id("straw_block"));
|
||||
|
||||
addZapWoodset();
|
||||
addPalmWoodset();
|
||||
addCloudBlocksets();
|
||||
addChitinBlocksets();
|
||||
addFruitTrees();
|
||||
|
||||
getOrCreateTagBuilder(UTags.CRYSTAL_HEART_BASE).add(
|
||||
Blocks.DIAMOND_BLOCK,
|
||||
Blocks.QUARTZ_BLOCK, Blocks.QUARTZ_BRICKS, Blocks.QUARTZ_SLAB, Blocks.QUARTZ_STAIRS, Blocks.QUARTZ_PILLAR,
|
||||
Blocks.SMOOTH_QUARTZ, Blocks.SMOOTH_QUARTZ_SLAB, Blocks.SMOOTH_QUARTZ_STAIRS, Blocks.CHISELED_QUARTZ_BLOCK,
|
||||
Blocks.AMETHYST_BLOCK, Blocks.NETHERITE_BLOCK, Blocks.EMERALD_BLOCK
|
||||
);
|
||||
getOrCreateTagBuilder(UTags.CRYSTAL_HEART_ORNAMENT).add(Blocks.END_ROD);
|
||||
|
||||
getOrCreateTagBuilder(UTags.FRAGILE)
|
||||
.forceAddTag(ConventionalBlockTags.GLASS_BLOCKS)
|
||||
.forceAddTag(ConventionalBlockTags.GLASS_PANES)
|
||||
.add(Blocks.VINE, Blocks.LILY_PAD);
|
||||
|
||||
getOrCreateTagBuilder(UTags.INTERESTING).add(
|
||||
Blocks.SEA_LANTERN, Blocks.ENDER_CHEST, Blocks.END_PORTAL_FRAME,
|
||||
Blocks.JUKEBOX, Blocks.SPAWNER
|
||||
).forceAddTag(ConventionalBlockTags.ORES);
|
||||
|
||||
getOrCreateTagBuilder(UTags.KICKS_UP_DUST).forceAddTag(BlockTags.SAND).add(
|
||||
Blocks.SUSPICIOUS_SAND,
|
||||
Blocks.GRAVEL, Blocks.SUSPICIOUS_GRAVEL
|
||||
).forceAddTag(TagKey.of(RegistryKeys.BLOCK, new Identifier("c", "concrete_powders")));
|
||||
|
||||
getOrCreateTagBuilder(UTags.UNAFFECTED_BY_GROW_ABILITY).add(Blocks.GRASS_BLOCK);
|
||||
}
|
||||
|
||||
private void addFruitTrees() {
|
||||
Block[] leaves = {
|
||||
UBlocks.GREEN_APPLE_LEAVES, UBlocks.SWEET_APPLE_LEAVES, UBlocks.SOUR_APPLE_LEAVES,
|
||||
UBlocks.GOLDEN_OAK_LEAVES, UBlocks.MANGO_LEAVES
|
||||
};
|
||||
|
||||
getOrCreateTagBuilder(BlockTags.LEAVES).add(leaves);
|
||||
getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(leaves);
|
||||
|
||||
Block[] burnableLogs = { UBlocks.GOLDEN_OAK_LOG };
|
||||
getOrCreateTagBuilder(BlockTags.LOGS).add(burnableLogs);
|
||||
getOrCreateTagBuilder(BlockTags.LOGS_THAT_BURN).add(burnableLogs);
|
||||
|
||||
var saplings = Tree.REGISTRY.stream().flatMap(tree -> tree.sapling().stream()).toArray(Block[]::new);
|
||||
|
||||
getOrCreateTagBuilder(BlockTags.SAPLINGS).add(saplings);
|
||||
getOrCreateTagBuilder(BlockTags.MAINTAINS_FARMLAND).add(saplings);
|
||||
getOrCreateTagBuilder(BlockTags.GUARDED_BY_PIGLINS).add(UBlocks.GOLDEN_OAK_LEAVES, UBlocks.GOLDEN_OAK_LOG, UBlocks.GOLDEN_OAK_SPROUT, UBlocks.GOLDEN_APPLE);
|
||||
}
|
||||
|
||||
private void addZapWoodset() {
|
||||
getOrCreateTagBuilder(BlockTags.LEAVES).add(UBlocks.ZAP_LEAVES, UBlocks.FLOWERING_ZAP_LEAVES);
|
||||
getOrCreateTagBuilder(UTags.POLEARM_MINEABLE).add(
|
||||
UBlocks.ZAP_LEAVES, UBlocks.FLOWERING_ZAP_LEAVES,
|
||||
UBlocks.ZAP_PLANKS,
|
||||
UBlocks.ZAP_LOG, UBlocks.ZAP_WOOD, UBlocks.STRIPPED_ZAP_LOG, UBlocks.STRIPPED_ZAP_WOOD,
|
||||
UBlocks.ZAP_FENCE_GATE, UBlocks.ZAP_FENCE,
|
||||
UBlocks.ZAP_SLAB,
|
||||
UBlocks.ZAP_STAIRS
|
||||
);
|
||||
|
||||
getOrCreateTagBuilder(UTags.Blocks.ZAP_LOGS).add(UBlocks.ZAP_LOG, UBlocks.ZAP_WOOD, UBlocks.STRIPPED_ZAP_LOG, UBlocks.STRIPPED_ZAP_WOOD);
|
||||
getOrCreateTagBuilder(UTags.Blocks.WAXED_ZAP_LOGS).add(UBlocks.WAXED_ZAP_LOG, UBlocks.WAXED_ZAP_WOOD, UBlocks.WAXED_STRIPPED_ZAP_LOG, UBlocks.WAXED_STRIPPED_ZAP_WOOD);
|
||||
getOrCreateTagBuilder(BlockTags.LOGS).forceAddTag(UTags.Blocks.ZAP_LOGS).forceAddTag(UTags.Blocks.WAXED_ZAP_LOGS);
|
||||
getOrCreateTagBuilder(BlockTags.LOGS_THAT_BURN).forceAddTag(UTags.Blocks.ZAP_LOGS);
|
||||
getOrCreateTagBuilder(BlockTags.PLANKS).add(UBlocks.ZAP_PLANKS, UBlocks.WAXED_ZAP_PLANKS);
|
||||
|
||||
//getOrCreateTagBuilder(BlockTags.WOODEN_BUTTONS).add(UBlocks.ZAP_BUTTON);
|
||||
//getOrCreateTagBuilder(BlockTags.WOODEN_DOORS).add(UBlocks.ZAP_DOOR);
|
||||
getOrCreateTagBuilder(BlockTags.FENCE_GATES).add(UBlocks.ZAP_FENCE_GATE, UBlocks.WAXED_ZAP_FENCE_GATE);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_FENCES).add(UBlocks.ZAP_FENCE, UBlocks.WAXED_ZAP_FENCE);
|
||||
//getOrCreateTagBuilder(BlockTags.PRESSURE_PLATES).add(UBlocks.ZAP_PRESSURE_PLATE);
|
||||
//getOrCreateTagBuilder(BlockTags.WOODEN_PRESSURE_PLATES).add(UBlocks.ZAP_PRESSURE_PLATE);
|
||||
getOrCreateTagBuilder(BlockTags.SLABS).add(UBlocks.ZAP_SLAB, UBlocks.WAXED_ZAP_SLAB);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_SLABS).add(UBlocks.ZAP_SLAB, UBlocks.WAXED_ZAP_SLAB);
|
||||
getOrCreateTagBuilder(BlockTags.STAIRS).add(UBlocks.ZAP_STAIRS, UBlocks.WAXED_ZAP_STAIRS);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_STAIRS).add(UBlocks.ZAP_STAIRS, UBlocks.WAXED_ZAP_STAIRS);
|
||||
//getOrCreateTagBuilder(BlockTags.TRAPDOORS).add(UBlocks.ZAP_TRAPDOOR);
|
||||
//getOrCreateTagBuilder(BlockTags.WOODEN_TRAPDOORS).add(UBlocks.ZAP_TRAPDOOR);
|
||||
}
|
||||
|
||||
private void addPalmWoodset() {
|
||||
getOrCreateTagBuilder(BlockTags.LEAVES).add(UBlocks.PALM_LEAVES);
|
||||
getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(UBlocks.PALM_LEAVES);
|
||||
getOrCreateTagBuilder(UTags.Blocks.PALM_LOGS).add(UBlocks.PALM_LOG, UBlocks.PALM_WOOD, UBlocks.STRIPPED_PALM_LOG, UBlocks.STRIPPED_PALM_WOOD);
|
||||
getOrCreateTagBuilder(BlockTags.LOGS).forceAddTag(UTags.Blocks.PALM_LOGS);
|
||||
getOrCreateTagBuilder(BlockTags.LOGS_THAT_BURN).forceAddTag(UTags.Blocks.PALM_LOGS);
|
||||
getOrCreateTagBuilder(BlockTags.PLANKS).add(UBlocks.PALM_PLANKS);
|
||||
addSign(UBlocks.PALM_SIGN, UBlocks.PALM_WALL_SIGN, UBlocks.PALM_HANGING_SIGN, UBlocks.PALM_WALL_HANGING_SIGN);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_BUTTONS).add(UBlocks.PALM_BUTTON);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_DOORS).add(UBlocks.PALM_DOOR);
|
||||
getOrCreateTagBuilder(BlockTags.FENCE_GATES).add(UBlocks.PALM_FENCE_GATE);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_FENCES).add(UBlocks.PALM_FENCE);
|
||||
getOrCreateTagBuilder(BlockTags.PRESSURE_PLATES).add(UBlocks.PALM_PRESSURE_PLATE);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_PRESSURE_PLATES).add(UBlocks.PALM_PRESSURE_PLATE);
|
||||
getOrCreateTagBuilder(BlockTags.SLABS).add(UBlocks.PALM_SLAB);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_SLABS).add(UBlocks.PALM_SLAB);
|
||||
getOrCreateTagBuilder(BlockTags.STAIRS).add(UBlocks.PALM_STAIRS);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_STAIRS).add(UBlocks.PALM_STAIRS);
|
||||
getOrCreateTagBuilder(BlockTags.TRAPDOORS).add(UBlocks.PALM_TRAPDOOR);
|
||||
getOrCreateTagBuilder(BlockTags.WOODEN_TRAPDOORS).add(UBlocks.PALM_TRAPDOOR);
|
||||
}
|
||||
|
||||
private void addCloudBlocksets() {
|
||||
getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(
|
||||
UBlocks.CLOUD_BRICKS, UBlocks.CLOUD_BRICK_SLAB, UBlocks.CLOUD_BRICK_STAIRS, UBlocks.COMPACTED_CLOUD_BRICKS, UBlocks.CARVED_CLOUD
|
||||
);
|
||||
getOrCreateTagBuilder(BlockTags.AXE_MINEABLE).add(
|
||||
UBlocks.CLOUD_PLANKS, UBlocks.CLOUD_PLANK_SLAB, UBlocks.CLOUD_PLANK_STAIRS, UBlocks.COMPACTED_CLOUD_PLANKS
|
||||
);
|
||||
|
||||
getOrCreateTagBuilder(UTags.Blocks.CLOUD_BEDS).add(UBlocks.CLOUD_BED);
|
||||
getOrCreateTagBuilder(UTags.Blocks.CLOUD_SLABS).add(
|
||||
UBlocks.CLOUD_SLAB, UBlocks.SOGGY_CLOUD_SLAB, UBlocks.DENSE_CLOUD_SLAB, UBlocks.ETCHED_CLOUD_SLAB,
|
||||
UBlocks.CLOUD_PLANK_SLAB, UBlocks.CLOUD_BRICK_SLAB
|
||||
);
|
||||
getOrCreateTagBuilder(UTags.Blocks.CLOUD_STAIRS).add(
|
||||
UBlocks.CLOUD_STAIRS, UBlocks.SOGGY_CLOUD_STAIRS, UBlocks.DENSE_CLOUD_STAIRS, UBlocks.ETCHED_CLOUD_STAIRS,
|
||||
UBlocks.CLOUD_PLANK_STAIRS, UBlocks.CLOUD_BRICK_STAIRS
|
||||
);
|
||||
getOrCreateTagBuilder(UTags.Blocks.CLOUD_BLOCKS).add(
|
||||
UBlocks.CLOUD, UBlocks.CLOUD_PLANKS, UBlocks.CLOUD_BRICKS, UBlocks.DENSE_CLOUD,
|
||||
UBlocks.ETCHED_CLOUD, UBlocks.CARVED_CLOUD, UBlocks.CLOUD_PILLAR,
|
||||
UBlocks.COMPACTED_CLOUD, UBlocks.COMPACTED_CLOUD_PLANKS, UBlocks.COMPACTED_CLOUD_BRICKS,
|
||||
UBlocks.UNSTABLE_CLOUD, UBlocks.SOGGY_CLOUD, UBlocks.SHAPING_BENCH
|
||||
);
|
||||
}
|
||||
|
||||
private void addChitinBlocksets() {
|
||||
getOrCreateTagBuilder(UTags.Blocks.CHITIN_BLOCKS).add(
|
||||
UBlocks.CHITIN, UBlocks.SURFACE_CHITIN,
|
||||
UBlocks.CHISELLED_CHITIN, UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHISELLED_CHITIN_SLAB, UBlocks.CHISELLED_CHITIN_STAIRS,
|
||||
UBlocks.CHITIN_SPIKES
|
||||
);
|
||||
|
||||
|
||||
getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(
|
||||
UBlocks.CHITIN_SPIKES,
|
||||
UBlocks.CHISELLED_CHITIN, UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHISELLED_CHITIN_SLAB, UBlocks.CHISELLED_CHITIN_STAIRS
|
||||
);
|
||||
getOrCreateTagBuilder(BlockTags.SHOVEL_MINEABLE).add(UBlocks.CHITIN, UBlocks.SURFACE_CHITIN);
|
||||
}
|
||||
|
||||
private void addSign(Block standing, Block wall, Block hanging, Block wallHanging) {
|
||||
getOrCreateTagBuilder(BlockTags.STANDING_SIGNS).add(standing);
|
||||
getOrCreateTagBuilder(BlockTags.WALL_SIGNS).add(wall);
|
||||
|
||||
getOrCreateTagBuilder(BlockTags.CEILING_HANGING_SIGNS).add(hanging);
|
||||
getOrCreateTagBuilder(BlockTags.WALL_HANGING_SIGNS).add(wallHanging);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.UConventionalTags;
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.datagen.Datagen;
|
||||
import com.minelittlepony.unicopia.datagen.ItemFamilies;
|
||||
import com.minelittlepony.unicopia.item.BedsheetsItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.RegistryWrapper;
|
||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||
import net.minecraft.registry.tag.BlockTags;
|
||||
import net.minecraft.registry.tag.ItemTags;
|
||||
import net.minecraft.registry.tag.TagBuilder;
|
||||
import net.minecraft.registry.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
|
||||
|
||||
|
||||
private final UBlockTagProvider blockTagProvider;
|
||||
|
||||
public UItemTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture, UBlockTagProvider blockTagProvider) {
|
||||
super(output, registriesFuture, blockTagProvider);
|
||||
this.blockTagProvider = blockTagProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(TagKey<Block> blockTag, TagKey<Item> itemTag) {
|
||||
TagBuilder blockTagBuilder = Objects.requireNonNull(blockTagProvider, "Pass Block tag provider via constructor to use copy").getTagBuilder(blockTag);
|
||||
TagBuilder itemTagBuilder = getTagBuilder(itemTag);
|
||||
blockTagBuilder.build().forEach(entry -> {
|
||||
if (entry.canAdd(Registries.ITEM::containsId, tagId -> getTagBuilder(TagKey.of(RegistryKeys.ITEM, tagId)) != null)) {
|
||||
itemTagBuilder.add(entry);
|
||||
} else {
|
||||
Datagen.LOGGER.warn("Cannot copy missing entry {} to item tag {}", entry, itemTag.id());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(WrapperLookup arg) {
|
||||
copyBlockTags();
|
||||
exportConventionalTags();
|
||||
getOrCreateTagBuilder(ItemTags.BOOKSHELF_BOOKS).add(UItems.SPELLBOOK);
|
||||
getOrCreateTagBuilder(ItemTags.BEDS).add(UItems.CLOTH_BED, UItems.CLOUD_BED);
|
||||
|
||||
getOrCreateTagBuilder(ItemTags.CHEST_BOATS).add(UItems.PALM_CHEST_BOAT);
|
||||
getOrCreateTagBuilder(ItemTags.BOATS).add(UItems.PALM_BOAT);
|
||||
getOrCreateTagBuilder(ItemTags.MUSIC_DISCS).add(ItemFamilies.MUSIC_DISCS);
|
||||
getOrCreateTagBuilder(ItemTags.CREEPER_DROP_MUSIC_DISCS).add(UItems.MUSIC_DISC_CRUSADE, UItems.MUSIC_DISC_FUNK, UItems.MUSIC_DISC_PET, UItems.MUSIC_DISC_POPULAR);
|
||||
|
||||
getOrCreateTagBuilder(ItemTags.SIGNS).add(UBlocks.PALM_SIGN.asItem());
|
||||
getOrCreateTagBuilder(ItemTags.HANGING_SIGNS).add(UBlocks.PALM_HANGING_SIGN.asItem());
|
||||
|
||||
getOrCreateTagBuilder(UTags.HORSE_SHOES).add(ItemFamilies.HORSE_SHOES);
|
||||
getOrCreateTagBuilder(UTags.POLEARMS).add(ItemFamilies.POLEARMS);
|
||||
|
||||
getOrCreateTagBuilder(ItemTags.TOOLS).addTag(UTags.HORSE_SHOES).addTag(UTags.POLEARMS);
|
||||
|
||||
getOrCreateTagBuilder(UTags.BASKETS).add(ItemFamilies.BASKETS);
|
||||
getOrCreateTagBuilder(UTags.BADGES).add(Race.REGISTRY.stream()
|
||||
.map(race -> race.getId().withPath(p -> p + "_badge"))
|
||||
.flatMap(id -> Registries.ITEM.getOrEmpty(id).stream())
|
||||
.toArray(Item[]::new));
|
||||
getOrCreateTagBuilder(UTags.BED_SHEETS).add(BedsheetsItem.ITEMS.values().stream().toArray(Item[]::new));
|
||||
getOrCreateTagBuilder(UTags.APPLE_SEEDS).add(UItems.GREEN_APPLE_SEEDS, UItems.SWEET_APPLE_SEEDS, UItems.SOUR_APPLE_SEEDS);
|
||||
getOrCreateTagBuilder(UTags.MAGIC_FEATHERS).add(UItems.PEGASUS_FEATHER, UItems.GRYPHON_FEATHER);
|
||||
getOrCreateTagBuilder(UTags.FRESH_APPLES).add(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE);
|
||||
getOrCreateTagBuilder(UTags.CLOUD_JARS).add(UItems.RAIN_CLOUD_JAR, UItems.STORM_CLOUD_JAR);
|
||||
getOrCreateTagBuilder(UTags.PIES).add(UItems.APPLE_PIE, UItems.APPLE_PIE_HOOF);
|
||||
|
||||
// technical tags
|
||||
getOrCreateTagBuilder(ItemTags.VILLAGER_PLANTABLE_SEEDS).addTag(UTags.APPLE_SEEDS);
|
||||
getOrCreateTagBuilder(UTags.CAN_CUT_PIE).forceAddTag(ConventionalItemTags.SHEARS).addOptionalTag(UConventionalTags.TOOL_KNIVES);
|
||||
getOrCreateTagBuilder(UTags.COOLS_OFF_KIRINS).add(Items.MELON_SLICE, UItems.JUICE).forceAddTag(ConventionalItemTags.WATER_BUCKETS);
|
||||
getOrCreateTagBuilder(UTags.FALLS_SLOWLY).add(Items.FEATHER, UItems.CLOUD_LUMP).forceAddTag(UTags.MAGIC_FEATHERS);
|
||||
getOrCreateTagBuilder(UTags.IS_DELIVERED_AGGRESSIVELY).forceAddTag(ItemTags.ANVIL);
|
||||
getOrCreateTagBuilder(UTags.SPOOKED_MOB_DROPS).add(Items.BRICK);
|
||||
getOrCreateTagBuilder(UTags.SHADES).add(
|
||||
Items.CARVED_PUMPKIN, Items.SKELETON_SKULL, Items.WITHER_SKELETON_SKULL, Items.PLAYER_HEAD,
|
||||
Items.ZOMBIE_HEAD, Items.CREEPER_HEAD, Items.DRAGON_HEAD, Items.PIGLIN_HEAD,
|
||||
UItems.SUNGLASSES
|
||||
);
|
||||
getOrCreateTagBuilder(UTags.FLOATS_ON_CLOUDS)
|
||||
.forceAddTag(UTags.Items.CLOUD_BEDS)
|
||||
.forceAddTag(UTags.Items.CLOUD_SLABS)
|
||||
.forceAddTag(UTags.Items.CLOUD_STAIRS)
|
||||
.forceAddTag(UTags.Items.CLOUD_BLOCKS)
|
||||
.add(UItems.CLOUD_LUMP);
|
||||
getOrCreateTagBuilder(UTags.HAS_NO_TRAITS).add(
|
||||
Items.AIR, Items.SPAWNER, Items.STRUCTURE_VOID, Items.STRUCTURE_BLOCK,
|
||||
Items.COMMAND_BLOCK, Items.CHAIN_COMMAND_BLOCK, Items.REPEATING_COMMAND_BLOCK,
|
||||
Items.LIGHT, Items.JIGSAW, Items.BARRIER, Items.BEDROCK, Items.END_PORTAL_FRAME,
|
||||
Items.DEBUG_STICK, Items.COMMAND_BLOCK_MINECART,
|
||||
UItems.PLUNDER_VINE
|
||||
).forceAddTag(UTags.BADGES);
|
||||
getOrCreateTagBuilder(UTags.LOOT_BUG_HIGH_VALUE_DROPS).add(
|
||||
Items.DIAMOND, Items.GOLDEN_APPLE, Items.GOLDEN_CARROT,
|
||||
Items.GOLDEN_HELMET, Items.GOLDEN_BOOTS, Items.GOLDEN_LEGGINGS, Items.GOLDEN_CHESTPLATE,
|
||||
Items.GOLDEN_HORSE_ARMOR,
|
||||
Items.GOLDEN_PICKAXE, Items.GOLDEN_SHOVEL, Items.GOLDEN_AXE, Items.GOLDEN_SWORD, Items.GOLDEN_HOE,
|
||||
UItems.GOLDEN_HORSE_SHOE, UItems.GOLDEN_POLEARM, UItems.GOLDEN_FEATHER, UItems.GOLDEN_WING,
|
||||
UItems.GOLDEN_OAK_SEEDS
|
||||
).forceAddTag(ConventionalItemTags.NUGGETS)
|
||||
.forceAddTag(ConventionalItemTags.GOLD_INGOTS).forceAddTag(ConventionalItemTags.RAW_GOLD_ORES).forceAddTag(ConventionalItemTags.RAW_GOLD_BLOCKS)
|
||||
.addOptionalTag(new Identifier("farmersdelight:golden_knife"));
|
||||
|
||||
exportFarmersDelightItems();
|
||||
}
|
||||
|
||||
private void copyBlockTags() {
|
||||
copy(BlockTags.LEAVES, ItemTags.LEAVES);
|
||||
copy(BlockTags.LOGS_THAT_BURN, ItemTags.LOGS_THAT_BURN);
|
||||
copy(BlockTags.LOGS, ItemTags.LOGS);
|
||||
copy(BlockTags.PLANKS, ItemTags.PLANKS);
|
||||
copy(BlockTags.WOODEN_BUTTONS, ItemTags.WOODEN_BUTTONS);
|
||||
copy(BlockTags.WOODEN_DOORS, ItemTags.WOODEN_DOORS);
|
||||
copy(BlockTags.FENCE_GATES, ItemTags.FENCE_GATES);
|
||||
copy(BlockTags.WOODEN_FENCES, ItemTags.WOODEN_FENCES);
|
||||
copy(BlockTags.WOODEN_PRESSURE_PLATES, ItemTags.WOODEN_PRESSURE_PLATES);
|
||||
copy(BlockTags.SLABS, ItemTags.SLABS);
|
||||
copy(BlockTags.WOODEN_SLABS, ItemTags.WOODEN_SLABS);
|
||||
copy(BlockTags.STAIRS, ItemTags.STAIRS);
|
||||
copy(BlockTags.WOODEN_STAIRS, ItemTags.WOODEN_STAIRS);
|
||||
copy(BlockTags.TRAPDOORS, ItemTags.TRAPDOORS);
|
||||
copy(BlockTags.WOODEN_TRAPDOORS, ItemTags.WOODEN_TRAPDOORS);
|
||||
copy(BlockTags.SAPLINGS, ItemTags.SAPLINGS);
|
||||
|
||||
copy(UTags.Blocks.ZAP_LOGS, UTags.Items.ZAP_LOGS);
|
||||
copy(UTags.Blocks.WAXED_ZAP_LOGS, UTags.Items.WAXED_ZAP_LOGS);
|
||||
copy(UTags.Blocks.PALM_LOGS, UTags.Items.PALM_LOGS);
|
||||
copy(UTags.Blocks.CLOUD_BEDS, UTags.Items.CLOUD_BEDS);
|
||||
copy(UTags.Blocks.CLOUD_SLABS, UTags.Items.CLOUD_SLABS);
|
||||
copy(UTags.Blocks.CLOUD_STAIRS, UTags.Items.CLOUD_STAIRS);
|
||||
copy(UTags.Blocks.CLOUD_BLOCKS, UTags.Items.CLOUD_BLOCKS);
|
||||
copy(UTags.Blocks.CHITIN_BLOCKS, UTags.Items.CHITIN_BLOCKS);
|
||||
}
|
||||
|
||||
private void exportConventionalTags() {
|
||||
getOrCreateTagBuilder(UConventionalTags.ACORNS).add(UItems.ACORN);
|
||||
getOrCreateTagBuilder(UConventionalTags.APPLES)
|
||||
.add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, UItems.ROTTEN_APPLE)
|
||||
.forceAddTag(UTags.FRESH_APPLES)
|
||||
.addOptionalTag(new Identifier("c", "pyrite_apples")) // no idea which mod add pyrite apples
|
||||
;
|
||||
getOrCreateTagBuilder(UConventionalTags.BANANAS).add(UItems.BANANA);
|
||||
getOrCreateTagBuilder(UConventionalTags.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON);
|
||||
getOrCreateTagBuilder(UConventionalTags.STICKS).add(Items.STICK);
|
||||
getOrCreateTagBuilder(UConventionalTags.PINECONES).add(UItems.PINECONE);
|
||||
getOrCreateTagBuilder(UConventionalTags.PINEAPPLES).add(UItems.PINEAPPLE);
|
||||
getOrCreateTagBuilder(UConventionalTags.MANGOES).add(UItems.MANGO);
|
||||
getOrCreateTagBuilder(UConventionalTags.MUSHROOMS).add(Items.RED_MUSHROOM, Items.BROWN_MUSHROOM);
|
||||
getOrCreateTagBuilder(UConventionalTags.MUFFINS).add(UItems.MUFFIN);
|
||||
getOrCreateTagBuilder(UConventionalTags.SEEDS).add(Items.BEETROOT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.TORCHFLOWER_SEEDS, Items.WHEAT_SEEDS)
|
||||
.add(UItems.OAT_SEEDS)
|
||||
.forceAddTag(UTags.APPLE_SEEDS);
|
||||
getOrCreateTagBuilder(UConventionalTags.OEATMEALS).add(UItems.OATMEAL);
|
||||
getOrCreateTagBuilder(UConventionalTags.GRAIN).add(Items.WHEAT, UItems.OATS);
|
||||
getOrCreateTagBuilder(UConventionalTags.NUTS).addOptionalTag(UConventionalTags.CROPS_PEANUTS);
|
||||
|
||||
getOrCreateTagBuilder(UConventionalTags.FRUITS)
|
||||
.forceAddTag(UConventionalTags.MANGOES)
|
||||
.forceAddTag(UConventionalTags.PINEAPPLES)
|
||||
.forceAddTag(UConventionalTags.APPLES)
|
||||
.forceAddTag(UConventionalTags.BANANAS);
|
||||
}
|
||||
|
||||
private void exportFarmersDelightItems() {
|
||||
getOrCreateTagBuilder(UTags.COOLS_OFF_KIRINS)
|
||||
.addOptional(new Identifier("farmersdelight:melon_popsicle"))
|
||||
.addOptional(new Identifier("farmersdelight:melon_juice"));
|
||||
getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight:cabbage_roll_ingredients"))).add(UItems.OATS, UItems.ROCK, UItems.WHEAT_WORMS);
|
||||
getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight:comfort_foods"))).add(UItems.OATMEAL, UItems.ROCK_STEW, UItems.MUFFIN);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.datagen.DataCollector;
|
||||
import com.minelittlepony.unicopia.item.BedsheetsItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.DataOutput;
|
||||
import net.minecraft.data.DataWriter;
|
||||
import net.minecraft.data.client.BlockStateModelGenerator;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.data.client.ItemModelGenerator;
|
||||
import net.minecraft.data.client.ModelIds;
|
||||
import net.minecraft.data.client.TextureKey;
|
||||
import net.minecraft.data.client.TextureMap;
|
||||
|
||||
public class UModelProvider extends FabricModelProvider {
|
||||
public static final Map<Block, Item> FRUITS = Map.of(UBlocks.GREEN_APPLE, UItems.GREEN_APPLE,
|
||||
UBlocks.GOLDEN_APPLE, Items.GOLDEN_APPLE,
|
||||
UBlocks.MANGO, UItems.MANGO,
|
||||
UBlocks.SOUR_APPLE, UItems.SOUR_APPLE,
|
||||
UBlocks.SWEET_APPLE, UItems.SWEET_APPLE,
|
||||
UBlocks.ZAP_APPLE, UItems.ZAP_APPLE,
|
||||
UBlocks.ZAP_BULB, UItems.ZAP_BULB
|
||||
);
|
||||
|
||||
private final DataCollector seasonsModels;
|
||||
|
||||
public UModelProvider(FabricDataOutput output) {
|
||||
super(output);
|
||||
seasonsModels = new DataCollector(output.getResolver(DataOutput.OutputType.RESOURCE_PACK, "seasons/models"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateBlockStateModels(BlockStateModelGenerator modelGenerator0) {
|
||||
UBlockStateModelGenerator.create(modelGenerator0).register();
|
||||
new SeasonsModelGenerator(modelGenerator0, seasonsModels.prime()).register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(DataWriter writer) {
|
||||
return CompletableFuture.allOf(
|
||||
super.run(writer),
|
||||
seasonsModels.upload(writer)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateItemModels(ItemModelGenerator itemModelGenerator) {
|
||||
ItemModels.register(itemModelGenerator,
|
||||
UItems.ACORN, UItems.APPLE_PIE_HOOF, UItems.APPLE_PIE_SLICE, UItems.APPLE_PIE,
|
||||
UItems.BANANA, UItems.BOTCHED_GEM, UItems.BROKEN_SUNGLASSES, UItems.BURNED_JUICE, UItems.BURNED_TOAST,
|
||||
UItems.CARAPACE, UItems.CLAM_SHELL, UItems.COOKED_ZAP_APPLE, UItems.CLOUD_LUMP, UItems.CRISPY_HAY_FRIES, UItems.CRYSTAL_HEART, UItems.CRYSTAL_SHARD,
|
||||
UItems.DAFFODIL_DAISY_SANDWICH, UItems.DRAGON_BREATH_SCROLL,
|
||||
UItems.EMPTY_JAR,
|
||||
UItems.FRIENDSHIP_BRACELET,
|
||||
UItems.GIANT_BALLOON, UItems.GOLDEN_FEATHER, UItems.GOLDEN_OAK_SEEDS, UItems.GOLDEN_WING, UItems.GREEN_APPLE_SEEDS, UItems.GREEN_APPLE, UItems.GROGARS_BELL,
|
||||
UItems.GRYPHON_FEATHER,
|
||||
UItems.HAY_BURGER, UItems.HAY_FRIES, UItems.HORSE_SHOE_FRIES,
|
||||
UItems.IMPORTED_OATS,
|
||||
UItems.JAM_TOAST, UItems.JUICE,
|
||||
UItems.LIGHTNING_JAR,
|
||||
UItems.MANGO, UItems.MUFFIN,
|
||||
UItems.OATMEAL,
|
||||
UItems.PEBBLES, UItems.PEGASUS_FEATHER, UItems.PINECONE, UItems.PINEAPPLE_CROWN,
|
||||
UItems.RAIN_CLOUD_JAR, UItems.ROCK_STEW, UItems.ROCK, UItems.ROTTEN_APPLE,
|
||||
UItems.SALT_CUBE, UItems.SCALLOP_SHELL, UItems.SHELLY, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, UItems.SPELLBOOK, UItems.STORM_CLOUD_JAR,
|
||||
UItems.SWEET_APPLE_SEEDS, UItems.SWEET_APPLE,
|
||||
UItems.TOAST, UItems.TOM, UItems.TURRET_SHELL,
|
||||
UItems.WEIRD_ROCK, UItems.WHEAT_WORMS, UBlocks.WEATHER_VANE.asItem(),
|
||||
UItems.ZAP_APPLE_JAM_JAR, UItems.ZAP_APPLE, UItems.ZAP_BULB,
|
||||
// discs
|
||||
UItems.MUSIC_DISC_CRUSADE, UItems.MUSIC_DISC_FUNK, UItems.MUSIC_DISC_PET, UItems.MUSIC_DISC_POPULAR,
|
||||
// baskets
|
||||
UItems.ACACIA_BASKET, UItems.BAMBOO_BASKET, UItems.BIRCH_BASKET, UItems.CHERRY_BASKET,
|
||||
UItems.DARK_OAK_BASKET, UItems.JUNGLE_BASKET, UItems.MANGROVE_BASKET, UItems.OAK_BASKET, UItems.SPRUCE_BASKET,
|
||||
UItems.PALM_BASKET,
|
||||
// boats
|
||||
UItems.PALM_BOAT, UItems.PALM_CHEST_BOAT,
|
||||
// horseshoes
|
||||
UItems.COPPER_HORSE_SHOE, UItems.GOLDEN_HORSE_SHOE, UItems.IRON_HORSE_SHOE, UItems.NETHERITE_HORSE_SHOE
|
||||
);
|
||||
// spawn eggs
|
||||
ItemModels.register(itemModelGenerator, ItemModels.TEMPLATE_SPAWN_EGG, UItems.BUTTERFLY_SPAWN_EGG, UItems.LOOT_BUG_SPAWN_EGG);
|
||||
// amulets
|
||||
ItemModels.register(itemModelGenerator, ItemModels.TEMPLATE_AMULET, UItems.ALICORN_AMULET, UItems.BROKEN_ALICORN_AMULET, UItems.PEARL_NECKLACE, UItems.PEGASUS_AMULET, UItems.UNICORN_AMULET);
|
||||
// mugs
|
||||
ItemModels.register(itemModelGenerator, ItemModels.TEMPLATE_MUG, UItems.CIDER, UItems.LOVE_BOTTLE, UItems.LOVE_BUCKET, UItems.LOVE_MUG, UItems.MUG);
|
||||
// jars
|
||||
ItemModels.register(itemModelGenerator, ItemModels.BUILTIN_ENTITY, UItems.FILLED_JAR);
|
||||
// eyewear
|
||||
ItemModels.register(itemModelGenerator, ItemModels.TEMPLATE_EYEWEAR, UItems.SUNGLASSES);
|
||||
// staffs
|
||||
ItemModels.register(itemModelGenerator, ItemModels.HANDHELD_STAFF, UItems.MEADOWBROOKS_STAFF);
|
||||
ItemModels.item("handheld_staff", TextureKey.LAYER0, TextureKey.LAYER1).upload(ModelIds.getItemModelId(UItems.MAGIC_STAFF), new TextureMap()
|
||||
.put(TextureKey.LAYER0, ModelIds.getItemSubModelId(UItems.MAGIC_STAFF, "_base"))
|
||||
.put(TextureKey.LAYER1, ModelIds.getItemSubModelId(UItems.MAGIC_STAFF, "_magic")), itemModelGenerator.writer);
|
||||
|
||||
// polearms
|
||||
List.of(UItems.DIAMOND_POLEARM, UItems.GOLDEN_POLEARM, UItems.NETHERITE_POLEARM, UItems.STONE_POLEARM, UItems.WOODEN_POLEARM, UItems.IRON_POLEARM).forEach(item -> ItemModels.registerPolearm(itemModelGenerator, item));
|
||||
// sheets
|
||||
ItemModels.register(itemModelGenerator, BedsheetsItem.ITEMS.values().stream().toArray(Item[]::new));
|
||||
// badges
|
||||
ItemModels.register(itemModelGenerator, Race.REGISTRY.stream()
|
||||
.map(race -> race.getId().withPath(p -> p + "_badge"))
|
||||
.flatMap(id -> Registries.ITEM.getOrEmpty(id).stream())
|
||||
.toArray(Item[]::new));
|
||||
|
||||
// butterflies
|
||||
ItemModels.registerButterfly(itemModelGenerator, UItems.BUTTERFLY);
|
||||
ItemModels.registerSpectralBlock(itemModelGenerator, UItems.SPECTRAL_CLOCK);
|
||||
ModelOverrides.of(ItemModels.GENERATED)
|
||||
.addUniform("count", 2, 16, ModelIds.getItemModelId(UItems.ROCK_CANDY))
|
||||
.upload(UItems.ROCK_CANDY, itemModelGenerator);
|
||||
|
||||
List.of(UItems.PINEAPPLE, UItems.CANDIED_APPLE).forEach(item -> {
|
||||
ModelOverrides.of(ItemModels.GENERATED)
|
||||
.addOverride(ModelIds.getItemSubModelId(item, "_bite1"), "damage", 0.3F)
|
||||
.addOverride(ModelIds.getItemSubModelId(item, "_bite2"), "damage", 0.6F)
|
||||
.upload(item, itemModelGenerator);
|
||||
});
|
||||
|
||||
// gemstone
|
||||
ModelOverrides.of(ItemModels.GENERATED)
|
||||
.addOverride(ModelIds.getItemSubModelId(UItems.GEMSTONE, "_pure"), "affinity", 0)
|
||||
.addOverride(ModelIds.getItemSubModelId(UItems.GEMSTONE, "_corrupted"), "affinity", 1)
|
||||
.upload(UItems.GEMSTONE, itemModelGenerator);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.NoSuchElementException;
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.datagen.ItemFamilies;
|
||||
import com.minelittlepony.unicopia.datagen.UBlockFamilies;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.data.server.recipe.RecipeExporter;
|
||||
import net.minecraft.data.server.recipe.RecipeProvider;
|
||||
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
|
||||
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
|
||||
import net.minecraft.data.server.recipe.VanillaRecipeProvider;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.recipe.book.RecipeCategory;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class URecipeProvider extends FabricRecipeProvider {
|
||||
public URecipeProvider(FabricDataOutput output) {
|
||||
super(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(RecipeExporter exporter) {
|
||||
Arrays.stream(ItemFamilies.BASKETS).forEach(basket -> {
|
||||
offerBasketRecipe(exporter, basket, getMaterial(basket, "_basket", "_planks"));
|
||||
});
|
||||
|
||||
offerBoatRecipe(exporter, UItems.PALM_BOAT, UBlocks.PALM_PLANKS);
|
||||
offerChestBoatRecipe(exporter, UItems.PALM_CHEST_BOAT, UItems.PALM_BOAT);
|
||||
offerHangingSignRecipe(exporter, UBlocks.PALM_HANGING_SIGN, UBlocks.PALM_PLANKS);
|
||||
offerPlanksRecipe(exporter, UBlocks.PALM_PLANKS, UTags.Items.PALM_LOGS, 4);
|
||||
offerPlanksRecipe(exporter, UBlocks.ZAP_PLANKS, UTags.Items.ZAP_LOGS, 4);
|
||||
offerPlanksRecipe(exporter, UBlocks.WAXED_ZAP_PLANKS, UTags.Items.WAXED_ZAP_LOGS, 4);
|
||||
offerBarkBlockRecipe(exporter, UBlocks.PALM_WOOD, UBlocks.PALM_LOG);
|
||||
offerBarkBlockRecipe(exporter, UBlocks.ZAP_WOOD, UBlocks.ZAP_LOG);
|
||||
offerBarkBlockRecipe(exporter, UBlocks.WAXED_ZAP_WOOD, UBlocks.WAXED_ZAP_LOG);
|
||||
|
||||
generateFamily(exporter, UBlockFamilies.PALM);
|
||||
generateFamily(exporter, UBlockFamilies.ZAP);
|
||||
generateFamily(exporter, UBlockFamilies.WAXED_ZAP);
|
||||
offerWaxingRecipes(exporter);
|
||||
}
|
||||
|
||||
private static Item getMaterial(Item output, String toStrip, String suffex) {
|
||||
Identifier id = Registries.ITEM.getId(output).withPath(p -> p.replace(toStrip, "") + suffex);
|
||||
return Registries.ITEM.getOrEmpty(id)
|
||||
.or(() -> Registries.ITEM.getOrEmpty(new Identifier(Identifier.DEFAULT_NAMESPACE, id.getPath())))
|
||||
.orElseThrow(() -> new NoSuchElementException("No item with id " + id));
|
||||
}
|
||||
|
||||
public static void offerBasketRecipe(RecipeExporter exporter, ItemConvertible output, ItemConvertible input) {
|
||||
ShapedRecipeJsonBuilder.create(RecipeCategory.TRANSPORTATION, output)
|
||||
.input(Character.valueOf('#'), input)
|
||||
.pattern("# #")
|
||||
.pattern("# #")
|
||||
.pattern("###")
|
||||
.group("basket")
|
||||
.criterion(VanillaRecipeProvider.hasItem(input), VanillaRecipeProvider.conditionsFromItem(input))
|
||||
.offerTo(exporter);
|
||||
}
|
||||
|
||||
public static void offerWaxingRecipes(RecipeExporter exporter) {
|
||||
UBlockFamilies.WAXED_ZAP.getVariants().forEach((variant, output) -> {
|
||||
Block input = UBlockFamilies.ZAP.getVariant(variant);
|
||||
offerWaxingRecipe(exporter, output, input);
|
||||
});
|
||||
offerWaxingRecipe(exporter, UBlocks.WAXED_ZAP_PLANKS, UBlocks.ZAP_PLANKS);
|
||||
offerWaxingRecipe(exporter, UBlocks.WAXED_ZAP_WOOD, UBlocks.ZAP_WOOD);
|
||||
}
|
||||
|
||||
public static void offerWaxingRecipe(RecipeExporter exporter, ItemConvertible output, ItemConvertible input) {
|
||||
ShapelessRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, output)
|
||||
.input(input)
|
||||
.input(Items.HONEYCOMB).group(RecipeProvider.getItemPath(output))
|
||||
.criterion(RecipeProvider.hasItem(input), RecipeProvider.conditionsFromItem(input))
|
||||
.offerTo(exporter, RecipeProvider.convertBetween(output, Items.HONEYCOMB));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers.loot;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.data.server.loottable.BlockLootTableGenerator;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.condition.MatchToolLootCondition;
|
||||
import net.minecraft.loot.condition.RandomChanceLootCondition;
|
||||
import net.minecraft.loot.condition.TableBonusLootCondition;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.ApplyBonusLootFunction;
|
||||
import net.minecraft.loot.function.SetCountLootFunction;
|
||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
||||
import net.minecraft.loot.provider.number.UniformLootNumberProvider;
|
||||
import net.minecraft.predicate.NumberRange;
|
||||
import net.minecraft.predicate.item.EnchantmentPredicate;
|
||||
import net.minecraft.predicate.item.ItemPredicate;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvider {
|
||||
public static final LootCondition.Builder WITH_GEM_FINDER = MatchToolLootCondition.builder(ItemPredicate.Builder.create().enchantment(new EnchantmentPredicate(UEnchantments.GEM_FINDER, NumberRange.IntRange.atLeast(1))));
|
||||
|
||||
public static final LootCondition.Builder WITHOUT_SILK_TOUCH_AND_GEM_FINDER = WITHOUT_SILK_TOUCH.and(WITH_GEM_FINDER);
|
||||
public static final float[] GEMSTONES_FORTUNE_CHANCE = { 0.1F, 0.14285715F, 0.25F, 1F };
|
||||
|
||||
public UBlockAdditionsLootTableProvider(FabricDataOutput dataOutput) {
|
||||
super(dataOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Block Loot Table Additions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate() {
|
||||
addVanillaDrop(Blocks.STONE, this::gemstoneDrops);
|
||||
addVanillaDrop(Blocks.DIRT, block -> gemstoneAndWormDrops(block, 2, 0.05F, 0.052222223F, 0.055F, 0.066666665F, 0.1F));
|
||||
addVanillaDrop(Blocks.COARSE_DIRT, block -> gemstoneAndWormDrops(block, 2, 0.05F, 0.052222223F, 0.055F, 0.066666665F, 0.1F));
|
||||
addVanillaDrop(Blocks.GRASS_BLOCK, block -> gemstoneAndWormDrops(block, 2, 0.05F, 0.052222223F, 0.055F, 0.066666665F, 0.1F));
|
||||
addVanillaDrop(Blocks.GRASS, block -> wormDrops(block, 2, 0.05F, 0.052222223F, 0.055F, 0.066666665F, 0.1F));
|
||||
addVanillaDrop(Blocks.MYCELIUM, block -> wormDrops(block, 3, 0.06F, 0.062222223F, 0.065F, 0.077777776F, 0.2F));
|
||||
addVanillaDrop(Blocks.PODZOL, block -> wormDrops(block, 4, 0.06F, 0.062222223F, 0.065F, 0.077777776F, 0.2F));
|
||||
addVanillaDrop(Blocks.DIAMOND_ORE, this::crystalShardDrops);
|
||||
addVanillaDrop(Blocks.DEEPSLATE_DIAMOND_ORE, this::crystalShardDrops);
|
||||
}
|
||||
|
||||
private void addVanillaDrop(Block block, Function<Block, LootTable.Builder> lootTableFunction) {
|
||||
lootTables.put(new Identifier("unicopiamc", block.getLootTableId().getPath()), lootTableFunction.apply(block));
|
||||
}
|
||||
|
||||
public LootTable.Builder wormDrops(Block block, int max, float...chance) {
|
||||
return LootTable.builder()
|
||||
.pool(LootPool.builder()
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.conditionally(WITHOUT_SILK_TOUCH)
|
||||
.with(wheatwormDrops(block, max, chance))
|
||||
);
|
||||
}
|
||||
|
||||
public LootTable.Builder gemstoneAndWormDrops(Block block, int max, float...chance) {
|
||||
return LootTable.builder()
|
||||
.pool(LootPool.builder()
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.conditionally(WITHOUT_SILK_TOUCH)
|
||||
.with(gemstoneDrops(block, 0.1F))
|
||||
.with(wheatwormDrops(block, max, chance))
|
||||
);
|
||||
}
|
||||
|
||||
public LootTable.Builder gemstoneDrops(Block block) {
|
||||
return LootTable.builder()
|
||||
.pool(LootPool.builder()
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.conditionally(WITHOUT_SILK_TOUCH)
|
||||
.with(gemstoneDrops(block, 0.1F))
|
||||
);
|
||||
}
|
||||
|
||||
public LootTable.Builder crystalShardDrops(Block block) {
|
||||
return LootTable.builder()
|
||||
.pool(LootPool.builder()
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.conditionally(WITHOUT_SILK_TOUCH)
|
||||
.with(applyExplosionDecay(block, ItemEntry.builder(UItems.CRYSTAL_SHARD)
|
||||
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2)))
|
||||
.apply(ApplyBonusLootFunction.oreDrops(Enchantments.FORTUNE))
|
||||
)
|
||||
.conditionally(RandomChanceLootCondition.builder(0.25F))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public LootPoolEntry.Builder<?> gemstoneDrops(Block block, float chance) {
|
||||
return applyExplosionDecay(block, ItemEntry.builder(UItems.GEMSTONE)
|
||||
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2)))
|
||||
)
|
||||
.conditionally(WITH_GEM_FINDER)
|
||||
.conditionally(RandomChanceLootCondition.builder(0.1F))
|
||||
.conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, GEMSTONES_FORTUNE_CHANCE));
|
||||
}
|
||||
|
||||
public LootPoolEntry.Builder<?> wheatwormDrops(Block block, int max, float...chance) {
|
||||
return applyExplosionDecay(block, ItemEntry.builder(UItems.WHEAT_WORMS)
|
||||
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, max)))
|
||||
)
|
||||
.conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, chance));
|
||||
}
|
||||
|
||||
|
||||
public static LootTable.Builder dropsWithGemfinding(Block drop, LootPoolEntry.Builder<?> child) {
|
||||
return BlockLootTableGenerator.drops(drop, WITHOUT_SILK_TOUCH_AND_GEM_FINDER, child);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers.loot;
|
||||
|
||||
import java.util.List;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.datagen.providers.UModelProvider;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.server.world.Tree;
|
||||
import com.minelittlepony.unicopia.server.world.UTreeGen;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
|
||||
import net.minecraft.block.BedBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.enums.BedPart;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.condition.TableBonusLootCondition;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.loot.function.SetCountLootFunction;
|
||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
||||
import net.minecraft.loot.provider.number.UniformLootNumberProvider;
|
||||
|
||||
public class UBlockLootTableProvider extends FabricBlockLootTableProvider {
|
||||
|
||||
public UBlockLootTableProvider(FabricDataOutput output) {
|
||||
super(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate() {
|
||||
// simple drops
|
||||
List.of(
|
||||
UBlocks.CARVED_CLOUD, UBlocks.UNSTABLE_CLOUD,
|
||||
UBlocks.CHISELLED_CHITIN_STAIRS, UBlocks.CHISELLED_CHITIN,
|
||||
UBlocks.CLOUD_BRICK_STAIRS, UBlocks.CLOUD_BRICKS,
|
||||
UBlocks.CLOUD_PLANK_STAIRS, UBlocks.CLOUD_PLANKS,
|
||||
UBlocks.CURING_JOKE,
|
||||
UBlocks.GOLDEN_OAK_LOG,
|
||||
UBlocks.HIVE,
|
||||
|
||||
UBlocks.PALM_BUTTON, UBlocks.PALM_FENCE_GATE, UBlocks.PALM_FENCE, UBlocks.PALM_LOG, UBlocks.PALM_PLANKS,
|
||||
UBlocks.PALM_PRESSURE_PLATE, UBlocks.PALM_SIGN, UBlocks.PALM_HANGING_SIGN, UBlocks.PALM_STAIRS, UBlocks.PALM_TRAPDOOR, UBlocks.PALM_WOOD,
|
||||
|
||||
UBlocks.STRIPPED_PALM_LOG, UBlocks.STRIPPED_PALM_WOOD,
|
||||
UBlocks.STRIPPED_ZAP_LOG, UBlocks.STRIPPED_ZAP_WOOD,
|
||||
|
||||
UBlocks.WAXED_STRIPPED_ZAP_LOG, UBlocks.WAXED_STRIPPED_ZAP_WOOD,
|
||||
UBlocks.WAXED_ZAP_FENCE_GATE, UBlocks.WAXED_ZAP_FENCE,
|
||||
UBlocks.WAXED_ZAP_LOG, UBlocks.WAXED_ZAP_PLANKS, UBlocks.WAXED_ZAP_STAIRS, UBlocks.WAXED_ZAP_WOOD,
|
||||
|
||||
UBlocks.WEATHER_VANE,
|
||||
|
||||
UBlocks.ZAP_FENCE_GATE, UBlocks.ZAP_FENCE,
|
||||
UBlocks.ZAP_LOG, UBlocks.ZAP_PLANKS, UBlocks.ZAP_STAIRS, UBlocks.ZAP_WOOD
|
||||
).forEach(this::addDrop);
|
||||
|
||||
// slabs
|
||||
List.of(
|
||||
UBlocks.CHISELLED_CHITIN_SLAB, UBlocks.CLOUD_BRICK_SLAB,
|
||||
UBlocks.CLOUD_PLANK_SLAB, UBlocks.PALM_SLAB, UBlocks.ZAP_SLAB, UBlocks.WAXED_ZAP_SLAB
|
||||
).forEach(slab -> addDrop(slab, this::slabDrops));
|
||||
|
||||
// fruit
|
||||
UModelProvider.FRUITS.forEach((block, drop) -> {
|
||||
if (block != UBlocks.GOLDEN_APPLE) {
|
||||
addDrop(block, drop);
|
||||
}
|
||||
});
|
||||
List.of(UBlocks.GREEN_APPLE_LEAVES, UBlocks.SOUR_APPLE_LEAVES, UBlocks.SWEET_APPLE_LEAVES, UBlocks.GOLDEN_OAK_LEAVES).forEach(block -> addDrop(block, this::fruitLeavesDrops));
|
||||
addDrop(UBlocks.MANGO_LEAVES, block -> leavesDrops(block, UTreeGen.MANGO_TREE.sapling().get(), 0.025F, 0.027777778F, 0.03125F, 0.041666668F, 0.1F)); // same chance as jungle
|
||||
addDrop(UBlocks.ZAP_LEAVES, block -> leavesDrops(block, UTreeGen.ZAP_APPLE_TREE.sapling().get(), SAPLING_DROP_CHANCE));
|
||||
addDrop(UBlocks.FLOWERING_ZAP_LEAVES, block -> leavesDrops(block, UTreeGen.ZAP_APPLE_TREE.sapling().get(), SAPLING_DROP_CHANCE));
|
||||
addDrop(UBlocks.PALM_LEAVES, block -> leavesDrops(block, UTreeGen.BANANA_TREE.sapling().get(), SAPLING_DROP_CHANCE));
|
||||
|
||||
Tree.REGISTRY.forEach(tree -> {
|
||||
tree.sapling().ifPresent(this::addDrop);
|
||||
tree.pot().ifPresent(this::addPottedPlantDrops);
|
||||
});
|
||||
|
||||
// doors
|
||||
List.of(
|
||||
UBlocks.CLOUD_DOOR, UBlocks.CRYSTAL_DOOR,
|
||||
UBlocks.DARK_OAK_DOOR, UBlocks.PALM_DOOR, UBlocks.STABLE_DOOR
|
||||
).forEach(door -> addDrop(door, this::doorDrops));
|
||||
|
||||
//beds
|
||||
List.of(
|
||||
UBlocks.CLOUD_BED, UBlocks.CLOTH_BED
|
||||
).forEach(bed -> addDrop(bed, b -> dropsWithProperty(b, BedBlock.PART, BedPart.HEAD)));
|
||||
|
||||
addDrop(UBlocks.CHITIN_SPIKES, drops(UBlocks.CHITIN_SPIKES, UItems.CARAPACE, ConstantLootNumberProvider.create(6)));
|
||||
addDrop(UBlocks.CHITIN, drops(UBlocks.CHITIN, UItems.CARAPACE, ConstantLootNumberProvider.create(9)));
|
||||
addDrop(UBlocks.SURFACE_CHITIN, drops(UBlocks.SURFACE_CHITIN, UItems.CARAPACE, ConstantLootNumberProvider.create(9)));
|
||||
|
||||
addDrop(UBlocks.CLOUD, drops(UBlocks.CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(4)));
|
||||
addDrop(UBlocks.CLOUD_STAIRS, drops(UBlocks.CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(6)));
|
||||
|
||||
addDrop(UBlocks.SOGGY_CLOUD, drops(UBlocks.CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(4)));
|
||||
addDrop(UBlocks.SOGGY_CLOUD_STAIRS, drops(UBlocks.CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(6)));
|
||||
|
||||
addDrop(UBlocks.DENSE_CLOUD, drops(UBlocks.DENSE_CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(9)));
|
||||
addDrop(UBlocks.DENSE_CLOUD_STAIRS, drops(UBlocks.DENSE_CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(13)));
|
||||
addDrop(UBlocks.ETCHED_CLOUD, drops(UBlocks.ETCHED_CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(9)));
|
||||
addDrop(UBlocks.ETCHED_CLOUD_STAIRS, drops(UBlocks.ETCHED_CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(13)));
|
||||
|
||||
addDrop(UBlocks.CLOUD_PILLAR, drops(UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, ConstantLootNumberProvider.create(6)));
|
||||
|
||||
addDrop(UBlocks.FROSTED_OBSIDIAN, Blocks.OBSIDIAN);
|
||||
}
|
||||
|
||||
private LootTable.Builder fruitLeavesDrops(Block leaves) {
|
||||
return LootTable.builder()
|
||||
.pool(LootPool.builder()
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.with(ItemEntry.builder(leaves).conditionally(WITH_SILK_TOUCH_OR_SHEARS))
|
||||
)
|
||||
.pool(LootPool.builder()
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.conditionally(WITHOUT_SILK_TOUCH_NOR_SHEARS)
|
||||
.with(
|
||||
applyExplosionDecay(leaves, ItemEntry.builder(Items.STICK)
|
||||
.apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2)))
|
||||
)
|
||||
.conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, LEAVES_STICK_DROP_CHANCE))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package com.minelittlepony.unicopia.datagen.providers.loot;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider;
|
||||
import net.minecraft.loot.LootTable.Builder;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.LootTables;
|
||||
import net.minecraft.loot.context.LootContextTypes;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.loot.entry.TagEntry;
|
||||
import net.minecraft.loot.function.SetCountLootFunction;
|
||||
import net.minecraft.loot.provider.number.UniformLootNumberProvider;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvider {
|
||||
|
||||
public UChestAdditionsLootTableProvider(FabricDataOutput dataOutput) {
|
||||
super(dataOutput, LootContextTypes.CHEST);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept(BiConsumer<Identifier, Builder> exporter) {
|
||||
acceptAdditions((id, builder) -> exporter.accept(new Identifier("unicopiamc", id.getPath()), builder));
|
||||
}
|
||||
|
||||
public void acceptAdditions(BiConsumer<Identifier, Builder> exporter) {
|
||||
exporter.accept(LootTables.ABANDONED_MINESHAFT_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(2, 4))
|
||||
.with(ItemEntry.builder(UItems.GRYPHON_FEATHER).weight(2).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 4))))
|
||||
));
|
||||
exporter.accept(LootTables.WOODLAND_MANSION_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(2, 4))
|
||||
.with(ItemEntry.builder(UItems.GRYPHON_FEATHER).weight(10).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 7))))
|
||||
.with(ItemEntry.builder(UItems.GOLDEN_WING).weight(1).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2))))
|
||||
.with(TagEntry.expandBuilder(UTags.FRESH_APPLES).weight(1).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(2, 5))))
|
||||
));
|
||||
exporter.accept(LootTables.VILLAGE_FLETCHER_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(2, 4))
|
||||
.with(ItemEntry.builder(UItems.GRYPHON_FEATHER).weight(10).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2))))
|
||||
.with(ItemEntry.builder(UItems.PEGASUS_FEATHER).weight(1).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2))))
|
||||
));
|
||||
exporter.accept(LootTables.VILLAGE_PLAINS_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(3, 4))
|
||||
.with(TagEntry.expandBuilder(UTags.FRESH_APPLES).weight(1))
|
||||
.with(TagEntry.expandBuilder(UTags.APPLE_SEEDS).weight(1))
|
||||
));
|
||||
|
||||
exporter.accept(LootTables.ANCIENT_CITY_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(0, 1))
|
||||
.with(ItemEntry.builder(UItems.GROGARS_BELL).weight(1))
|
||||
));
|
||||
exporter.accept(LootTables.BURIED_TREASURE_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
.with(TagEntry.expandBuilder(UTags.item("food_types/shells")).weight(3))
|
||||
));
|
||||
exporter.accept(LootTables.SHIPWRECK_SUPPLY_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 6))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(3))
|
||||
));
|
||||
exporter.accept(LootTables.SHIPWRECK_TREASURE_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(3))
|
||||
));
|
||||
exporter.accept(LootTables.UNDERWATER_RUIN_BIG_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 2))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
.with(ItemEntry.builder(UItems.SHELLY).weight(4))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(8))
|
||||
));
|
||||
exporter.accept(LootTables.UNDERWATER_RUIN_SMALL_CHEST, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(1))
|
||||
));
|
||||
|
||||
exporter.accept(LootTables.DESERT_WELL_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.WEIRD_ROCK).weight(2))
|
||||
.with(ItemEntry.builder(UItems.ROCK).weight(1))
|
||||
.with(ItemEntry.builder(UItems.TOM).weight(1))
|
||||
.with(ItemEntry.builder(UItems.ROCK_STEW).weight(1))
|
||||
.with(ItemEntry.builder(UItems.PEBBLES).weight(1))
|
||||
.with(ItemEntry.builder(UItems.SHELLY).weight(1))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(1))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
));
|
||||
exporter.accept(LootTables.TRAIL_RUINS_COMMON_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.MEADOWBROOKS_STAFF).weight(2))
|
||||
.with(ItemEntry.builder(UItems.BOTCHED_GEM).weight(3))
|
||||
.with(ItemEntry.builder(UItems.PEGASUS_FEATHER).weight(1))
|
||||
));
|
||||
exporter.accept(LootTables.TRAIL_RUINS_RARE_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.BROKEN_SUNGLASSES).weight(2))
|
||||
.with(ItemEntry.builder(UItems.EMPTY_JAR).weight(2))
|
||||
.with(ItemEntry.builder(UItems.MUSIC_DISC_CRUSADE).weight(1))
|
||||
));
|
||||
exporter.accept(LootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(1))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
));
|
||||
|
||||
exporter.accept(LootTables.FISHING_GAMEPLAY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(TagEntry.expandBuilder(UTags.SHELLS).weight(2))
|
||||
));
|
||||
|
||||
exporter.accept(LootTables.FISHING_JUNK_GAMEPLAY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.BROKEN_SUNGLASSES).weight(2))
|
||||
.with(ItemEntry.builder(UItems.WHEAT_WORMS).weight(2))
|
||||
.with(ItemEntry.builder(UItems.BOTCHED_GEM).weight(4))
|
||||
));
|
||||
|
||||
exporter.accept(LootTables.FISHING_TREASURE_GAMEPLAY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
.with(ItemEntry.builder(UItems.SHELLY).weight(1))
|
||||
));
|
||||
|
||||
exporter.accept(LootTables.HERO_OF_THE_VILLAGE_FISHERMAN_GIFT_GAMEPLAY, LootTable.builder().pool(LootPool.builder()
|
||||
.rolls(UniformLootNumberProvider.create(1, 4))
|
||||
.with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1))
|
||||
.with(ItemEntry.builder(UItems.SHELLY).weight(1))
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -80,8 +80,11 @@ public record DietProfile(
|
|||
return null;
|
||||
}
|
||||
|
||||
float hunger = food.getHunger() * ratios.getFirst();
|
||||
int baseline = (int)hunger;
|
||||
|
||||
return FoodAttributes.copy(food)
|
||||
.hunger(Math.max(1, (int)(food.getHunger() * ratios.getFirst())))
|
||||
.hunger(Math.max(1, (hunger - baseline) >= 0.5F ? baseline + 1 : baseline))
|
||||
.saturationModifier(food.getSaturationModifier() * ratios.getSecond())
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public record Effect(
|
|||
});
|
||||
if (tooltip.size() == size) {
|
||||
if (stack.isFood()) {
|
||||
tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.fruits_and_vegetables")).formatted(Formatting.GRAY));
|
||||
tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.misc")).formatted(Formatting.GRAY));
|
||||
} else if (stack.getUseAction() == UseAction.DRINK) {
|
||||
tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.drinks")).formatted(Formatting.GRAY));
|
||||
}
|
||||
|
|
|
@ -82,6 +82,15 @@ public class PonyDiets implements DietView {
|
|||
|
||||
tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE));
|
||||
getEffects(stack, pony).appendTooltip(stack, tooltip, context);
|
||||
|
||||
/*for (Race race : Race.REGISTRY) {
|
||||
var diet = diets.get(race);
|
||||
if (diet != null) {
|
||||
tooltip.add(race.getDisplayName());
|
||||
diet.appendTooltip(stack, user, tooltip, context);
|
||||
}
|
||||
}*/
|
||||
|
||||
getDiet(pony).appendTooltip(stack, user, tooltip, context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.*;
|
|||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.util.*;
|
||||
|
@ -67,19 +69,23 @@ public class ItemTracker implements NbtSerialisable, Copyable<ItemTracker>, Tick
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
update(living, living.getArmourStacks());
|
||||
update(living.getArmourStacks());
|
||||
}
|
||||
|
||||
private void update(Living<?> living, Stream<ItemStack> stacks) {
|
||||
private void update(Stream<ItemStack> stacks) {
|
||||
final Set<Trackable> found = new HashSet<>();
|
||||
final Set<ItemStack> foundStacks = new HashSet<>();
|
||||
|
||||
stacks.forEach(stack -> {
|
||||
if (stack.getItem() instanceof Trackable trackable) {
|
||||
items.compute(trackable, (item, prev) -> prev == null ? 1 : prev + 1);
|
||||
if (items.compute(trackable, (item, prev) -> prev == null ? 1 : prev + 1) == 1) {
|
||||
trackable.onEquipped(this.living);
|
||||
}
|
||||
found.add(trackable);
|
||||
foundStacks.add(stack);
|
||||
}
|
||||
});
|
||||
|
||||
items.entrySet().removeIf(e -> {
|
||||
if (!found.contains(e.getKey())) {
|
||||
e.getKey().onUnequipped(living, e.getValue());
|
||||
|
@ -90,13 +96,16 @@ public class ItemTracker implements NbtSerialisable, Copyable<ItemTracker>, Tick
|
|||
|
||||
if (!(living instanceof Pony)) {
|
||||
foundStacks.forEach(stack -> {
|
||||
if (getTicks((Trackable)stack.getItem()) == 1) {
|
||||
stack.inventoryTick(living.asWorld(), living.asEntity(), 0, false);
|
||||
}
|
||||
stack.inventoryTick(living.asWorld(), living.asEntity(), 0, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public long forceRemove(Trackable charm) {
|
||||
@Nullable Long time = items.remove(charm);
|
||||
return time == null ? 0 : time;
|
||||
}
|
||||
|
||||
public long getTicks(Trackable charm) {
|
||||
return items.getOrDefault(charm.asItem(), 0L);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.minelittlepony.unicopia.entity.behaviour.Guest;
|
|||
import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity;
|
||||
import com.minelittlepony.unicopia.entity.damage.MagicalDamageSource;
|
||||
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.UEffects;
|
||||
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.DamageTypes;
|
||||
import net.minecraft.entity.data.*;
|
||||
import net.minecraft.entity.mob.HostileEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
|
@ -519,6 +521,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();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.entity.effect;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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.effect.StatusEffect;
|
||||
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.player.PlayerEntity;
|
||||
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);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void applyUpdateEffect(LivingEntity entity, int amplifier) {
|
||||
|
||||
|
@ -32,7 +35,7 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
|
|||
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();
|
||||
|
||||
|
@ -48,25 +51,12 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
|
|||
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) {
|
||||
entity.damage(Living.living(entity).damageOf(UDamageTypes.ALICORN_AMULET), 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,4 +68,31 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
|
|||
public boolean canApplyUpdateEffect(int duration, int amplifier) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,16 @@ import net.minecraft.registry.Registries;
|
|||
public interface UEffects {
|
||||
StatusEffect FOOD_POISONING = register("food_poisoning", new FoodPoisoningStatusEffect(3484199));
|
||||
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 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));
|
||||
|
||||
private static StatusEffect register(String name, StatusEffect effect) {
|
||||
|
|
|
@ -386,12 +386,13 @@ public class ButterflyEntity extends AmbientEntity {
|
|||
public static final Variant[] VALUES = Variant.values();
|
||||
private static final Map<String, Variant> REGISTRY = Arrays.stream(VALUES).collect(Collectors.toMap(a -> a.name().toLowerCase(Locale.ROOT), Function.identity()));
|
||||
|
||||
private final Identifier skin = Unicopia.id("textures/entity/butterfly/" + name().toLowerCase() + ".png");
|
||||
private final Identifier skin = Unicopia.id("textures/entity/butterfly/" + name().toLowerCase(Locale.ROOT) + ".png");
|
||||
|
||||
public Identifier getSkin() {
|
||||
return skin;
|
||||
}
|
||||
static Variant byId(int index) {
|
||||
|
||||
public static Variant byId(int index) {
|
||||
return VALUES[Math.max(0, index) % VALUES.length];
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.function.Predicate;
|
|||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity;
|
||||
|
||||
|
@ -32,7 +33,7 @@ public interface UEntities {
|
|||
.trackRangeBlocks(100)
|
||||
.trackedUpdateRate(2)
|
||||
.dimensions(EntityDimensions.fixed(0.25F, 0.25F)));
|
||||
EntityType<MagicProjectileEntity> MAGIC_BEAM = register("magic_beam", FabricEntityTypeBuilder.<MagicProjectileEntity>create(SpawnGroup.MISC, MagicProjectileEntity::new)
|
||||
EntityType<MagicBeamEntity> MAGIC_BEAM = register("magic_beam", FabricEntityTypeBuilder.<MagicBeamEntity>create(SpawnGroup.MISC, MagicBeamEntity::new)
|
||||
.trackRangeBlocks(100)
|
||||
.trackedUpdateRate(2)
|
||||
.dimensions(EntityDimensions.fixed(0.25F, 0.25F)));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ import com.minelittlepony.unicopia.server.world.UGameRules;
|
|||
import com.minelittlepony.unicopia.server.world.WeatherConditions;
|
||||
import com.minelittlepony.unicopia.util.*;
|
||||
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
|
@ -195,7 +196,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
if ((RegistryUtils.isIn(entity.getWorld(), dimension, RegistryKeys.DIMENSION_TYPE, UTags.HAS_NO_ATMOSPHERE)
|
||||
|| Unicopia.getConfig().dimensionsWithoutAtmosphere.get().contains(RegistryUtils.getId(entity.getWorld(), dimension, RegistryKeys.DIMENSION_TYPE).toString()))
|
||||
&& !OxygenUtils.entityHasOxygen(entity.getWorld(), entity)) {
|
||||
&& !OxygenUtils.API.hasOxygen(entity)) {
|
||||
return FlightType.NONE;
|
||||
}
|
||||
|
||||
|
@ -252,6 +253,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
final MutableVector velocity = new MutableVector(entity.getVelocity());
|
||||
|
||||
if (isGravityNegative()) {
|
||||
velocity.y *= -1;
|
||||
}
|
||||
|
||||
if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) {
|
||||
float currentHeight = entity.getDimensions(entity.getPose()).height;
|
||||
float sneakingHeight = entity.getDimensions(EntityPose.STANDING).height;
|
||||
|
@ -343,7 +348,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
}
|
||||
|
||||
if (((LivingEntityDuck)entity).isJumping()) {
|
||||
velocity.y -= 0.2F * getGravitySignum();
|
||||
velocity.y -= 0.2F;
|
||||
velocity.y /= 2F;
|
||||
}
|
||||
|
||||
|
@ -391,6 +396,10 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
velocity.z /= heavyness;
|
||||
}
|
||||
|
||||
if (isGravityNegative()) {
|
||||
velocity.y *= -1;
|
||||
}
|
||||
|
||||
entity.setVelocity(velocity.toImmutable());
|
||||
|
||||
if (isFlying() && !entity.isFallFlying() && !pony.getAcrobatics().isHanging() && pony.isClient()) {
|
||||
|
@ -448,7 +457,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
}
|
||||
}
|
||||
|
||||
velocity.y -= 0.02 * getGravitySignum();
|
||||
velocity.y -= 0.02;
|
||||
velocity.x *= 0.9896;
|
||||
velocity.z *= 0.9896;
|
||||
}
|
||||
|
@ -541,7 +550,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
boolean takeOffCondition =
|
||||
(horMotion > 0.05 || motion > 0.05)
|
||||
&& pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE);
|
||||
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum() && entity.fallDistance > 1;
|
||||
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 && entity.fallDistance > 1;
|
||||
|
||||
if ((takeOffCondition || fallingTakeOffCondition) && !pony.getAcrobatics().isHanging() && !isCancelled) {
|
||||
initiateTakeoff(velocity);
|
||||
|
@ -551,9 +560,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
private void initiateTakeoff(MutableVector velocity) {
|
||||
startFlying(false);
|
||||
|
||||
if (!isGravityNegative()) {
|
||||
velocity.y += getHorizontalMotion() + 0.3;
|
||||
}
|
||||
velocity.y += getHorizontalMotion() + 0.3;
|
||||
applyThrust(velocity);
|
||||
|
||||
velocity.x *= 0.2;
|
||||
|
@ -635,6 +642,9 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
} else {
|
||||
float targetUpdraft = (float)WeatherConditions.getUpdraft(new BlockPos.Mutable().set(entity.getBlockPos()), entity.getWorld()) / 3F;
|
||||
targetUpdraft *= 1 + motion;
|
||||
if (isGravityNegative()) {
|
||||
targetUpdraft *= -1;
|
||||
}
|
||||
this.updraft.update(targetUpdraft, targetUpdraft > this.updraft.getTarget() ? 30_000 : 3000);
|
||||
double updraft = this.updraft.getValue();
|
||||
velocity.y += updraft;
|
||||
|
@ -647,7 +657,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
descentRate *= 0.8F;
|
||||
}
|
||||
|
||||
velocity.y -= descentRate * getGravityModifier();
|
||||
velocity.y -= descentRate;
|
||||
}
|
||||
|
||||
private void applyThrust(MutableVector velocity) {
|
||||
|
@ -695,7 +705,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
} else {
|
||||
velocity.x += direction.x * 1.3F;
|
||||
velocity.z += direction.z * 1.3F;
|
||||
velocity.y += ((direction.y * 2.45 + Math.abs(direction.y) * 10)) * getGravitySignum();// - heavyness / 5F
|
||||
velocity.y += ((direction.y * 2.45 + Math.abs(direction.y) * 10));// - heavyness / 5F
|
||||
}
|
||||
|
||||
if (velocity.y < 0 && hovering) {
|
||||
|
@ -759,9 +769,9 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
entity.addVelocity(orientation.x, orientation.y, orientation.z);
|
||||
|
||||
boolean isEarthPonySmash = pony.getObservedSpecies().canUseEarth() && !isFlying();
|
||||
int damage = TraceHelper.findBlocks(entity, speed + 4, 1, state -> (isEarthPonySmash && !state.isAir()) || state.isIn(UTags.GLASS_PANES)).stream()
|
||||
int damage = TraceHelper.findBlocks(entity, speed + 4, 1, state -> (isEarthPonySmash && !state.isAir()) || state.isIn(ConventionalBlockTags.GLASS_PANES)).stream()
|
||||
.flatMap(pos -> BlockPos.streamOutwards(pos, 2, 2, 2))
|
||||
.filter(pos -> (isEarthPonySmash && !entity.getWorld().isAir(pos)) || entity.getWorld().getBlockState(pos).isIn(UTags.GLASS_PANES))
|
||||
.filter(pos -> (isEarthPonySmash && !entity.getWorld().isAir(pos)) || entity.getWorld().getBlockState(pos).isIn(ConventionalBlockTags.GLASS_PANES))
|
||||
.reduce(0, (u, pos) -> {
|
||||
if (pony.canModifyAt(pos, ModificationType.PHYSICAL)) {
|
||||
if (isEarthPonySmash) {
|
||||
|
|
|
@ -92,6 +92,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
private final PlayerCamera camera = new PlayerCamera(this);
|
||||
private final TraitDiscovery discoveries = new TraitDiscovery(this);
|
||||
private final Acrobatics acrobatics = new Acrobatics(this);
|
||||
private final CorruptionHandler corruptionHandler = new CorruptionHandler(this);
|
||||
|
||||
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::updateCorruptionDecay);
|
||||
addTicker(new PlayerAttributes(this));
|
||||
addTicker(corruptionHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -289,6 +291,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
return corruption;
|
||||
}
|
||||
|
||||
public CorruptionHandler getCorruptionhandler() {
|
||||
return corruptionHandler;
|
||||
}
|
||||
|
||||
public boolean canUseSuperMove() {
|
||||
return entity.isCreative() || getMagicalReserves().getCharge().get() >= getMagicalReserves().getCharge().getMax();
|
||||
}
|
||||
|
@ -572,24 +578,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.hurtTime == 1 && getCompositeRace().physical().canCast()) {
|
||||
corruption.add(1);
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -789,6 +778,12 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
@Override
|
||||
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();
|
||||
|
||||
if (!partyMembers.isEmpty()) {
|
||||
|
@ -956,10 +951,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
@Override
|
||||
public void onSpellSet(@Nullable Spell spell) {
|
||||
if (spell != null) {
|
||||
if (spell.getAffinity() == Affinity.BAD && entity.getWorld().random.nextInt(120) == 0) {
|
||||
getCorruption().add(1);
|
||||
if (spell.getAffinity() == Affinity.BAD && entity.getWorld().random.nextInt(20) == 0) {
|
||||
getCorruption().add(entity.getRandom().nextBetween(1, 10));
|
||||
}
|
||||
getCorruption().add((int)spell.getTraits().getCorruption());
|
||||
getCorruption().add((int)spell.getTraits().getCorruption() * 10);
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
|
|||
|
||||
@Override
|
||||
public void onEquipped(Living<?> wearer) {
|
||||
wearer.playSound(USounds.ITEM_ALICORN_AMULET_CURSE, 3, 1);
|
||||
wearer.playSound(USounds.ITEM_ALICORN_AMULET_CURSE, 0.5F, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -234,7 +234,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
|
|||
// butterfingers effects
|
||||
if (daysAttached >= 2) {
|
||||
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 -> {
|
||||
|
|
|
@ -68,7 +68,7 @@ public class AmuletItem extends WearableItem implements ChargeableItem {
|
|||
|
||||
@Override
|
||||
public EquipmentSlot getSlotType(ItemStack stack) {
|
||||
return EquipmentSlot.CHEST;
|
||||
return TrinketsDelegate.hasTrinkets() ? EquipmentSlot.OFFHAND : EquipmentSlot.CHEST;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class BedsheetsItem extends Item {
|
||||
private static final Map<CloudBedBlock.SheetPattern, Item> ITEMS = new HashMap<>();
|
||||
public static final Map<CloudBedBlock.SheetPattern, Item> ITEMS = new HashMap<>();
|
||||
|
||||
private final CloudBedBlock.SheetPattern pattern;
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public class BellItem extends Item implements ChargeableItem {
|
|||
public ActionResult useOnEntity(ItemStack stack, PlayerEntity player, LivingEntity target, Hand hand) {
|
||||
player.setCurrentHand(hand);
|
||||
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);
|
||||
Living<?> targetLiving = target instanceof MobEntity || target instanceof PlayerEntity ? Living.getOrEmpty(target)
|
||||
.filter(living -> !(living instanceof Creature c && c.isDiscorded()))
|
||||
|
@ -79,7 +79,7 @@ public class BellItem extends Item implements ChargeableItem {
|
|||
|
||||
if (hasCharge(stack)) {
|
||||
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) {
|
||||
float maxChargeBy = chargeable.getMaxCharge() - ChargeableItem.getEnergy(offhandStack);
|
||||
float energyTransferred = Math.min(ChargeableItem.getEnergy(stack), maxChargeBy);
|
||||
|
|
|
@ -177,7 +177,7 @@ public interface UItems {
|
|||
Item GREEN_BED_SHEETS = register(CloudBedBlock.SheetPattern.GREEN);
|
||||
Item CYAN_BED_SHEETS = register(CloudBedBlock.SheetPattern.CYAN);
|
||||
Item LIGHT_BLUE_BED_SHEETS = register(CloudBedBlock.SheetPattern.LIGHT_BLUE);
|
||||
Item BLUE_SHEETS = register(CloudBedBlock.SheetPattern.BLUE);
|
||||
Item BLUE_BED_SHEETS = register(CloudBedBlock.SheetPattern.BLUE);
|
||||
Item PURPLE_BED_SHEETS = register(CloudBedBlock.SheetPattern.PURPLE);
|
||||
Item MAGENTA_BED_SHEETS = register(CloudBedBlock.SheetPattern.MAGENTA);
|
||||
Item PINK_BED_SHEETS = register(CloudBedBlock.SheetPattern.PINK);
|
||||
|
|
|
@ -54,11 +54,17 @@ public interface URecipes {
|
|||
LootTable table = manager.getLootTable(modId);
|
||||
|
||||
if (table != LootTable.EMPTY) {
|
||||
supplier.modifyPools(poolBuilder -> {
|
||||
if (id.getPath().startsWith("blocks/")) {
|
||||
for (var pool : table.pools) {
|
||||
poolBuilder.with(pool.entries);
|
||||
supplier.pool(pool);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
supplier.modifyPools(poolBuilder -> {
|
||||
for (var pool : table.pools) {
|
||||
poolBuilder.with(pool.entries);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.item;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.UConventionalTags;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
@ -103,7 +103,7 @@ public class ZapAppleItem extends Item implements ChameleonItem, MultiItem {
|
|||
public List<ItemStack> getDefaultStacks() {
|
||||
return Unicopia.SIDE.getPony().map(Pony::asWorld)
|
||||
.stream()
|
||||
.flatMap(world -> RegistryUtils.valuesForTag(world, UTags.APPLES))
|
||||
.flatMap(world -> RegistryUtils.valuesForTag(world, UConventionalTags.APPLES))
|
||||
.filter(a -> a != this).map(item -> {
|
||||
ItemStack stack = new ItemStack(this);
|
||||
stack.getOrCreateNbt().putString("appearance", Registries.ITEM.getId(item).toString());
|
||||
|
|
|
@ -59,7 +59,7 @@ public class SimpleEnchantment extends Enchantment {
|
|||
|
||||
@Override
|
||||
public final boolean isAvailableForRandomSelection() {
|
||||
return options.looted;
|
||||
return options.table;
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
|
@ -77,8 +77,8 @@ public class SimpleEnchantment extends Enchantment {
|
|||
public static class Options {
|
||||
private boolean cursed;
|
||||
private boolean treasured;
|
||||
private boolean traded = true;
|
||||
private boolean looted = true;
|
||||
private boolean traded;
|
||||
private boolean table;
|
||||
private Rarity rarity;
|
||||
private int maxLevel = 1;
|
||||
private EquipmentSlot[] slots;
|
||||
|
@ -102,6 +102,9 @@ public class SimpleEnchantment extends Enchantment {
|
|||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enchantment to apply to all items.
|
||||
*/
|
||||
public Options ignoreTarget() {
|
||||
allItems = true;
|
||||
return this;
|
||||
|
@ -128,8 +131,7 @@ public class SimpleEnchantment extends Enchantment {
|
|||
}
|
||||
|
||||
/**
|
||||
* Treasure enchantments only generate in loot tables with high-value items or by trading with villagers.
|
||||
* They do not appear in the enchanting table.
|
||||
* Whether this enchantment should be limited to high value trades or leveled up enchanting table offers.
|
||||
*/
|
||||
public Options treasure() {
|
||||
treasured = true;
|
||||
|
@ -137,25 +139,24 @@ public class SimpleEnchantment extends Enchantment {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loot-Only enchantments do not appear in villager trades.
|
||||
* They may still appear in loot table generation and can be found in the enchanting table.
|
||||
* Set whether this enchantment should appear in villager trades.
|
||||
*/
|
||||
public Options lootedOnly() {
|
||||
traded = false;
|
||||
looted = true;
|
||||
public Options traded() {
|
||||
this.traded = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trade-Only enchantments are excluded from loot table generation and do not appear in the enchanting table.
|
||||
* They can only be found by trading with villagers.
|
||||
* Sets whether the enchantment should appear in enchanting table draws.
|
||||
*/
|
||||
public Options tradedOnly() {
|
||||
looted = false;
|
||||
traded = true;
|
||||
public Options table() {
|
||||
this.table = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum level for the enchantment.
|
||||
*/
|
||||
public Options maxLevel(int level) {
|
||||
maxLevel = level;
|
||||
return this;
|
||||
|
|
|
@ -24,18 +24,30 @@ public interface UEnchantments {
|
|||
|
||||
/**
|
||||
* Makes a sound when there are interesting blocks in your area.
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment GEM_FINDER = register("gem_finder", new GemFindingEnchantment(Options.create(EnchantmentTarget.DIGGER, UEnchantmentValidSlots.HANDS).rarity(Rarity.RARE).maxLevel(3).treasure()));
|
||||
Enchantment GEM_FINDER = register("gem_finder", new GemFindingEnchantment(Options.create(EnchantmentTarget.DIGGER, UEnchantmentValidSlots.HANDS).rarity(Rarity.RARE).maxLevel(3).treasure().traded().table()));
|
||||
|
||||
/**
|
||||
* Protects against wall collisions and earth pony attacks!
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment PADDED = register("padded", new SimpleEnchantment(Options.armor().rarity(Rarity.UNCOMMON).maxLevel(3)));
|
||||
Enchantment PADDED = register("padded", new SimpleEnchantment(Options.armor().rarity(Rarity.UNCOMMON).maxLevel(3).traded().table()));
|
||||
|
||||
/**
|
||||
* Heavy players move more slowly but are less likely to be flung around wildly.
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment HEAVY = register("heavy", new AttributedEnchantment(Options.armor().rarity(Rarity.RARE).maxLevel(4)))
|
||||
Enchantment HEAVY = register("heavy", new AttributedEnchantment(Options.armor().rarity(Rarity.RARE).maxLevel(4).traded().table()))
|
||||
.addModifier(EntityAttributes.GENERIC_MOVEMENT_SPEED, (user, level) -> {
|
||||
return new EntityAttributeModifier(UUID.fromString("a3d5a94f-4c40-48f6-a343-558502a13e10"), "Heavyness", (1 - level/(float)10) - 1, Operation.MULTIPLY_TOTAL);
|
||||
});
|
||||
|
@ -44,13 +56,20 @@ public interface UEnchantments {
|
|||
* It's dangerous to go alone, take this!
|
||||
*
|
||||
* Weapons will become stronger the more allies you have around.
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment HERDS = register("herds", new CollaboratorEnchantment(Options.create(EnchantmentTarget.WEAPON, EquipmentSlot.MAINHAND).rarity(Rarity.RARE).maxLevel(3)));
|
||||
Enchantment HERDS = register("herds", new CollaboratorEnchantment(Options.create(EnchantmentTarget.WEAPON, EquipmentSlot.MAINHAND).rarity(Rarity.RARE).maxLevel(3).treasure().traded().table()));
|
||||
|
||||
/**
|
||||
* Alters gravity
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
*/
|
||||
Enchantment REPULSION = register("repulsion", new AttributedEnchantment(Options.create(EnchantmentTarget.ARMOR_FEET, EquipmentSlot.FEET).rarity(Rarity.VERY_RARE).maxLevel(3)))
|
||||
Enchantment REPULSION = register("repulsion", new AttributedEnchantment(Options.create(EnchantmentTarget.ARMOR_FEET, EquipmentSlot.FEET).rarity(Rarity.VERY_RARE).maxLevel(3).treasure().traded()))
|
||||
.addModifier(UEntityAttributes.ENTITY_GRAVITY_MODIFIER, (user, level) -> {
|
||||
return new EntityAttributeModifier(UUID.fromString("1734bbd6-1916-4124-b710-5450ea70fbdb"), "Anti Grav", (0.5F - (0.375 * (level - 1))) - 1, Operation.MULTIPLY_TOTAL);
|
||||
});
|
||||
|
@ -60,35 +79,52 @@ public interface UEnchantments {
|
|||
*
|
||||
* Mobs really want your candy. You'd better give it to them.
|
||||
*/
|
||||
Enchantment WANT_IT_NEED_IT = register("want_it_need_it", new WantItNeedItEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().treasure()));
|
||||
Enchantment WANT_IT_NEED_IT = register("want_it_need_it", new WantItNeedItEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().treasure().traded()));
|
||||
|
||||
/**
|
||||
* Hahaha geddit?
|
||||
*
|
||||
* Random things happen.
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
*/
|
||||
PoisonedJokeEnchantment POISONED_JOKE = register("poisoned_joke", new PoisonedJokeEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().tradedOnly()));
|
||||
PoisonedJokeEnchantment POISONED_JOKE = register("poisoned_joke", new PoisonedJokeEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().traded()));
|
||||
|
||||
/**
|
||||
* Who doesn't like a good freakout?
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
*/
|
||||
Enchantment STRESSED = register("stressed", new StressfulEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().treasure().maxLevel(3)));
|
||||
Enchantment STRESSED = register("stressed", new StressfulEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().treasure().traded().maxLevel(3)));
|
||||
|
||||
/**
|
||||
* This item just wants to be held.
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment CLINGY = register("clingy", new SimpleEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).curse().maxLevel(6)));
|
||||
Enchantment CLINGY = register("clingy", new SimpleEnchantment(Options.allItems().rarity(Rarity.VERY_RARE).maxLevel(6).traded().table().treasure()));
|
||||
|
||||
/**
|
||||
* Items with loyalty are kept after death.
|
||||
* Only works if they don't also have curse of binding.
|
||||
*
|
||||
* Appears in:
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment HEART_BOUND = register("heart_bound", new SimpleEnchantment(Options.create(EnchantmentTarget.VANISHABLE, UEnchantmentValidSlots.ANY).rarity(Rarity.UNCOMMON).maxLevel(5)));
|
||||
Enchantment HEART_BOUND = register("heart_bound", new SimpleEnchantment(Options.create(EnchantmentTarget.VANISHABLE, UEnchantmentValidSlots.ANY).rarity(Rarity.UNCOMMON).maxLevel(5).treasure().table()));
|
||||
|
||||
/**
|
||||
* Consumes drops whilst mining and produces experience instead
|
||||
*
|
||||
* Appears in:
|
||||
* - Trades
|
||||
* - Enchanting Table
|
||||
*/
|
||||
Enchantment CONSUMPTION = register("consumption", new ConsumptionEnchantment(Options.create(EnchantmentTarget.DIGGER, UEnchantmentValidSlots.HANDS).rarity(Rarity.VERY_RARE)));
|
||||
Enchantment CONSUMPTION = register("consumption", new ConsumptionEnchantment(Options.create(EnchantmentTarget.DIGGER, UEnchantmentValidSlots.HANDS).rarity(Rarity.VERY_RARE).treasure().table().traded()));
|
||||
|
||||
static void bootstrap() { }
|
||||
|
||||
|
|
|
@ -1,20 +1,30 @@
|
|||
package com.minelittlepony.unicopia.mixin.ad_astra;
|
||||
|
||||
import org.spongepowered.asm.mixin.Dynamic;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.world.World;
|
||||
import com.minelittlepony.unicopia.compat.ad_astra.OxygenUtils;
|
||||
|
||||
@Pseudo
|
||||
@Mixin(
|
||||
targets = { "earth.terrarium.ad_astra.common.util.OxygenUtils" },
|
||||
targets = { "earth.terrarium.adastra.api.systems.OxygenApi" },
|
||||
remap = false
|
||||
)
|
||||
public interface MixinOxygenUtils {
|
||||
@Invoker("entityHasOxygen")
|
||||
static boolean entityHasOxygen(World world, LivingEntity entity) {
|
||||
return true;
|
||||
public interface MixinOxygenUtils extends OxygenUtils.OxygenApi {
|
||||
@Accessor("API")
|
||||
@Coerce
|
||||
static Object getAPI() {
|
||||
throw new AbstractMethodError("stub");
|
||||
}
|
||||
|
||||
@Dynamic("Compiler-generated class-init() method")
|
||||
@Inject(method = "<clinit>()V", at = @At("RETURN"), remap = false)
|
||||
private static void classInit() {
|
||||
OxygenUtils.API = (OxygenUtils.OxygenApi)getAPI();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ public interface Channel {
|
|||
C2SPacketType<MsgPlayerFlightControlsInput> FLIGHT_CONTROLS_INPUT = SimpleNetworking.clientToServer(Unicopia.id("flight_controls"), MsgPlayerFlightControlsInput::new);
|
||||
|
||||
S2CPacketType<MsgPlayerCapabilities> SERVER_PLAYER_CAPABILITIES = SimpleNetworking.serverToClient(Unicopia.id("player_capabilities"), MsgPlayerCapabilities::new);
|
||||
S2CPacketType<MsgSpawnProjectile> SERVER_SPAWN_PROJECTILE = SimpleNetworking.serverToClient(Unicopia.id("projectile_entity"), MsgSpawnProjectile::new);
|
||||
S2CPacketType<MsgBlockDestruction> SERVER_BLOCK_DESTRUCTION = SimpleNetworking.serverToClient(Unicopia.id("block_destruction"), MsgBlockDestruction::new);
|
||||
S2CPacketType<MsgCancelPlayerAbility> CANCEL_PLAYER_ABILITY = SimpleNetworking.serverToClient(Unicopia.id("player_ability_cancel"), MsgCancelPlayerAbility::read);
|
||||
S2CPacketType<MsgCasterLookRequest> SERVER_REQUEST_PLAYER_LOOK = SimpleNetworking.serverToClient(Unicopia.id("request_player_look"), MsgCasterLookRequest::new);
|
||||
|
|
|
@ -2,8 +2,6 @@ package com.minelittlepony.unicopia.network.handler;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.data.Rot;
|
||||
import com.minelittlepony.unicopia.ability.data.tree.TreeTypes;
|
||||
|
@ -16,14 +14,11 @@ import com.minelittlepony.unicopia.client.gui.TribeSelectionScreen;
|
|||
import com.minelittlepony.unicopia.client.gui.spellbook.ClientChapters;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookChapterList.Chapter;
|
||||
import com.minelittlepony.unicopia.diet.PonyDiets;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.network.*;
|
||||
import com.minelittlepony.unicopia.network.MsgCasterLookRequest.Reply;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
|
@ -32,7 +27,6 @@ public class ClientNetworkHandlerImpl {
|
|||
|
||||
public ClientNetworkHandlerImpl() {
|
||||
Channel.SERVER_SELECT_TRIBE.receiver().addPersistentListener(this::handleTribeScreen);
|
||||
Channel.SERVER_SPAWN_PROJECTILE.receiver().addPersistentListener(this::handleSpawnProjectile);
|
||||
Channel.SERVER_BLOCK_DESTRUCTION.receiver().addPersistentListener(this::handleBlockDestruction);
|
||||
Channel.CANCEL_PLAYER_ABILITY.receiver().addPersistentListener(this::handleCancelAbility);
|
||||
Channel.UNLOCK_TRAITS.receiver().addPersistentListener(this::handleUnlockTraits);
|
||||
|
@ -47,31 +41,6 @@ public class ClientNetworkHandlerImpl {
|
|||
client.setScreen(new TribeSelectionScreen(packet.availableRaces(), packet.serverMessage()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handleSpawnProjectile(PlayerEntity sender, MsgSpawnProjectile packet) {
|
||||
ClientWorld world = client.world;
|
||||
Entity entity = packet.getEntityType().create(world);
|
||||
|
||||
entity.updateTrackedPosition(packet.getX(), packet.getY(), packet.getZ());
|
||||
entity.refreshPositionAfterTeleport(packet.getX(), packet.getY(), packet.getZ());
|
||||
entity.setVelocity(packet.getVelocityX(), packet.getVelocityY(), packet.getVelocityZ());
|
||||
entity.setPitch(packet.getPitch() * 360 / 256F);
|
||||
entity.setYaw(packet.getYaw() * 360 / 256F);
|
||||
entity.setId(packet.getId());
|
||||
entity.setUuid(packet.getUuid());
|
||||
|
||||
if (entity instanceof Owned.Mutable) {
|
||||
((Owned.Mutable<Entity>) entity).setMaster(world.getEntityById(packet.getEntityData()));
|
||||
}
|
||||
|
||||
if (entity.getType() == UEntities.MAGIC_BEAM) {
|
||||
InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_MAGIC_BEAM, entity.getId());
|
||||
}
|
||||
|
||||
entity.onSpawnPacket(packet);
|
||||
world.addEntity(entity);
|
||||
}
|
||||
|
||||
private void handleBlockDestruction(PlayerEntity sender, MsgBlockDestruction packet) {
|
||||
ClientBlockDestructionManager destr = ((ClientBlockDestructionManager.Source)client.worldRenderer).getDestructionManager();
|
||||
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
package com.minelittlepony.unicopia.projectile;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer.Operation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.block.state.StatePredicate;
|
||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||
import com.minelittlepony.unicopia.entity.MagicImmune;
|
||||
import com.minelittlepony.unicopia.entity.Physics;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.network.datasync.EffectSync;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class MagicBeamEntity extends MagicProjectileEntity implements Caster<MagicBeamEntity>, MagicImmune {
|
||||
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
||||
|
||||
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
||||
|
||||
private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this, GRAVITY);
|
||||
|
||||
public MagicBeamEntity(EntityType<MagicBeamEntity> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
public MagicBeamEntity(World world, Entity owner, float divergance, Spell spell) {
|
||||
super(UEntities.MAGIC_BEAM, world);
|
||||
setPosition(owner.getX(), owner.getEyeY() - 0.1F, owner.getZ());
|
||||
setOwner(owner);
|
||||
setVelocity(owner, owner.getPitch(), owner.getYaw(), 0, 1.5F, divergance);
|
||||
setNoGravity(true);
|
||||
spell.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDataTracker() {
|
||||
super.initDataTracker();
|
||||
getDataTracker().startTracking(GRAVITY, 1F);
|
||||
getDataTracker().startTracking(HYDROPHOBIC, false);
|
||||
getDataTracker().startTracking(EFFECT, new NbtCompound());
|
||||
}
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (getOwner() != null) {
|
||||
effectDelegate.tick(Situation.PROJECTILE);
|
||||
}
|
||||
|
||||
|
||||
if (getHydrophobic()) {
|
||||
if (StatePredicate.isFluid(getWorld().getBlockState(getBlockPos()))) {
|
||||
Vec3d vel = getVelocity();
|
||||
|
||||
double velY = vel.y;
|
||||
|
||||
velY *= -1;
|
||||
|
||||
if (!hasNoGravity()) {
|
||||
velY += 0.16;
|
||||
}
|
||||
|
||||
setVelocity(new Vec3d(vel.x, velY, vel.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setHydrophobic() {
|
||||
getDataTracker().set(HYDROPHOBIC, true);
|
||||
}
|
||||
|
||||
public boolean getHydrophobic() {
|
||||
return getDataTracker().get(HYDROPHOBIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MagicBeamEntity asEntity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getLevel() {
|
||||
return getMasterReference().getTarget().map(target -> target.level()).orElse(Levelled.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getCorruption() {
|
||||
return getMasterReference().getTarget().map(target -> target.corruption()).orElse(Levelled.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Physics getPhysics() {
|
||||
return physics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Affinity getAffinity() {
|
||||
return getSpellSlot().get(true).map(Affine::getAffinity).orElse(Affinity.NEUTRAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellContainer getSpellSlot() {
|
||||
return effectDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean subtractEnergyCost(double amount) {
|
||||
return Caster.of(getMaster()).filter(c -> c.subtractEnergyCost(amount)).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawnPacket(EntitySpawnS2CPacket packet) {
|
||||
super.onSpawnPacket(packet);
|
||||
InteractionManager.instance().playLoopingSound(this, InteractionManager.SOUND_MAGIC_BEAM, getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(RemovalReason reason) {
|
||||
super.remove(reason);
|
||||
getSpellSlot().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends ProjectileDelegate> void forEachDelegates(Consumer<T> consumer, Function<Object, T> predicate) {
|
||||
effectDelegate.tick(spell -> {
|
||||
Optional.ofNullable(predicate.apply(spell)).ifPresent(consumer);
|
||||
return Operation.SKIP;
|
||||
});
|
||||
super.forEachDelegates(consumer, predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readCustomDataFromNbt(NbtCompound compound) {
|
||||
super.readCustomDataFromNbt(compound);
|
||||
getDataTracker().set(HYDROPHOBIC, compound.getBoolean("hydrophobic"));
|
||||
physics.fromNBT(compound);
|
||||
if (compound.contains("effect")) {
|
||||
getSpellSlot().put(Spell.readNbt(compound.getCompound("effect")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCustomDataToNbt(NbtCompound compound) {
|
||||
super.writeCustomDataToNbt(compound);
|
||||
compound.putBoolean("hydrophobic", getHydrophobic());
|
||||
physics.toNBT(compound);
|
||||
getSpellSlot().get(true).ifPresent(effect -> {
|
||||
compound.put("effect", Spell.writeNbt(effect));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -6,28 +6,12 @@ import java.util.function.Function;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.WeaklyOwned;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer.Operation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.block.state.StatePredicate;
|
||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.MagicImmune;
|
||||
import com.minelittlepony.unicopia.entity.Physics;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
|
||||
import com.minelittlepony.unicopia.network.datasync.EffectSync;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -40,41 +24,28 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.particle.ItemStackParticleEffect;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* A generalised version of Mojang's projectile entity class with added support for a custom appearance and water phobia.
|
||||
*
|
||||
* Can also carry a spell if needed.
|
||||
*/
|
||||
public class MagicProjectileEntity extends ThrownItemEntity implements Caster<MagicProjectileEntity>, WeaklyOwned.Mutable<LivingEntity>, MagicImmune {
|
||||
public class MagicProjectileEntity extends ThrownItemEntity implements WeaklyOwned.Mutable<LivingEntity> {
|
||||
private static final TrackedData<Float> DAMAGE = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
||||
|
||||
public static final byte PROJECTILE_COLLISSION = 3;
|
||||
|
||||
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
||||
|
||||
private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this, GRAVITY);
|
||||
|
||||
private final EntityReference<Entity> homingTarget = new EntityReference<>();
|
||||
private EntityReference<LivingEntity> owner;
|
||||
|
||||
private int maxAge = 90;
|
||||
|
||||
public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world) {
|
||||
public MagicProjectileEntity(EntityType<? extends MagicProjectileEntity> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
|
@ -86,27 +57,24 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
super(UEntities.THROWN_ITEM, thrower, world);
|
||||
}
|
||||
|
||||
protected MagicProjectileEntity(EntityType<? extends MagicProjectileEntity> type, World world, LivingEntity thrower) {
|
||||
super(type, thrower, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDataTracker() {
|
||||
super.initDataTracker();
|
||||
getDataTracker().startTracking(GRAVITY, 1F);
|
||||
getDataTracker().startTracking(DAMAGE, 0F);
|
||||
getDataTracker().startTracking(EFFECT, new NbtCompound());
|
||||
getDataTracker().startTracking(HYDROPHOBIC, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public World asWorld() {
|
||||
return getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDefaultItem() {
|
||||
switch (getSpellSlot().get(false).map(Spell::getAffinity).orElse(Affinity.NEUTRAL)) {
|
||||
case GOOD: return Items.SNOWBALL;
|
||||
case BAD: return Items.MAGMA_CREAM;
|
||||
default: return Items.AIR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MagicProjectileEntity asEntity() {
|
||||
return this;
|
||||
return Items.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -140,36 +108,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
homingTarget.set(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getLevel() {
|
||||
return getMasterReference().getTarget().map(target -> target.level()).orElse(Levelled.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getCorruption() {
|
||||
return getMasterReference().getTarget().map(target -> target.corruption()).orElse(Levelled.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Physics getPhysics() {
|
||||
return physics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Affinity getAffinity() {
|
||||
return getSpellSlot().get(true).map(Affine::getAffinity).orElse(Affinity.NEUTRAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellContainer getSpellSlot() {
|
||||
return effectDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean subtractEnergyCost(double amount) {
|
||||
return Caster.of(getMaster()).filter(c -> c.subtractEnergyCost(amount)).isPresent();
|
||||
}
|
||||
|
||||
public void addThrowDamage(float damage) {
|
||||
setThrowDamage(getThrowDamage() + damage);
|
||||
}
|
||||
|
@ -182,14 +120,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
return getDataTracker().get(DAMAGE);
|
||||
}
|
||||
|
||||
public void setHydrophobic() {
|
||||
getDataTracker().set(HYDROPHOBIC, true);
|
||||
}
|
||||
|
||||
public boolean getHydrophobic() {
|
||||
return getDataTracker().get(HYDROPHOBIC);
|
||||
}
|
||||
|
||||
public void setMaxAge(int maxAge) {
|
||||
this.maxAge = maxAge;
|
||||
}
|
||||
|
@ -202,28 +132,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
|
||||
super.tick();
|
||||
|
||||
if (getOwner() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
effectDelegate.tick(Situation.PROJECTILE);
|
||||
|
||||
if (getHydrophobic()) {
|
||||
if (StatePredicate.isFluid(getWorld().getBlockState(getBlockPos()))) {
|
||||
Vec3d vel = getVelocity();
|
||||
|
||||
double velY = vel.y;
|
||||
|
||||
velY *= -1;
|
||||
|
||||
if (!hasNoGravity()) {
|
||||
velY += 0.16;
|
||||
}
|
||||
|
||||
setVelocity(new Vec3d(vel.x, velY, vel.z));
|
||||
}
|
||||
}
|
||||
|
||||
homingTarget.ifPresent(getWorld(), e -> {
|
||||
setNoGravity(true);
|
||||
noClip = true;
|
||||
|
@ -261,12 +169,8 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
@Override
|
||||
public void readCustomDataFromNbt(NbtCompound compound) {
|
||||
super.readCustomDataFromNbt(compound);
|
||||
physics.fromNBT(compound);
|
||||
homingTarget.fromNBT(compound.getCompound("homingTarget"));
|
||||
getMasterReference().fromNBT(compound.getCompound("owner"));
|
||||
if (compound.contains("effect")) {
|
||||
getSpellSlot().put(Spell.readNbt(compound.getCompound("effect")));
|
||||
}
|
||||
if (compound.contains("maxAge", NbtElement.INT_TYPE)) {
|
||||
maxAge = compound.getInt("maxAge");
|
||||
}
|
||||
|
@ -275,13 +179,9 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
@Override
|
||||
public void writeCustomDataToNbt(NbtCompound compound) {
|
||||
super.writeCustomDataToNbt(compound);
|
||||
physics.toNBT(compound);
|
||||
compound.put("homingTarget", homingTarget.toNBT());
|
||||
compound.put("owner", getMasterReference().toNBT());
|
||||
compound.putInt("maxAge", maxAge);
|
||||
getSpellSlot().get(true).ifPresent(effect -> {
|
||||
compound.put("effect", Spell.writeNbt(effect));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -296,12 +196,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(RemovalReason reason) {
|
||||
super.remove(reason);
|
||||
getSpellSlot().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBlockHit(BlockHitResult hit) {
|
||||
super.onBlockHit(hit);
|
||||
|
@ -313,7 +207,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
protected void onEntityHit(EntityHitResult hit) {
|
||||
Entity entity = hit.getEntity();
|
||||
|
||||
if (EquinePredicates.IS_MAGIC_IMMUNE.test(entity) || !EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.test(entity)) {
|
||||
if (EquinePredicates.IS_MAGIC_IMMUNE.test(entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -329,20 +223,10 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Ma
|
|||
}
|
||||
|
||||
protected <T extends ProjectileDelegate> void forEachDelegates(Consumer<T> consumer, Function<Object, T> predicate) {
|
||||
effectDelegate.tick(spell -> {
|
||||
Optional.ofNullable(predicate.apply(spell)).ifPresent(consumer);
|
||||
return Operation.SKIP;
|
||||
});
|
||||
try {
|
||||
Optional.ofNullable(predicate.apply(getItem().getItem())).ifPresent(consumer);
|
||||
} catch (Throwable t) {
|
||||
Unicopia.LOGGER.error("Error whilst ticking spell on entity {}", getMasterReference(), t);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Packet<ClientPlayPacketListener> createSpawnPacket() {
|
||||
return (Packet<ClientPlayPacketListener>)(Object)Channel.SERVER_SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,25 @@ package com.minelittlepony.unicopia.util;
|
|||
|
||||
import com.minelittlepony.common.util.Color;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.passive.SheepEntity;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public interface ColorHelper {
|
||||
static int getRainbowColor(Entity entity, int speed, float tickDelta) {
|
||||
int n = entity.age / speed + entity.getId();
|
||||
int o = DyeColor.values().length;
|
||||
int p = n % o;
|
||||
int q = (n + 1) % o;
|
||||
float r = (entity.age % speed + tickDelta) / 25.0f;
|
||||
float[] fs = SheepEntity.getRgbColor(DyeColor.byId(p));
|
||||
float[] gs = SheepEntity.getRgbColor(DyeColor.byId(q));
|
||||
float s = fs[0] * (1.0f - r) + gs[0] * r;
|
||||
float t = fs[1] * (1.0f - r) + gs[1] * r;
|
||||
float u = fs[2] * (1.0f - r) + gs[2] * r;
|
||||
return Color.argbToHex(1, s, t, u);
|
||||
}
|
||||
|
||||
static float[] changeSaturation(float red, float green, float blue, float intensity) {
|
||||
float avg = (red + green + blue) / 3F;
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.util;
|
|||
import com.minelittlepony.unicopia.EntityConvertable;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
@ -26,7 +27,11 @@ public interface SoundEmitter<E extends Entity> extends EntityConvertable<E> {
|
|||
}
|
||||
|
||||
static void playSoundAt(Entity entity, SoundEvent sound, SoundCategory category, float volume, float pitch) {
|
||||
entity.getWorld().playSound(null, entity.getX(), entity.getY(), entity.getZ(), sound, category, volume, pitch);
|
||||
if (entity.getWorld().isClient && entity instanceof PlayerEntity p) {
|
||||
entity.getWorld().playSound(p, entity.getX(), entity.getY(), entity.getZ(), sound, category, volume, pitch);
|
||||
} else {
|
||||
entity.getWorld().playSound(null, entity.getX(), entity.getY(), entity.getZ(), sound, category, volume, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
static float getRandomPitch(Random rng) {
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"bites=0,stomped=false": { "model": "unicopia:block/apple_pie" },
|
||||
"bites=1,stomped=false": { "model": "unicopia:block/apple_pie_elbow" },
|
||||
"bites=2,stomped=false": { "model": "unicopia:block/apple_pie_straight" },
|
||||
"bites=3,stomped=false": { "model": "unicopia:block/apple_pie_corner" },
|
||||
"bites=0,stomped=true": { "model": "unicopia:block/stomped_apple_pie" },
|
||||
"bites=1,stomped=true": { "model": "unicopia:block/stomped_apple_pie_elbow" },
|
||||
"bites=2,stomped=true": { "model": "unicopia:block/stomped_apple_pie_straight" },
|
||||
"bites=3,stomped=true": { "model": "unicopia:block/stomped_apple_pie_corner" }
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "unicopia:block/bananas"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=up": { "model": "unicopia:block/carved_cloud" },
|
||||
"facing=down": { "model": "unicopia:block/carved_cloud", "x": 180 },
|
||||
"facing=north": { "model": "unicopia:block/carved_cloud", "x": 90 },
|
||||
"facing=south": { "model": "unicopia:block/carved_cloud", "x": -90 },
|
||||
"facing=east": { "model": "unicopia:block/carved_cloud", "x": 90, "y": 90 },
|
||||
"facing=west": { "model": "unicopia:block/carved_cloud", "x": 90, "y": -90 }
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/chiselled_chitin" }
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=up": { "model": "unicopia:block/chiselled_chitin_hull" },
|
||||
"facing=down": { "model": "unicopia:block/chiselled_chitin_hull", "x": 180 },
|
||||
"facing=north": { "model": "unicopia:block/chiselled_chitin_hull", "x": 90 },
|
||||
"facing=south": { "model": "unicopia:block/chiselled_chitin_hull", "x": -90 },
|
||||
"facing=east": { "model": "unicopia:block/chiselled_chitin_hull", "x": 90, "y": 90 },
|
||||
"facing=west": { "model": "unicopia:block/chiselled_chitin_hull", "x": 90, "y": -90 }
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"type=double": { "model": "unicopia:block/chiselled_chitin" },
|
||||
"type=bottom": { "model": "unicopia:block/chiselled_chitin_slab" },
|
||||
"type=top": { "model": "unicopia:block/chiselled_chitin_slab_top" }
|
||||
}
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=east,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner"
|
||||
},
|
||||
"facing=east,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer"
|
||||
},
|
||||
"facing=east,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs"
|
||||
},
|
||||
"facing=east,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=east,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=east,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,half=top,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=north,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=north,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=north,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=north,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=north,half=top,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=south,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner"
|
||||
},
|
||||
"facing=south,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer"
|
||||
},
|
||||
"facing=south,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,half=top,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=west,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=west,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=west,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,half=top,shape=straight": {
|
||||
"model": "unicopia:block/chiselled_chitin_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/chitin" }
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=up": { "model": "unicopia:block/chitin_spikes" },
|
||||
"facing=down": { "model": "unicopia:block/chitin_spikes", "x": 180 },
|
||||
"facing=north": { "model": "unicopia:block/chitin_spikes", "x": 90 },
|
||||
"facing=south": { "model": "unicopia:block/chitin_spikes", "x": -90 },
|
||||
"facing=east": { "model": "unicopia:block/chitin_spikes", "x": 90, "y": 90 },
|
||||
"facing=west": { "model": "unicopia:block/chitin_spikes", "x": 90, "y": -90 }
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"count=1": { "model": "unicopia:block/clam_shell_1" },
|
||||
"count=2": { "model": "unicopia:block/clam_shell_2" },
|
||||
"count=3": { "model": "unicopia:block/clam_shell_3" },
|
||||
"count=4": { "model": "unicopia:block/clam_shell_4" }
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/cloth_bed" }
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/cloud" }
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/cloud_bed" }
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"type=double": { "model": "unicopia:block/cloud_bricks" },
|
||||
"type=bottom": { "model": "unicopia:block/cloud_brick_slab" },
|
||||
"type=top": { "model": "unicopia:block/cloud_brick_slab_top" }
|
||||
}
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=east,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner"
|
||||
},
|
||||
"facing=east,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer"
|
||||
},
|
||||
"facing=east,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs"
|
||||
},
|
||||
"facing=east,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=east,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=east,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,half=top,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=north,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=north,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=north,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=north,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=north,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180
|
||||
},
|
||||
"facing=north,half=top,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=south,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner"
|
||||
},
|
||||
"facing=south,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer"
|
||||
},
|
||||
"facing=south,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=south,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,half=top,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 90
|
||||
},
|
||||
"facing=west,half=bottom,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=west,half=bottom,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=bottom,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 90
|
||||
},
|
||||
"facing=west,half=bottom,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=bottom,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=top,shape=inner_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=top,shape=inner_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_inner",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,half=top,shape=outer_left": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,half=top,shape=outer_right": {
|
||||
"model": "unicopia:block/cloud_brick_stairs_outer",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,half=top,shape=straight": {
|
||||
"model": "unicopia:block/cloud_brick_stairs",
|
||||
"uvlock": true,
|
||||
"x": 180,
|
||||
"y": 180
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/cloud_bricks" }
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "unicopia:block/cloud_chest" }
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=east,half=lower,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom" },
|
||||
"facing=south,half=lower,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom", "y": 90 },
|
||||
"facing=west,half=lower,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom", "y": 180 },
|
||||
"facing=north,half=lower,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom", "y": 270 },
|
||||
"facing=east,half=lower,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh" },
|
||||
"facing=south,half=lower,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 90 },
|
||||
"facing=west,half=lower,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 180 },
|
||||
"facing=north,half=lower,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 270 },
|
||||
"facing=east,half=lower,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 90 },
|
||||
"facing=south,half=lower,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 180 },
|
||||
"facing=west,half=lower,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 270 },
|
||||
"facing=north,half=lower,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom_rh" },
|
||||
"facing=east,half=lower,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom", "y": 270 },
|
||||
"facing=south,half=lower,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom" },
|
||||
"facing=west,half=lower,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom", "y": 90 },
|
||||
"facing=north,half=lower,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_bottom", "y": 180 },
|
||||
"facing=east,half=upper,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_top" },
|
||||
"facing=south,half=upper,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_top", "y": 90 },
|
||||
"facing=west,half=upper,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_top", "y": 180 },
|
||||
"facing=north,half=upper,hinge=left,open=false,powered=false": { "model": "unicopia:block/door/cloud_top", "y": 270 },
|
||||
"facing=east,half=upper,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_top_rh" },
|
||||
"facing=south,half=upper,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_top_rh", "y": 90 },
|
||||
"facing=west,half=upper,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_top_rh", "y": 180 },
|
||||
"facing=north,half=upper,hinge=right,open=false,powered=false": { "model": "unicopia:block/door/cloud_top_rh", "y": 270 },
|
||||
"facing=east,half=upper,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_top_rh", "y": 90 },
|
||||
"facing=south,half=upper,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_top_rh", "y": 180 },
|
||||
"facing=west,half=upper,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_top_rh", "y": 270 },
|
||||
"facing=north,half=upper,hinge=left,open=true,powered=false": { "model": "unicopia:block/door/cloud_top_rh" },
|
||||
"facing=east,half=upper,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_top", "y": 270 },
|
||||
"facing=south,half=upper,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_top" },
|
||||
"facing=west,half=upper,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_top", "y": 90 },
|
||||
"facing=north,half=upper,hinge=right,open=true,powered=false": { "model": "unicopia:block/door/cloud_top", "y": 180 },
|
||||
"facing=east,half=lower,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom" },
|
||||
"facing=south,half=lower,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom", "y": 90 },
|
||||
"facing=west,half=lower,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom", "y": 180 },
|
||||
"facing=north,half=lower,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom", "y": 270 },
|
||||
"facing=east,half=lower,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh" },
|
||||
"facing=south,half=lower,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 90 },
|
||||
"facing=west,half=lower,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 180 },
|
||||
"facing=north,half=lower,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 270 },
|
||||
"facing=east,half=lower,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 90 },
|
||||
"facing=south,half=lower,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 180 },
|
||||
"facing=west,half=lower,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh", "y": 270 },
|
||||
"facing=north,half=lower,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom_rh" },
|
||||
"facing=east,half=lower,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom", "y": 270 },
|
||||
"facing=south,half=lower,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom" },
|
||||
"facing=west,half=lower,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom", "y": 90 },
|
||||
"facing=north,half=lower,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_bottom", "y": 180 },
|
||||
"facing=east,half=upper,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_top" },
|
||||
"facing=south,half=upper,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_top", "y": 90 },
|
||||
"facing=west,half=upper,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_top", "y": 180 },
|
||||
"facing=north,half=upper,hinge=left,open=false,powered=true": { "model": "unicopia:block/door/cloud_top", "y": 270 },
|
||||
"facing=east,half=upper,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_top_rh" },
|
||||
"facing=south,half=upper,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_top_rh", "y": 90 },
|
||||
"facing=west,half=upper,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_top_rh", "y": 180 },
|
||||
"facing=north,half=upper,hinge=right,open=false,powered=true": { "model": "unicopia:block/door/cloud_top_rh", "y": 270 },
|
||||
"facing=east,half=upper,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_top_rh", "y": 90 },
|
||||
"facing=south,half=upper,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_top_rh", "y": 180 },
|
||||
"facing=west,half=upper,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_top_rh", "y": 270 },
|
||||
"facing=north,half=upper,hinge=left,open=true,powered=true": { "model": "unicopia:block/door/cloud_top_rh" },
|
||||
"facing=east,half=upper,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_top", "y": 270 },
|
||||
"facing=south,half=upper,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_top" },
|
||||
"facing=west,half=upper,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_top", "y": 90 },
|
||||
"facing=north,half=upper,hinge=right,open=true,powered=true": { "model": "unicopia:block/door/cloud_top", "y": 180 }
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue