Jump to content

Toma™

Members
  • Posts

    80
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Toma™

  1. So in the end I went with the TEISR. However I have some problems now. The item is rendering properly, but I sometimes move the model and it moves it in the GUI and that is another problem because I would like to keep the json item model for the gui. How would I do that? I am not sure, if I should post some code, since it won't propably help. But anyway, there are some bits of the code:

    My baked model:

    Spoiler
    
    public class BakedModelGun implements IBakedModel
    {
    	public BakedModelGun()
    	{
    	}
    	
    	@Override
    	public boolean isBuiltInRenderer()
    	{
    		return true;
    	}
    	
    	@Override
    	public ItemOverrideList getOverrides()
    	{
    		return ItemOverrideList.NONE;
    	}
    	
    	@Override
    	public TextureAtlasSprite getParticleTexture()
    	{
    		TextureMap map = Minecraft.getMinecraft().getTextureMapBlocks();
    		return map.getMissingSprite();
    	}
    	
    	@Override
    	public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
    	{
    		return Collections.EMPTY_LIST;
    	}
    	
    	@Override
    	public boolean isAmbientOcclusion() 
    	{
    		return false;
    	}
    	
    	@Override
    	public boolean isGui3d()
    	{
    		return false;
    	}
    }

     

     

    The teisr class:

    Spoiler
    
    public class WeaponTeisr extends TileEntityItemStackRenderer
    {
    	//model
    	private final ModelP92 p92 = new ModelP92();
    	
    	@Override
    	public void renderByItem(ItemStack stack)
    	{
    		//For every item
    		if(stack.getItem() == PMCItems.FLARE_GUN)
    		{
    			
    		}
    		
    		else if(stack.getItem() == PMCItems.P92)
    		{
    			GlStateManager.pushMatrix();
    			bindTexture("p92");
    			setupDefaultItemTranslationAndRotation();
    			p92.render();
    			GlStateManager.popMatrix();
    		}
    	}
    	
    	private void bindTexture(String name)
    	{
    		ResourceLocation rl = new ResourceLocation(Main.MOD_ID + ":textures/weapons/" + name + ".png");
    		Minecraft.getMinecraft().getTextureManager().bindTexture(rl);
    	}
    	
    	private static void setupDefaultItemTranslationAndRotation()
    	{
    		GlStateManager.scale(0.1, 0.1, 0.1);
    		GlStateManager.translate(6, 6, 3);
    		GlStateManager.rotate(180, 1, 0, 0);
    		GlStateManager.scale(0.8, 0.8, 0.8);
    	}
    }

     

     

    and the bake method:

    Spoiler
    
    	@SubscribeEvent
    	public void bakeModels(ModelBakeEvent e)
    	{
    		ModelResourceLocation location;
    		IBakedModel main;
    		
    		//Weapons
    		for(int i = 0; i < GunBase.GUNS.size(); i++)
    		{
    			GunBase gun = GunBase.GUNS.get(i);
    			location = new ModelResourceLocation(gun.getRegistryName(), "inventory");
    			main = e.getModelRegistry().getObject(location);
    			e.getModelRegistry().putObject(location, new BakedModelGun());
    		}
    	}

     

     

  2. 29 minutes ago, Animefan8888 said:

    It supports multipart models and there is a doc page for it here. And there is more information in the following pages after the intro.

     

    Might be this.

    Okay so based on my quick look into the intro for animations you sent here it looks like I will have to go with the JSON models since they're getting the biggest support by most forge features. I'll propably start making some test models and see how it all goes.

  3. 1 hour ago, V0idWa1k3r said:

    Isn't that mod stuck in 1.7.10? I might be looking at a wrong mod though.

     

    Yes, and that's quite easy.

     

    I am not sure this is possible with IBakedModel without some hacky solutions. 

     

    Why would you scale it up dynamically? There is no reason to do so.

    No, but you can use a custom IBakedModel and have a custom model matrix with IBakedModel#handlePerspective(or just transform the quads on the fly when you need to do so).

     

    However ultimately I am actually leaning for this being a TEISR use case. Please can you provide some more points of functionality for your gun? Are there part-independent animations? Dynamic textures? Custom shaders? Do you need to render the player's hand? How should your gun be transformed? Are there transformation animations? Are they independent for parts? Do you have parts like gun ammunition clips that may not be rendered at points in time? etc.

    In any case a basic JSON is out of the question here unfortunately. The question is - would a custom IBakedModel be sufficient or not.

     

    Well I would like to possibly add more parts like magazines and use them for animation for reloading. I have 3 different magazine atachments so I would need to create the animation for every single of them.

    I don't need dynamic textures, I just need dynamic model rendering based on NBT as explained above.

    I wasn't really thinking about shaders and I think I'll leave that alone.

    Well if it would be possible (and I know it is) I would like to implement some sort of rendering the arm based on the weapons current state (like reloading to move the hand with the clip etc). Also possibly render the hand holding weapons grip when atached. I know this is not easy, but as soon as I start understanding it atleast a bit I should be able to do more stuff.

    I would like to have few animations like reloading and most importantly ADS mode so the shooting can feel more "realistic" rather than just holding your weapon on right side of the screen.

    And yes, I have magazines which as explained above should move when reloading. I don't there's need to not render them at all, even when the weapon is empty it should be rendered.

    I haven't started models yet, since I'm trying to get the best way to do it.

  4. 10 hours ago, Cadiboo said:

    It depends on your use case. If your model doesn’t move, or doesn’t much at all use JSON. If you have something that moves a lot (like a player) use programed models. If you find JSON hard to use, check out http://blockbench.net

    I know about that, but I think I didn't provide enough information on misunderstood you somewhere. So I will repeat everything here:

    1) Using the JSON system will allow me to change the model dynamically based on it's NBT (I have made inventory for ataching atachments to weapons so I would like to render the atachment based on the NBT - so will the JSON model allow me to do that?)

     

    2) I would like to implement something like ADS mode for aiming. With some scope atachments I simply render overlay over player screen, but when weapon doesn't have scope I would like to be able to move the model in front of player view to simulate the ADS (possibly in render tick event using some GL methods, I'm not sure if that is the correct way)

     

    3) Would it be possible to scale the model in something like render tick event (since I will propably have to do model of some size and then scale it up - I know JSON has function for scaling but if I would need to scale it even more would it allow me to use the GL scale method)?

     

    I'm confused with this rendering so thanks everybody for helping me

  5. 7 minutes ago, Cadiboo said:

    I’d say use JSON so resource packs can change your models. How is it harder to use JSON than model base? It seems like it would be a lot easier to me

    Well I'm bit confused with the JSON system, specially with rendering another models into it. For the model base renderer it looks a little easier (i was looking into some of the flans mod model code). I know there is system similar to blockstate system which is used for the bow, but I'm bit confused with it's usage. Because bow has like 3 states and every state has it's texture. So if I have 5 atachment types + some variants for each of them would I have to write every single combination for the item state or is there easier way? I still have feeling modelbase would be easier, but I'm not really experienced.

  6. I have been thinking about few things recently and I would like to know something before I start working. Using IBakedModel for rendering will still allow me to do dynamic rendering (like rendering additional models on my base model based on NBT) and other stuff like animations? Also is using ModelBase bad idea, since I don't really like just scaling the .json model because I think I will want more details and it might be a lot of work to make it properly in smaller scale. So I'm just making sure I don't need the TEISR.

  7. 3 minutes ago, V0idWa1k3r said:

    So far you have not explained what you need a TEISR for. Please elaborate, the functionality you want might be acheivable with basic json.

     

    I want to create weapon with better details so default scale function is not enough for me. Also I was looking when vanilla uses the TEISR and that's for the shield based on it's NBT. I want to do something like that (render atachments on the weapon based on NBT). I have the NBT working, I'm just looking for the rendering. From what I have found the .json is limited to 3x3 block size and becausd of that I think I'll need to use ModelBase

  8. I have few questions about ModelBase rendering (I'm looking for few hints to point me to right direction):

    1. How to tell the game to register the model (from my research there was method in ForgeClient class to register item renderer, but now I can't find it)

     

    2. Based on Forge docs there is TEISR which I have atached to the items I want to on client side. Now I need baked model to use the isBuiltInRenderer method. So from my understanding I would need 3 classes for each item (base class, renderer and model), I guess.

     

    I would like to use the ModelBase models since the .json is limited in the size so then I think I can't use the item blockstates.

  9. 21 hours ago, diesieben07 said:

    Okay I have reworked it a bit (based on the forge example). Is it good now?

    The code:

    Spoiler
    
    package com.toma.pubgmc.common.network.server;
    
    import com.toma.pubgmc.common.items.guns.GunBase;
    
    import io.netty.buffer.ByteBuf;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.item.ItemStack;
    import net.minecraft.server.MinecraftServer;
    import net.minecraft.util.CooldownTracker;
    import net.minecraft.world.World;
    import net.minecraftforge.fml.common.FMLCommonHandler;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
    import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
    
    public class PacketShoot implements IMessage, IMessageHandler<PacketShoot, IMessage>
    {
    	@Override
    	public void toBytes(ByteBuf buf) {
    		// TODO Auto-generated method stub
    		
    	}
    	
    	@Override
    	public void fromBytes(ByteBuf buf) {
    		// TODO Auto-generated method stub
    		
    	}
    	
    	@Override
    	public IMessage onMessage(PacketShoot message, MessageContext ctx)
    	{
    		World world = ctx.getServerHandler().player.world;
    		EntityPlayer player = ctx.getServerHandler().player;
    		ItemStack stack = player.getHeldItemMainhand();
    		if(stack.getItem() instanceof GunBase)
    		{
    			GunBase gun = (GunBase)stack.getItem();
    			CooldownTracker tracker = player.getCooldownTracker();
    			
    			if(stack.getItemDamage() < stack.getMaxDamage())
    			{
    				MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
    				
    				server.addScheduledTask(() ->
    				{	
    					if(!tracker.hasCooldown(gun))
    					{
    						gun.shoot(world, player, stack);
    						tracker.setCooldown(gun, gun.getFireRate());
    					}
    				});
    			}
    		}
    		return null;
    	}
    }

     

    It seems to be working, but I'm not sure, but thank you both for your help

  10. My minecraft does "randomly" crash when I start shooting with one weapon with small firerate, however this happens quite randomly and sometimes it's working fine for a long time and then suddenly crash. 

    So there's some of the code:

    BulletEntity

    GunCode

    Shooting code for Single firemode

    Shooting code for Automatic firemode

     

    Entity is registered in my main class under FMLInit event using the registerModEntityMethod (I also tried to play a bit with the tracking range and update frequency since the crash was saying something about it)

    Crash report:

    Spoiler
    
    ---- Minecraft Crash Report ----
    // I'm sorry, Dave.
    
    Time: 11/15/18 1:51 PM
    Description: Exception in server tick loop
    
    java.util.ConcurrentModificationException
    	at java.util.HashMap$HashIterator.nextNode(Unknown Source)
    	at java.util.HashMap$KeyIterator.next(Unknown Source)
    	at net.minecraft.entity.EntityTracker.tick(EntityTracker.java:295)
    	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:854)
    	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:743)
    	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
    	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:592)
    	at java.lang.Thread.run(Unknown Source)
    
    
    A detailed walkthrough of the error, its code path and all known details is as follows:
    ---------------------------------------------------------------------------------------
    
    -- System Details --
    Details:
    	Minecraft Version: 1.12.2
    	Operating System: Windows 10 (amd64) version 10.0
    	Java Version: 1.8.0_172, Oracle Corporation
    	Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
    	Memory: 780420984 bytes (744 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
    	JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
    	IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
    	FML: MCP 9.42 Powered by Forge 14.23.5.2768 5 mods loaded, 5 mods active
    	States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
    
    	| State     | ID        | Version      | Source                           | Signature |
    	|:--------- |:--------- |:------------ |:-------------------------------- |:--------- |
    	| UCHIJAAAA | minecraft | 1.12.2       | minecraft.jar                    | None      |
    	| UCHIJAAAA | mcp       | 9.42         | minecraft.jar                    | None      |
    	| UCHIJAAAA | FML       | 8.0.99.99    | forgeSrc-1.12.2-14.23.5.2768.jar | None      |
    	| UCHIJAAAA | forge     | 14.23.5.2768 | forgeSrc-1.12.2-14.23.5.2768.jar | None      |
    	| UCHIJAAAA | pubgmc    | 2.2.2        | bin                              | None      |
    
    	Loaded coremods (and transformers): 
    	GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread.
    	Profiler Position: N/A (disabled)
    	Player Count: 1 / 8; [EntityPlayerMP['Player789'/137, l='New World', x=250.34, y=7.66, z=-292.53]]
    	Type: Integrated Server (map_client.txt)
    	Is Modded: Definitely; Client brand changed to 'fml,forge'

     

    I hope I didn't mess some basic stuff again somewhere 

  11. Okay, since I haven't seen anywhere exact solution for this I will write my solution I have found here just in case someone has the same problem.

    OnUsingTick as it has been explained above and in the other threads is quite bad for doing this NBT related stuff, but you can subscribe to the ClientTickEvent and detect from here using the Minecraft GameSettings if your key (keyBindingAttack/UseItem - for different mouse buttons) is being held and run the code from here. But keep in mind you will have to sync some stuff with server in order to work properly.

    I'm not saying that this is how it should be done, this is just how it works fine for me. 

    • Like 1
  12. Ok, I have been thinking about this and I think the easiest way to render my overlay as close as possible to the default HUD would be to calculate the position based on MC pos. I would need to find the class where minecraft does that. Tbh I didn't do much research about it, but I think the rendering code will be maybe hardcoded in some class with a lot of code so my question is:

    Do you know where minecraft does the HUD rendering code? If so, what's the class name?

  13. Hello I have created some overlays which I would like to have fixed in some x and y coords. I tried it with ScaledResolution but since your minecraft window resolution may change when you switch to fullscreen etc, the overlay is offset a bit. I think there's something simple I have missed, so I am asking for help. Is there some way to lock my overlay to hotbar for example?

    There is what I have tried so far:

    Rendering

    Spoiler
    
        @SubscribeEvent
        public void renderOverlays(RenderGameOverlayEvent.Pre e)
        {
        	Minecraft mc = Minecraft.getMinecraft();
        	EntityPlayerSP sp = mc.player;
        	ScaledResolution res = new ScaledResolution(mc);
        	
        	if(e.getType() == ElementType.EXPERIENCE)
        	{
        		e.setCanceled(true);
        	}
        	
        	if(e.getType() == ElementType.ALL && sp.hasCapability(PlayerDataProvider.PLAYER_DATA, null))
        	{
        		IPlayerData data = sp.getCapability(PlayerDataProvider.PLAYER_DATA, null);
        		
        		renderCustomSizedOverlay(res.getScaledWidth() / 4 + 16, res.getScaledHeight() - 29, res.getScaledWidth() / 4 + 16 + 182, res.getScaledHeight() - 24, BOOST, true);
        		if(data.getBoost() > 0)
        		{
        			double startX = res.getScaledWidth_double() / 4 + 16;
        			int boost = (int)data.getBoost();
        			double sizeX = ((182D / 100D) * boost);
        			renderCustomSizedOverlay(res.getScaledWidth() / 4 + 16, res.getScaledHeight() - 29, startX + sizeX, res.getScaledHeight() - 24, BOOST_FULL, true);
        		}
        	}
        }

     

     

    Method which is doing all the position stuff

    Spoiler
    
        private void renderCustomSizedOverlay(int x, int y, double x2, double y2, ResourceLocation location, boolean transparent)
        {
        	Minecraft mc = Minecraft.getMinecraft();
        	Tessellator tes = Tessellator.getInstance();
        	BufferBuilder buffer = tes.getBuffer();
        	
        	mc.getTextureManager().bindTexture(location);
        	buffer.begin(7, DefaultVertexFormats.POSITION_TEX);
        	buffer.pos(x, y2, 0).tex(0, 1).endVertex();
        	buffer.pos(x2, y2, 0).tex(1, 1).endVertex();
        	buffer.pos(x2, y, 0).tex(1, 0).endVertex();
        	buffer.pos(x, y, 0).tex(0, 0).endVertex();
        	
        	if(transparent)
        	{
            	GlStateManager.pushMatrix();
            	{
            		GlStateManager.enableAlpha();
            		GlStateManager.enableBlend();
            		GlStateManager.enableDepth();
            		
            		tes.draw();
            		
            		GlStateManager.disableAlpha();
            		GlStateManager.disableBlend();
            		GlStateManager.disableDepth();
            	}
            	GlStateManager.popMatrix();
        	}
        	
        	else
        	{
        		tes.draw();
        	}
        }

     

     

    Only problem I have with this is the offset in fullscreen

  14. 2 minutes ago, diesieben07 said:

    This will crash on a dedicated server. Code that is specific to a physical side (client in this case) must be encapsulated using @SidedProxy.

     

    Problematic code, Issue 16.

    Oh well, I didn't know that. For some reason I thought that the ctx.side.isClient will prevent that

     

    4 minutes ago, diesieben07 said:

    PlayerEvent.Clone is not the right event to send packets or set any data. It's sole purpose is to copy data from the player entity that died to the new player entity. Do not use it for anything else. If you want to do something on respawn, use PlayerEvent.PlayerRespawnEvent.

    But this still has to be used to copy the data when player switches dimensions, am I right?

  15. Okay, it's me again with another problem. I implemented my custom capability and attached it to player, but every time the player respawns, it should write some data into capability, however it doesn't work. I made custom overlay rendering which should display the data, but on respawn I see the data set to the value I want and next tick the data is gone. I managed to make the data persist after player disconnects so my syncing packet should be okay. The only problem I have is the respawn event. I subscribed to PlayerEvent.Clone (on server, since I think it is supposed to be handled from server, but I'm not sure about that) and registered it in server proxy.

    There's the related code:

    Spoiler
    
    	@SubscribeEvent
    	public void onPlayerClone(PlayerEvent.Clone e)
    	{
    		if(e.isWasDeath())
    		{
    			IPlayerData data = e.getEntityPlayer().getCapability(PlayerDataProvider.PLAYER_DATA, null);
    			data.setThirst(20f);
    			data.setBloodLevel(100f);
    			data.setInfectionLevel(0);
    			data.setBleeding(false);
    			
    			PacketSPSyncPlayerData packet = new PacketSPSyncPlayerData();
    			packet.setThirst(data.getThirst());
    			packet.setBlood(data.getBloodLevel());
    			packet.setInfection(data.getInfectionLevel());
    			packet.setBleeding(data.isBleeding());
    			PacketHandler.INSTANCE.sendTo(packet, (EntityPlayerMP)e.getEntityPlayer());
    		}
    	}

     

     

    and the packet just in case: (it is registered for client side)

    Spoiler
    
    public class PacketSPSyncPlayerData implements IMessage, IMessageHandler<PacketSPSyncPlayerData, IMessage>
    {
    	private float thirst;
    	private float blood;
    	private int infection;
    	private boolean bleeding;
    	
    	@Override
    	public void toBytes(ByteBuf buf)
    	{
    		buf.writeFloat(this.thirst);
    		buf.writeFloat(this.blood);
    		buf.writeInt(this.infection);
    		buf.writeBoolean(this.bleeding);
    	}
    	
    	@Override
    	public void fromBytes(ByteBuf buf) 
    	{
    		thirst = buf.readFloat();
    		blood = buf.readFloat();
    		infection = buf.readInt();
    		bleeding = buf.readBoolean();
    	}
    	
    	@Override
    	public IMessage onMessage(PacketSPSyncPlayerData message, MessageContext ctx)
    	{
    		if(ctx.side.isClient())
    		{
    			EntityPlayerSP player = Minecraft.getMinecraft().player;
    			if(player != null)
    			{
    				if(player.getCapability(PlayerDataProvider.PLAYER_DATA, null) != null)
    				{
    					IPlayerData data = player.getCapability(PlayerDataProvider.PLAYER_DATA, null);
    					data.setThirst(message.thirst);
    					data.setBloodLevel(message.blood);
    					data.setInfectionLevel(message.infection);
    					data.setBleeding(message.bleeding);
    				}
    			}
    		}
    		return null;
    	}
    	
    	public float setThirst(float thirst)
    	{
    		return this.thirst = thirst;
    	}
    	
    	public float getThirst()
    	{
    		return this.thirst;
    	}
    	
    	public void setBlood(float blood)
    	{
    		this.blood = blood;
    	}
    	
    	public float getBlood()
    	{
    		return blood;
    	}
    	
    	public void setInfection(int infection)
    	{
    		this.infection = infection;
    	}
    	
    	public int getInfection()
    	{
    		return infection;
    	}
    	
    	public void setBleeding(boolean bleeding) 
    	{
    		this.bleeding = bleeding;
    	}
    	
    	public boolean isBleeding()
    	{
    		return bleeding;
    	}

     

    What am I doing wrong here?

  16. Okay so I have reworked it a bit the teisr is now at the item, however nothing is rendering except my normal item model.

    I'm pretty sure that is because the ItemOverrideList is empty. I created my own model class which extends the Shield model and implements the baked model. I'm new to all this stuff so I might be making some terrible mistake somewhere... 

     

    So there's the updated code:

    The item class:

    Spoiler
    
    public class PistolP92 extends GunBase
    {	
    	public PistolP92(String name)
    	{
    		super(name);
    		this.setMaxStackSize(1);
    		this.setCreativeTab(Main.pmcgunstab);
    		
    		this.setDamage(ConfigHandler.p92);
    		this.setVelocity(7);
    		this.setGravityModifier(0.015);
    		this.setGravityStartTime(5);
    		this.setFireRate(6);
    		this.setMaxAmmo(15);
    		this.setReloadTime(50);
    		this.canSwitchMode(false);
    		this.setVerticalRecoil(2.0f);
    		this.setHorizontalRecoil(0.5f);
    		
    		this.setAmmoType(AmmoType.AMMO9MM);
    		this.setFiremode(Firemode.SINGLE);
    		this.setReloadType(ReloadType.MAGAZINE);
    		this.setGunType(GunType.PISTOL);
    		
    		this.setGunSound(PMCSounds.gun_p92);
    		this.setGunSoundVolume(5f);
    		this.setGunSilencedSound(PMCSounds.gun_p92_silenced);
    		this.setGunSilencedSoundVolume(getGunVolume() * 0.4f);
    		
    		this.setMaxDamage(this.getMaxAmmo());
    		
    		this.setTileEntityItemStackRenderer(new WeaponTeisr());
    	}
    	
    	public class WeaponTeisr extends TileEntityItemStackRenderer
    	{
    	    private final ModelP92 model = new ModelP92();
    		
    		@Override
    		public void renderByItem(ItemStack itemStackIn)
    		{
    			if(itemStackIn.getItem() == PMCItems.P92)
    			{
    				this.model.render();
    			}
    		}
    	}
    }

     

     

    The model class:

    Spoiler
    
    package com.toma.pubgmc.render.model;
    
    import java.util.Collections;
    import java.util.List;
    
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.client.Minecraft;
    import net.minecraft.client.model.ModelShield;
    import net.minecraft.client.renderer.block.model.BakedQuad;
    import net.minecraft.client.renderer.block.model.IBakedModel;
    import net.minecraft.client.renderer.block.model.ItemOverrideList;
    import net.minecraft.client.renderer.texture.TextureAtlasSprite;
    import net.minecraft.client.renderer.texture.TextureMap;
    import net.minecraft.util.EnumFacing;
    
    public class ModelP92 extends ModelShield implements IBakedModel
    {
    	@Override
    	public ItemOverrideList getOverrides() 
    	{
    		return ItemOverrideList.NONE;
    	}
    	
    	@Override
    	public TextureAtlasSprite getParticleTexture()
    	{
    		TextureMap map = Minecraft.getMinecraft().getTextureMapBlocks();
    		return map.getMissingSprite();
    	}
    	
    	@Override
    	public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
    	{
    		return Collections.EMPTY_LIST;
    	}
    	
    	@Override
    	public boolean isAmbientOcclusion()
    	{
    		// TODO Auto-generated method stub
    		return false;
    	}
    	
    	@Override
    	public boolean isBuiltInRenderer()
    	{
    		// TODO Auto-generated method stub
    		return true;
    	}
    	
    	@Override
    	public boolean isGui3d() {
    		// TODO Auto-generated method stub
    		return false;
    	}
    	
    	
    }

     

     

     

    And also you wanted the registry code (I don't know if I need to rewrite it, but most likely I will have to since a lot of the code is old and I was following some registry tutorials for this)

    Spoiler
    
    @EventBusSubscriber
    public class RegistryHandler
    {
    	
    	@SubscribeEvent
    	public static void onItemRegister(RegistryEvent.Register<Item> event)
    	{
    		event.getRegistry().registerAll(PMCItems.ITEMS.toArray(new Item[0]));
    	}
    	
    	@SubscribeEvent
    	public static void onBlockRegister(RegistryEvent.Register<Block> event)
    	{
    		event.getRegistry().registerAll(PMCBlocks.BLOCKS.toArray(new Block[0]));
    	}
    	
    	@SubscribeEvent
    	public static void onModelRegister(ModelRegistryEvent event)
    	{
    		for(Item item : PMCItems.ITEMS)
    		{
    			if(item instanceof IModItem)
    			{
    				((IModItem)item).registerModels();
    			}
    		}
    		
    		for(Block block : PMCBlocks.BLOCKS)
    		{
    			if(block instanceof IModItem)
    			{
    				((IModItem)block).registerModels();
    			}
    		}
    		
    	}
    	
    	public static void serverRegistries(FMLServerStartingEvent event)
    	{
    		event.registerServerCommand(new Leavecmd());
    		event.registerServerCommand(new GenerateLootcmd());
    		event.registerServerCommand(new CommandClearPlayerCrates());
    	}
    }

     

     

  17. I want to use the TileEntityItemStackRenderer for my weapons to use java models etc so I decided to go through the Forge docs. I'm confused a bit by it because I tried to follow it but I can't understand few things:

     

    1) Is my implementation correct? (Atleast a bit?)

    2) Do I need to implement the baked model on the item as I do or different way?

    3) From my understanding I don't need anything else than setTileEntityItemStackRenderer, isBuiltinRenderer and getOverrides methods?

     

    There is what I have tried for now:

    Spoiler
    
    public class PistolP92 extends GunBase implements IBakedModel
    {	
    	public PistolP92(String name)
    	{
    		super(name);
    		this.setMaxStackSize(1);
    		this.setCreativeTab(Main.pmcgunstab);
    		
    		this.setDamage(ConfigHandler.p92);
    		this.setVelocity(7);
    		this.setGravityModifier(0.015);
    		this.setGravityStartTime(5);
    		this.setFireRate(6);
    		this.setMaxAmmo(15);
    		this.setReloadTime(50);
    		this.canSwitchMode(false);
    		this.setVerticalRecoil(2.0f);
    		this.setHorizontalRecoil(0.5f);
    		
    		this.setAmmoType(AmmoType.AMMO9MM);
    		this.setFiremode(Firemode.SINGLE);
    		this.setReloadType(ReloadType.MAGAZINE);
    		this.setGunType(GunType.PISTOL);
    		
    		this.setGunSound(PMCSounds.gun_p92);
    		this.setGunSoundVolume(5f);
    		this.setGunSilencedSound(PMCSounds.gun_p92_silenced);
    		this.setGunSilencedSoundVolume(getGunVolume() * 0.4f);
    		
    		this.setMaxDamage(this.getMaxAmmo());
    	}
    	//=============================
    	
    	@Override
    	public boolean isBuiltInRenderer()
    	{
    		return true;
    	}
    
    	//This is propably problem
    	@Override
    	public ItemOverrideList getOverrides()
    	{
    		return null;
    	}
    	
    	@Override
    	public TextureAtlasSprite getParticleTexture()
    	{
    		return null;
    	}
    	
    	@Override
    	public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
    	{
    		return null;
    	}
    	
    	@Override
    	public boolean isAmbientOcclusion()
    	{
    		return false;
    	}
    	
    	@Override
    	public boolean isGui3d()
    	{
    		return false;
    	}
    	
    	//==============================
    	
    	@Override
    	public void setTileEntityItemStackRenderer(TileEntityItemStackRenderer teisr)
    	{
    		teisr = new WeaponTeisr();
    	}
    	
    	public class WeaponTeisr extends TileEntityItemStackRenderer
    	{
    	    private final ModelShield modelShield = new ModelShield();
    		
    		@Override
    		public void renderByItem(ItemStack itemStackIn, float ticks)
    		{
    			if(itemStackIn.getItem() == PMCItems.P92)
    			{
    				this.modelShield.render();
    			}
    		}
    	}
    }

     

     

    Also I decided to use the vanilla shield model for it now since I don't have the model yet. The TEISR class is copied from vanilla.

    The code doesn't crash or anything like that, it doesn't do anything at all. Maybe that's because the ItemOverrideList is null. 

  18. Hello, I have tried creating guns with different firemodes, but I have noticed some problems:

    1) For Single firemode I have to right click the weapon twice for it to shoot (So far it looks like problem with maxItemUseDuration + onUsingTick methods)

    2) For Auto firemode as soon as I start shooting I can't stop it until I switch the items in hands

     

    The code for the methods is here: (Also it might be a bit messy since I was trying to quickly fix it)

    Spoiler
    
    	@Override
    	public void onUsingTick(ItemStack stack, EntityLivingBase entity, int count)
    	{
    		if(ConfigHandler.enableGuns)
    		{
    			EntityPlayer player = (EntityPlayer)entity;
    			
    			if(this.getFiremode() == Firemode.AUTO && stack.getItemDamage() < stack.getMaxDamage() || player.capabilities.isCreativeMode)
    			{
    				CooldownTracker tracker = player.getCooldownTracker();
    				
    				if(!tracker.hasCooldown(stack.getItem()))
    				{
    					tracker.setCooldown(stack.getItem(), getFireRate());
    					shoot(player.world, player, stack);
    				}
    			}
    			
    			else
    			{
    				return;
    			}
    		}
    	}
    	
    	@Override
    	public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
    	{
    		ItemStack stack = playerIn.getHeldItem(handIn);
    		
    		if(ConfigHandler.enableGuns)
    		{
    			if(!playerIn.getDataManager().get(ServerSideEvents.RELOADING))
    			{	
    				if(hasAmmo(playerIn, stack) || playerIn.capabilities.isCreativeMode)
    				{	
    					CooldownTracker tracker = playerIn.getCooldownTracker();
    					if(playerIn.isHandActive())
    					{
    						return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    					}
    					if(!tracker.hasCooldown(stack.getItem()))
    					{
    						playerIn.setActiveHand(handIn);
    						tracker.setCooldown(stack.getItem(), getFireRate());
    						shoot(worldIn, playerIn, stack);
    						return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    					}
    				}
    				else
    				{
    					worldIn.playSound(playerIn, playerIn.posX, playerIn.posY, playerIn.posZ, SoundEvents.BLOCK_DISPENSER_FAIL, SoundCategory.BLOCKS, 2.0f, 0.0f);
    				}
    			}
    			
    			else
    			{
    				if(hasAmmo(playerIn, stack))
    				{
    					if(playerIn.isHandActive())
    					{
    						return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    					}
    					
    					playerIn.getDataManager().set(ServerSideEvents.RELOADING, false);
    					PacketHandler.INSTANCE.sendToServer(new PacketReload(false));
    				}
    			}
    		}
    		
    		else
    		{
    			if(!worldIn.isRemote)
    			{
    				playerIn.sendMessage(new TextComponentString(TextFormatting.RED + "Weapons are disabled! You have to enable them in pubgmc.cfg in your minecraft config folder!"));
    			}
    		}
    		
    		return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    	}

     

    Max item use duration is set to 7200

     

    The rest of the class is here just in case:

    Spoiler
    
    	public enum Firemode
    	{
    		SINGLE, BURST, AUTO;
    	}
    	
    	public enum ReloadType
    	{
    		MAGAZINE, SINGLE, KAR98K;
    	}
    	
    	public enum GunType
    	{
    		PISTOL, SHOTGUN, SMG, AR, LMG, DMR, SR;
    	}
    	
    /** ====================================================================[Basic gun functions]================================================================================== **/
    	
    	@Override
    	public int getMaxItemUseDuration(ItemStack stack)
    	{
    		return 7200;
    	}
    	
    	@Override
    	public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack)
    	{
    		EntityPlayer player = (EntityPlayer)entityLiving;
    		if(player.world.isRemote)
    		{
    			if(!player.getDataManager().get(ServerSideEvents.AIMING) && !player.getDataManager().get(ServerSideEvents.RELOADING))
    			{
    				player.getDataManager().set(ServerSideEvents.AIMING, true);
    				PacketHandler.INSTANCE.sendToServer(new PacketAim(true));
    			}
    			
    			else
    			{
    				player.getDataManager().set(ServerSideEvents.AIMING, false);
    				PacketHandler.INSTANCE.sendToServer(new PacketAim(false));
    			}
    		}
    		return true;
    	}
    	
    	@Override
    	public void onUsingTick(ItemStack stack, EntityLivingBase entity, int count)
    	{
    		if(ConfigHandler.enableGuns)
    		{
    			EntityPlayer player = (EntityPlayer)entity;
    			
    			if(this.getFiremode() == Firemode.AUTO && stack.getItemDamage() < stack.getMaxDamage() || player.capabilities.isCreativeMode)
    			{
    				CooldownTracker tracker = player.getCooldownTracker();
    				
    				if(!tracker.hasCooldown(stack.getItem()))
    				{
    					tracker.setCooldown(stack.getItem(), getFireRate());
    					shoot(player.world, player, stack);
    				}
    			}
    			
    			else
    			{
    				return;
    			}
    		}
    	}
    	
    	@Override
    	public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
    	{
    		ItemStack stack = playerIn.getHeldItem(handIn);
    		
    		if(ConfigHandler.enableGuns)
    		{
    			if(!playerIn.getDataManager().get(ServerSideEvents.RELOADING))
    			{	
    				if(hasAmmo(playerIn, stack) || playerIn.capabilities.isCreativeMode)
    				{	
    					CooldownTracker tracker = playerIn.getCooldownTracker();
    					if(playerIn.isHandActive())
    					{
    						return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    					}
    					if(!tracker.hasCooldown(stack.getItem()))
    					{
    						playerIn.setActiveHand(handIn);
    						tracker.setCooldown(stack.getItem(), getFireRate());
    						shoot(worldIn, playerIn, stack);
    						return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    					}
    				}
    				else
    				{
    					worldIn.playSound(playerIn, playerIn.posX, playerIn.posY, playerIn.posZ, SoundEvents.BLOCK_DISPENSER_FAIL, SoundCategory.BLOCKS, 2.0f, 0.0f);
    				}
    			}
    			
    			else
    			{
    				if(hasAmmo(playerIn, stack))
    				{
    					if(playerIn.isHandActive())
    					{
    						return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    					}
    					
    					playerIn.getDataManager().set(ServerSideEvents.RELOADING, false);
    					PacketHandler.INSTANCE.sendToServer(new PacketReload(false));
    				}
    			}
    		}
    		
    		else
    		{
    			if(!worldIn.isRemote)
    			{
    				playerIn.sendMessage(new TextComponentString(TextFormatting.RED + "Weapons are disabled! You have to enable them in pubgmc.cfg in your minecraft config folder!"));
    			}
    		}
    		
    		return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
    	}
    	
    	/**
    	 * Used to spawn bullet entity
    	 * 
    	 * @param world
    	 * @param player
    	 * @param stack
    	 */
    	public void shoot(World world, EntityPlayer player, ItemStack stack)
    	{
            if(this.hasAmmo(player, stack) || player.capabilities.isCreativeMode && !player.getDataManager().get(ServerSideEvents.RELOADING))
            {
            	if(!world.isRemote)
            	{
                    EntityBullet bullet = new EntityBullet(world, player, this);
                    world.spawnEntity(bullet);
                    if(!player.capabilities.isCreativeMode)
                    {
                        stack.damageItem(1, player);
                    }
            	}
            	
            	applyRecoil(player);
                world.playSound(player.posX, player.posY, player.posZ, SoundEvents.ENTITY_GHAST_SHOOT, SoundCategory.HOSTILE, 50.0f, 0.0f, true);
            }
            	
            if(stack.getItemDamage() == maxAmmo && !player.getDataManager().get(ServerSideEvents.RELOADING) && !player.capabilities.isCreativeMode)
            {	
            	if(world.isRemote)
            	{
            		
            	}
            }
    	}
    	
    	/**
    	 * Call only client side!
    	 * @param gun
    	 * @param playerIn
    	 */
    	public void applyRecoil(EntityPlayer playerIn)
    	{
    		Random rand = new Random();
    		//check server side TODO
    		//Set horizontal recoil based on if player is sneaking or not
    		if(playerIn.isSneaking())
    		{
    			playerIn.rotationPitch = playerIn.rotationPitch - ((getVerticalRecoil() * (float)rand.nextDouble() * 1.5f) * 0.9f);
    		}
    		else
    		{
    			playerIn.rotationPitch = playerIn.rotationPitch - (getVerticalRecoil() * (float)rand.nextDouble() * 1.5f);
    		}
    		
    		//set horizontal recoil (50% to go right and 50% to go left)
    		if(Math.random() * 100 <= 50)
    		{
    			playerIn.rotationYaw = playerIn.rotationYaw - (getHorizontalRecoil() * (float)rand.nextDouble() * 1.5f);
    		}
    		
    		else
    		{
    			playerIn.rotationYaw = playerIn.rotationYaw + (getHorizontalRecoil() * (float)rand.nextDouble() * 1.5f);
    		}
    	}
    	
    	@Override
    	public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) 
    	{
    		return false;
    	}
    	
    	public Firemode getNextFiremode(EntityPlayer player)
    	{
    		switch(this.getFiremode())
    		{
    			case SINGLE: 
    			{
    				if(canGunBurstFire())
    				{
    					return setFiremode(Firemode.BURST);
    				}
    				
    				else
    				{
    					return setFiremode(Firemode.AUTO);
    				}
    			}
    			
    			case BURST:
    			{
    				if(canGunAutofire())
    				{
    					return setFiremode(Firemode.AUTO);
    				}
    				
    				else
    				{
    					return setFiremode(Firemode.SINGLE);
    				}
    			}
    			
    			case AUTO: return setFiremode(Firemode.SINGLE);
    		}
    		PacketHandler.INSTANCE.sendToServer(new PacketFiremode(firemode));
    		return firemode;
    	}
    	
    	public boolean hasAmmo(EntityPlayer player, ItemStack itemStack)
    	{
    		return itemStack.getItemDamage() < maxAmmo;
    	}
    	
    	public String descAmmoType()
    	{
    		switch(this.getAmmoType())
    		{
    			case AMMO9MM: return I18n.format("ammo.9mm");
    			case AMMO12G: return I18n.format("ammo.12g");
    			case AMMO45ACP: return I18n.format("ammo.45acp");
    			case AMMO556: return I18n.format("ammo.556mm");
    			case AMMO762: return I18n.format("ammo.762mm");
    			case AMMO100M: return I18n.format("ammo.100m");
    			case FLARE: return I18n.format("ammo.flare");
    			default: return "Unknown ammo";
    		}
    	}
    	
    	public String getFiremodeTranslation()
    	{
    		switch(this.getFiremode())
    		{
    			case SINGLE: return I18n.format("gun.firemode.single");
    			case BURST: return I18n.format("gun.firemode.burst");
    			case AUTO: return I18n.format("gun.firemode.auto");
    			default: return "";
    		}
    	}
    	
    	@Override
    	public void addInformation(ItemStack stack, World worldIn, List<String> tooltip, ITooltipFlag flagIn) 
    	{
    		ammo = maxAmmo - stack.getItemDamage();
    		
    		tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.ammo") + ": " + TextFormatting.RESET + "" + TextFormatting.RED + this.ammo);
    		tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.firemode") + ": " + TextFormatting.RESET + "" + TextFormatting.GRAY + getFiremodeTranslation());
    		
    		if(GuiScreen.isShiftKeyDown())
    		{
    			DecimalFormat f = new DecimalFormat("###.##");
    			DecimalFormat g = new DecimalFormat("###.###");
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.damage") + ": " + TextFormatting.RESET + "" + TextFormatting.DARK_RED + this.getDamage());
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.reloadtime") + ": " + TextFormatting.RESET + "" + TextFormatting.GREEN + reloadTime / 20 + " " + I18n.format("gun.reloadtime.info"));
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.velocity") + ": " + TextFormatting.RESET + "" + TextFormatting.BLUE + f.format(velocity * 5.5) + " " + I18n.format("gun.velocity.info"));
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.gravity") + ": " + TextFormatting.RESET + "" + TextFormatting.BLUE + f.format(gravity * 20) + " " + I18n.format("gun.gravity.info"));
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.firerate") + ": " + TextFormatting.RESET + "" + TextFormatting.AQUA + g.format(20.00 / this.getFireRate()) + " " + I18n.format("gun.firerate.info"));
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.ammotype") + ": " + TextFormatting.BLUE + descAmmoType());
    			tooltip.add(TextFormatting.BOLD + I18n.format("gun.desc.maxammo") + ": " + TextFormatting.RESET + "" + TextFormatting.RED + maxAmmo);
    		}
    		
    		else tooltip.add(TextFormatting.YELLOW + I18n.format("gun.desc.moreinfo"));
    	}
    	
    /*	For attachments
    	@Override
    	public NBTTagCompound serializeNBT() 
    	{
    		NBTTagCompound c = new NBTTagCompound();
    		return c;
    	}
    	
    	@Override
    	public void deserializeNBT(NBTTagCompound nbt)
    	{
    		
    	}
    */
    }

    The rest are just setters and getters

     

     

    I have also noticed that the onUsingTick method is sometimes called more than once on each side, so that might be a problem too

    I've tried looking into ItemBow class, but that didn't tell me much since it's using only onStoppedUsing method

  19. 36 minutes ago, V0idWa1k3r said:

    I am able to launch your mod in a normal(non-dev) environment. There were a few compile errors I had to correct though and one of your classes was referencing the upper-case package.

    Use github integration instead of uploading files manually. Or at least the command line git client.

     

    Alright, I'll try to change some stuff you suggested me above and build the mod and try it. Thanks for your time and help

×
×
  • Create New...

Important Information

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