Compare commits

..

2 commits

Author SHA1 Message Date
24e5854d8c Add non working achievements 2023-10-21 17:19:40 +03:00
78f9b80861 Minor code improvements 2023-10-21 14:25:47 +03:00
20 changed files with 344 additions and 272 deletions

View file

@ -31,5 +31,12 @@
This version focuses on QOL and bug fixes This version focuses on QOL and bug fixes
* Added Russian translation (ru_ru) * Added Russian translation (ru_ru)
* Fixed some issues with blocks being non opaque * Added button to open config file when using Mod Menu
* Deleted some unused textures and models * Added several new achievements and challenges
* Minor bug fixes
* Fixed issue with some blocks being non opaque
* Switches no longer emit redstone particle
* Slightly improved cigarette's GUI model
* Technical changes
* Simplified recipe data generation
* Deleted various unused files - code, textures and models

View file

@ -101,6 +101,7 @@ publishing {
modrinth { modrinth {
token = System.getenv(modrinth_token) // DO NOT REVEAL THE TOKEN!!! token = System.getenv(modrinth_token) // DO NOT REVEAL THE TOKEN!!!
projectId = mod_id projectId = mod_id
versionName = mod_name + " " + mod_version
versionNumber = mod_version versionNumber = mod_version
versionType = "beta" // release/beta/alpha versionType = "beta" // release/beta/alpha
uploadFile = remapJar uploadFile = remapJar

View file

@ -9,6 +9,7 @@ yarn_mappings=1.20.1+build.10
loader_version=0.14.23 loader_version=0.14.23
# Mod Properties # Mod Properties
mod_name=New Soviet Era
mod_version=0.2 mod_version=0.2
maven_group=su.a71 maven_group=su.a71
mod_id=new_soviet mod_id=new_soviet

View file

@ -31,15 +31,6 @@ public class NewSovietClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.VINTAGE_IRON_BARS, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.VINTAGE_IRON_BARS, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.BARBED_WIRE, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.BARBED_WIRE, RenderLayer.getCutout());
// TODO: Needed?
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.RED_CONCRETE_WITH_BARS, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.GREEN_CONCRETE_WITH_BARS, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.WHITE_CONCRETE_WITH_BARS, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.BEIGE_CONCRETE_WITH_BARS, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.YELLOW_CONCRETE_WITH_BARS, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Blocks.BLUE_CONCRETE_WITH_BARS, RenderLayer.getCutout());
// BlockEntityRendererRegistry.register(NSE_Custom.TV_BLOCK_ENTITY, TVBlockEntityRenderer::new);
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Custom.TV, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(NSE_Custom.TV, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Custom.RED_TV, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(NSE_Custom.RED_TV, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(NSE_Custom.BROWN_TV, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(NSE_Custom.BROWN_TV, RenderLayer.getCutout());

View file

@ -1,58 +0,0 @@
package su.a71.new_soviet;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.block.SignBlock;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.math.Vec3d;
import su.a71.new_soviet.entities.TVBlockEntity;
@Environment(EnvType.CLIENT)
public class TVBlockEntityRenderer implements BlockEntityRenderer<TVBlockEntity> {
// private static TextRenderer textRenderer;
private static final Vec3d TEXT_OFFSET = new Vec3d(0.0, 0.3333333432674408, 0.046666666865348816);
public TVBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {
// textRenderer = ctx.getTextRenderer();
}
@Override
public void render(TVBlockEntity blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
matrices.push();
// Rendering stuff here
// this.setTextAngles(matrices, true, TEXT_OFFSET);
// textRenderer.draw("Test amogus", 0, 0, 999999, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextRenderer.TextLayerType.POLYGON_OFFSET, 19999, light);
matrices.pop();
}
public float getScale() {
return 0.6666667F;
}
void setAngles(MatrixStack matrices, float rotationDegrees, BlockState state) {
matrices.translate(0.5F, 0.75F * this.getScale(), 0.5F);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(rotationDegrees));
if (!(state.getBlock() instanceof SignBlock)) {
matrices.translate(0.0F, -0.3125F, -0.4375F);
}
}
private void setTextAngles(MatrixStack matrices, boolean front, Vec3d translation) {
if (!front) {
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180.0F));
}
float f = 0.015625F * this.getScale();
matrices.translate(translation.x, translation.y, translation.z);
matrices.scale(f, -f, f);
}
}

View file

@ -0,0 +1,56 @@
{
"parent": "minecraft:new_soviet/root",
"criteria": {
"rolled_100": {
"conditions": {
"item": {
"tag": "new_soviet:dice"
},
"player": [
{
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"type": "minecraft:player",
"type_specific": {
"type": "player",
"stats": [
{
"type": "minecraft:custom",
"stat": "minecraft:roll_dice",
"value": {
"min": 100
}
}
]
}
}
}
]
},
"trigger": "minecraft:using_item"
}
},
"display": {
"announce_to_chat": true,
"background": "minecraft:textures/gui/advancements/backgrounds/adventure.png",
"description": {
"translate": "advancement.new_soviet.gambler.desc"
},
"frame": "task",
"hidden": false,
"icon": {
"item": "new_soviet:dice_d6"
},
"show_toast": true,
"title": {
"translate": "advancement.new_soviet.gambler.name"
}
},
"requirements": [
[
"rolled_100"
]
],
"sends_telemetry_event": true
}

View file

@ -0,0 +1,56 @@
{
"parent": "minecraft:new_soviet/gambler",
"criteria": {
"rolled_100_perfect": {
"conditions": {
"item": {
"tag": "new_soviet:dice"
},
"player": [
{
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"type": "minecraft:player",
"type_specific": {
"type": "player",
"stats": [
{
"type": "minecraft:custom",
"stat": "minecraft:roll_perfect_dice",
"value": {
"min": 100
}
}
]
}
}
}
]
},
"trigger": "minecraft:using_item"
}
},
"display": {
"announce_to_chat": true,
"background": "minecraft:textures/gui/advancements/backgrounds/adventure.png",
"description": {
"translate": "advancement.new_soviet.lucky_throw.desc"
},
"frame": "challenge",
"hidden": false,
"icon": {
"item": "new_soviet:dice_d4"
},
"show_toast": true,
"title": {
"translate": "advancement.new_soviet.lucky_throw.name"
}
},
"requirements": [
[
"rolled_100_perfect"
]
],
"sends_telemetry_event": true
}

View file

@ -0,0 +1,56 @@
{
"parent": "minecraft:new_soviet/gambler",
"criteria": {
"rolled_1000": {
"conditions": {
"item": {
"tag": "new_soviet:dice"
},
"player": [
{
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"type": "minecraft:player",
"type_specific": {
"type": "player",
"stats": [
{
"type": "minecraft:custom",
"stat": "minecraft:roll_dice",
"value": {
"min": 1000
}
}
]
}
}
}
]
},
"trigger": "minecraft:using_item"
}
},
"display": {
"announce_to_chat": true,
"background": "minecraft:textures/gui/advancements/backgrounds/adventure.png",
"description": {
"translate": "advancement.new_soviet.serious_addiction.desc"
},
"frame": "challenge",
"hidden": false,
"icon": {
"item": "new_soviet:dice_d20"
},
"show_toast": true,
"title": {
"translate": "advancement.new_soviet.serious_addiction.name"
}
},
"requirements": [
[
"rolled_1000"
]
],
"sends_telemetry_event": true
}

View file

@ -4,7 +4,6 @@ import net.minecraft.block.*;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.FluidState; import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids; import net.minecraft.fluid.Fluids;
import net.minecraft.item.BucketItem;
import net.minecraft.item.DyeItem; import net.minecraft.item.DyeItem;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
@ -13,7 +12,6 @@ import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.IntProperty; import net.minecraft.state.property.IntProperty;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -56,7 +54,7 @@ public class BoundaryMarkerBlock extends Block implements Waterloggable {
player.getInventory().getMainHandStack().decrement(1); player.getInventory().getMainHandStack().decrement(1);
} }
world.setBlockState(pos, state.with(COLOUR, id)); world.setBlockState(pos, state.with(COLOUR, id));
world.playSound((PlayerEntity)null, pos, SoundEvents.ITEM_DYE_USE, SoundCategory.BLOCKS, 1.0F, 1.0F); world.playSound(null, pos, SoundEvents.ITEM_DYE_USE, SoundCategory.BLOCKS, 1.0F, 1.0F);
} }
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }

View file

@ -1,7 +1,6 @@
package su.a71.new_soviet.blocks; package su.a71.new_soviet.blocks;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.enums.Thickness;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.fluid.FluidState; import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids; import net.minecraft.fluid.Fluids;
@ -16,8 +15,6 @@ import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import org.jetbrains.annotations.Nullable;
public class ConcreteWithBarsBlock extends HorizontalFacingBlock implements Waterloggable { public class ConcreteWithBarsBlock extends HorizontalFacingBlock implements Waterloggable {
public static final DirectionProperty VERTICAL_DIRECTION; public static final DirectionProperty VERTICAL_DIRECTION;

View file

@ -1,6 +1,5 @@
package su.a71.new_soviet.blocks; package su.a71.new_soviet.blocks;
import com.mojang.authlib.minecraft.client.MinecraftClient;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.piston.PistonBehavior; import net.minecraft.block.piston.PistonBehavior;
@ -67,9 +66,9 @@ public class SirenBlock extends HorizontalFacingBlock implements Waterloggable {
if (bl) { if (bl) {
world.scheduleBlockTick(pos, this, 4); world.scheduleBlockTick(pos, this, 4);
} else { } else {
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).getSound(), SoundCategory.NEUTRAL, getSirenVolume(world, pos), 1f); world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).sound(), SoundCategory.NEUTRAL, getSirenVolume(world, pos), 1f);
world.setBlockState(pos, state.cycle(ON), 2); world.setBlockState(pos, state.cycle(ON), 2);
world.scheduleBlockTick(pos, this, SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).getDuration()); world.scheduleBlockTick(pos, this, SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).duration());
} }
} }
} }
@ -81,7 +80,7 @@ public class SirenBlock extends HorizontalFacingBlock implements Waterloggable {
if (!world.isClient) { if (!world.isClient) {
incrementSoundIndex(world, pos); incrementSoundIndex(world, pos);
} }
player.sendMessage(Text.translatable("block.new_soviet.siren.set", SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).getName()), true); player.sendMessage(Text.translatable("block.new_soviet.siren.set", SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).name()), true);
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
return super.onUse(state, world, pos, player, hand, hit); return super.onUse(state, world, pos, player, hand, hit);
@ -119,8 +118,8 @@ public class SirenBlock extends HorizontalFacingBlock implements Waterloggable {
if (state.get(ON) && !world.isReceivingRedstonePower(pos)) { if (state.get(ON) && !world.isReceivingRedstonePower(pos)) {
world.setBlockState(pos, state.cycle(ON), 2); world.setBlockState(pos, state.cycle(ON), 2);
} else { } else {
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).getSound(), SoundCategory.NEUTRAL, getSirenVolume(world, pos), 1f); world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).sound(), SoundCategory.NEUTRAL, getSirenVolume(world, pos), 1f);
world.scheduleBlockTick(pos, this, SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).getDuration()); world.scheduleBlockTick(pos, this, SIREN_SOUNDS.get(world.getBlockState(pos).get(SOUND_INDEX)).duration());
} }
} }
@ -166,27 +165,6 @@ public class SirenBlock extends HorizontalFacingBlock implements Waterloggable {
WATERLOGGED = Properties.WATERLOGGED; WATERLOGGED = Properties.WATERLOGGED;
} }
public class SirenSound { public record SirenSound(String name, SoundEvent sound, int duration) {
private final SoundEvent sound;
private final int duration;
private final String name;
public SirenSound( String name, SoundEvent sound, int duration) {
this.sound = sound;
this.duration = duration;
this.name = name;
}
public SoundEvent getSound() {
return sound;
}
public int getDuration() {
return duration;
}
public String getName() {
return name;
}
} }
} }

View file

@ -4,7 +4,6 @@ import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.enums.WallMountLocation; import net.minecraft.block.enums.WallMountLocation;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.particle.DustParticleEffect;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.state.StateManager; import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.BooleanProperty;
@ -14,10 +13,10 @@ import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.event.GameEvent; import net.minecraft.world.event.GameEvent;
import su.a71.new_soviet.registration.NSE_Sounds; import su.a71.new_soviet.registration.NSE_Sounds;
@ -77,14 +76,8 @@ public class SwitchBlock extends LeverBlock {
return ActionResult.CONSUME; return ActionResult.CONSUME;
} }
private static void spawnParticles(BlockState state, WorldAccess world, BlockPos pos, float alpha) { // Remove those annoying redstone particles
Direction direction = state.get(FACING).getOpposite(); public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {}
Direction direction2 = SwitchBlock.getDirection(state).getOpposite();
double d = (double)pos.getX() + 0.5 + 0.1 * (double)direction.getOffsetX() + 0.2 * (double)direction2.getOffsetX();
double e = (double)pos.getY() + 0.5 + 0.1 * (double)direction.getOffsetY() + 0.2 * (double)direction2.getOffsetY();
double f = (double)pos.getZ() + 0.5 + 0.1 * (double)direction.getOffsetZ() + 0.2 * (double)direction2.getOffsetZ();
world.addParticle(new DustParticleEffect(DustParticleEffect.RED, alpha), d, e, f, 0.0, 0.0, 0.0);
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {

View file

@ -3,19 +3,24 @@ package su.a71.new_soviet.datagen;
import net.minecraft.advancement.Advancement; import net.minecraft.advancement.Advancement;
import net.minecraft.advancement.AdvancementFrame; import net.minecraft.advancement.AdvancementFrame;
import net.minecraft.advancement.criterion.InventoryChangedCriterion; import net.minecraft.advancement.criterion.InventoryChangedCriterion;
import net.minecraft.advancement.criterion.ItemCriterion;
import net.minecraft.advancement.criterion.OnKilledCriterion; import net.minecraft.advancement.criterion.OnKilledCriterion;
import net.minecraft.advancement.criterion.PlayerHurtEntityCriterion; import net.minecraft.advancement.criterion.UsingItemCriterion;
import net.minecraft.entity.EntityType;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.predicate.NumberRange;
import net.minecraft.predicate.entity.DamageSourcePredicate; import net.minecraft.predicate.entity.DamageSourcePredicate;
import net.minecraft.predicate.entity.EntityEquipmentPredicate; import net.minecraft.predicate.entity.EntityEquipmentPredicate;
import net.minecraft.predicate.entity.EntityPredicate; import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.predicate.entity.PlayerPredicate;
import net.minecraft.predicate.item.ItemPredicate; import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.registry.tag.ItemTags; import net.minecraft.stat.Stats;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.UseAction;
import su.a71.new_soviet.NewSoviet; import su.a71.new_soviet.NewSoviet;
import su.a71.new_soviet.items.DiceItem;
import su.a71.new_soviet.registration.NSE_Items; import su.a71.new_soviet.registration.NSE_Items;
import su.a71.new_soviet.registration.NSE_Stats;
import su.a71.new_soviet.registration.NSE_Tags; import su.a71.new_soviet.registration.NSE_Tags;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -71,34 +76,54 @@ public class Advancements implements Consumer<Consumer<Advancement>> {
.build(consumer, NewSoviet.MOD_ID + "/sickle_kill"); .build(consumer, NewSoviet.MOD_ID + "/sickle_kill");
// // Throw a die 100 times // Throw a die 100 times
// Advancement gambler = Advancement.Builder.create() Advancement gambler = Advancement.Builder.create()
// .display( .display(
// NSE_Items.DICE_D6, NSE_Items.DICE_D6,
// Text.translatable("advancement.new_soviet.gambler.name"), Text.translatable("advancement.new_soviet.gambler.name"),
// Text.translatable("advancement.new_soviet.gambler.desc"), Text.translatable("advancement.new_soviet.gambler.desc"),
// new Identifier("textures/gui/advancements/backgrounds/adventure.png"), new Identifier("textures/gui/advancements/backgrounds/adventure.png"),
// AdvancementFrame.CHALLENGE, AdvancementFrame.TASK,
// true, // Toast true, // Toast
// true, // Announcement true, // Announcement
// false // Hidden false // Hidden
// ) )
// .criterion("threw_dice", InventoryChangedCriterion.Conditions.items(Items.DIRT)) .parent(root)
// .build(consumer, NewSoviet.MOD_ID + "/gambler"); .criterion("rolled_100", UsingItemCriterion.Conditions.create(
EntityPredicate.Builder.create().type(EntityType.PLAYER).typeSpecific(PlayerPredicate.Builder.create().stat(Stats.CUSTOM.getOrCreateStat(NSE_Stats.ROLL_ANY_DICE), NumberRange.IntRange.atLeast(100)).build()),
ItemPredicate.Builder.create().tag(NSE_Tags.Items.DICE)))
.build(consumer, NewSoviet.MOD_ID + "/gambler");
// Throw a die 1000 times // Throw a die 1000 times
// Advancement serious_addiction = Advancement.Builder.create() Advancement serious_addiction = Advancement.Builder.create()
// .display( .display(
// NSE_Items.DICE_D20, NSE_Items.DICE_D20,
// Text.translatable("advancement.new_soviet.serious_addiction.name"), Text.translatable("advancement.new_soviet.serious_addiction.name"),
// Text.translatable("advancement.new_soviet.serious_addiction.desc"), Text.translatable("advancement.new_soviet.serious_addiction.desc"),
// new Identifier("textures/gui/advancements/backgrounds/adventure.png"), new Identifier("textures/gui/advancements/backgrounds/adventure.png"),
// AdvancementFrame.CHALLENGE, AdvancementFrame.CHALLENGE,
// true, // Toast true, // Toast
// true, // Announcement true, // Announcement
// false // Hidden false // Hidden
// ) )
// .criterion("threw_dice", InventoryChangedCriterion.Conditions.items(Items.DIRT)) .criterion("rolled_1000", UsingItemCriterion.Conditions.create(EntityPredicate.Builder.create().type(EntityType.PLAYER).typeSpecific(PlayerPredicate.Builder.create().stat(Stats.CUSTOM.getOrCreateStat(NSE_Stats.ROLL_ANY_DICE), NumberRange.IntRange.atLeast(1000)).build()), ItemPredicate.Builder.create().tag(NSE_Tags.Items.DICE)))
// .parent(gambler) .parent(gambler)
// .build(consumer, NewSoviet.MOD_ID + "/serious_addiction"); .build(consumer, NewSoviet.MOD_ID + "/serious_addiction");
// Roll perfect die 100 times
Advancement lucky_throw = Advancement.Builder.create()
.display(
NSE_Items.DICE_D4,
Text.translatable("advancement.new_soviet.lucky_throw.name"),
Text.translatable("advancement.new_soviet.lucky_throw.desc"),
new Identifier("textures/gui/advancements/backgrounds/adventure.png"),
AdvancementFrame.CHALLENGE,
true, // Toast
true, // Announcement
false // Hidden
)
.parent(gambler)
.criterion("rolled_100_perfect", UsingItemCriterion.Conditions.create(EntityPredicate.Builder.create().type(EntityType.PLAYER).typeSpecific(PlayerPredicate.Builder.create().stat(Stats.CUSTOM.getOrCreateStat(NSE_Stats.ROLL_PERFECT_DICE), NumberRange.IntRange.atLeast(100)).build()), ItemPredicate.Builder.create().tag(NSE_Tags.Items.DICE)))
.build(consumer, NewSoviet.MOD_ID + "/lucky_throw");
} }
} }

View file

@ -4,13 +4,10 @@ package su.a71.new_soviet.datagen;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.PaneBlock;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;
import net.minecraft.block.StairsBlock; import net.minecraft.block.StairsBlock;
import net.minecraft.data.client.*; import net.minecraft.data.client.*;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import su.a71.new_soviet.registration.NSE_Blocks; import su.a71.new_soviet.registration.NSE_Blocks;
@ -61,18 +58,6 @@ public class ModelGenerator extends FabricModelProvider {
blockStateModelGenerator.blockStateCollector.accept(BlockStateModelGenerator.createStairsBlockState(stairs, stairs_model_inner, stairs_model, stairs_model_outer)); blockStateModelGenerator.blockStateCollector.accept(BlockStateModelGenerator.createStairsBlockState(stairs, stairs_model_inner, stairs_model, stairs_model_outer));
} }
// public final void registerPaneFence(BlockStateModelGenerator blockStateModelGenerator, PaneBlock block, String texturePath) {
// TextureMap textureMap = (new TextureMap()).put(TextureKey.PANE, getId(block)).put(TextureKey.EDGE, getSubId(top, "_top"));
// Identifier identifier = Models.TEMPLATE_GLASS_PANE_POST.upload(glassPane, textureMap, this.modelCollector);
// Identifier identifier2 = Models.TEMPLATE_GLASS_PANE_SIDE.upload(glassPane, textureMap, this.modelCollector);
// Identifier identifier3 = Models.TEMPLATE_GLASS_PANE_SIDE_ALT.upload(glassPane, textureMap, this.modelCollector);
// Identifier identifier4 = Models.TEMPLATE_GLASS_PANE_NOSIDE.upload(glassPane, textureMap, this.modelCollector);
// Identifier identifier5 = Models.TEMPLATE_GLASS_PANE_NOSIDE_ALT.upload(glassPane, textureMap, this.modelCollector);
// Item item = glassPane.asItem();
// Models.GENERATED.upload(ModelIds.getItemModelId(item), TextureMap.layer0(glass), this.modelCollector);
// this.blockStateCollector.accept(MultipartBlockStateSupplier.create(glassPane).with(BlockStateVariant.create().put(VariantSettings.MODEL, identifier)).with(When.create().set(Properties.NORTH, true), BlockStateVariant.create().put(VariantSettings.MODEL, identifier2)).with(When.create().set(Properties.EAST, true), BlockStateVariant.create().put(VariantSettings.MODEL, identifier2).put(VariantSettings.Y, VariantSettings.Rotation.R90)).with(When.create().set(Properties.SOUTH, true), BlockStateVariant.create().put(VariantSettings.MODEL, identifier3)).with(When.create().set(Properties.WEST, true), BlockStateVariant.create().put(VariantSettings.MODEL, identifier3).put(VariantSettings.Y, VariantSettings.Rotation.R90)).with(When.create().set(Properties.NORTH, false), BlockStateVariant.create().put(VariantSettings.MODEL, identifier4)).with(When.create().set(Properties.EAST, false), BlockStateVariant.create().put(VariantSettings.MODEL, identifier5)).with(When.create().set(Properties.SOUTH, false), BlockStateVariant.create().put(VariantSettings.MODEL, identifier5).put(VariantSettings.Y, VariantSettings.Rotation.R90)).with(When.create().set(Properties.WEST, false), BlockStateVariant.create().put(VariantSettings.MODEL, identifier4).put(VariantSettings.Y, VariantSettings.Rotation.R270)));
// }
@Override @Override
public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) {
registerDoor(blockStateModelGenerator, NSE_Blocks.CHISELED_BIRCH_DOOR); registerDoor(blockStateModelGenerator, NSE_Blocks.CHISELED_BIRCH_DOOR);

View file

@ -9,12 +9,10 @@ import net.minecraft.data.server.recipe.RecipeJsonProvider;
import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.DyeItem;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.ItemTags;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import su.a71.new_soviet.registration.NSE_Blocks; import su.a71.new_soviet.registration.NSE_Blocks;
@ -156,102 +154,6 @@ public class RecipeGenerator extends FabricRecipeProvider {
.offerTo(exporter); .offerTo(exporter);
} }
private void radioRecipe(Consumer<RecipeJsonProvider> exporter, ItemConvertible output) {
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 1)
.pattern(" N")
.pattern("MMM")
.pattern("III")
.input('M', Blocks.NOTE_BLOCK)
.input('N', Items.IRON_NUGGET)
.input('I', Items.IRON_INGOT)
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.criterion(RecipeProvider.hasItem(Items.NOTE_BLOCK),
RecipeProvider.conditionsFromItem(Items.NOTE_BLOCK))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.offerTo(exporter);
}
private void ceilingFanRecipe(Consumer<RecipeJsonProvider> exporter, ItemConvertible output) {
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 1)
.pattern(" I ")
.pattern("NNN")
.input('I', Items.IRON_INGOT)
.input('N', Items.IRON_NUGGET)
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.offerTo(exporter);
}
private void tableLampRecipe(Consumer<RecipeJsonProvider> exporter, ItemConvertible output) {
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 3)
.pattern("WWW")
.pattern("WTW")
.pattern(" S ")
.input('S', Items.STICK)
.input('T', Items.TORCH)
.input('W', ItemTags.WOOL)
.criterion(RecipeProvider.hasItem(Items.TORCH),
RecipeProvider.conditionsFromItem(Items.TORCH))
.criterion(RecipeProvider.hasItem(Items.STICK),
RecipeProvider.conditionsFromItem(Items.STICK))
.criterion("has_wool", RecipeProvider.conditionsFromTag(ItemTags.WOOL))
.offerTo(exporter);
}
private void vintageLampRecipe(Consumer<RecipeJsonProvider> exporter, ItemConvertible output) {
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 3)
.pattern("NNN")
.pattern("GTG")
.pattern(" N ")
.input('N', Items.IRON_NUGGET)
.input('T', Items.TORCH)
.input('G', Items.GREEN_STAINED_GLASS)
.criterion(RecipeProvider.hasItem(Items.TORCH),
RecipeProvider.conditionsFromItem(Items.TORCH))
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.criterion(RecipeProvider.hasItem(Items.GREEN_STAINED_GLASS),
RecipeProvider.conditionsFromItem(Items.GREEN_STAINED_GLASS))
.offerTo(exporter);
}
private void sickleRecipe(Consumer<RecipeJsonProvider> exporter, ItemConvertible output) {
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 1)
.pattern(" I ")
.pattern(" I")
.pattern(" S ")
.input('S', Items.STICK)
.input('I', Items.IRON_INGOT)
.criterion(RecipeProvider.hasItem(Items.STICK),
RecipeProvider.conditionsFromItem(Items.STICK))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.offerTo(exporter);
}
private void rakeRecipe(Consumer<RecipeJsonProvider> exporter, ItemConvertible output) {
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 1)
.pattern("III")
.pattern(" N ")
.pattern(" S ")
.input('S', Items.STICK)
.input('I', Items.IRON_INGOT)
.input('N', Items.IRON_NUGGET)
.criterion(RecipeProvider.hasItem(Items.STICK),
RecipeProvider.conditionsFromItem(Items.STICK))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.offerTo(exporter);
}
private void offerStairsAndSlab(Consumer<RecipeJsonProvider> exporter, ItemConvertible output_stairs, ItemConvertible output_slab, ItemConvertible input) { private void offerStairsAndSlab(Consumer<RecipeJsonProvider> exporter, ItemConvertible output_stairs, ItemConvertible output_slab, ItemConvertible input) {
createStairsRecipe(output_stairs, Ingredient.ofItems(input)) createStairsRecipe(output_stairs, Ingredient.ofItems(input))
.criterion(hasItem(input), conditionsFromItem(input)).offerTo(exporter); .criterion(hasItem(input), conditionsFromItem(input)).offerTo(exporter);
@ -272,12 +174,6 @@ public class RecipeGenerator extends FabricRecipeProvider {
tvRecipe(exporter, NSE_Custom.TV, Items.ORANGE_DYE); tvRecipe(exporter, NSE_Custom.TV, Items.ORANGE_DYE);
tvRecipe(exporter, NSE_Custom.BROWN_TV, Items.BROWN_DYE); tvRecipe(exporter, NSE_Custom.BROWN_TV, Items.BROWN_DYE);
tvRecipe(exporter, NSE_Custom.RED_TV, Items.RED_DYE); tvRecipe(exporter, NSE_Custom.RED_TV, Items.RED_DYE);
radioRecipe(exporter, NSE_Custom.RADIO_RECEIVER);
ceilingFanRecipe(exporter, NSE_Custom.CEILING_FAN);
tableLampRecipe(exporter, NSE_Custom.TABLE_LAMP);
vintageLampRecipe(exporter, NSE_Custom.VINTAGE_LAMP);
sickleRecipe(exporter, NSE_Items.SICKLE);
rakeRecipe(exporter, NSE_Items.RAKE);
// Cracked blocks // Cracked blocks
offerCrackingRecipe(exporter, NSE_Blocks.CRACKED_BRICK_TILES, NSE_Blocks.BRICK_TILES); offerCrackingRecipe(exporter, NSE_Blocks.CRACKED_BRICK_TILES, NSE_Blocks.BRICK_TILES);
@ -540,6 +436,90 @@ public class RecipeGenerator extends FabricRecipeProvider {
offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, NSE_Blocks.CHISELED_SPRUCE_DOOR, Blocks.SPRUCE_DOOR); offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, NSE_Blocks.CHISELED_SPRUCE_DOOR, Blocks.SPRUCE_DOOR);
offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, NSE_Blocks.CHISELED_BIRCH_DOOR, Blocks.BIRCH_DOOR); offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, NSE_Blocks.CHISELED_BIRCH_DOOR, Blocks.BIRCH_DOOR);
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, NSE_Custom.RADIO_RECEIVER, 1)
.pattern(" N")
.pattern("MMM")
.pattern("III")
.input('M', Blocks.NOTE_BLOCK)
.input('N', Items.IRON_NUGGET)
.input('I', Items.IRON_INGOT)
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.criterion(RecipeProvider.hasItem(Items.NOTE_BLOCK),
RecipeProvider.conditionsFromItem(Items.NOTE_BLOCK))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.offerTo(exporter);
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, NSE_Custom.CEILING_FAN, 1)
.pattern(" I ")
.pattern("NNN")
.input('I', Items.IRON_INGOT)
.input('N', Items.IRON_NUGGET)
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.offerTo(exporter);
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, NSE_Custom.TABLE_LAMP, 3)
.pattern("WWW")
.pattern("WTW")
.pattern(" S ")
.input('S', Items.STICK)
.input('T', Items.TORCH)
.input('W', ItemTags.WOOL)
.criterion(RecipeProvider.hasItem(Items.TORCH),
RecipeProvider.conditionsFromItem(Items.TORCH))
.criterion(RecipeProvider.hasItem(Items.STICK),
RecipeProvider.conditionsFromItem(Items.STICK))
.criterion("has_wool", RecipeProvider.conditionsFromTag(ItemTags.WOOL))
.offerTo(exporter);
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, NSE_Custom.VINTAGE_LAMP, 3)
.pattern("NNN")
.pattern("GTG")
.pattern(" N ")
.input('N', Items.IRON_NUGGET)
.input('T', Items.TORCH)
.input('G', Items.GREEN_STAINED_GLASS)
.criterion(RecipeProvider.hasItem(Items.TORCH),
RecipeProvider.conditionsFromItem(Items.TORCH))
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.criterion(RecipeProvider.hasItem(Items.GREEN_STAINED_GLASS),
RecipeProvider.conditionsFromItem(Items.GREEN_STAINED_GLASS))
.offerTo(exporter);
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, NSE_Items.SICKLE, 1)
.pattern(" I ")
.pattern(" I")
.pattern(" S ")
.input('S', Items.STICK)
.input('I', Items.IRON_INGOT)
.criterion(RecipeProvider.hasItem(Items.STICK),
RecipeProvider.conditionsFromItem(Items.STICK))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.offerTo(exporter);
ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, NSE_Items.RAKE, 1)
.pattern("III")
.pattern(" N ")
.pattern(" S ")
.input('S', Items.STICK)
.input('I', Items.IRON_INGOT)
.input('N', Items.IRON_NUGGET)
.criterion(RecipeProvider.hasItem(Items.STICK),
RecipeProvider.conditionsFromItem(Items.STICK))
.criterion(RecipeProvider.hasItem(Items.IRON_INGOT),
RecipeProvider.conditionsFromItem(Items.IRON_INGOT))
.criterion(RecipeProvider.hasItem(Items.IRON_NUGGET),
RecipeProvider.conditionsFromItem(Items.IRON_NUGGET))
.offerTo(exporter);
ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, NSE_Items.LIGHT_BULB, 1) ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, NSE_Items.LIGHT_BULB, 1)
.input('B', Items.GLASS_BOTTLE).input('N', Items.IRON_NUGGET).input('D', Items.GLOWSTONE_DUST) .input('B', Items.GLASS_BOTTLE).input('N', Items.IRON_NUGGET).input('D', Items.GLOWSTONE_DUST)
.pattern(" D ").pattern(" B ").pattern(" N ") .pattern(" D ").pattern(" B ").pattern(" N ")

View file

@ -13,10 +13,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import su.a71.new_soviet.NewSoviet; import su.a71.new_soviet.NewSoviet;
import su.a71.new_soviet.registration.NSE_Sounds; import su.a71.new_soviet.registration.NSE_Sounds;

View file

@ -48,7 +48,7 @@ public class DiceItem extends Item {
user.sendMessage(Text.translatable(itemStack.getCount() == 1 ? "item.new_soviet.dice.thrown" : "item.new_soviet.dice.thrown_multiple").append(" " + output.subSequence(0, output.length() - 2)), true); user.sendMessage(Text.translatable(itemStack.getCount() == 1 ? "item.new_soviet.dice.thrown" : "item.new_soviet.dice.thrown_multiple").append(" " + output.subSequence(0, output.length() - 2)), true);
} }
} }
user.increaseStat(Stats.CUSTOM.getOrCreateStat(NSE_Stats.ROLL_ANY_DICE), itemStack.getCount());
user.increaseStat(Stats.USED.getOrCreateStat(this), itemStack.getCount()); user.increaseStat(Stats.USED.getOrCreateStat(this), itemStack.getCount());
return TypedActionResult.success(itemStack, world.isClient()); return TypedActionResult.success(itemStack, world.isClient());
} }

View file

@ -8,10 +8,14 @@ import net.minecraft.util.Identifier;
import su.a71.new_soviet.NewSoviet; import su.a71.new_soviet.NewSoviet;
public class NSE_Stats extends NSE_BaseRegistration { public class NSE_Stats extends NSE_BaseRegistration {
public static final Identifier ROLL_ANY_DICE = new Identifier(NewSoviet.MOD_ID, "roll_dice");
public static final Identifier ROLL_PERFECT_DICE = new Identifier(NewSoviet.MOD_ID, "roll_perfect_dice"); public static final Identifier ROLL_PERFECT_DICE = new Identifier(NewSoviet.MOD_ID, "roll_perfect_dice");
public static void init() { public static void init() {
Registry.register(Registries.CUSTOM_STAT, "roll_perfect_dice", ROLL_PERFECT_DICE); Registry.register(Registries.CUSTOM_STAT, "roll_perfect_dice", ROLL_PERFECT_DICE);
Stats.CUSTOM.getOrCreateStat(ROLL_PERFECT_DICE, StatFormatter.DEFAULT); Stats.CUSTOM.getOrCreateStat(ROLL_PERFECT_DICE, StatFormatter.DEFAULT);
Registry.register(Registries.CUSTOM_STAT, "roll_dice", ROLL_ANY_DICE);
Stats.CUSTOM.getOrCreateStat(ROLL_ANY_DICE, StatFormatter.DEFAULT);
} }
} }

View file

@ -474,5 +474,11 @@
"advancement.new_soviet.sickle.name": "Tool of a worker", "advancement.new_soviet.sickle.name": "Tool of a worker",
"advancement.new_soviet.sickle.desc": "Acquire a sickle", "advancement.new_soviet.sickle.desc": "Acquire a sickle",
"advancement.new_soviet.sickle_kill.name": "Kolkhoz Warrior", "advancement.new_soviet.sickle_kill.name": "Kolkhoz Warrior",
"advancement.new_soviet.sickle_kill.desc": "Kill someone with a sickle" "advancement.new_soviet.sickle_kill.desc": "Kill someone with a sickle",
"advancement.new_soviet.gambler.name": "Gambler",
"advancement.new_soviet.gambler.desc": "Roll dice 100 times",
"advancement.new_soviet.serious_addiction.name": "Serious addiction",
"advancement.new_soviet.serious_addiction.desc": "Throw a die 1000 times, and then reevaluate your life choices",
"advancement.new_soviet.lucky_throw.name": "Lucky throw",
"advancement.new_soviet.lucky_throw.desc": "Roll a perfect die 100 times"
} }

View file

@ -33,8 +33,8 @@
"rotation": [90, 0, 0] "rotation": [90, 0, 0]
}, },
"gui": { "gui": {
"rotation": [-157, 0, 0], "rotation": [-155, 225, 0],
"scale": [3.5, 3.5, 3.5] "scale": [2.5, 2.5, 2.5]
}, },
"head": { "head": {
"rotation": [90, 0, 0], "rotation": [90, 0, 0],