Jump to content

Meldexun

Members
  • Posts

    184
  • Joined

  • Last visited

Posts posted by Meldexun

  1. 23 minutes ago, V0idWa1k3r said:

    You haven't provided neither enough of your code nor a better description of your issue. What does "can't use the slot" mean? Is it not physically there? Can you not put anything in it? Is it not saved? We need more details than a simple "doesn't work".

    Ok, i'm sorry that really is a bad description... So the GUI shows up with all the normal inventory slots of the player and i can use them normally. But when i hover over my extra slot it makes that white overlay. So the slot is there but i can't put any item in it.

    What other code do you want to see?

     

    27 minutes ago, V0idWa1k3r said:

    Your container slot ID is wrong. Since this is slot 0 in your inventory it's ID should also be 0. IDs are relative to the inventory, not the slot's index. See any vanilla's container for an example. 

    I have also thought that but when i change the ID to 0 my extra slot is just a copy of the vanilla inventory slot with the ID 0.

  2. I made an entity which can be ridden. But when the player turns to the left or to the right to body of the player isn't fixed to the rotation of the head/entity which is ridden. How can i achieve that the body of a player is rotating the same. You can compare a Minecart and a Boat from vanilla. With a boat the rotation of the body of the player is fixed.

  3. 18 minutes ago, V0idWa1k3r said:

    The parameters to the tracker are range, frequency and whether or not to send velocity updates. 

    Frequency is the rate at which the entity sends the data. 20 would mean it sends 1 update per 20 ticks. In your case it's 80 meaning it sends the data once per 80 ticks.

    Range is the range that the entity must be within in relation to a player to receive updates.

    The last parameter is self-explanatory.

    Thanks for the explanation.

    But i now tried to set the frequency higher/lower with updates true/false with no difference.

    18 minutes ago, V0idWa1k3r said:

    Don't use static initializers. Instantinate your stuff directly in the appropriate registry event.

    I can change that.

     

    18 minutes ago, V0idWa1k3r said:

    You can't reference client-only code in a common environment like the update method as it will crash the dedicated server. You must use a proxy for something like this. No, the fact that it is hidden behind a World.isRemote check doesn't stop the crash, it is still referenced. Standard JVM won't load the class until it is required, but I can't be so sure about third-party JVM implementations.

    Yes my code is often messy and buggy with the server/client side stuff. I usually clean that when my stuff works probably. Or when i forget that i normally try my mod in singleplayer and on a dedicated server and then when something crashes i go and clean the code. (Thanks anyway)

     

    Edit: Also the entity moves a bit faster than the player who rides it.

  4. 1 hour ago, V0idWa1k3r said:

    You do not need to invoke Entity#move manually since it already does that for you in it's update method.

    I'm extending my class the Entity class directly so i have to call it myself since it's not called in the Entity class.

    But that's no my issue anymore.

     

    Now i have this code to update the movement:

    	@Override
    	public void onUpdate() {
    		super.onUpdate();
    		
    		if (this.world.isRemote) {
    			if (this.getControllingPassenger() instanceof EntityPlayer) {
    				GameSettings settings = Minecraft.getMinecraft().gameSettings;
    				
    				this.inputForward = settings.keyBindForward.isKeyDown();
    				this.inputRight = settings.keyBindRight.isKeyDown();
    				this.inputBack = settings.keyBindBack.isKeyDown();
    				this.inputLeft = settings.keyBindLeft.isKeyDown();
    				this.inputUp = settings.keyBindJump.isKeyDown();
    				this.inputDown = settings.keyBindSneak.isKeyDown();
    			} else {
    				this.inputForward = false;
    				this.inputRight = false;
    				this.inputBack = false;
    				this.inputLeft = false;
    				this.inputUp = false;
    				this.inputDown = false;
    			}
    			
    			this.updateRotation();
    			
    			this.updateMotion();
    			
    			this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ);
    		}
        }

     

    Now my entity seems to move correctly. But the problem now is that the movement looks laggy. So the movement of the player who is riding the entity is smooth similar to movement with a boat. But the entity is a lagging behind and it's movement is jerkily. Also it's a bit faster than the player.

     

    Here i registered my entity because i read something about velocity updates but i don't really know where they are defined (i think it has something to do with the tracker but i don't know excatly what that does either):

    	public static final EntityEntry ENTITY_ENTRY_C_ENTITY = createEntityEntry(EntityCEntity.class, "entity_c_entity", 0xFFFFFF, 0xAAAAAA);
    	
    	@SubscribeEvent
    	public static void registerTileEntities(RegistryEvent.Register<EntityEntry> event) {
    		event.getRegistry().registerAll(
    				ENTITY_ENTRY_C_ENTITY
    		);
    	}
    	
    	private static EntityEntry createEntityEntry(Class entityClass, String name, int eggCcolor1, int eggColor2) {
    		return EntityEntryBuilder.create().entity(entityClass).id(new ResourceLocation(BetterDiving.MOD_ID, name), ID++).name(name).egg(eggCcolor1, eggColor2).tracker(64, 80, true).build();
    	}

     

  5. So i have created a custom entity which can be ridden but when i ride the entity it stops moving and it won't move in any way.

    That's my entity class:

    	public boolean inputForward = false;
    	public boolean inputRight = false;
    	public boolean inputBack = false;
    	public boolean inputLeft = false;
    	public boolean inputUp = false;
    	public boolean inputDown = false;
    	
    	private int debug = 0;
    	
    	public EntitySeamoth(World worldIn) {
    		super(worldIn);
    		setSize(1.0f, 1.0f);
    		isImmuneToFire = true;
    	}
    	
    	@Override
    	public boolean canBeCollidedWith() {
    		return !this.isDead;
    	}
    	
    	@Override
    	public boolean canBePushed() {
    		return true;
    	}
    	
    	@Override
    	protected boolean canBeRidden(Entity entityIn) {
    		return true;
    	}
    	
    	@Override
    	public boolean canRiderInteract() {
    		return true;
    	}
    	
    	@Override
    	public boolean shouldDismountInWater(Entity rider) {
    		return false;
    	}
    	
    	@Override
    	public double getMountedYOffset() {
    		return 0.0d;
    	}
    	
    	@Override
    	public boolean canPassengerSteer() {
    		return getControllingPassenger() instanceof EntityPlayer;
    	}
    	
    	@Override
    	public boolean processInitialInteract(EntityPlayer player, EnumHand hand) {
    		if (player.isSneaking()) {
    			return false;
    		} else {
    			if (!this.world.isRemote) {
    				player.startRiding(this);
    			}
    			return true;
    		}
    	}
    	
    	@Override
    	public AxisAlignedBB getCollisionBox(Entity entityIn) {
    		return getEntityBoundingBox();
    	}
    	
    	@Override
    	public boolean attackEntityFrom(DamageSource source, float amount) {
    		if (source.getTrueSource() instanceof EntityPlayer) {
    			this.setDead();
    			return true;
    		}
    		return false;
    	}
    	
    	@Override
    	public Entity getControllingPassenger() {
    		List<Entity> list = this.getPassengers();
    		return list.isEmpty() ? null : (Entity) list.get(0);
    	}
    	
    	@Override
    	public AxisAlignedBB getCollisionBoundingBox() {
    		return null;
    	}
    	
    	@Override
    	public void onUpdate() {
    		super.onUpdate();
    		
    		if (this.world.isRemote) {
    			BetterDiving.CONNECTION.sendToServer(new PacketVehicleKeyPress());
    		}
    		
    		this.updateRotation();
    		
    		this.updateMotion();
    		
    		this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ);
    		
    	}
    	
    	public void updateRotation() {
    		if (this.getControllingPassenger() instanceof EntityPlayer) {
    			this.rotationYaw = MathHelper.wrapDegrees(this.getControllingPassenger().rotationYaw);
    			this.rotationPitch = this.getControllingPassenger().rotationPitch;
    		}
    	}
    	
    	public void updateMotion() {
    		double rotX  = -MathHelper.sin(this.rotationYaw * 0.017453292F);
    		double rotZ  =  MathHelper.cos(this.rotationYaw * 0.017453292F);
    		float fakeRotationPitch = this.rotationPitch;
    		
    		double speed = 0.02d;
    		
    		if (inputDown && !inputUp) {
    			if (inputForward) {
    				fakeRotationPitch = (fakeRotationPitch + 90f) / 2f;
    			} else if (inputBack) {
    				fakeRotationPitch = (fakeRotationPitch - 90f) / 2f;
    			} else {
    				this.motionY -= speed;
    			}
    		}
    		
    		if (inputUp && !inputDown) {
    			if (inputForward) {
    				fakeRotationPitch = (fakeRotationPitch - 90f) / 2f;
    			} else if (inputBack) {
    				fakeRotationPitch = (fakeRotationPitch + 90f) / 2f;
    			} else {
    				this.motionY += speed;
    			}
    		}
    		
    		double lookVecX = rotX * MathHelper.cos(fakeRotationPitch * 0.017453292F);
    		double lookVecY = -MathHelper.sin(fakeRotationPitch * 0.017453292F);
    		double lookVecZ = rotZ * MathHelper.cos(fakeRotationPitch * 0.017453292F);
    		
    		if (inputForward) {
    			this.motionX += speed * lookVecX;
    			this.motionY += speed * lookVecY;
    			this.motionZ += speed * lookVecZ;
    		}
    		if (inputBack) {
    			this.motionX -= speed * lookVecX;
    			this.motionY -= speed * lookVecY;
    			this.motionZ -= speed * lookVecZ;
    		}
    		if (inputLeft) {
    			this.motionX += speed * rotZ;
    			this.motionZ += speed * -rotX;
    		}
    		if (inputRight) {
    			this.motionX += speed * -rotZ;
    			this.motionZ += speed * rotZ;
    		}
    		
    		this.motionX *= 0.90d;
    		if (this.motionX < 0.0001d) this.motionX = 0;
    		this.motionY *= 0.90d;
    		if (this.motionY < 0.0001d) this.motionY = 0;
    		this.motionZ *= 0.90d;
    		if (this.motionZ < 0.0001d) this.motionZ = 0;
    	}
    	
    	@Override
    	protected void entityInit() {
    		
    	}
    	
    	@Override
    	protected void readEntityFromNBT(NBTTagCompound compound) {
    		
    	}
    	
    	@Override
    	protected void writeEntityToNBT(NBTTagCompound compound) {
    		
    	}

     

    The update methods are fine because i tried this without success:

    @Override
    	public void onUpdate() {
    		super.onUpdate();
    		this.motionY += 0.001d;
    		this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ);
    		
    	}

     

    I seem to miss something...

  6. I want to create an extra inventory slot for the player. But i can't use the slot when the GUI is opened. I think it has to do with how i use the capability. Also I'm not that much familiar with capabilities .

    Provider:

    Spoiler
    
    public class ExtraSlotProvider implements ICapabilitySerializable<NBTBase> {
    
    	@CapabilityInject(IItemHandler.class)
    	public static final Capability<IItemHandler> EXTRA_SLOT = null;
    	
    	private IItemHandler instance = new ItemStackHandler(1);
    	
    	@Override
    	public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
    		return capability == EXTRA_SLOT;
    	}
    
    	@Override
    	public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
    		return capability == EXTRA_SLOT ? EXTRA_SLOT.<T> cast(this.instance) : null;
    	}
    
    	@Override
    	public NBTBase serializeNBT() {
    		return EXTRA_SLOT.getStorage().writeNBT(EXTRA_SLOT, this.instance, null);
    	}
    
    	@Override
    	public void deserializeNBT(NBTBase nbt) {
    		EXTRA_SLOT.getStorage().readNBT(EXTRA_SLOT, this.instance, null, nbt);
    	}
    
    }

     

     

    Attach Capabilies:

    Spoiler
    
    @EventBusSubscriber
    public class SQUATEventHandler {
    
    	public static final ResourceLocation EXTRA_SLOT = new ResourceLocation(TEST_MOD.MOD_ID, "extra_slot");
    	
    	@SubscribeEvent
    	public static void attachCapability(AttachCapabilitiesEvent<Entity> event) {
    		if (event.getObject() instanceof EntityPlayer) {
    			event.addCapability(EXTRA_SLOT, new ExtraSlotProvider());
    		}
    	}
    }

     

     

    Container:

    Spoiler
    
    	public ContainerFlightInventory(InventoryPlayer playerInv) {
    		IItemHandler inventory = playerInv.player.getCapability(ExtraSlotProvider.EXTRA_SLOT, null);
    		
    		int slot = 0;
    
    		for (int k = 0; k < 9; k++) {
    			addSlotToContainer(new Slot(playerInv, slot++, 8 + k * 18, 142));
    		}
    		
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 9; j++) {
    				addSlotToContainer(new Slot(playerInv, slot++, 8 + j * 18, 84 + i * 18));
    			}
    		}
    		
    		for (int l = 0; l < 4; l++) {
    			addSlotToContainer(new Slot(playerInv, slot++, 8, 62 - l * 18));
    		}
    		
    		addSlotToContainer(new Slot(playerInv, slot++, 77, 62));
    		
    		//extra slot
    		addSlotToContainer(new SlotItemHandler(inventory, slot++, 152, 8));
    		
    	}

     

     

    Any help is appreciated.

  7. Now i got this:

    	private static final Gson GSON_INSTANCE = (new GsonBuilder()).registerTypeAdapter(RandomValueRange.class, new RandomValueRange.Serializer()).registerTypeAdapter(LootPool.class, new LootPool.Serializer()).registerTypeAdapter(LootTable.class, new LootTable.Serializer()).registerTypeHierarchyAdapter(LootEntry.class, new LootEntry.Serializer()).registerTypeHierarchyAdapter(LootFunction.class, new LootFunctionManager.Serializer()).registerTypeHierarchyAdapter(LootCondition.class, new LootConditionManager.Serializer()).registerTypeHierarchyAdapter(LootContext.EntityTarget.class, new LootContext.EntityTarget.Serializer()).create();
    	
    	@SubscribeEvent
    	public static void loadLootTable(LootTableLoadEvent event) {
    		if (event.getName() == TileEntityChestArmor.LOOT_TABLE) {
    			File f = new File(CrystalicVoid.configFolderLoot + "/chest_armor.json");
    			if (f.exists() && f.isFile()) {
    				String s = null;
    				try {
    					s = Files.toString(f, StandardCharsets.UTF_8);
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    				event.setTable(GSON_INSTANCE.fromJson(s, LootTable.class));
    		}
    	}

    But it just says

    Invalid call stack, could not grab json context!

    The json loot table that i try to load is fine. So someone has any idea?

  8. I want to generate a chest with my loot table. This works fine when i use a loot table from my assets. But is there a way to spawn a chest with a loot table from the config folder?

     

    Edit: I just found the LootTableLoadEvent. Could i just pass the loot table from the config folder when the loot table from my mod is loaded?

  9. 17 minutes ago, diesieben07 said:

    use Class#getResource or Class#getResourceAsStream

    I always get null returned when using one of these methods. I have my CrystalicVoid Class in src/main/java/meldexun/crystalicVoid and i want to get a file in src/main/resources/assets/crystalicVoid.

    When using CrystalicVoid.class.getResource("") it gives me the path to that class. I just don't know how to use the method properly.

    (also changed the \)

  10. How could i copy a file from my assets to the config folder?

    I currently have this in FMLPreInitializationEvent:

    File source = new File(/*assets folder of my mod*/, "tower.nbt");
    File destination = new File(event.getModConfigurationDirectory().getPath() + "\\CrystalicVoidStructures", "tower.nbt");
    try {
    	Files.copy(source.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
    	e.printStackTrace();
    }

    But i don't know how to get the file in my assets folder.

  11. It looks like i have to open the GUI server side. I'm using a GuiHandler and when calling player#openGui at the end of my packet handler on the client side it seems to create a broken gui.

    So what i now try to do is:

    When the block is right clicked on server side it will send a packet to the client which tells him to update the tile entity with the data sent from the server. As an answer the client then sends a packet which requests the server to open the gui. When received on the server it checks if the player is in creative mode and then opens the gui.

  12. 1 hour ago, diesieben07 said:

    that is the same as vanilla syncing then.

    I thought vanilla sends more packets. But that doesn't matter. You are right. I will change it so it only sends a packet from server to client when the block is right clicked. Often opening the gui will cause much traffic but when not opening the gui it causes zero traffic. Seems the best option.

  13. 1 hour ago, diesieben07 said:

    Okay. So then: When the TE is right clicked (or whatever the interaction is), send a packet from server to client which contains the data. The client can then open the GUI. 

    But then it always sends a packet from server to the client when the block is right clicked. When you right click the block it 3 times in a short period of time it sends 3 packets.

    Currently it sends only a packet when the tile entity is loaded. So it sends just 1 packet.

    1 hour ago, diesieben07 said:

    Except if you use the same packet the packet can be sent by survival clients as well. For blocks that are thousands of blocks away. 

    I don't understand how a new second packet solves this issue.

    I could check when the packet is received server side if the sender is in creative mode.

  14. 23 minutes ago, DavidM said:

    Please elaborate. 

    I need the data for opening the gui. It should display the data from the server.

    21 minutes ago, diesieben07 said:

    Vanilla already has a perfectly adequate data-syncing mechanism for tile entities.

    I have read that i should create my own packet and handler to sync my tile entity most efficiently. And my tile entity should just sync when someone interactes with it. I think vanilla always syncs the tile entities and that would create much network traffic (i just think so. Correct me when i'm wrong)

     

    21 minutes ago, diesieben07 said:

    If you treat them the same, you enable cheating.

    It should be kind of cheating. The block is creative only and the client should say "This is the new data, use it from now on"

×
×
  • Create New...

Important Information

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