Jump to content

AndrewFM

Members
  • Posts

    14
  • Joined

  • Last visited

Everything posted by AndrewFM

  1. Here's a useful list of forge events and their descriptions: https://dl.dropboxusercontent.com/s/h777x7ugherqs0w/forgeevents.html
  2. First of all, you don't want to use PlayerEvent. For what you're doing you should probably either use LivingEvent.LivingUpdateEvent, or TickEvent.PlayerTickEvent (the latter must be registered to the FML bus, not the Event bus). Obviously since your mod is client side only, it's not going to print in the server log... but did you check the client log (fml-client-latest.log in the .minecraft/logs folder)?
  3. I almost have this figured out. I'm trying to delete the contents of my custom dimension whenever the player returns to the overworld (or more specifically, when there's no more players in the dimension), so it'll generate fresh next time they enter. The only remaining issue I'm encountering is that when I try to delete the dimension's folder, it fails, because it's unable to delete some of the files in the dimension's 'region' folder. For the record, this is after the player has returned to the overworld, and also after the dimension has been unloaded (I'm sure of this, because if I call DimensionManager.unloadWorld() on the dimension, it tells me it's already unloaded). I took a look around through the source files, and as far as I can tell, all open file pointers to the region files are tracked inside Minecraft's RegionFileCache class. I tried calling RegionFileCache.clearRegionFileReferences(), which closes all of the region file pointers, but even with that it still fails to delete the folder.
  4. I'd like my code to be able to apply potion effects added by other mods, but the IDs of those potion effects aren't necessarily static (certain mods allow you to change the potion IDs via a config file). So instead of doing something like: entityPlayer.addPotionEffect(new PotionEffect(48, 200)); I'd prefer to do something like: entityPlayer.addPotionEffect(new PotionEffect("witchery:potion.insane", 200)); But I'm not sure how to get the corresponding integer ids from the unlocalized names of the potions.
  5. If it is just a problem with something getting messed up/corrupted in your workspace, and it's not anything wrong with your code, then maybe something as simple as "Project -> Clean..." in Eclipse will fix it?
  6. I've narrowed down the issue, it seems whatever controls the natural spawn of monsters does not take fluid blocks into consideration. If I set the spawn check to detect lava 2+ blocks beneath it, then the blazes will spawn, but only if there is a solid platform above the lava pool. Likewise, if I set the spawn check to detect lava in a radius around the blaze instead of directly beneath, then they will only spawn on the coastline around the lava pool, not on the lava itself. Does anyone know where the code is located that controls natural spawn, and/or if there's a way to modify that behavior?
  7. I'm trying to make a biome where Blazes can spawn naturally above any lava blocks. I made a new monster that extends the EntityBlaze class, and made this its spawn check: public boolean getCanSpawnHere() { boolean boundCheck = this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty(); int i = MathHelper.floor_double(this.posX); int j = MathHelper.floor_double(this.boundingBox.minY); int k = MathHelper.floor_double(this.posZ); return boundCheck && this.worldObj.getBlock(i, j - 1, k) == Blocks.lava; } and then added it to the biome spawn list with: this.spawnableMonsterList.add(new SpawnListEntry(ESIVBlaze.EntityESIVBlaze.class, 100, 2, 4)); However, the blazes never spawn in the biome.
  8. The value contained in event.ammount for onEntityDamaged -- is that the amount of damage before armor/potion effects/etc are applied, or the amount of damage after all of that has been factored in? Also, is there an event for the opposite case? I'd like to be able to modify the damage for both.
  9. I wound up doing the chunk thing. When I spawn the monsters, I mark them as being custom spawned, and then on a chunk load, I remove any entities in the chunk that are marked as having been spawned by a spawner. I guess this is basically like what delpi suggested... avoiding the whole issue by just killing everything and starting from a clean slate each time. This works sufficiently well for my purposes. It's still not the perfectly ideal solution... so if anyone has a better suggestion, I'm still open to ideas. But I'm pretty happy with this.
  10. I haven't tried implementing it yet, but I'm not sure if that would work (please correct me if I'm wrong). Let's say the spawner spawns an entity, and it gets added as a weak reference. Then if I traveled far enough away that the chunk the entity was in gets unloaded, wouldn't the entity be unloaded from memory as well? In that case, garbage collection will kick in, killing the weak reference, and causing it to get removed from the hash map. Then if I traveled back to that chunk, and the entity was still there (gets reloaded from file)... the spawner wouldn't have a reference to that entity anymore, and wouldn't acknowledge its existence, right? I think there is a forge event for chunk unloading, though... perhaps on a chunk unload, I could use that to force Minecraft to kill all entities in the chunk that don't have persistence enabled?
  11. Okay, I'm still having problems with this. I tried a variant of this, where I loop through the loadedEntityList, and compare the UUIDs of the loaded entities against the UUIDs of the entities in the spawner's list. If any of the UUIDs in the spawner are missing, they get removed from the list (in the assumption that that monster is no longer in the world -- either killed or despawned). This assumption doesn't really work, though. If the monster wanders too far away from the spawner, it's possible for the spawner to be in a chunk that is loaded, while the monster is in a chunk that is not loaded. In that case, the spawner incorrectly determines that the monster no longer exists. I couldn't get this method to work either, because LivingDeathEvent does not get called when an entity is despawned. It only gets called when the entity's HP reaches 0. I can't find any forge events that are called upon an entity despawn, either.
  12. Okay, I finally got it all working. Delpi is right, UUID has to be used (particularly the getPersistentID() function in Entity). I tried using the ids from getEntityID() and quickly found that they do not get saved with the entities. Those ids also get arbitrarily reassigned every session, so that does not work for this purpose at all. The only annoying thing is there doesn't seem to be a parallel function to getEntityByID() for the UUIDs, so the method I wound up using was to iterate through the "loadedEntityList" in World until I found an entity with a matching UUID. That was a bit annoying to do, because loadedEntityList is initially null when the world session starts, and gets populated as the chunks are loaded. So I had to implement it in such a way so that it would wait a few seconds after readFromNBT was called, before actually going and searching for the UUIDs to populate its reference list. (Fyi to anyone trying to implement something similar... since iterating through the entity list can be an expensive operation, I tried to minimize the amount of times that I had to use it by only using the UUIDs when saving/loading from NBT. I used the entity IDs from getEntityID() anywhere else, such as in the spawner's local reference list)
  13. Haha, whoops, I forgot you can just use world coordinates to grab a block object. Thanks! Only issue I've run into now is that if I want the spawner to be persistent across game sessions, I can't use raw Java object references to keep track of the spawned entities. I need to use something that can be saved/loaded from NBT... Do entities have unique per-instance ids, and is there a function to find an entity object in the world by that id? Edit: found it... it's getEntityID() in Entity, and getEntityByID() in World
  14. The thing I'm trying to work on is a custom mob spawner that has a strict limit on the number of monsters it has spawned into the world at any one time. For example, if the limit is set as 2, then after spawning two monsters, it cannot spawn any more until one of those two monsters are killed or despawned. My idea is to give the spawner a data structure that stores references to the spawned entities, easy enough. But then, once they are no longer in the game world, the spawner has to remove them from the reference list. That part seems potentially tricky. A couple ideas I have: 1. Call isEntityAlive() every tick, and remove the mob when the function returns false. However, since the entity is destroyed exactly one tick after being killed, I can foresee the following happening if the execution order does not work out in my favor: (isEntityAlive -> yes), (entity killed), (end of tick), (start of next tick), (entity destroyed), (isEntityAlive -> nullPointerException). Also, I'd like to avoid looping through the list of entity references every tick. 2. Give each entity a custom IAttribute that stores a reference to the spawner that spawned it, then use that to tell the spawner to remove the mob during a LivingDeathEvent. This seems like a potentially good method, but I don't know if an IAttribute can store an object reference, and I don't know if LivingDeathEvent is called when an entity is "killed" by being naturally despawned. I'm quite new to forge modding, so there's likely better solutions. For all of you that know a lot more about the available functionality... what would be your recommended method for going about this problem?
×
×
  • Create New...

Important Information

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