mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47:59 +01:00
Added a cuccoon entity (WIP)
This commit is contained in:
parent
734fa9d140
commit
79a5f215de
5 changed files with 385 additions and 3 deletions
|
@ -0,0 +1,240 @@
|
||||||
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.minelittlepony.unicopia.Predicates;
|
||||||
|
import com.minelittlepony.unicopia.Race;
|
||||||
|
import com.minelittlepony.unicopia.init.USounds;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.item.EntityXPOrb;
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.network.datasync.DataParameter;
|
||||||
|
import net.minecraft.network.datasync.DataSerializers;
|
||||||
|
import net.minecraft.network.datasync.EntityDataManager;
|
||||||
|
import net.minecraft.util.EnumHandSide;
|
||||||
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.event.ForgeEventFactory;
|
||||||
|
|
||||||
|
public class EntityCuccoon extends EntityLivingBase implements IMagicals, IInAnimate {
|
||||||
|
|
||||||
|
private static final DataParameter<Integer> STRUGGLE_COUNT = EntityDataManager.createKey(EntityCuccoon.class, DataSerializers.VARINT);
|
||||||
|
|
||||||
|
private final List<ItemStack> armour = Lists.newArrayList();
|
||||||
|
|
||||||
|
private boolean captiveLastSneakState;
|
||||||
|
|
||||||
|
public EntityCuccoon(World world) {
|
||||||
|
super(world);
|
||||||
|
setSize(0.6f, 0.6f);
|
||||||
|
|
||||||
|
width = 1.5F;
|
||||||
|
height = 1.6F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void entityInit() {
|
||||||
|
super.entityInit();
|
||||||
|
getDataManager().register(STRUGGLE_COUNT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStruggleCount() {
|
||||||
|
return getDataManager().get(STRUGGLE_COUNT) % 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStruggleCount(int count) {
|
||||||
|
getDataManager().set(STRUGGLE_COUNT, count % 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canBeRidden(Entity entity) {
|
||||||
|
return super.canBeRidden(entity)
|
||||||
|
&& !entity.isSneaking()
|
||||||
|
&& !isBeingRidden()
|
||||||
|
&& entity instanceof EntityLivingBase
|
||||||
|
&& !Predicates.BUGGY.test(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRenderOnFire() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canTriggerWalking() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMountedYOffset() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPassengerSteer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate() {
|
||||||
|
super.onUpdate();
|
||||||
|
|
||||||
|
if (isBeingRidden()) {
|
||||||
|
Entity passenger = getPassengers().get(0);
|
||||||
|
|
||||||
|
boolean sneaking = passenger.isSneaking();
|
||||||
|
|
||||||
|
if (sneaking && !attemptDismount(passenger)) {
|
||||||
|
passenger.setSneaking(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
captiveLastSneakState = sneaking;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world.isRemote) {
|
||||||
|
double x = posX + width * world.rand.nextFloat() - width/2;
|
||||||
|
double y = posY + height * world.rand.nextFloat();
|
||||||
|
double z = posZ + width * world.rand.nextFloat() - width/2;
|
||||||
|
|
||||||
|
world.spawnParticle(EnumParticleTypes.DRIP_LAVA, x, y, z, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBreatheAmount(float stutter) {
|
||||||
|
return MathHelper.sin((ticksExisted + stutter) / 40) / 2
|
||||||
|
+ hurtTime / 10F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean attemptDismount(Entity captive) {
|
||||||
|
if (captive.isSneaking() != captiveLastSneakState) {
|
||||||
|
setStruggleCount(getStruggleCount() + 1);
|
||||||
|
|
||||||
|
for (int k = 0; k < 20; k++) {
|
||||||
|
double d2 = rand.nextGaussian() * 0.02;
|
||||||
|
double d0 = rand.nextGaussian() * 0.02;
|
||||||
|
double d1 = rand.nextGaussian() * 0.02;
|
||||||
|
|
||||||
|
world.spawnParticle(EnumParticleTypes.BLOCK_CRACK,
|
||||||
|
posX + rand.nextFloat() * width * 2 - width,
|
||||||
|
posY + rand.nextFloat() * height,
|
||||||
|
posZ + rand.nextFloat() * width * 2 - width,
|
||||||
|
d2, d0, d1, Block.getStateId(Blocks.SLIME_BLOCK.getDefaultState()));
|
||||||
|
}
|
||||||
|
|
||||||
|
captive.playSound(USounds.SLIME_RETRACT, 1, 1);
|
||||||
|
this.hurtTime += 15;
|
||||||
|
|
||||||
|
if (getStruggleCount() == 0) {
|
||||||
|
setDead();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeathUpdate() {
|
||||||
|
if (++deathTime == 20) {
|
||||||
|
if (!world.isRemote && (isPlayer() || recentlyHit > 0 && canDropLoot() && world.getGameRules().getBoolean("doMobLoot"))) {
|
||||||
|
int i = ForgeEventFactory.getExperienceDrop(this, attackingPlayer, getExperiencePoints(attackingPlayer));
|
||||||
|
|
||||||
|
while (i > 0) {
|
||||||
|
int j = EntityXPOrb.getXPSplit(i);
|
||||||
|
|
||||||
|
i -= j;
|
||||||
|
|
||||||
|
world.spawnEntity(new EntityXPOrb(world, posX, posY, posZ, j));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dismountRidingEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
setDead();
|
||||||
|
|
||||||
|
for (int k = 0; k < 20; k++) {
|
||||||
|
double d2 = rand.nextGaussian() * 0.02;
|
||||||
|
double d0 = rand.nextGaussian() * 0.02;
|
||||||
|
double d1 = rand.nextGaussian() * 0.02;
|
||||||
|
|
||||||
|
world.spawnParticle(EnumParticleTypes.BLOCK_CRACK,
|
||||||
|
posX + rand.nextFloat() * width * 2 - width,
|
||||||
|
posY + rand.nextFloat() * height,
|
||||||
|
posZ + rand.nextFloat() * width * 2 - width,
|
||||||
|
d2, d0, d1, Block.getStateId(Blocks.SLIME_BLOCK.getDefaultState()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public AxisAlignedBB getCollisionBox(Entity entity) {
|
||||||
|
return entity.canBeCollidedWith() ? entity.getEntityBoundingBox() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public AxisAlignedBB getCollisionBoundingBox() {
|
||||||
|
return getEntityBoundingBox().shrink(0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void collideWithEntity(Entity entity) {
|
||||||
|
if (canBeRidden(entity)) {
|
||||||
|
entity.playSound(USounds.SLIME_ADVANCE, 1, 1);
|
||||||
|
entity.startRiding(this, true);
|
||||||
|
} else {
|
||||||
|
super.collideWithEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readEntityFromNBT(NBTTagCompound compound) {
|
||||||
|
super.readEntityFromNBT(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeEntityToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeEntityToNBT(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canInteract(Race race) {
|
||||||
|
return race == Race.CHANGELING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<ItemStack> getArmorInventoryList() {
|
||||||
|
return armour;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStackFromSlot(EntityEquipmentSlot slotIn) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setItemStackToSlot(EntityEquipmentSlot slotIn, ItemStack stack) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumHandSide getPrimaryHand() {
|
||||||
|
return EnumHandSide.LEFT;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.init;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.entity.EntityCloud;
|
import com.minelittlepony.unicopia.entity.EntityCloud;
|
||||||
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
|
import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
|
||||||
|
import com.minelittlepony.unicopia.entity.EntityCuccoon;
|
||||||
import com.minelittlepony.unicopia.entity.EntityRacingCloud;
|
import com.minelittlepony.unicopia.entity.EntityRacingCloud;
|
||||||
import com.minelittlepony.unicopia.entity.EntityRainbow;
|
import com.minelittlepony.unicopia.entity.EntityRainbow;
|
||||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
|
@ -12,6 +13,7 @@ import com.minelittlepony.unicopia.entity.EntityWildCloud;
|
||||||
import com.minelittlepony.unicopia.forgebullshit.BiomeBS;
|
import com.minelittlepony.unicopia.forgebullshit.BiomeBS;
|
||||||
import com.minelittlepony.unicopia.forgebullshit.EntityType;
|
import com.minelittlepony.unicopia.forgebullshit.EntityType;
|
||||||
import com.minelittlepony.unicopia.render.RenderCloud;
|
import com.minelittlepony.unicopia.render.RenderCloud;
|
||||||
|
import com.minelittlepony.unicopia.render.RenderCuccoon;
|
||||||
import com.minelittlepony.unicopia.render.RenderGem;
|
import com.minelittlepony.unicopia.render.RenderGem;
|
||||||
import com.minelittlepony.unicopia.render.RenderProjectile;
|
import com.minelittlepony.unicopia.render.RenderProjectile;
|
||||||
import com.minelittlepony.unicopia.render.RenderRainbow;
|
import com.minelittlepony.unicopia.render.RenderRainbow;
|
||||||
|
@ -40,6 +42,7 @@ public class UEntities {
|
||||||
builder.creature(EntitySpell.class, "magic_spell"),
|
builder.creature(EntitySpell.class, "magic_spell"),
|
||||||
builder.creature(EntitySpellbook.class, "spellbook"),
|
builder.creature(EntitySpellbook.class, "spellbook"),
|
||||||
builder.creature(EntityRainbow.Spawner.class, "rainbow_spawner"),
|
builder.creature(EntityRainbow.Spawner.class, "rainbow_spawner"),
|
||||||
|
builder.creature(EntityCuccoon.class, "cuccoon").withEgg(0, 0),
|
||||||
builder.projectile(EntityRainbow.class, "rainbow", 500, 5),
|
builder.projectile(EntityRainbow.class, "rainbow", 500, 5),
|
||||||
builder.projectile(EntityProjectile.class, "thrown_item", 10, 5)
|
builder.projectile(EntityProjectile.class, "thrown_item", 10, 5)
|
||||||
);
|
);
|
||||||
|
@ -51,6 +54,7 @@ public class UEntities {
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityProjectile.class, RenderProjectile::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityProjectile.class, RenderProjectile::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpellbook.class, RenderSpellbook::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntitySpellbook.class, RenderSpellbook::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityRainbow.class, RenderRainbow::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityRainbow.class, RenderRainbow::new);
|
||||||
|
RenderingRegistry.registerEntityRenderingHandler(EntityCuccoon.class, RenderCuccoon::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerSpawnEntries(Biome biome) {
|
public static void registerSpawnEntries(Biome biome) {
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.minelittlepony.unicopia.model;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.EntityCuccoon;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.ModelBase;
|
||||||
|
import net.minecraft.client.model.ModelRenderer;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
public class ModelCuccoon extends ModelBase {
|
||||||
|
|
||||||
|
ModelRenderer body;
|
||||||
|
|
||||||
|
public ModelCuccoon() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
boxList.clear();
|
||||||
|
|
||||||
|
body = new ModelRenderer(this, 0, 0);
|
||||||
|
body.setTextureSize(250, 250);
|
||||||
|
|
||||||
|
body.setTextureOffset(0, 0);
|
||||||
|
|
||||||
|
// cuccoon shape
|
||||||
|
body.addBox(-4, -2, -4, 8, 2, 8);
|
||||||
|
body.addBox(-7.5F, 0, -7.5F, 15, 6, 15);
|
||||||
|
body.addBox(-10, 4, -10, 20, 6, 20);
|
||||||
|
body.addBox(-11.5F, 10, -11.5F, 23, 8, 23);
|
||||||
|
body.addBox(-10, 17, -10, 20, 6, 20);
|
||||||
|
body.addBox(-11.5F, 22, -11.5F, 23, 2, 23);
|
||||||
|
|
||||||
|
|
||||||
|
// pile of blocks
|
||||||
|
// body.addBox(-10, offsetY + 10, -10, 12, 12, 12);
|
||||||
|
// body.addBox(-14, offsetY + 14, 4, 10, 10, 10);
|
||||||
|
// body.addBox(-17, offsetY + 17, 3, 8, 8, 8);
|
||||||
|
// body.addBox(0, offsetY + 10, 0, 12, 12, 12);
|
||||||
|
// body.addBox(-7, offsetY + 6, -7, 16, 16, 16);
|
||||||
|
// body.addBox(-7, offsetY + 0, -7, 12, 12, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
|
||||||
|
|
||||||
|
float breatheAmount = ((EntityCuccoon)entity).getBreatheAmount(ageInTicks) / 8;
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.enableAlpha();
|
||||||
|
GlStateManager.enableNormalize();
|
||||||
|
|
||||||
|
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
GlStateManager.scale(1 - breatheAmount, 1 + breatheAmount, 1 - breatheAmount);
|
||||||
|
GlStateManager.translate(0, -breatheAmount * 1.3F, 0);
|
||||||
|
|
||||||
|
body.render(scale);
|
||||||
|
|
||||||
|
GlStateManager.scale(0.9, 0.9, 0.9);
|
||||||
|
GlStateManager.translate(0, 0.2F, 0);
|
||||||
|
|
||||||
|
body.render(scale);
|
||||||
|
|
||||||
|
GlStateManager.disableNormalize();
|
||||||
|
GlStateManager.disableAlpha();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import com.minelittlepony.model.anim.IInterpolator;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.enchanting.PageState;
|
import com.minelittlepony.unicopia.enchanting.PageState;
|
||||||
|
import com.minelittlepony.unicopia.entity.EntityCuccoon;
|
||||||
import com.minelittlepony.unicopia.init.UEffects;
|
import com.minelittlepony.unicopia.init.UEffects;
|
||||||
import com.minelittlepony.unicopia.init.UItems;
|
import com.minelittlepony.unicopia.init.UItems;
|
||||||
import com.minelittlepony.unicopia.item.ICastable;
|
import com.minelittlepony.unicopia.item.ICastable;
|
||||||
|
@ -221,10 +222,18 @@ class PlayerCapabilities implements IPlayer {
|
||||||
|
|
||||||
Entity ridee = entity.getRidingEntity();
|
Entity ridee = entity.getRidingEntity();
|
||||||
|
|
||||||
entity.dismountRidingEntity();
|
if (ridee instanceof EntityCuccoon) {
|
||||||
|
if (((EntityCuccoon)ridee).attemptDismount(entity)) {
|
||||||
|
entity.dismountRidingEntity();
|
||||||
|
} else {
|
||||||
|
entity.setSneaking(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entity.dismountRidingEntity();
|
||||||
|
|
||||||
if (ridee instanceof EntityPlayerMP) {
|
if (ridee instanceof EntityPlayerMP) {
|
||||||
((EntityPlayerMP)ridee).getServerWorld().getEntityTracker().sendToTrackingAndSelf(ridee, new SPacketSetPassengers(ridee));
|
((EntityPlayerMP)ridee).getServerWorld().getEntityTracker().sendToTrackingAndSelf(ridee, new SPacketSetPassengers(ridee));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.minelittlepony.unicopia.render;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.UClient;
|
||||||
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.entity.EntityCuccoon;
|
||||||
|
import com.minelittlepony.unicopia.model.ModelCuccoon;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public class RenderCuccoon extends RenderLivingBase<EntityCuccoon> {
|
||||||
|
|
||||||
|
private static final ResourceLocation TEXTURE = new ResourceLocation(Unicopia.MODID, "textures/entity/cuccoon.png");
|
||||||
|
|
||||||
|
public RenderCuccoon(RenderManager manager) {
|
||||||
|
super(manager, new ModelCuccoon(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ResourceLocation getEntityTexture(EntityCuccoon entity) {
|
||||||
|
return TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getDeathMaxRotation(EntityCuccoon entity) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doRender(EntityCuccoon entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||||
|
|
||||||
|
if (entity.isBeingRidden()) {
|
||||||
|
Entity rider = entity.getPassengers().get(0);
|
||||||
|
|
||||||
|
if (!(rider == Minecraft.getMinecraft().player) || UClient.instance().getViewMode() != 0) {
|
||||||
|
GlStateManager.enableAlpha();
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
|
||||||
|
renderManager.renderEntity(rider, x, y + rider.getYOffset(), z, entityYaw, partialTicks, true);
|
||||||
|
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
GlStateManager.disableAlpha();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue