Jump to content

WeAthFolD

Members
  • Posts

    23
  • Joined

  • Last visited

Posts posted by WeAthFolD

  1. In a nutshell: ISBRH is cached for efficiency and is called infrequently, TESR is not and gets called every frame.

     

    in ISBRH you are already in a context of Tessellator.startDrawing(GL_QUADS). All you can do is specific quad geometries to the tessellator. The ISBRH represents a huge global draw call, where the draw call is sent once for every block in the world (or the blocks needed for render update). This is done only when world render state needs to update. (e.g. light state chagned).

     

    in TESR you send out draw calls by yourself, and they get called every frame. This allows rendering of *dynamic* effects and complex geometries, also enables you to do transformation using ``GL11.glTranslate`` and ``glRotate``. However because that each TESR call needs at least one draw call, it is generally slower.

     

    So, use TESR only when it's necessary.

     

    NOTE: Those conclusion comes from reading the source code and might be somehow inaccurate. Feel free to correct me >.<

     

     

  2. Simple vector maths >_>

    The code can be further improved to improve performance, current there are some redundant calcs.

    float rad(float angle) { 
    return angle * (float) Math.PI / 180; 
    }
    
    Vec3 lookVector(Entity player) {
    float rotationYaw = player.rotationYaw, rotationPitch = player.rotationPitch;
    float vx = -MathHelper.sin(rad(rotationYaw)) * MathHelper.cos(rad(rotationPitch));
    float vz = MathHelper.cos(rad(rotationYaw)) * MathHelper.cos(rad(rotationPitch));
    float vy = -MathHelper.sin(rad(rotationPitch));
    return Vec3.createVectorHelper(vx, vy, vz);
    }
    

    The returned Vec3 is the player's looking direction vector.

     

    You can also use ```player.getLookVec()``` for the exact same result.

     

  3. That is a pretty complicated topic though...

     

    I'm author of https://github.com/LambdaInnovation/AcademyCraft, which is a mod that focuses entirely on super abilities, so I will explain a bit about my thoughts on a skill system and experience gained through developement.

     

    1. Controlling

    ---

    It differs largely by how you want your skills to be controlled. In my mod the skills are controlled using independant keys. In this way, you probably want to implement a personal key-listening mechanism and have vanilla MC key disabled when your skills are ready to use. Or you can use one or two keys that doesn't collide with vanilla keys, that's completely fine.

     

    2. Data storage

    ---

    Skills usually point to per-player data storage for skill points and other properties. You can use IExtendedEntityProperties for that. Note that there are some tricky points to implement it correctly, especially PlayerEvent.Clone......

     

    If you want your client to display GUIs or something about those states, you also have to create packets(messages) to synchronize the data.

     

    3. Actual effects

    ---

    Skills almost always affects both server and client. Creating a uniformed way to represent those changes easily can be challenging, depends on what effect you want to implement. If it is as simple as press a key and do things right away, just send packets when the key is pressed. But if you want to have skills that charges themselves, have interactive interfaces, and more complicated features, things starts to get messy quickly if you don't think hard. Here's a few tips:

     

    * Create an 'action' class that communicates in client/server and sends event about keydown/tick/keyup/abort.

    * Client-side render can be achieved by client-only entities, or server-side synced entities. You can choose as what you like, but the client-only approach might be cleaner.

     

     

    That's pretty much all the basic points I can think of. The design decision really differs greatly, depends on what kind of effect and content you are trying to achieve. Feel free to refer to the src :)

  4. Didn't look completely through the code, but I think you could try playing with ```GL11.glCullFace()``` with parameter GL_FRONT and GL_BACK. Remember to restore that to GL_BACK as it's likely to be the standard option.

     

    Also it looks like you are trying to render blocks using standard methods. Then you should probably avoid all that render code copiese, which might cause your problems and are subject to error.

     

    Here is a similar piece of code in TERenderer I have written, hope that could be useful for you:

    /**
    * Vanilla mc block rendering pipeline caches block rendering. If you want to render some block
    * that renders dynamically and wants to use the original IIcon approach, use this on your TileEntity.
    */
    public class RenderDynamicBlock extends TileEntitySpecialRenderer {
    
    public static RenderBlocks renderBlocks = RenderBlocks.getInstance();
    
    @Override
    public void renderTileEntityAt(TileEntity t, double x,
    		double y, double z, float pt) {
    	Block blockType = t.getBlockType();
    
    	Tessellator tes = Tessellator.instance;
    	tes.setColorOpaque_F(1.0F, 1.0F, 1.0F);
    
    	renderBlocks.blockAccess = t.getWorldObj();
    
    	{
    		if (Minecraft.isAmbientOcclusionEnabled()) {
                    GL11.glShadeModel(GL11.GL_SMOOTH);
                } else {
                    GL11.glShadeModel(GL11.GL_FLAT);
                }
    		RenderHelper.disableStandardItemLighting();
    
    		RenderUtils.loadTexture(TextureMap.locationBlocksTexture);
                
    		tes.startDrawingQuads();
    		tes.setTranslation(x - t.xCoord, y - t.yCoord, z - t.zCoord);
    
    		renderBlocks.renderBlockAllFaces(blockType, t.xCoord, t.yCoord, t.zCoord);
    		tes.setTranslation(0, 0, 0);
    		tes.draw();
    
    		RenderHelper.enableStandardItemLighting();
    	}
    }
    
    }
    

  5. I've been recently working on some special effects in my mod, so I started using transparent PNG textures in my entity rendering. But I noticed one(Rather annoying) flaw:

    When the back of the entity are plain blocks, the rendering is perfectly OK. However, if the back of the entity are some water blocks, then part of water(To be exact, part which the texture's pixels are really drawn) are not being renderered at all, so I'm blending with whatever block that is beneath the water.

    When testing with blended TileEntities, same error occurs.

    I also noticed that the GL_ALPHA_TEST switch is enabled and some low-alpha pixels are being filtered. When I turn that switch off, the whole picture area I'm rendering ruins the water rendering.

    With multiple entities in the world, sometimes the same problem occurs. It seems that the problem is highly dependent on the drawing order.

    So, how can I fix that? Or it is a fixed problem of the MC render engine and we have to just stand it?(If it's the latter one I'll be really sad :()

    BTW, all I did in my EntityRender class is equivalent to the following:

    @Override
    public void doRender(Entity ent, double x, double y, double z, float wtf, float isthis) {
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    GL11.glPushMatrix(); {
    GL11.glTranslated(x, y, z);
    //bind the texture
    //render the model or whatever by calling tessellator
    } GL11.glPopMatrix();
    GL11.glDisable(GL11.GL_BLEND);
    }
    

     

    221759opm0k0j4kmddtxt7.jpg

    A screenshot(When disabled GL_ALPHA_TEST)

    The MC version is 172 and Forge version is 172 recommended.

     

    Thanks for your time reading and answering!

     

    EDIT: After looking up some informations, I found that this problem is hardly solveable because of limits on OpenGL rendering pipeline. Depth test is done regardless of pixel transparency, and alpha blending is done in later stages. To make it right you have to either not write Z value of current drawing (Which may cause this draw call to be improperly covered), or make depth sorting for all of the transparent stuff within the render scene(Which for current MC rendering routine, impossible). So currently maybe we can just stand this design flaw and use original alpha tests?

  6. Aha, I think I've figured this out.

    I tried System.out.println() in onEntitySwing(), however nothing appeared on the console in any situation.

    I belive that this function is not called in update codes by mistake (Or for some special reason?)

    in EntityLiving, there's a boolean named isSwingInProgress, so I tried the code below :

    @Override
    public void onUpdate(ItemStack par1ItemStack, World par2World,
    		Entity par3Entity, int par4, boolean par5) {
    	super.onUpdate(par1ItemStack, par2World, par3Entity, par4,par5);
    	if(par5 && par3Entity instanceof EntityLiving) { //par5:isCurrentHeldItem
    		((EntityLiving)par3Entity).isSwingInProgress = false;
    	}
    }
    

    EDIT: Tested in forge 1.5.2.

    Then all of the function works well. Binding with canceling event and abort interacting, this is the effect that I exactly want :D

    Thanks all for answering again> >

  7. I've noticed that in some weapon-related mods such as iChun's portal gun, player can use both left key and right key to shoot.

    I found this really good, so I started trying doing something similar. Having tried custom KeyCode and simple processing, all them works well. However I can't manage to find the related function to abort player's clicking action on left click.

    I've tried all the codes below :

        public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity)
        {
        	return true;
        }
        
        public boolean onEntitySwing(EntityLiving entityLiving, ItemStack stack)
        {
        	return true;
        }
        
        public EnumAction getItemUseAction(ItemStack par1ItemStack)
        {
        	return EnumAction.none;
        }
        
        public boolean onBlockStartBreak(ItemStack itemstack, int i, int j, int k, EntityPlayer player)
        {
          return true;
        }
        
        public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
        {
          return true;
        }
    

     

    Also tried this in EventHandler :

      @ForgeSubscribe
      public void onInteract(EntityInteractEvent event)
      {
    	  ItemStack curItem = event.entityPlayer.getCurrentEquippedItem();
    	  if(curItem != null && curItem.getItem() instanceof MyItem) {
                                event.setCanceled(true);
    	  }
      }
    

    But the result isn't what I expected. Though left clicking won't attack mobs or break blocks anymore, The player's right hand always keep that 'swinging' animation when I click the left mouse button.

    What should I do if I want to abort the left-clicking action? Is there something I should do with EntityPlayer class or custom render?

    Thanks a lot for your time reading and answering  ;)

  8. I have written some custom keys that provides specific functions for the player. For example, open the armor flashlight while equipped, but I met with some problems.

    Using Minecraft's KeyHandler, the keyDown(...) function is fired regardless of the world presentation, or player is opening GUIs or not.

    This is defintely not what I'm looking for. I know I can skip the process with if(Minecraft.getMinecraft().thePlayer != null)check, but I want the key not to fire when player is chatting/opening a GUI, however I didn't see similar functions in EntityPlayerSP, nor Minecraft class itself.

    Any Ideas ? :)

  9. 20130716200935.jpg

    ♪~ It works.

     

    The terrifying pigs are rendered with glDisable(GL11.GL_LIGHTING) and OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f). Yep, Minecraft also use lightmap to control brightness. The door is drew with setBrightness(15728880).

    BTW, resetting the lightmap without disabling OpenGL light source will make Entities more soft.

     

    Codes of Standardized Entity Render

    GL11.glPushMatrix();
    GL11.glDisable(GL11.GL_LIGHTING);
    OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
    ...render...
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glPopMatrix();

     

    Codes of Tessellator Drawer

    tessellator.setBrightness(15728880);

     

    If you are curious about why I chose 15728880...

     

    15728880 = 15 << 20 | 15 << 4

    The first 15 is lighting of environment, and the second 15 is lighting of itself.

    So, I guess that 15728880 is potential the brightest lighting in game...

    > >Thanks a lot! That's exactly the answer I am looking for! Also gained lots of knowledge about Minecraft rendering...

    (BTW:其实我们可以说中文)

  10. I'm recently doing some stuff like weapon ray and lightballs, so I'm trying to find a way to make the entity/TileEntity renders in a constant brightness, regardless of daytime and environment, but I've met some problem.

    First I tried to disable GL_LIGHTING, like what I saw in the original src code.

    in my RenderXXX extends Render :

    public void render(entity e, ...) {
    Tessellator t = Tessellator.instance;
    GL11.glPushMatrix();
    GL11.glDisable(GL11.GL_LIGHTING);
    //....other gl settings ignored
    
    t.startDrawingQuads();
    //...Actual draw call
    t.draw();
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glPopMatrix();
    }
    

    But disable lighting just won't do, the entity renders as it used to be.

    After then I found Tessellator#setBrightness(int) function, and I modified my code to this:

    public void render(entity e, ...) {
    Tessellator t = Tessellator.instance;
    GL11.glPushMatrix();
    GL11.glDisable(GL11.GL_LIGHTING);
    //....other gl settings ignored
    
    t.startDrawingQuads();
    t.setBrightness(0xFFFFFF);
    //...Actual draw call
    t.draw();
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glPopMatrix();
    }
    

    Now the rendering behaves somehow different but I didn't get what I expected. When I was trying with brightness 255, the entity looks kinda dark during the day, but really bright at night. I also tried 65535 and 0xFFFFFF but it became even darker.

    I've looked Beacon's TileRender and didn't see it doing anything special but disabling GL_LIGHTING.

    So what's wrong with my code? What should I do if I want an entity/TileEntity to render in full brightness always?

    Thanks a lot for your help>_<

  11. I've created a some sort of weapon item, which does a screen uplift when shooting

    I use this in EntityPlayer onItemUsing:

    entityPlayer.rotationPitch -= this.upliftRadius;

    and it works quite well.

    But when I try to do the rotation recover inside onUpdate(..)method,something onusual happened.

     

    inside my abstract class WeaponGeneral:

    public InformationWeapon onWpnUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5){
    
    	if(!(par3Entity instanceof EntityPlayer))
    		return null;
    
    	InformationWeapon information = loadInformation(par1ItemStack, (EntityPlayer) par3Entity);
    
    	ItemStack currentItem = ((EntityPlayer)par3Entity).inventory.getCurrentItem();
    	if(currentItem == null || !currentItem.equals(par1ItemStack))
    		return null;	
    
    	if(information == null){
    		System.err.println(par2World.isRemote + " side is null");
    		return null;
    	}
    	if(!par2World.isRemote)
    		return information;
    	if(information.isRecovering){
    		par3Entity.rotationPitch += recoverRadius;
    		information.recoverTick++;
    		if(information.recoverTick >= (upLiftRadius / recoverRadius))
    			information.isRecovering = false;
    	}		
    	return information;
    
    }
    

    well,InformationWeapon is a class I've written to provide information for ItemStack,you can skip this.

    When I extend this WeaponGeneral class, and call onWeaponUpdate(...) in onUpdate(...) method, it doesn't work quite well.

    1:On INTERGRATED Server, both Creative mode and Survival mode works quite well.

    2:On CLIENT/SERVER testing, Creative mode works quite well;

    BUT when testing in survival mode, player's rotationpitch SOMETIMES recover, MOST TIMES stay the same.

    I tried debugging in console,

    the result showing when in Survival Mode, each recovering process adds the player's rotationPitch.

    but in the next recovering process, the rotationPitch went back to the oringinal pitch, as if the screen output is lying.

    So what am I supposed to do to fix this?

    Thanks a lot >)

  12. I have created an Item which plays sound when rightclick, and it does a charge function.

    When the mouse is released, the item will to the charge function.

    But when I use worldObj.playSoundAtEntity(Entity,...) in onItemRightClick() function,

    I don't find any method that could stop playing the sound while on onPlayerStoppedUsing();

    So is there any ways I can use to stop playing sound that has been previously played at a specfic place?

    Thanks a lot for your reading and answering :)

  13. I have created an Item which plays sound when rightclick, and it does a charge function.

    When the mouse is released, the item will to the charge function.

    But when I use worldObj.playSoundAtEntity(Entity,...) in onItemRightClick() function,

    I don't find any method that could stop playing the sound while on onPlayerStoppedUsing();

    So is there any ways I can use to stop playing sound that has been previously played at a specfic place?

    Thanks a lot for your reading and answering :)

  14. I've been trying to work out something like guns, and I tried to use Minecraft's RayTraceBlocks function,and I've met with a strange difficulty.

    class BulletManager{
            ....Other methods
    public static void Shoot(ItemStack itemStack, EntityLiving entityPlayer, World worldObj, String particle){
    
    	if(!(itemStack.getItem() instanceof WeaponGeneral))
    		return;
    
    	WeaponGeneral item = (WeaponGeneral) itemStack.getItem();
    	InformationWeapon inf = item.getInformation(itemStack).getProperInf(worldObj);
    	int mode = inf.mode;
    	int damage = item.damage[mode];
    	int offset = item.offset[mode]; //load Information of the specfic ItemStack
    	MotionXYZ prem = new MotionXYZ(entityPlayer, 0).updateMotion(0.5D); //right before player
    	MotionXYZ afterm = new MotionXYZ(entityPlayer, 0).updateMotion(300D); //end position
    
    	worldObj.spawnParticle(particle , prem.posX, prem.posY, prem.posZ, prem.motionX, prem.motionY, prem.motionZ);
    
    
    	//do rayTrace
    	Vec3 pre = prem.asVec3(worldObj), after = afterm.asVec3(worldObj);
    	MovingObjectPosition result = doTrace(worldObj, pre, after, entityPlayer);//Trace both blocks and entities
                    //*******SERVER AND CLIENT BEHAVES DIFFERENTLY,WHY?QaQ
    
    	if(result != null)
    		System.out.println("RayTrace result: " + result.typeOfHit + ",isRemote: " + worldObj.isRemote);
    
    	switch(result.typeOfHit){
    	case ENTITY:
    		doEntityCollision(result, itemStack, worldObj, entityPlayer, prem);
    		if( worldObj.getBlockId(result.blockX,result.blockY,result.blockZ) > 0 ){
    			doBlockCollision(result, itemStack, worldObj, entityPlayer, prem);
    		}
    		break;
    	case TILE:
    		doBlockCollision(result, itemStack, worldObj, entityPlayer, prem);
    		break;
    
    	default:
    		break;
    	}
    	return;
    
    }
    
    private static MovingObjectPosition doTrace(World world, Vec3 pre, Vec3 after, EntityLiving player){
    
    	MovingObjectPosition result;
    
    	result = world.rayTraceBlocks_do(pre, after, true);
    	MotionXYZ var0 = new MotionXYZ(player,0).updateMotion(0.5D);
    	int blocksAway = 0;
    	if(result != null){
    		after = result.hitVec;
    		blocksAway = (int) Math.round((after.xCoord - var0.posX)/var0.motionX);
    	} else {
    		after = new MotionXYZ(player, 0).asVec3(world);
    		blocksAway = ENTITY_TRACE_RANGE;
    	}
    	System.out.println("BlocksAway : " + blocksAway);
    	AxisAlignedBB bBox;
    	List list;
    
    	for(int i = 0; i < blocksAway; i++){
    		bBox = AxisAlignedBB.getBoundingBox(var0.posX-BB_SIZE, var0.posY-BB_SIZE, var0.posZ-BB_SIZE,
    				var0.posX+BB_SIZE, var0.posY+BB_SIZE, var0.posZ+BB_SIZE);
    		list = world.getEntitiesWithinAABBExcludingEntity(player, bBox);
    		if(list.size() >0){
    			Entity var1;
    			for(int j=0; j< list.size(); j++){
    				var1 = (Entity) list.get(j);
    				if(var1 instanceof EntityLiving){
    					if(result == null)
    						result = new MovingObjectPosition(var1);
    					result.entityHit = var1;
    					result.typeOfHit = EnumMovingObjectType.ENTITY;
    				}
    			}
    		}
    		var0.updateMotion(2*BB_SIZE);
    	}
    	return result;
    
    }
    
    public static void doEntityCollision(MovingObjectPosition result, ItemStack itemStack, World worldObj, EntityLiving player, MotionXYZ begin){
    
    	if(result == null)
    		return;
    	if(!(result.entityHit instanceof EntityLiving))
    		return;
    
    	WeaponGeneral item = (WeaponGeneral) itemStack.getItem();
    	InformationWeapon inf = item.getInformation(itemStack).getProperInf(worldObj);
    	int mode = inf.mode;
    	double pf = item.pushForce[mode];
    	double dx = begin.motionX * pf, dy = begin.motionY * pf, dz = begin.motionZ * pf;
    	EntityLiving mob = (EntityLiving) result.entityHit;
    	System.out.println("Hit side: " + worldObj.isRemote + ", Mob Side: " + mob.worldObj.isRemote);
                    //Attack Mob and add Velocity,which doesn't work everytime(ACTUALLY A LOT OF TIME)
    	mob.attackEntityFrom(DamageSource.causeMobDamage(player), item.damage[mode]);
    	mob.addVelocity(dx, dy, dz);
    
    }
    
    }
    

    MotionXYZ is a class I created which contains PosXYZ and MotionXYZ information.

    BTW,0 on the constructor is offset,which make MotionXYZ a random range.

    The Shoot Method is called within Item class when holding Right mouse.

    I expected the result to work out just fine,but it turns out that the collision result I get from Server and Client side is really different.

    Once shot, I can see the mob being hit(Velocity changed),but it wasn't hurt and comes back to its origin position few seconds later.

    on console I can see that Trace results between Client and Server are totally different,one on the CLIENT is ENTITY, another one on the SERVER is TILE.

    I was really confused. How could it be possibly different when I use the same Vec3 at almost exact same tick?How do I fix this?If I can't , can I use other ways such as Trace only in CLIENT and hurt the mob on Serverside?

    Sorry for my bad English, and thanks for your reading and answering my question :D

  15. I saw codes like this in ItemBow's code:

     

        public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, int par4)
        {
            int var6 = this.getMaxItemUseDuration(par1ItemStack) - par4;
    
            ArrowLooseEvent event = new ArrowLooseEvent(par3EntityPlayer, par1ItemStack, var6);
            MinecraftForge.EVENT_BUS.post(event);
            if (event.isCanceled())
            {
                return;
            }
    

     

        public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
        {
        	
            ArrowNockEvent event = new ArrowNockEvent(par3EntityPlayer, par1ItemStack);
            MinecraftForge.EVENT_BUS.post(event);
            if (event.isCanceled())
            {
                return event.result;
            }
    

     

    Judging from the code, I think those two events' function is to determine whether the movement of shooting arrow is normally continuing, if not the arrow will not be shot and action is cancelled.

     

    but the two events' classes are so simple that I don't really understand how the func is done.

     

    Question 1 : When and where are the events "setCancel"ed, and how does Forge EventBus handle this during the player's movement?

    Question 2: How do I do similar task in my Items? Do I need to just simply copy and paste the event code and do "MinecraftForge.EVENT_BUS.register()"?

    Question 3: What can I do with events mainly ?

     

    Thanks a lot for you time of reading this topic and answering ;D

  16. I wonder how does ItemStack's calling function works.

    if two ItemStacks were used and called theirs' item's onItemRightClick() function,etc

    are they calling the exactly same instance of the item?

     

    if I made an Item like this:

     

    public class WeaponWhatever extends Item {
             
            public Boolean isUsed;
    
    public WeaponWhatever(int par1ID) {
    	super(par1ID);
    	setItemName("Whateveer it is");
    	setTextureFile(ClientProxy.ITEMS_TEXTURE_PATH);
    	setIconCoord(0,0);
    
                    isUsed = false;
    }
    
    
    public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
        {
    
                  if(!isUsed)System.out.println("Item hasn't been yet used." );
                  else System.out.println("Item has been used. ");
                  isUsed = true;
                  return par1ItemStack;
        }
    }
    

     

    if I put two of the Item in my inventory,and I right click the first one

    when I right click the second one,will the result be "Item has been used"?

     

    If so , how can I do to make ItemStacks use seperate same processing func with different local variables?

     

    Thanks a lot  ;D

  17. I read the tuotrial in the forge wiki(though it's outdated and only compatitable with 1.3.2) and try exactly as it said

    first I created a class called SoundEvents

    public class CBCSoundEvents {
    
    @ForgeSubscribe
    public void onSound(SoundLoadEvent event)
    {
    
    	System.out.println("but a simple try");
    	File file=new File("/mod/sounds/pin.wav");
    	if(file==null){
    			System.err.println("Fail to load the damn file.>)");
    			return;
    	} 
    	System.out.println(file.getPath());
    	try{
    		SoundPoolEntry snd = event.manager.soundPoolSounds.addSound("abc", file);
    		System.out.println(snd.soundName);
    	}catch(Exception e){
    
    		System.out.println("Sound registering failed.");
    
    	}
    }
    }
    

     

    at @PreInit method of my mod I added this:

    MinecraftForge.EVENT_BUS.register(new CBCSoundEvents());
    

     

    and at my Item's onItemRightClick method I added this:

    par2World.playSoundAtEntity(par3EntityPlayer, "abc", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
    

     

    Clearly it doesn't work.

    The debug console shows "but a simple try" ,which indicates the function has been registered successfully,

    also File loading and path printing works fine

    but when it try to add sound there's an error.

    2013-02-20 19:15:42 [iNFO] [sTDERR] java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at java.lang.String.substring(String.java:1911)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraft.client.audio.SoundPool.addSound(SoundPool.java:63)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraft.client.audio.SoundPool.addSound(SoundPool.java:42)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at cbproject.misc.CBCSoundEvents.onSound(CBCSoundEvents.java:29)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraftforge.event.ASMEventHandler_4_CBCSoundEvents_onSound_SoundLoadEvent.invoke(.dynamic)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraftforge.event.ASMEventHandler.invoke(ASMEventHandler.java:35)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraftforge.event.EventBus.post(EventBus.java:103)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraft.client.audio.SoundManager.loadSoundSettings(SoundManager.java:80)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraft.client.Minecraft.startGame(Minecraft.java:442)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraft.client.MinecraftAppletImpl.startGame(MinecraftAppletImpl.java:44)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at net.minecraft.client.Minecraft.run(Minecraft.java:744)
    2013-02-20 19:15:42 [iNFO] [sTDERR] 	at java.lang.Thread.run(Thread.java:722)
    2013-02-20 19:15:42 [iNFO] [sTDOUT] Sound registering failed.
    

    It says "String out of index" so I think the problem is exactly at here.

    Am I using the wrong methods or doing anything wrong with the EventBus?

    Using event.manager.addSound("abc",ModClass.class.getResource("path")) also won't work

    Help me plz , I really don't know what to do now :'(

×
×
  • Create New...

Important Information

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