Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Posts posted by coolAlias

  1. The graceful way of doing it is to use the AI system for its intended purpose, rather than hard-coding everything in the entity action state / update methods. With the right combination of mutex bits and a lot of patience, you can do some very complex things, especially once you start getting into making custom path navigators and such ;)

  2. You could do that and print the result to the console, or use your logger to print a message and it will automatically let you know which side it printed from.

     

    But I'm 90% sure that those specific events also get called on the client when the entity involved is a player, but maybe that is only if the attacking entity is a player... can't remember off the top of my head, which is why I suggested testing it for yourself.

     

    If it turns out that LivingHurtEvent is only called server side when attacked by mobs (which, now that I think about it more, I believe is the case), you will have to send a packet.

  3. LivingHurtEvent and the various attack events all have a DamageSource field which has the getSourceOfDamage() method - that returns the entity ultimately responsible for causing the damage, such as the shooter of an arrow or melee attacker.

     

    You'll want to double-check that the event is firing on the client side - for non-players, these are server only events.

  4. #1 If you can get the player skin as a TextureAtlasSprite, then you can add it using TGG's createBakedQuadForFace method from the chess board tutorial.

     

    #2 That's the entire point of IPerspectiveAwareModel. Look at the examples in the two posts I mentioned earlier - they both return different models based on perspective.

  5. Oh... yeah, that's right, sorry - I didn't see you had that in there :$

     

    However, that means the entity is only either ranged OR melee - he can't be both at the same time with your code as it is. You need both AI tasks to be added at the same time, and then limit how often either one can trigger in the respective attack methods, either with your current attackTimer or some other method of tracking whether it most recently attacked via ranged or melee. Maybe you could have two attack timers.

     

    The better solution would be to write your own AI class(es) to cycle between modes / only attack if the current target is within (or outside of) a certain range.

  6. You're not really supposed to... but that was the only way I could get that particular one to work. Ideally, it should all be done within the Model class.

     

    You don't even have to create an IModel to hold the references - you can do it directly in the Item class much like storing IIcon in 1.7.10:

    @SideOnly(Side.CLIENT)
    private List<ModelResourceLocation> models;
    
    // I have a method called automatically for every Item, much like the previous registerIcons method:
    @Override
    @SideOnly(Side.CLIENT)
    public void registerRenderers(ItemModelMesher mesher) {
    String name = getUnlocalizedName(); // don't yell at me Lex - it's the 2nd R of RRR 
    name = ModInfo.ID + ":" + name.substring(name.lastIndexOf(".") + 1);
    models = new ArrayList<ModelResourceLocation>();
    for (int i = 0; i < 4; ++i) {
    	models.add(new ModelResourceLocation(name + "_" + i, "inventory"));
    }
    // Register the first model as the base resource
    mesher.register(this, 0, models.get(0));
    }
    
    @Override
    @SideOnly(Side.CLIENT)
    public ModelResourceLocation getModel(ItemStack stack, EntityPlayer player, int ticksRemaining) {
    if (!player.isUsingItem()) {
    	return models.get(0);
    }
    int ticks = stack.getMaxItemUseDuration() - ticksRemaining;
    int i = (ticks > 17 ? 3 : ticks > 13 ? 2 : ticks > 0 ? 1 : 0);
    return models.get(i);
    }
    [code]
    As long as you only access (including initialization) the models List (or array, whatever you want) on the client side, you can use it quite easily to return a valid model that is defined in JSON. The example above is taken from my Hero's Bow, and the models are the different states of 'pulling'.

  7. So fetch all of the entities in a given radius around the player and kill them, or attackEntityFrom with a player-based damage source. You can fetch all of the entities using World#getEntitiesWithinAABB(EntityBlaze.class, player.getEntityBoundingBox().expand(8, 8, 8)) or however far you want.

     

    Do it on the server and it will be much faster by not eating up tons of bandwidth with packets.

  8. I do have subtypes

    Well you can't very well have every single subtype crafted in exactly the same way - if I put in one shard and one coal, what type of shard do I get back? Does the recipe require the same type of shard as input?

     

    Then you can just loop through the subtypes and add the one recipe for each:

    for (int i = 0; i < numSubtypes; ++i) {
    ItemStack stack = new ItemStack(shard, 1, i); // shard of appropriate subtype
    GameRegistry.addShapelessRecipe(stack, stack, Items.coal); // combining the shard with coal gives you... itself?
    }
    

    You're going to have to explain exactly what you are trying to do - what items combined give what item?

  9. Vanilla global entity IDs only go up to 255, which is why it is HIGHLY recommended NOT to use them, and use only the registerModEntity. In 1.8, you don't need to manually add mappings like that anymore to get a spawn egg, you can use instead EntityRegister#registerEgg.

     

    The frequency I mentioned is not related to spawn rate, just something I see all the time that is probably not very good to do.

     

    Put some println statements in your mob's onInitialSpawn method and see if that is getting called. Also, you probably want to call super.getCanSpawnHere() - the super methods generally have useful checks, depending on what class your mob extends.

     

     

  10. The last parameter of ItemStack is the damage value, not the stack size - do you have different item subtypes?

     

    If not, and you just want one item per coal, i.e. 1 coal = 1 shard, 2 coals = 2 shards, etc., then all you need is to register the first recipe:

    GameRegistry.addShapelessRecipe(new ItemStack(VioletMod.violetShard), VioletMod.violetShard, Items.coal);
    

    Then the player just clicks away and voilá, they have tons of shards.

  11. every single vanilla mob uses this.tasks.addtask();

     

    What do u mean?

    Nevermind, you just extend EntityGolem, not EntityIronGolem, so that's fine, but you still need to add your AI tasks, the ones you made as class fields:

    private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
    private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, true);
    

    You never add those to your entity's task list.

  12. Each time you call playerController.attackEntity it sends a packet, among other things, not to mention objectMouseOver, which is the position of the mouse cursor on the screen, cannot possibly be hovering over 90 mobs at one time.

     

    What exactly are you trying to do? Explain the logic of your attack code.

  13. A few things:

     

    1. Do NOT use '1' for the update frequency (the number after '80') - vanilla animals / mobs all use '3'

     

    2. 205 is a magic number - use a counter or something of that nature

     

    3. Entity spawning logic is mostly done in the actual Entity class getCanSpawnHere method - show us yours.

  14. Basically, I want the player to behave as if they were flying in creative mode all the time.

    Then make them flying all the time:

    player.capabilities.allowFlying = true;
    player.isFlying = true; // this may not work perfectly, as it gets set back to false when they touch the ground
    

    You could set up a player tick handler to check if isFlying is false and motionY < 0, then set isFlying to true at that time. Trouble is, motionY is often only accurate on the client side, so you may have to send a packet.

  15. I'm going to go see if TGG has any tutorials. Thanks!

    He does ;)

     

    It is quite intimidating at first, but once you get used to it and start learning your way around, it's not so bad. One thing that is super obvious but that I didn't realize for longer than I care to admit is that you can return 'this' from any of the model methods, which helps enormously. I don't know why, but I thought I had to return a previously baked model or something, and that was causing me all sorts of grief.

  16. if (!this.getAggressive()) {
    

    Means your mob WILL NOT ATTACK when 'aggressive', i.e. it will only attack when passive, which makes no sense at all.

     

    EDIT: ^^^ that part was ninja'd by TheRealMcrafter

     

    Also, collideWithEntity is usually not used for mob attacks as it only applies in a very small area - why don't you give your mob an AI task for EntityAIAttackOnCollide and override attackEntityAsMob? That would make a lot more sense.

×
×
  • Create New...

Important Information

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