jabelar
Members-
Posts
3266 -
Joined
-
Last visited
-
Days Won
39
Everything posted by jabelar
-
Hi, I want to make an entity (an elephant) that rears up instead of fleeing when attacked. I know how to make complex model animations, so the actual rearing isn't hard -- to control it I just need a Boolean to indicate it isRearing and a rearingCounter to progress the animation through the cycle. So I don't need help with that. I have also set the knockbackResistance attribute to 1.0D so that it doesn't get knocked back. So I don't need help with that. However, for the life of me I can't get the EntityElephant to stop running away after being hit. I thought the fleeingTick variable was a clue based on its name and description, however I've overridden places where it is used and frankly after inspecting the vanilla code I don't think it really does much in terms of controlling the actual fleeing. There is only one place in the vanilla code where fleeingTick is even set (to 60) and if I override that and set it to other values it doesn't change the duration of the fleeing, so I'm pretty confident that isn't it (or enough). It seems that fleeingTick only controls whether the entity will try to attack, but doesn't control the actual duration it runs away. So then I figured that maybe overriding any sprinting would do it, but when the entity runs away it doesn't seem to test isSprinting as true (returns false even while entity is running away) so I guess the fleeing isn't counted as a type of sprint. It does seem that when it is fleeing it is using AIWander for the actual pathfinding and seems that it maybe overrides the movementSpeed attribute somehow. But basically I'm stuck and can't figure it out. I thought I could simply override the attackEntityFrom() method but it seems I'm missing something. I guess my main question is -- what is the field that controls/indicates that an Entity is fleeing? It seems to me that there is no such variable but rather it is a wander AI plus a movement modifier. Here is my attackEntityFrom() code, which is just lightly modified code from same method in EntityLivingBase class. (The fleeingTick = 1 is just my last attempt to control that variable, I tried 0 and also not setting it to anything, plus tried other values like 20 and 120 to see if it affected the length of the flight, but it didn't) /** * Called when the entity is attacked. */ @Override public boolean attackEntityFrom(DamageSource par1DamageSource, float parDamageAmount) { if (ForgeHooks.onLivingAttack(this, par1DamageSource, parDamageAmount)) return false; if (isEntityInvulnerable()) { return false; // not really "attacked" if invulnerable } else { if (worldObj.isRemote) // don't process attack on client side { return false; } else // on server side so process attack { fleeingTick = 1; // setting to 0 doesn't seem wise, because there is a decrement in super method if statement entityToAttack = null; resetInLove();; setRearing(true); // herd animals will rear when attacked entityAge = 0; if (getHealth() <= 0.0F) // not really "attacked" if already dead { return false; } else if (par1DamageSource.isFireDamage() && isPotionActive(Potion.fireResistance)) // fire resistance negates fire attack { return false; } else { if ((par1DamageSource == DamageSource.anvil || par1DamageSource == DamageSource.fallingBlock) && getEquipmentInSlot(4) != null) { getEquipmentInSlot(4).damageItem((int)(parDamageAmount * 4.0F + rand.nextFloat() * parDamageAmount * 2.0F), this); parDamageAmount *= 0.75F; } limbSwingAmount = 1.5F; boolean flag = true; if (hurtResistantTime > maxHurtResistantTime / 2.0F) { if (parDamageAmount <= lastDamage) { return false; } damageEntity(par1DamageSource, parDamageAmount - lastDamage); lastDamage = parDamageAmount; flag = false; } else { lastDamage = parDamageAmount; prevHealth = getHealth(); hurtResistantTime = maxHurtResistantTime; damageEntity(par1DamageSource, parDamageAmount); hurtTime = maxHurtTime = 10; } // process based on what is attacking attackedAtYaw = 0.0F; Entity entity = par1DamageSource.getEntity(); if (entity != null) { if (entity instanceof EntityLivingBase) // set revenge on any living entity that attacks { setRevengeTarget((EntityLivingBase)entity); } if (entity instanceof EntityPlayer) // identify attacking player or wolf with kill time determination { recentlyHit = 100; attackingPlayer = (EntityPlayer)entity; } else if (entity instanceof EntityWolf) { EntityWolf entitywolf = (EntityWolf)entity; if (entitywolf.isTamed()) { recentlyHit = 100; attackingPlayer = null; } } } if (flag) { worldObj.setEntityState(this, (byte)2); if (par1DamageSource != DamageSource.drown) { setBeenAttacked(); } if (entity != null) { double d1 = entity.posX - posX; double d0; for (d0 = entity.posZ - posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) { d1 = (Math.random() - Math.random()) * 0.01D; } attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - rotationYaw; knockBack(entity, parDamageAmount, d1, d0); } else // not an entity that caused damage { attackedAtYaw = (int)(Math.random() * 2.0D) * 180; } } // play sounds for hurt or death String s; if (getHealth() <= 0.0F) // dead { s = getDeathSound(); if (flag && s != null) { playSound(s, getSoundVolume(), getSoundPitch()); } onDeath(par1DamageSource); } else // hurt { s = getHurtSound(); if (flag && s != null) { playSound(s, getSoundVolume(), getSoundPitch()); } } return true; } } } }
-
I certainly always think it is weird how we often associate the moon with the night, when of course it is up in the day just as much. Sure, it is more prominent at night, but most people seem to actually talk and think like the moon comes up at night. Sounds like you should make a "true sky" mod, complete with constellations!
-
Well, I understand that the monster spawning is logically "is there light", but I don't like to assume that the logic is exactly related to real, rendered lighting. Like the "is there light" logic might really be "should there be light based on time of day". You probably looked at it already, but the check for light for monster spawning may include some check for time of day whether or not it is rendering an actual sky or a sky with the sun in it.
-
Where do you specify this? In the arguments of the Eclipse run configuration?
-
Thanks. I do love you! The IResource class is what I was missing, that will do what I want. Thanks!
-
Block made in Techne does not render correctly in-game.
jabelar replied to Spideynn's topic in Modder Support
Yeah, it took me a long time to realize that the texture file had to have the 2:1 proportions. My kids were making all my texture maps for me and sometimes they just weren't working, but eventually we realized that it was scaling in one dimension and causing the trouble. I'm not entirely sure why the texture maps work that way -- you think they would just take pixels as they need them based on the offset (who cares if there are extra pixels in the file) -- but it is important to remember. -
Block made in Techne does not render correctly in-game.
jabelar replied to Spideynn's topic in Modder Support
I find that when you're working on the model, it is best to have a texture file that is filled in with a solid coloar (don't worry about proper texture map, just have a 64 x 32 file that is some color that is easy to see like orange. What it looks like to me is that your model isn't finding the right texture. (Do you see any errors in the console log indicating that it didn't find the texture?) Or maybe your texture is found but the texture offsets are wrong (this can be tricky to get right). Lastly, you might have got your texture improperly scaled. You MUST have your texture file keep the same 2:1 width to height ratio, otherwise it will squish the texture in one dimension and cause transparent gaps. Anyway, it is one of those three things. In all cases, if you try with a fully filled texture image you can confirm that the model is working properly before you fool around further with the texture mapping itself. -
Yeah, for one thing it seems to me that monster spawning might screw up if they are supposed to spawn at night but it is really daytime with just a night sky... I'm still interested in how you might fix the time similar to the /time set command. If you could just issue that command every tick, it seems to me that it would work, although delpi is indicating above that it is somehow being overwritten or ignored when he tried it (plus the /time set command seems to affect all worldservers simultaneously).
-
Actually I guess I really just want an answer to a simple question: what is proper relative path to my assets folder? If I had a file called my_file.txt in /assets/configurations/ then what would I put in my new File path argument: File myFile = new File("/configurations/my_file.txt"); or File myFile = new File("/assets/configurations/my_file.txt"); Or what?
-
Thanks. That is actually what I want to do -- but my problem is when you create a Configuration you need to pass it a file. Most examples for Configuration pass a file using suggestedConfigFile for the path and then they create the file from within the executing code with a config.save() method. However, I want to be able to place a pre-made file in some assets directory where edit it externally and only load it (not save it). So I need to know how to create a File instance that points to the path of my file so I can pass it to the Configuration. I suspect I can use the path variables within the ResourceLocation, but I'm not entirely confident I'm not sure they are proper relative paths (i.e. can I use them as is) or whether I need to prepend or trim something from the path string. I'll probably play around with it more when I'm at a computer with my development environment, but was hoping that someone might have experience on the simple question -- how can I create a File with a reference the relative path to my assets folder (and is ResourceLocation a good way to do it).
-
Okay, I want do do some file manipulation in my mod. I generally understand file operations, but have a question specific to Minecraft modding -- what is best way to specify the file path such that I can use it in dev environment but it will also be available in my published mod? ResourceLocations obviously seem like the right thing, since it provides a mod-specific relative path to various non-code file assets. However, I wasn't sure how to use the ResourceLocation to create a Java File object. Or more specifically, maybe if I new how relative paths in File object map into the assets folder path. I'd love to be able to do something like File myFile = new File(ResourceLocation) but I think I need some method to transform ResourceLocationinto a relative path string for File constructor. Any tips?
-
[unSOLVED] Trigonometry with connected entities
jabelar replied to david476's topic in Modder Support
In mathematics you pretty much always use radians because it easier for differential and integral calculus in a neater/perfect form (using Pi constant instead of some irrational number constant with some error). In computer science, like TGG says it simply depends on how the method was written. The base methods in most computer language libraries are usually radians as far as I've experienced. To help my own brain keep from straining, I'll often create my own methods that work in degrees by converting the parameter to radians then calling the library function that uses radians. -
[unSOLVED] Trigonometry with connected entities
jabelar replied to david476's topic in Modder Support
Yeah, I said it backwards. The functions are in radians. Anyway, my point is to make sure you include the conversions as necessary. It is really easy to do something like take arcsin (to get angle from position) and then add degrees to it then try to sin it again and mess it all up because you forgot to convert from rad and back again. -
[unSOLVED] Trigonometry with connected entities
jabelar replied to david476's topic in Modder Support
It might be easier to help if you drew a picture of what you're trying to do -- trigonometry is usually easier if you can visualize. I'm not sure about your equations doing what you want (not quite sure what you want), but they are not correct from a coding correctness: 1) you have a typo mistake where you don't have the final closing ) in the equations. 2) Also you need to remember that the rotations are in radians, not in degrees but degrees are a lot easier for humans to visualize so you probably want to write your equations with the conversions. You can use math radToDeg() type methods (or make your own for floats). 3) you need to use a * for the multiplication. I realize you weren't necessarily writing code, but probably good to do it exactly to avoid any mistakes. Overall I am not sure what exactly you're trying to achieve, but at a glance I suspect they are wrong. You usually need to have both a sin and a cos if you're translating an angle into a position on each 2D plane. You really need to draw it out, then it would probably be easy to figure out which angles and which sin versus cos function to use. -
Now that I think about it, you only have to ensure the time is set before it is actually used. I'm not sure the order of all the underlying steps on the server side, but depending on the effect you're actually after maybe you just have to override the method that renders the celestial sky? Also, there is a command "/gamerule doDaylightCycle false" that simply stops the day-night cycle which you may want to check out for ideas.
-
[1.7.2] Dimensional teleporting, without the portals
jabelar replied to whiskeyfur's topic in Modder Support
What's wrong with that? That is probably the way you would want to do it, and I think delpi is proposing to give you such an example. Logically it sounds like what you want -- a custom command that teleports. -
Well it is only setting it in all dimensions because it has a FOR loop that goes through each dimension. If you can just identify the world server you care about, seems like you could just set the one? Then to find out where the sync is happening, I guess search for other methods that affect the worldservers with same methods and see how that behaves and where it is invoked. I'm not at a computer with source on it, otherwise I'd help you look. But I think you know what I mean -- find all the other places in the code where the worldserver time is set and you should find out the method that is causing the sync. The only question then is whether you can intercept that method (prevent it from happening), or override it (set it yourself right after the sync).
-
When modding I find it is best to start with the closest vanilla Minecraft method and see how it is done there. In that case, I would look at the vanilla command for /time set. So I think you should look the CommandTime class. In there there is a setTime() method which looks likely to give ideas on how to do what you want.
-
[SOLVED][1.7.2]Render scaling affects beyond my render method
jabelar replied to jabelar's topic in Modder Support
If I drew my own bounding box, I'd have to be careful about that. But it seems that the built-in key binding (F3+B) draws separately and correctly. By the way, I recommend to anyone playing with their own models to use this feature to see the bounding box to confirm all the positioning is working correctly. Anyway, the issue is solved. The correct translation was 1.5F in Y direction prior to scaling (in same matrix). The main take away is that it seems there is a translation between the pre-render callback and the render so keep that in mind if you use the callback. -
[SOLVED][1.7.2]Render scaling affects beyond my render method
jabelar replied to jabelar's topic in Modder Support
Yeah, that was certainly what it looked like. I was just surprised that there would be a translate between the pre-render callback -- it sort of makes that method more difficult to use if you have to anticipate a translation. Thanks. I'm pretty good with spatial transformation, but mainly was surprised by the unexpected translation as mentioned above. I understand that you have to be careful about the center point location before scaling, otherwise you get an effective translation where it will be moved further from the center point. I think it is correct because (a) the entities are happily moving around despite being "submerged" in the ground, (b) if I press F3+B I can see the hitboxes which look correct and are actually the hit box if I try to hit the entity. That should be sufficient to prove that it is correct, right? Also, why do you think that scaling would affect the BB anyway -- isn't the GL scaling purely rendering? -
[SOLVED][1.7.2]Render scaling affects beyond my render method
jabelar replied to jabelar's topic in Modder Support
Thanks. I just came across some other info where it was leading me to the fact that I need to put in extra push and pop of the matrix since mine wasn't inside a pop and push. Okay previously I had the scaling in the preRenderCallback() method but since I need the matrix to include the rendering and since I don't know of a post render method I figure I have to do the push and pop of the matrix right in the render event. I did that, and it does scale but the weird thing is that the elephants now are only halfway above the ground. The hit box (visible with F3+B) is still proper size above ground. And they move around okay so I assume that the bounding box is indeed still okay (and it should be since rendering should be independent). I can translate the matrix in my render, but before I do that I would like to know why this happened. Why would a scaling in the pre-render callback have different result than doing the scaling as first thing in the render? My render method currently with the overall scaling included: -
Assuming you want to continue to use a straight arm model (instead of creating an articulating one with an elbow) then as TGG says it is in the RenderPlayer class in the renderFirstPersonArm() method, but the actual work of setting the rotations is in the ModelPlayer class in the setRotationAngles() method. If you look at that method, it only really moves the rotationAngleX for the arm whereas you probably need to also use at least rotationAngleY as well. I'm not really certain how easy it would be to override all this but I assume you have to subscribe to the RenderPlayerEvent (which is cancelable which means you can fully replace with your own handler). In that one you'll have to invoke your own renderer which will have to invoke your own model. The good news is I think you can mostly copy the existing player renderer and model and just make the edits you want.
-
Okay, so I have an elephant entity with a custom model that is working quite great (including articulated trunk). My kids of course wanted the elephant to be bigger so I decided to scale it by factor of 2.0F. I did this by putting this in entity constructor And also putting this in the render for the entity: And it works great. Got a nice big elephant and bounding box seems to be right as it navigates around. However, I had one really weird thing happen. I spawned the elephant right next to a village that had a forge. And suddenly there were giant flames coming out of the building. It seemed that the fire was scaled as well, as it would sort of glitch if I moved around it. It didn't quite seem like the elephant itself was on fire as it wandered off and the fire stayed in the town. But wasn't quite like the town was on fire either. Anyway, it seemed that the fire was being scaled, maybe because the GL scaling persisted into another rendering method. If I'm using a GL Scale function is it a good practice to set it back to 1.0F in some post render method?
-
[Solved]How to make the server call a method (Tick Handler)?
jabelar replied to Mecblader's topic in Modder Support
Yes, this is an important point that took me a while to understand. The @SideOnly will only load the annotated class or method on the side referenced, whereas checking side with such things as isRemote() methods it is actually running (maybe even on both sides) but you can use the method to choose the code path. Particularly confusing is that when you use a Client run configuration (like when you run your mod from Eclipse) there will still be code running on server side because Minecraft always has a server running, even in single player. That is why some people prefer to call the run configuration a "combined client". I think the @SideOnly is mostly useful during the time where FML is loading up and registering things since at that point you're not in a world. That is why you see it a lot for the proxy and preInit() type stuff. Also in cases where you're absolutely sure you won't need it in a given run configuration, like rendering and models only being needed on client, I guess it saves some memory to use @SideOnly to prevent the unnecessary classes from loading. -
[1.7.2] Changing harvest level of vanilla Block
jabelar replied to ISQUISHALL's topic in Modder Support
I played around with the code myself and tried to get a console message out when the initTools() method was run but it never printed out. So I'm really not sure when that is run. I thought the static initializer for ForgeHooks class would run when that class was loaded, but I couldn't find a way to prove that. I think you should try setting the harvest level once game is fully loaded, like perhaps have a block where onActivate you set the harvest level of the diamond_ore. If that works, then maybe you can use some method you know will run during the game and use that to change the harvest level.