mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Added buckets, bottles, and mugs full of love + Changelings can now collect love from the crystal heart
This commit is contained in:
parent
02eaf365c8
commit
3ca28335bd
17 changed files with 106 additions and 26 deletions
|
@ -1,12 +1,11 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.google.common.base.Suppliers;
|
||||||
import com.minelittlepony.unicopia.UTags;
|
import com.minelittlepony.unicopia.*;
|
||||||
import com.minelittlepony.unicopia.entity.FloatingArtefactEntity;
|
import com.minelittlepony.unicopia.entity.*;
|
||||||
import com.minelittlepony.unicopia.entity.UEntities;
|
|
||||||
import com.minelittlepony.unicopia.entity.FloatingArtefactEntity.State;
|
import com.minelittlepony.unicopia.entity.FloatingArtefactEntity.State;
|
||||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
|
@ -16,17 +15,11 @@ import com.minelittlepony.unicopia.util.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.EndRodBlock;
|
import net.minecraft.block.EndRodBlock;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.*;
|
||||||
import net.minecraft.entity.Saddleable;
|
|
||||||
import net.minecraft.entity.SpawnGroup;
|
|
||||||
import net.minecraft.entity.SpawnReason;
|
|
||||||
import net.minecraft.entity.mob.MobEntity;
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
import net.minecraft.entity.passive.TameableEntity;
|
import net.minecraft.entity.passive.TameableEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.*;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.ItemUsageContext;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
@ -38,6 +31,28 @@ import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Artifact {
|
public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Artifact {
|
||||||
|
private static final Supplier<Map<Item, Item>> ITEM_MAP = Suppliers.memoize(() -> {
|
||||||
|
return Map.of(
|
||||||
|
Items.BUCKET, UItems.LOVE_BUCKET,
|
||||||
|
Items.GLASS_BOTTLE, UItems.LOVE_BOTTLE,
|
||||||
|
UItems.MUG, UItems.LOVE_MUG
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
private static boolean isFillable(ItemStack stack) {
|
||||||
|
return ITEM_MAP.get().containsKey(stack.getItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack fill(ItemStack stack) {
|
||||||
|
Item item = ITEM_MAP.get().getOrDefault(stack.getItem(), stack.getItem());
|
||||||
|
if (item == stack.getItem()) {
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
ItemStack newStack = item.getDefaultStack();
|
||||||
|
newStack.setNbt(stack.getNbt());
|
||||||
|
newStack.setCount(stack.getCount());
|
||||||
|
return newStack;
|
||||||
|
}
|
||||||
|
|
||||||
public CrystalHeartItem(Settings settings) {
|
public CrystalHeartItem(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
@ -55,16 +70,16 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
|
||||||
return ActionResult.FAIL;
|
return ActionResult.FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (world instanceof ServerWorld) {
|
if (world instanceof ServerWorld serverWorld) {
|
||||||
|
|
||||||
FloatingArtefactEntity entity = UEntities.FLOATING_ARTEFACT.create((ServerWorld)world, context.getStack().getNbt(), null, context.getPlayer(), blockPos, SpawnReason.SPAWN_EGG, false, true);
|
FloatingArtefactEntity entity = UEntities.FLOATING_ARTEFACT.create(serverWorld, context.getStack().getNbt(), null, context.getPlayer(), blockPos, SpawnReason.SPAWN_EGG, false, true);
|
||||||
|
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
return ActionResult.FAIL;
|
return ActionResult.FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.setStack(context.getStack().split(1));
|
entity.setStack(context.getStack().split(1));
|
||||||
((ServerWorld)world).spawnEntityAndPassengers(entity);
|
serverWorld.spawnEntityAndPassengers(entity);
|
||||||
|
|
||||||
entity.playSound(USounds.ENTITY_CRYSTAL_HEART_ACTIVATE, 0.75F, 0.8F);
|
entity.playSound(USounds.ENTITY_CRYSTAL_HEART_ACTIVATE, 0.75F, 0.8F);
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,6 +113,7 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
|
||||||
if (entity.world.getTime() % 80 == 0 && !entity.world.isClient) {
|
if (entity.world.getTime() % 80 == 0 && !entity.world.isClient) {
|
||||||
List<LivingEntity> inputs = new ArrayList<>();
|
List<LivingEntity> inputs = new ArrayList<>();
|
||||||
List<LivingEntity> outputs = new ArrayList<>();
|
List<LivingEntity> outputs = new ArrayList<>();
|
||||||
|
List<ItemEntity> containers = new ArrayList<>();
|
||||||
|
|
||||||
VecHelper.findInRange(entity, entity.world, entity.getPos(), 20, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(e -> !e.isRemoved() && (e instanceof PlayerEntity || e instanceof MobEntity))).forEach(e -> {
|
VecHelper.findInRange(entity, entity.world, entity.getPos(), 20, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(e -> !e.isRemoved() && (e instanceof PlayerEntity || e instanceof MobEntity))).forEach(e -> {
|
||||||
LivingEntity living = (LivingEntity)e;
|
LivingEntity living = (LivingEntity)e;
|
||||||
|
@ -112,8 +128,11 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
|
||||||
inputs.add(living);
|
inputs.add(living);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
VecHelper.findInRange(entity, entity.world, entity.getPos(), 20, i -> {
|
||||||
|
return i instanceof ItemEntity ie && isFillable(ie.getStack()) && PonyContainer.of(i).filter(p -> p.get().getSpecies() == Race.CHANGELING).isPresent();
|
||||||
|
}).forEach(i -> containers.add((ItemEntity)i));
|
||||||
|
|
||||||
int demand = outputs.size();
|
int demand = outputs.size() + containers.stream().mapToInt(i -> i.getStack().getCount()).sum();
|
||||||
int supply = inputs.size();
|
int supply = inputs.size();
|
||||||
|
|
||||||
if (demand == 0 || supply == 0) {
|
if (demand == 0 || supply == 0) {
|
||||||
|
@ -142,6 +161,10 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
|
||||||
ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, output, 0.2F), entity, 1);
|
ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, output, 0.2F), entity, 1);
|
||||||
output.heal(gives);
|
output.heal(gives);
|
||||||
});
|
});
|
||||||
|
containers.forEach(container -> {
|
||||||
|
ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, container, 0.2F), entity, 1);
|
||||||
|
container.setStack(fill(container.getStack()));
|
||||||
|
});
|
||||||
|
|
||||||
entity.addSpin(gives > 0 ? 20 : 10, 30);
|
entity.addSpin(gives > 0 ? 20 : 10, 30);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,12 @@ public class DrinkableItem extends Item {
|
||||||
serverPlayerEntity.incrementStat(Stats.USED.getOrCreateStat(this));
|
serverPlayerEntity.incrementStat(Stats.USED.getOrCreateStat(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
((ToxicHolder)this).getToxic(stack).finishUsing(stack, world, user);
|
||||||
|
|
||||||
if (user instanceof PlayerEntity && !((PlayerEntity)user).getAbilities().creativeMode) {
|
if (user instanceof PlayerEntity && !((PlayerEntity)user).getAbilities().creativeMode) {
|
||||||
stack.decrement(1);
|
stack.decrement(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
((ToxicHolder)this).getToxic(stack).finishUsing(stack, world, user);
|
|
||||||
|
|
||||||
return stack.isEmpty() ? new ItemStack(getRecipeRemainder()) : stack;
|
return stack.isEmpty() ? new ItemStack(getRecipeRemainder()) : stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public interface UItemGroups {
|
||||||
ItemGroup UNICORN_ITEMS = forTag("unicorn", UItems.SPELLBOOK::getDefaultStack);
|
ItemGroup UNICORN_ITEMS = forTag("unicorn", UItems.SPELLBOOK::getDefaultStack);
|
||||||
ItemGroup PEGASUS_ITEMS = forTag("pegasus", UItems.PEGASUS_FEATHER::getDefaultStack);
|
ItemGroup PEGASUS_ITEMS = forTag("pegasus", UItems.PEGASUS_FEATHER::getDefaultStack);
|
||||||
ItemGroup BAT_PONY_ITEMS = forTag("bat_pony", UItems.SUNGLASSES::getDefaultStack);
|
ItemGroup BAT_PONY_ITEMS = forTag("bat_pony", UItems.SUNGLASSES::getDefaultStack);
|
||||||
ItemGroup CHANGELING_ITEMS = forTag("changeling", Items.SCULK_SHRIEKER::getDefaultStack);
|
ItemGroup CHANGELING_ITEMS = forTag("changeling", UItems.LOVE_BOTTLE::getDefaultStack);
|
||||||
|
|
||||||
static ItemGroup forTag(String name, Supplier<ItemStack> icon) {
|
static ItemGroup forTag(String name, Supplier<ItemStack> icon) {
|
||||||
TagKey<Item> key = UTags.item("groups/" + name);
|
TagKey<Item> key = UTags.item("groups/" + name);
|
||||||
|
|
|
@ -86,6 +86,10 @@ public interface UItems {
|
||||||
Item APPLE_PIE = register("apple_pie", new BlockItem(UBlocks.APPLE_PIE, new Item.Settings().group(ItemGroup.FOOD).maxCount(1)));
|
Item APPLE_PIE = register("apple_pie", new BlockItem(UBlocks.APPLE_PIE, new Item.Settings().group(ItemGroup.FOOD).maxCount(1)));
|
||||||
Item APPLE_PIE_SLICE = register("apple_pie_slice", new Item(new Item.Settings().group(ItemGroup.FOOD).maxCount(16).food(UFoodComponents.PIE)));
|
Item APPLE_PIE_SLICE = register("apple_pie_slice", new Item(new Item.Settings().group(ItemGroup.FOOD).maxCount(16).food(UFoodComponents.PIE)));
|
||||||
|
|
||||||
|
Item LOVE_BOTTLE = register("love_bottle", new DrinkableItem(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.LOVE_BOTTLE).maxCount(1).recipeRemainder(Items.GLASS_BOTTLE)));
|
||||||
|
Item LOVE_BUCKET = register("love_bucket", new DrinkableItem(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.LOVE_BUCKET).recipeRemainder(Items.BUCKET)));
|
||||||
|
Item LOVE_MUG = register("love_mug", new DrinkableItem(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.LOVE_MUG).recipeRemainder(MUG)));
|
||||||
|
|
||||||
Item GOLDEN_FEATHER = register("golden_feather", new Item(new Item.Settings().rarity(Rarity.UNCOMMON).group(ItemGroup.MATERIALS)));
|
Item GOLDEN_FEATHER = register("golden_feather", new Item(new Item.Settings().rarity(Rarity.UNCOMMON).group(ItemGroup.MATERIALS)));
|
||||||
Item GOLDEN_WING = register("golden_wing", new Item(new Item.Settings().rarity(Rarity.UNCOMMON).group(ItemGroup.MATERIALS)));
|
Item GOLDEN_WING = register("golden_wing", new Item(new Item.Settings().rarity(Rarity.UNCOMMON).group(ItemGroup.MATERIALS)));
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,9 @@ public interface Toxics {
|
||||||
.with(Race.BAT, Ailment.INNERT)
|
.with(Race.BAT, Ailment.INNERT)
|
||||||
);
|
);
|
||||||
|
|
||||||
Toxic LOVE = register("love", new Toxic.Builder(Ailment.INNERT));
|
Toxic LOVE = register("love", new Toxic.Builder(Ailment.INNERT)
|
||||||
|
.with(Race.CHANGELING, of(Toxicity.SAFE, Toxin.LOVE_CONSUMPTION))
|
||||||
|
);
|
||||||
|
|
||||||
static void bootstrap() {}
|
static void bootstrap() {}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,14 @@ public interface Toxin extends Affliction {
|
||||||
player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2);
|
player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2);
|
||||||
}).and(STRONG_NAUSEA).and(IF_NOT_PEACEFUL.then(WEAK_FOOD_POISONING.withChance(20))).and(WEAKNESS);
|
}).and(STRONG_NAUSEA).and(IF_NOT_PEACEFUL.then(WEAK_FOOD_POISONING.withChance(20))).and(WEAKNESS);
|
||||||
|
|
||||||
|
Toxin LOVE_CONSUMPTION = of(Text.literal("love"), (player, stack) -> {
|
||||||
|
player.heal(stack.isFood() ? stack.getItem().getFoodComponent().getHunger() : 1);
|
||||||
|
player.removeStatusEffect(StatusEffects.NAUSEA);
|
||||||
|
if (player.world.random.nextInt(10) == 0) {
|
||||||
|
player.removeStatusEffect(UEffects.FOOD_POISONING);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
default void appendTooltip(List<Text> tooltip) {
|
default void appendTooltip(List<Text> tooltip) {
|
||||||
tooltip.add(getName());
|
tooltip.add(getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,10 @@ public interface UFoodComponents {
|
||||||
.statusEffect(new StatusEffectInstance(StatusEffects.BAD_OMEN, 100, 0), 0.6F)
|
.statusEffect(new StatusEffectInstance(StatusEffects.BAD_OMEN, 100, 0), 0.6F)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
FoodComponent LOVE_BOTTLE = builder(2, 0.125F).alwaysEdible().snack().build();
|
||||||
|
FoodComponent LOVE_MUG = builder(4, 0.125F).snack().build();
|
||||||
|
FoodComponent LOVE_BUCKET = builder(8, 0.125F).build();
|
||||||
|
|
||||||
static FoodComponent.Builder builder(int hunger, float saturation) {
|
static FoodComponent.Builder builder(int hunger, float saturation) {
|
||||||
return new FoodComponent.Builder()
|
return new FoodComponent.Builder()
|
||||||
.hunger(hunger)
|
.hunger(hunger)
|
||||||
|
|
|
@ -33,6 +33,10 @@
|
||||||
"item.unicopia.zap_apple": "Zap Apple",
|
"item.unicopia.zap_apple": "Zap Apple",
|
||||||
"item.unicopia.zap_bulb": "Unripened Zap Apple",
|
"item.unicopia.zap_bulb": "Unripened Zap Apple",
|
||||||
|
|
||||||
|
"item.unicopia.love_bottle": "Bottle o' Love",
|
||||||
|
"item.unicopia.love_bucket": "Love Bucket",
|
||||||
|
"item.unicopia.love_mug": "Mug o' Love",
|
||||||
|
|
||||||
"item.unicopia.empty_jar": "Glass Jar",
|
"item.unicopia.empty_jar": "Glass Jar",
|
||||||
"item.unicopia.filled_jar": "%s in a Jar",
|
"item.unicopia.filled_jar": "%s in a Jar",
|
||||||
"item.unicopia.rain_cloud_jar": "Rain in a Jar",
|
"item.unicopia.rain_cloud_jar": "Rain in a Jar",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "unicopia:item/mug",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/love_bottle"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "unicopia:item/mug",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/love_bucket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "unicopia:item/mug",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/love_mug"
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/unicopia/textures/item/love_bottle.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/item/love_bottle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
src/main/resources/assets/unicopia/textures/item/love_bucket.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/item/love_bucket.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
src/main/resources/assets/unicopia/textures/item/love_mug.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/item/love_mug.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"unicopia:love_bottle",
|
||||||
|
"unicopia:love_bucket",
|
||||||
|
"unicopia:love_mug"
|
||||||
|
]
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"#unicopia:food_types/cooked_meat",
|
"#unicopia:food_types/cooked_meat",
|
||||||
"#unicopia:food_types/raw_meat",
|
"#unicopia:food_types/raw_meat",
|
||||||
"#unicopia:food_types/raw_insect",
|
"#unicopia:food_types/raw_insect",
|
||||||
"#unicopia:food_types/rotten_meat"
|
"#unicopia:food_types/rotten_meat",
|
||||||
|
"#unicopia:food_types/love"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
"replace": false,
|
||||||
"values": [
|
"values": [
|
||||||
|
"unicopia:green_apple_leaves",
|
||||||
|
"unicopia:sweet_apple_leaves",
|
||||||
|
"unicopia:sour_apple_leaves",
|
||||||
|
"unicopia:zap_leaves",
|
||||||
|
"unicopia:zap_log",
|
||||||
|
"unicopia:zap_wood",
|
||||||
|
"unicopia:stripped_zap_log",
|
||||||
|
"unicopia:stripped_zap_wood",
|
||||||
"minecraft:apple",
|
"minecraft:apple",
|
||||||
"unicopia:green_apple",
|
"unicopia:green_apple",
|
||||||
"unicopia:sweet_apple",
|
"unicopia:sweet_apple",
|
||||||
|
@ -8,6 +16,9 @@
|
||||||
"unicopia:zap_apple",
|
"unicopia:zap_apple",
|
||||||
"unicopia:zap_bulb",
|
"unicopia:zap_bulb",
|
||||||
"unicopia:rotten_apple",
|
"unicopia:rotten_apple",
|
||||||
|
"unicopia:green_apple_seeds",
|
||||||
|
"unicopia:sweet_apple_seeds",
|
||||||
|
"unicopia:sour_apple_seeds",
|
||||||
"unicopia:empty_jar",
|
"unicopia:empty_jar",
|
||||||
"unicopia:cooked_zap_apple",
|
"unicopia:cooked_zap_apple",
|
||||||
"unicopia:zap_apple_jam_jar",
|
"unicopia:zap_apple_jam_jar",
|
||||||
|
@ -24,9 +35,6 @@
|
||||||
"unicopia:rock",
|
"unicopia:rock",
|
||||||
"unicopia:weird_rock",
|
"unicopia:weird_rock",
|
||||||
"unicopia:rock_stew",
|
"unicopia:rock_stew",
|
||||||
"unicopia:green_apple_seeds",
|
|
||||||
"unicopia:sweet_apple_seeds",
|
|
||||||
"unicopia:sour_apple_seeds",
|
|
||||||
"unicopia:mug",
|
"unicopia:mug",
|
||||||
"unicopia:cider",
|
"unicopia:cider",
|
||||||
"unicopia:juice",
|
"unicopia:juice",
|
||||||
|
|
Loading…
Reference in a new issue