Jump to content

V0idWa1k3r

Members
  • Posts

    1773
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by V0idWa1k3r

  1. Any reason you are using 1.9? You should update to the latest version. You can see how the game handles it's own lists at GuiScrollingList. Alternatively the algorithm is basically the following: You have a variable that represents your scrollbar position, in a range of [0-1] {scrollbar}. You have a scrollbar area itself, that starts at {startY} and spans {Height} When the scrollbar is clicked interpolate the mouse coordinates relative to {startY} and {startY + Height} to a range of [0-1]. That is your new scrollbar position. When the mouse wheel is scrolled your scrollbar position changes by a certain value, I would use {entriesFittingIntoTheBox} / {entries}.size(), then clamped to a range of [0-1]. So that is how you determine the scrollbar position. Next you have a collection of entries {entries} that is all of entries you have. You can get the range of entries that are currently displayed as [{entries}.size() * {scrollbar}, {entries}.size() * {scrollbar} + {entriesFittingIntoTheBox}]. Obviously clamped to a [0-{entries}.size()]. Additionally if range[1] - range[0] is less than {entries}.size() and less than {entriesFittingIntoTheBox} then range[0] becomes range[0] - ({entriesFittingIntoTheBox} - (range[1] - range[0])). Again, clamp to [0-{entries}.size()]. Now expand the range by 1 keeping it in the [0-{entries}.size()] range. Now you can start drawing your stuff. Start iterating the collection in the range you've just calculated. The position of element 0 will be {baseY} + ({elementY} - {elementIndex} * {unifiedElementSize}) <- this is assuming all your elements are of a unified height. The position of all next elements becomes {offsetY} + {baseY} where {offsetY} is either kept as a variable and added to or calculated as ({elementIndex} - range[0]) * {unifiedElementSize}. The rendering of elements is up to you, I'm just telling you where to render them. Now comes the interesting part - the stencil test. Stencil test is opengl's way of discarding fragments that don't fit into a defined scope. The stencil is it's separate buffer and can be of any shape but you are only interested in the basic quad for now. You can look up how to setup stencil rect or ask here - I will be able to provide you with a sample if you need it.
  2. Obviously don't do translations on a server since languages are a thing of the client.
  3. You can use EntityAITasks#removeTask. Alternatively you can abuse the mutex bits of tasks. Basically each AI task has an int that represents a collection of bits(so 32 bits total). When the game wants to make the AI run it checks whether it conflicts with another higher priority AI by comparing their mutex bits field. The game performs a bitwise AND operation on them. If the AND returns 0 then both tasks can run concurrently, otherwise the one with the higher priority is the one that will run. The mutex of the targeting AI is 1.
  4. Didn't I tell you already not to do this?.. Why yes I did.
  5. https://github.com/Cadiboo/Example-Mod
  6. Well, there are two options I see. The first one would be to split the process - have a separate Entity that behaves like your particle and renders like one(but is an Entity, not a Particle). Since you have full control over that entity you know when it decays and when it does - spawn your explosion from the entity's class. The second one is to create a task system. Basically have a task class that contains a counter and the data needed to spawn the explosion - position, strength etc. Then when you spawn the particle add a new task to a collection. Every tick iterate the collection and increment/decrement/compare the counter. When the condition is satisfied spawn the explosion and remove the task from the collection. Something like this: class ExplosionTask implements INBTSerializable<NBTTagCompound> { int timestamp; BlockPos spawnPos; float strength; public static ExplosionTask newTask(int currentTick, int delay, BlockPos pos, float strength) { ExplosionTask ret = new ExplosionTask(); ret.timestamp = currentTick + delay; ret.spawnPos = pos; ret.strength = strength; } public boolean shouldFire(int ticks) { return ticks >= this.timestamp; } } class TE extends TileEntity implements ITickable { IList<ExplosionTask> tasks = Lists.newArrayList(); void onUpdate() { if (counter % 100 == 0) { ... // Spawn particle ... tasks.add(ExplosionTask.newTask(counter, 120, pos, strength)); } Iterator<ExplosionTask> it = tasks.getIterator(); while(it.hasNext()) { ExplosionTask task = it.next(); if (task.shouldFire(counter)) { world.newExplosion(null, task.spawnPos, strength, ...); it.remove(); } } } }
  7. What do you want to happen? What behaviour do you want? Having 2 counters will not change anything.
  8. Well, think about it. You have 2 events, one happening every 5 seconds the other every 6 seconds. Let's chart the timestamps of the events: 5, 10, 15, 20, 25, 30, 35, 40, ... 6, 12, 18, 24, 30, 36, 42, 48, ... Note how there are timestamps where both events will occure(30 is one, 60 would be the other one, etc).
  9. Why? Using TE's update is the preferred way of doing this. Since you are using timer your code will crash the game at some point without any warning with a ConcurrentModificationException, because Timer utilizes a different thread to run the passed runnable afaik. And the game isn't thread safe, especially when it comes to the world.
  10. Which part of my previous message did you not understand? This means that you need to do things at 2 different points of your AI. When the AI starts executing you calculate the angle. No, don't tell the dragon to move anywhere or do anything at all. Just calculate the angle and store it in a field. Nothing more. While the AI continually executes(aka each tick) you take that angle, add some number to it and do the rest of the calculations with it. I don't remember the method names in the AI class and am currently not home so I can't look them up but they should be fairly obvious.
  11. This is a bit more involved than that. This presumably needs to happen within the corresponding AI. When the AI begins it's job you calculate the angle. Then each tick you do angle = angle + NUM(you need to figure out the NUM yourself but effectively this is the speed of circling) and do the rest of the movement-related actions.
  12. The only difference between these two is that the first one uses doubles while the second one uses ints. You need the double one. It should be, but I wouldn't count on that.
  13. [0, 0, 1]. But I don't atually know what direction the game considers the forward one, so it might be some other unit vector.
  14. Don't directly access the registry, register your things in the appropriate RegistryEvent.Register, in this case it would be Register<Block>. In case of IHasModel - get rid of it and just register your models directly in the ModelRegistryEvent.
  15. That sounds bad. That sound directly accessing the registry levels of bad. And potentially IHasModel levels of bad too. IBlockState#getValue. I am not sure but you can override Block#getStateForPlacement and return the blockstate with the correct value. Yes, but you will need to override TileEntity#shouldRefresh in your TE class and make sure it returns false when the value of the property changes, but true otherwise or else the game will recreate your TE when you do that.
  16. Why are you using boxed values? BlockBase is an antipattern. There is already a BlockBase, it's called Block. This will always return 1. Serialize the value of the property, not it's property. TileEntity already implements ICapabilityProvider. Why is this static? This should never happen in onUpdate, and if it does some mod severely messes up and you should crash the game. active is static though. Why are you (de)serializing it for instances? The same way you would do it in your block class. You have the world(TileEntity.world) and the position(TileEntity.pos). Get the blockstate from the world at position and change the value of the property in the same way you would for your block.
  17. Well, the only thing that you are missing right now is What I am saying is vec1 is [dragonPos - playerPos] and vec2 is [unitZ]. This Is the line that calculates the angle, you just need to get the vec1 and vec2 right. Also this is a squared distance, as the name of the method implies. Have your radius be a constant or something, this will make your dragon fly away from the player at an exponential rate.
  18. You are still not doing that. Where did you get the impression that radius is somehow a vector?
  19. Did I tell you "Get the position of the dragon and the position of the center and do things with those vectors"? No, I told you to And you did none of that. Moving on Did I tell you "Oh, the radius of the circle is the angle you calculate"? No, because that makes zero sense. I told you Moving on Did I tell you "Use the dragon's rotation yaw plus an arbitrary number as an angle"? No, because unless you are rotating your dragon that makes no sense(and if you are - it is always looking away from the player and moves sideways). I told you to Moving on: So you have 2 vectors - midPoint and your [x, y, z]. [x, y, z] is midPoint + someNumbers. If you add them together you are essentially doubling the midPoint vector(kinda). So if your dragon is at [200, 100, 200] you are telling it to move to ~[400, 250, 400]. I don't think that it is what you want and that is not what I told you.
  20. A dot product of two vectors. arccos is the operation that is the reverse of the cos operation. The squared distance is just x*x + y*y + z*z. So the answer is no since these are completely different operations.
  21. I don't think you can draw a player's hand with a json model since, well, the game renders the quads you provide with the default texture atlas. The player's hand on the other hand uses the player's skin as it's texture, which is a separate texture object. I mean, I can kinda see how you might be able to do it with a custom IBakedModel but it would be breaking multiple things and borderline a dirty hack. I think that a TEISR is a solution here, but feel free to disagree.
  22. I didn't tell you "Oh, see these methods in the Item class? Yeah, copy them into your TEISR class, it will magically find your class by these methods and just work". I told you This means "invoke Item#setTileEntityItemStackRenderer to bind your TEISR to the item". No, don't invoke it in your TEISR. Do it somewhere that makes sense, somewhere where you know it will be executed by the game. Like in your client proxy.
  23. You've shown the methods I told you about. Yes, this is the method you could use.
  24. Exactly as it sounds. a TEISR needs to be assigned to the item using Item#setTileEntityItemStackRenderer(one of the options anyway). Code isn't magic, it's not going to just work because you've made some classes.
  25. does nothing in your implementation. Also show where you assign the TEISR to your item. ItemStack can't be null in 1.12.2. It can only be empty. But you already know that not to be the case if the render method is even executed. This check is pointless
×
×
  • Create New...

Important Information

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