Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Samaritans

Members
  • Posts

    39
  • Joined

Everything posted by Samaritans

  1. Following, I also have the same issue. Is there a designed way to make POIs or is AT the only way?
  2. IntelliJ double shift to search through classes. Do learn basic java before you just copy-pasta code though
  3. Hey, I'm trying to render an fluid containing item (fluid bottle, basically vanilla glass bottle with fluid rendered inside). I have looked at the DynBucket Model and kinda tweaked it to fit my needs, but now I'm confuse as to where i should register/bind it to my item. The code is kinda long so ill leave a github link here. https://github.com/anqingchen/Rustic-2
  4. @diesieben07 a little unrelated, but is there any situation tileentity world actually returns null?
  5. @diesieben07 Ah i see, so would something like this be correct: CrushingTubTileEntity.java public class CrushingTubTileEntity extends TileEntity { public static int capacity = FluidAttributes.BUCKET_VOLUME * 8; public LazyOptional<ItemStackHandler> itemStackHandler = LazyOptional.of(this::createItemHandler); public LazyOptional<FluidTank> fluidHandler = LazyOptional.of(this::createFluidHandler); public CrushingTubTileEntity() { super(ModTileEntityType.CRUSHING_TUB); } @Override public void read(CompoundNBT tag) { super.read(tag); getFluidHandler().readFromNBT(tag); if (tag.contains("items")) { getItemHandler().deserializeNBT((CompoundNBT) tag.get("items")); } } @Override public CompoundNBT write(CompoundNBT tag) { tag = super.write(tag); getFluidHandler().writeToNBT(tag); tag.put("items", getItemHandler().serializeNBT()); return tag; } @Nullable @Override public SUpdateTileEntityPacket getUpdatePacket() { return new SUpdateTileEntityPacket(getPos(), 3, getUpdateTag()); } @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { this.read(pkt.getNbtCompound()); } @Override public CompoundNBT getUpdateTag() { return this.write(new CompoundNBT()); } @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { if (!this.removed) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return this.itemStackHandler.cast(); } if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { return this.fluidHandler.cast(); } } return super.getCapability(cap, side); } public ItemStackHandler getItemHandler() { return itemStackHandler.orElseThrow(RuntimeException::new); } public FluidTank getFluidHandler() { return fluidHandler.orElseThrow(RuntimeException::new); } private ItemStackHandler createItemHandler() { return new ItemStackHandler(1) { @Override protected void onContentsChanged(int slot) { getWorld().addBlockEvent(getPos(), getBlockState().getBlock(), 1, 0); getWorld().notifyNeighborsOfStateChange(getPos(), getBlockState().getBlock()); markDirty(); } }; } private FluidTank createFluidHandler() { return new FluidTank(capacity) { @Override protected void onContentsChanged() { markDirty(); } }; }
  6. Mystical Agriculture is doing something wrong with coloring.
  7. Looks like a Mo' Bend's issue. Please post crashlog file or put them on hastebin or something, this is impossible to read
  8. @diesieben07 So I would do private final LazyOptional<IItemHandlerModifiable> potHandler = null; And then in get Capability I'm not sure what to do? How do i actually get whats inside the LazyOptional @Override public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> cap, Direction side) { if (!this.removed && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { this.potHandler = LazyOptional.of(this::createHandler); return this.potHandler.cast(); // Wouldn't this just be creating new handler all the time? } return super.getCapability(cap, side); } So when i interact with my capability, what would i to do actually get them? Do i do something like IItemHandler itemStackHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null); and then check null? Also, what if i want IItemHandlerModifiable, how would I get that capability since it just returns an IItemHandler, can I just straight up cast it?
  9. Hey, moving from 1.12 to 1.14 modding, looks like capabilities are in a LazyOptional container of some sort. Still a bit confused. I looked at the code in vanilla chest, if my tile with an inventory, would this code be the correct way: @Override public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> cap, Direction side) { if (!this.removed && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if (this.potHandler == null) { this.potHandler = LazyOptional.of(this::createHandler); } return this.potHandler.cast(); } return super.getCapability(cap, side); } private IItemHandlerModifiable createHandler() { return new InvWrapper(this); } So what if i want a tile with 2 capabilities, Fluid AND Item, would this be correct? @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { if (!this.removed) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if (this.itemStackHandler == null) { this.itemStackHandler = LazyOptional.of(this::createItemHandler); } return this.itemStackHandler.cast(); } if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { if (this.fluidHandler == null) { this.fluidHandler = LazyOptional.of(this::createFluidHandler); } return this.fluidHandler.cast(); } } return super.getCapability(cap, side); } private IItemHandlerModifiable createItemHandler() { return new ItemStackHandler(1) { @Override protected void onContentsChanged(int slot) { getWorld().addBlockEvent(getPos(), getBlockState().getBlock(), 1, 0); getWorld().notifyNeighborsOfStateChange(getPos(), getBlockState().getBlock()); markDirty(); } }; } private FluidTank createFluidHandler() { return new FluidTank(capacity) { @Override protected void onContentsChanged() { markDirty(); } }; } Now, if I want a tile that has both item and fluid capabilites, should my tile implement IInventory, IItemHandler, IFluidTank, IFluidHandler, etc. what is even the difference and what do i use? Thanks
  10. Hey guys, I recently added Mixin to my mod and it all works fine in my dev environment. However, after i ./gradlew build it, the jar isn't picked up as a forge mod. From the looks of the logs, the core mod (mixin) is loaded but the mod itself is never loaded somehow. Please help! here's my gradle: buildscript { repositories { jcenter() maven { url = "http://files.minecraftforge.net/maven" } maven { url "https://plugins.gradle.org/m2/" } maven { name = 'sponge' url = 'https://repo.spongepowered.org/maven' } } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' classpath 'com.wynprice.cursemaven:CurseMaven:2.1.1' classpath "org.spongepowered:mixingradle:0.6-SNAPSHOT" } } apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'com.wynprice.cursemaven' apply plugin: 'org.spongepowered.mixin' version = "1.12.2-0.0.21-testbuild13" group = "com.bewitchment" archivesBaseName = "bewitchment" sourceCompatibility = targetCompatibility = '1.8' compileJava { sourceCompatibility = targetCompatibility = '1.8' } minecraft { version = "1.12.2-14.23.5.2838" runDir = "run" mappings = "stable_39" clientRunArgs += "--username=Samaritans" clientJvmArgs += "-Dfml.coreMods.load=com.bewitchment.core.BewitchmentFMLLoadingPlugin" serverJvmArgs += "-Dfml.coreMods.load=com.bewitchment.core.BewitchmentFMLLoadingPlugin" } repositories { flatDir { dirs 'libs' } maven { url = "http://dvs1.progwml6.com/files/maven" } maven { url = "https://minecraft.curseforge.com/api/maven" } maven { url "http://maven.tterrag.com" } maven { url "https://maven.blamejared.com" } maven { url "https://maven.mcmoddev.com/" } maven { url "http://repo.spongepowered.org/maven" } } dependencies { deobfProvided "mezz.jei:jei_1.12.2:4.15.0.292" deobfProvided "thaumcraft:Thaumcraft:1.12.2:6.1.BETA26" deobfProvided "dynamictrees:DynamicTrees:1.12.2:0.9.5" deobfProvided "vazkii.botania:Botania:r1.10-363.119" deobfProvided "betteranimalsplus:betteranimalsplus:1.12.2:7.1.1" deobfProvided "curse.maven:rustic:2746408" deobfProvided "curse.maven:quark:2759240" deobfProvided "curse.maven:autoreglib:2746011" deobfProvided "curse.maven:mowzies-mobs:2699705" deobfProvided "curse.maven:chisel:2809394" deobfProvided "curse.maven:ctm:2809915" deobfCompile "net.ilexiconn:llibrary:1.7.9-1.12.2" compile "baubles:Baubles:1.12:1.5.2" compile "vazkii.patchouli:Patchouli:1.0-20.99" implementation('org.spongepowered:mixin:0.7.11-SNAPSHOT') { exclude module: "asm-commons" exclude module: "asm-tree" exclude module: "launchwrapper" exclude module: "guava" exclude module: "log4j-core" exclude module: "gson" exclude module: "commons-io" } implementation 'org.jetbrains:annotations:15.0' } jar { manifest.attributes( 'FMLCorePlugin': 'com.bewitchment.core.BewitchmentFMLLoadingPlugin', 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker', 'MixinConfigs': 'mixins.bewitchment.json', 'FMLCorePluginContainsFMLMod': 'true' ) } processResources { inputs.property "version", project.version inputs.property "mcversion", project.minecraft.version from(sourceSets.main.resources.srcDirs) { include 'mcmod.info' expand 'version': project.version, 'mcversion': project.minecraft.version } from(sourceSets.main.resources.srcDirs) { exclude 'mcmod.info' } }
  11. Hey, I'm adding some new tipped arrows using my mod's potions, but some of them have effect on impact to blocks not just entities, so I need my custom EntityPotion and EntityTippedArrows. However, currently I am basically getting any potion/arrow that enters the world and reconstructing them from NBT. This breaks compatibility with other mods that add custom arrows, is there any remedy? Event for joining world where i reconstruct them (trying to avoid): @SubscribeEvent public void joinWorld(EntityJoinWorldEvent event) { if (!event.getWorld().isRemote) { if (event.getEntity() instanceof EntityPotion && !(event.getEntity() instanceof ModEntityPotion)) { ModEntityPotion entity = new ModEntityPotion(event.getWorld()); entity.deserializeNBT(event.getEntity().serializeNBT()); event.getWorld().spawnEntity(entity); event.setCanceled(true); } else if (event.getEntity() instanceof EntityTippedArrow && !(event.getEntity() instanceof ModEntityTippedArrow)) { Entity shooter = ((EntityTippedArrow) event.getEntity()).shootingEntity; ModEntityTippedArrow entity = shooter instanceof EntityLivingBase ? new ModEntityTippedArrow(event.getWorld(), (EntityLivingBase) shooter) : new ModEntityTippedArrow(event.getWorld()); entity.deserializeNBT(event.getEntity().serializeNBT()); event.getWorld().spawnEntity(entity); event.setCanceled(true); } } } Where my recipe is registered: ForgeRegistries.RECIPES.register(new RecipeTippedArrow() { @Override public ItemStack getCraftingResult(InventoryCrafting inv) { ItemStack stack = super.getCraftingResult(inv); if (PotionUtils.getPotionFromItem(stack) == PotionTypes.EMPTY) stack.getTagCompound().setInteger("CustomPotionColor", PotionUtils.getPotionColorFromEffectList(PotionUtils.getFullEffectsFromItem(stack))); return stack; } }.setRegistryName("minecraft", "tippedarrow")); I know I could probably just copy vanilla code and make my own ItemTippedArrow, ItemPotion, and then put my own spawnarrow, etc.. but I'd also have to copy over stuff that handles textures, colors etc and it just seems inefficient. Thanks in advance!
  12. @MSpace-Dev Hey, it turns out ItemPickupEvent is deprecated, use EntityItemPickUp instead, but check us out on github if u want https://github.com/Um-Mitternacht/Bewitchment
  13. @MSpace-Dev I dunno, it was called without the world.isRemote check and it still doesn't shrink
  14. When i try to call ItemStack#shrink it doesn't actually shrink anything. For example inside my ItemPickupEvent @SubscribeEvent public void pickUpItems(ItemPickupEvent event) { if (!event.player.world.isRemote) { EntityPlayer player = event.player; for (int i = 0; i < player.inventory.getSizeInventory(); i++) { ItemStack stack = player.inventory.getStackInSlot(i); if (stack.getItem() instanceof ItemContract && stack.hasTagCompound() && stack.getTagCompound().hasKey("contract") && stack.getTagCompound().hasKey("boundId") && stack.getTagCompound().hasKey("items") && !((ItemContract) stack.getItem()).complete(stack)) { if (Util.findPlayer(stack.getTagCompound().getString("boundId")) == player) { NBTTagList list = stack.getTagCompound().getTagList("items", Constants.NBT.TAG_COMPOUND); for (int t = 0; t < list.tagCount(); t++) { NBTTagCompound tag = list.getCompoundTagAt(t); if (event.getStack().getItem() == ForgeRegistries.ITEMS.getValue(new ResourceLocation(tag.getString("item")))) { int complete = tag.getInteger("amountComplete"); int gained = event.getStack().getCount(); int toShrink = Math.min(tag.getInteger("amountTotal") - complete, gained); event.getStack().shrink(toShrink); tag.setInteger("amountComplete", complete + toShrink); break; } } } } } } } debugger says its shrinked, but the player still gets the full thing anyways. Same problem, I want item to goaway after right click, so i do player.getHeldItem(hand).shrink(1); but it still just stays in the inv. Thanks!
  15. I want to generate a special vine for my mod in world like how vines generate in vanilla swamps/jungles. Here's the code: private void generateMoss(World world, Random rand, int chunkX, int chunkZ, Predicate<Biome> predicate) { BlockPos position = new BlockPos(chunkX * 16 + 8, 64, chunkZ * 16 + 8); Biome biome = world.getBiome(position); if (!predicate.test(biome)) return; for (; position.getY() < 128; position = position.up()) { if (world.isAirBlock(position) && world.isAirBlock(position.down(1))) { for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL.facings()) { if (ModObjects.spanish_moss.canPlaceBlockOnSide(world, position, enumfacing)) { IBlockState iblockstate = ModObjects.spanish_moss.getDefaultState().withProperty(BlockVine.SOUTH, enumfacing == EnumFacing.NORTH).withProperty(BlockVine.WEST, enumfacing == EnumFacing.EAST).withProperty(BlockVine.NORTH, enumfacing == EnumFacing.SOUTH).withProperty(BlockVine.EAST, enumfacing == EnumFacing.WEST); world.setBlockState(position, iblockstate, 2); break; } } } else { position = position.add(rand.nextInt(4) - rand.nextInt(4), 0, rand.nextInt(4) - rand.nextInt(4)); } } } However, this just generates very parse patches of one block vines instead of long draping vines from trees in swamps. The code here is basically copied from the vanilla class though. Thanks!
  16. @Animefan8888 @diesieben07 Thank you both for the help, Looks like my gui is working both client and server now!
  17. @Animefan8888 I think it's really important that I can somehow pass the EntityPlayer in my packet because its not only used in the container to get the List<Tarot> but also when rendering GUI to determine how to render my tarots. Here's guiRendering stuff: As you can see the player is still used to determine what number to render the cards and if they should be rendered in reverse. (the tarot.getNumber or isReversed function checks a capability attached to the player by the mod). When i tried to send the packet with an Entityplayer by Serializing and then Deserializing, it gives me null string exception. Then I just tried to send the List<tarot> and forget about the other rendering stuff for now, but this gives me a NullPointer Error Executing Task ``at net.minecraft.network.play.server.SPacketEntityHeadLook.getEntity(SPacketEntityHeadLook.java:56) ~[SPacketEntityHeadLook.class:?]`` Here's what i got in the packet: The packet is sent in the GuiHandler under getServerGuiElement like this: if(!world.isRemote) Bewitchment.network.sendTo(new TarotMessage(stack.getTagCompound().getString("readId")), (EntityPlayerMP) player); Have I just done something fundamentally wrong and not achievable through packet and modify how my entire tarot system and GUI works?
  18. @Animefan8888 Why shouldn't the client care, the List<Tarot> toRead is the list of stuff that's gonna be rendered on the Gui. Or do you mean I shall find entityPlayer and also the List<Tarot> in handler and then just send the toRead List back to the client? that kinda make sense. But where in code would I call my network.sentTo(new ThisMessage(...)) to send this packet though? The constructor doesn't make sense because it's also called on the client side, do i send the packet to client when the getServerGuiElement in my GuiHandler?
  19. @Animefan8888 Honestly still kinda confused but lemme try to word this: 1. Keep the constructor that uses entityplayer like i posted above. 2. Another Container constructor? (still not sure for what?) 3. Send packet from server to client with the rng info, but #1. what do i do with my registry filter part that also needs my player? #2. sure i can process the stuff on the server, but how when would i even send that packet and where do i let the server do the work? so confused. #3. Where would i send that packet, like what would be in the handler? I really tried reading the forge docs and still don't quite understand how to utilize the packets to open gui. All i can see by debug mode and breaks are: 1. When i right click to open the gui, the server calls getServerGuiElement and successfully gets the gui. 2. but when the client calls getClientGuiElement and i return a new GuiTarotTable(new ContainerTarotTable(...)) it renders nothing because findPlayer returns null. I thought I need to send a packet at getClientGuiElement from client to server with the UUID and get entityPlayer inside the Message Handler. And then, another packet need to be sent back with the entityPlayer or at least the RNG result and the filtered List<Tarot>, but what would i do with the message is what I'm mostly confused with. Sorry for the word wall, I've had this bug for days and kinda frustrating that I have no clue how to fix it really appreciate your help!
  20. @Animefan8888 well here's thefull constructor for the container: public ContainerTarotTable(EntityPlayer player) { this.player = player; if (player != null) { List<Tarot> valid = GameRegistry.findRegistry(Tarot.class).getValuesCollection().stream().filter(f -> f.isCounted(this.player)).collect(Collectors.toList()); if (!valid.isEmpty()) { while (!valid.isEmpty() && toRead.size() < 4) { int i = player.getRNG().nextInt(valid.size()); toRead.add(valid.get(i)); valid.remove(i); } } } } as you can see, i need the playerRNG and also using the player to filter stuff from my registry.
  21. @Animefan8888 No, its an entityplayer obtained by using findPlayerbyUUID function and the UUID comes from an item in the player's hand when opening the GUI. Thus if i don't do packets, the findPlayerbyUUID returns null on client side and i get an empty GUI.
  22. @Animefan8888 You're right, I'm not sure what I'm doing. I'm trying to get the EntityPlayer from Server so when the client calls opengui, it would make a new container using the EntityPlayer that was passed in.
  23. I'm still really lost tbh, can you help me more here @diesieben07, would really appreciate it? Here's my messages: Server -> Client: public class TarotPlayerMessage implements IMessage { private EntityPlayer player; public TarotPlayerMessage() { } public TarotPlayerMessage(EntityPlayer player) { this.player = player; } @Override public void fromBytes(ByteBuf byteBuf) { this.player.deserializeNBT(ByteBufUtils.readTag(byteBuf)); } @Override public void toBytes(ByteBuf byteBuf) { ByteBufUtils.writeTag(byteBuf, player.serializeNBT()); } public static class Handler implements IMessageHandler<TarotPlayerMessage, IMessage> { @Override public IMessage onMessage(TarotPlayerMessage message, MessageContext ctx) { if (ctx.side.isClient()) { Minecraft.getMinecraft().addScheduledTask(() -> Minecraft.getMinecraft().player.openContainer = new ContainerTarotTable(message.player)); } return null; } } } Client -> Server: public class TarotMessage implements IMessage { private String uuid; public TarotMessage() { } public TarotMessage(String uuid) { this.uuid = uuid; } @Override public void fromBytes(ByteBuf byteBuf) { uuid = ByteBufUtils.readUTF8String(byteBuf); } @Override public void toBytes(ByteBuf byteBuf) { ByteBufUtils.writeUTF8String(byteBuf, uuid); } public static class Handler implements IMessageHandler<TarotMessage, IMessage> { @Override public IMessage onMessage(TarotMessage message, MessageContext ctx) { if (ctx.side.isServer()) { EntityPlayer player = Util.findPlayer(message.uuid); if (player != null) return new TarotPlayerMessage(player); } return null; } } } Don't think it works, also its got a null string not allowed error.
  24. So that'd be two packets right? One from client to server sending UUID over. and another from from server to client sending the EntityPlayer and on receiving the packet at client I check something like (sorry not at pc rn, psudo code here:) if(Minecraft.getMinecraft().player.openContainer instance of ContainerTarotTable) { Minecraft.getMinecraft.player.openContainer.player = message.player; } but then what would I do? The container is already constructed my entire guiHandler here: public class GuiHandler implements IGuiHandler { @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity tile = world.getTileEntity(new BlockPos(x, y, z)); if (tile instanceof TileEntityWitchesOven) return new ContainerWitchesOven(player.inventory, (TileEntityWitchesOven) tile); if (tile instanceof TileEntityDistillery) return new ContainerDistillery(player.inventory, (TileEntityDistillery) tile); if (tile instanceof TileEntitySpinningWheel) return new ContainerSpinningWheel(player.inventory, (TileEntitySpinningWheel) tile); if (tile instanceof TileEntityTarotTable) { ItemStack stack = player.getHeldItemMainhand(); if (stack.getItem() instanceof ItemTarotCards && stack.hasTagCompound() && stack.getTagCompound().hasKey("readId")) { return new ContainerTarotTable(UUID.fromString(stack.getTagCompound().getString("readId"))); } } if (tile instanceof TileEntityJuniperChest) return new ContainerJuniperChest(player.inventory, (TileEntityJuniperChest) tile); return null; } @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity tile = world.getTileEntity(new BlockPos(x, y, z)); if (tile instanceof TileEntityWitchesOven) return new GuiWitchesOven((ContainerWitchesOven) getServerGuiElement(ModGui.OVEN.ordinal(), player, world, x, y, z), player.inventory); if (tile instanceof TileEntityDistillery) return new GuiDistillery((ContainerDistillery) getServerGuiElement(ModGui.DISTILLERY.ordinal(), player, world, x, y, z)); if (tile instanceof TileEntitySpinningWheel) return new GuiSpinningWheel((ContainerSpinningWheel) getServerGuiElement(ModGui.SPINNING_WHEEL.ordinal(), player, world, x, y, z)); if (tile instanceof TileEntityTarotTable) return new GuiTarotTable((ContainerTarotTable) getServerGuiElement(ModGui.TAROT_TABLE.ordinal(), player, world, x, y, z)); if (tile instanceof TileEntityJuniperChest) return new GuiJuniperChest((ContainerJuniperChest) getServerGuiElement(ModGui.JUNIPER_CHEST.ordinal(), player, world, x, y, z), player.inventory); return null; } public enum ModGui { OVEN, DISTILLERY, SPINNING_WHEEL, TAROT_TABLE, JUNIPER_CHEST } } Or do i just simple make a new Constructor for the Container and pass in EntityPlayer. And on client reciveiving message just set player.openGui = new ContainerTarotTable(entityPlayer); ?
  25. Hey all, I have a container for a tile entity that would render different things depends on a player UUID appended to the item that is required to open the gui. In the container, it calls a method to find player by UUID and determine what the render based on the entityPlayer. However, when the getClientGuiElement is called, findPlayer returns null since its called on the client side, causing my GUI to render nothing. Is there a way to remedy this? Code here: public ContainerTarotTable(UUID uuid) { this.player = Util.findPlayer(uuid); if (player != null) { // do stuff with player rng and other stuff in a custom registry. } } Here's how EntityPlayer is obtained from uuid: public static EntityPlayer findPlayer(UUID uuid) { for (WorldServer ws : DimensionManager.getWorlds()) { EntityPlayer player = ws.getPlayerEntityByUUID(uuid); if (player != null) return player; } return null; } Edit: I know that it sounds like something to handle using Packets, however I'm confused by how to implement such a thing. i can send a packet to server and use server to get the entityPlayer, but how would i pass it back to the client when creating this new ContainerTarotTable.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.