Jump to content

Trying to make a gun; Bullet works, but model doesn't render properly[1.7.10]


Recommended Posts

Posted

Hello! This is my first post on the MC Forge forums. I am trying to make a mod. Part of that mod requires a gun. I have made a working gun that fires actual bullets. However, the bullets' model does not accurately display the bullet's position and pitch. Here are all the issues:

1. The bullet model's spawn position varies depending on the pitch that it is fired at. When I fire it downward, the bullet model spawns on my left, when when I fire it upward, the model spawns on my right. The y-position of the model is always in it's proper place.

2. The bullet model has no pitch. It is always is horizontal.

 

Those are the only issues that I do not know how to solve (so only try to address those). Here is the code:

 

EntityStdBullet.class (the entity itself):

 

 

package tutorial.alex.Entity;

 

import net.minecraft.entity.EntityLivingBase;

import net.minecraft.entity.monster.EntityBlaze;

import net.minecraft.entity.projectile.EntityThrowable;

import net.minecraft.util.DamageSource;

import net.minecraft.util.MovingObjectPosition;

import net.minecraft.world.World;

 

public class EntityStdBullet extends EntityThrowable{

 

public EntityStdBullet(World par1World) {

super(par1World);

}

public EntityStdBullet(World par1World, EntityLivingBase par2EntityLivingBase){

        super(par1World, par2EntityLivingBase);

    }

public EntityStdBullet(World par1World, double par2, double par4, double par6){

        super(par1World, par2, par4, par6);

    }

 

@Override

protected void onImpact(MovingObjectPosition pos) {

if (pos.entityHit != null)

        {

            pos.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 2.5f);

        }

 

        for (int i = 0; i < 8; ++i)

        {

            this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);

        }

 

        if (!this.worldObj.isRemote)

        {

            this.setDead();

        }

 

}

@Override

protected float getGravityVelocity()

{

return 0.0f;

}

 

}

 

RenderStdBullet (the Renderer):

 

 

package tutorial.alex.Render;

 

import org.lwjgl.opengl.GL11;

 

import tutorial.alex.Entity.EntityStdBullet;

import tutorial.alex.Model.ModelStdBullet;

import net.minecraft.entity.Entity;

import net.minecraft.client.model.ModelBase;

import net.minecraft.client.renderer.entity.Render;

import net.minecraft.util.ResourceLocation;

import cpw.mods.fml.relauncher.SideOnly;

import cpw.mods.fml.relauncher.Side;

 

@SideOnly(Side.CLIENT)

public class RenderStdBullet extends Render{

 

// ResourceLocations are typically static and final, but that is not an absolute requirement

private static final ResourceLocation texture = new ResourceLocation("alexmodid:textures/models/ModelStdBullet.png");

 

// if you want a model, be sure to add it here:

private ModelBase model;

 

public RenderStdBullet() {

// we could have initialized it above, but here is fine as well:

model = new ModelStdBullet();

}

 

@Override

protected ResourceLocation getEntityTexture(Entity entity) {

// this method should return your texture, which may be different based

// on certain characteristics of your custom entity; if that is the case,

// you may want to make a second method that takes your class:

return getCustomTexture((EntityStdBullet) entity);

}

 

private ResourceLocation getCustomTexture(EntityStdBullet entity) {

// now you have access to your custom entity fields and methods, if any,

// and can base the texture to return upon those

return texture;

}

 

// in whatever render method you are using; this one is from Render class:

@Override

public void doRender(Entity entity, double x, double y, double z, float yaw, float partialTick) {

// again, if you need some information from your custom entity class, you can cast to your

// custom class, either passing off to another method, or just doing it here

// in this example, it is not necessary

 

// if you are going to do any openGL matrix transformations, be sure to always Push and Pop

GL11.glPushMatrix();

 

// bind your texture:

bindTexture(texture);

 

// do whatever transformations you need, then render

 

// typically you will at least want to translate for x/y/z position:

GL11.glTranslated(x, y, z);

GL11.glRotatef(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTick, 0.0F, 1.0F, 0.0F);

GL11.glRotatef(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTick, 0.0F, 0.0F, 1.0F);

// if you are using a model, you can do so like this:

model.render(entity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);

 

// note all the values are 0 except the final argument, which is scale

// vanilla Minecraft almost excusively uses 0.0625F, but you can change it to whatever works

 

GL11.glPopMatrix();

}

}

 

ModelStdBullet.class (the model):

 

// Date: 12/28/2014 3:56:59 PM

// Template version 1.1

// Java generated by Techne

// Keep in mind that you still need to fill in some blanks

// - ZeuX

 

 

 

 

 

 

package tutorial.alex.Model;

 

import net.minecraft.client.model.ModelBase;

import net.minecraft.client.model.ModelRenderer;

import net.minecraft.entity.Entity;

import tutorial.alex.Entity.EntityStdBullet;

 

public class ModelStdBullet extends ModelBase

{

  //fields

    ModelRenderer Shape1;

    ModelRenderer Shape2;

    ModelRenderer Shape3;

    ModelRenderer Shape4;

    ModelRenderer Shape5;

 

  public ModelStdBullet()

  {

    textureWidth = 64;

    textureHeight = 32;

   

      Shape1 = new ModelRenderer(this, 0, 0);

      Shape1.addBox(0F, 0F, 0F, 5, 5, 5);

      Shape1.setRotationPoint(0F, 114F, 0F);

      Shape1.setTextureSize(64, 32);

      Shape1.mirror = true;

      setRotation(Shape1, 0F, 0F, 0F);

      Shape2 = new ModelRenderer(this, 0, 0);

      Shape2.addBox(0F, 0F, 0F, 4, 4, 4);

      Shape2.setRotationPoint(0.5F, 115F, 2F);

      Shape2.setTextureSize(64, 32);

      Shape2.mirror = true;

      setRotation(Shape2, 0F, 0F, 0F);

      Shape3 = new ModelRenderer(this, 0, 0);

      Shape3.addBox(0F, 0F, 0F, 3, 3, 3);

      Shape3.setRotationPoint(1F, 115F, 4F);

      Shape3.setTextureSize(64, 32);

      Shape3.mirror = true;

      setRotation(Shape3, 0F, 0F, 0F);

      Shape4 = new ModelRenderer(this, 0, 0);

      Shape4.addBox(0F, 0F, 0F, 2, 2, 2);

      Shape4.setRotationPoint(1.5F, 115.5F, 6F);

      Shape4.setTextureSize(64, 32);

      Shape4.mirror = true;

      setRotation(Shape4, 0F, 0F, 0F);

      Shape5 = new ModelRenderer(this, 0, 0);

      Shape5.addBox(0F, 0F, 0F, 1, 1, 1);

      Shape5.setRotationPoint(2F, 116F, 8F);

      Shape5.setTextureSize(64, 32);

      Shape5.mirror = true;

      setRotation(Shape5, 0F, 0F, 0F);

  }

 

  public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)

  {

    super.render(entity, f, f1, f2, f3, f4, f5);

    setRotationAngles(f, f1, f2, f3, f4, f5);

    Shape1.render(f5);

    Shape2.render(f5);

    Shape3.render(f5);

    Shape4.render(f5);

    Shape5.render(f5);

  }

 

  private void setRotation(ModelRenderer model, float x, float y, float z)

  {

    model.rotateAngleX = x;

    model.rotateAngleY = y;

    model.rotateAngleZ = z;

  }

 

  public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5)

  {

    super.setRotationAngles(f, f1, f2, f3, f4, f5, null);

  }

 

}

 

 

 

I also have screenshots illustrating the problem:

 

d65JyME.png

As you can see, when I am firing up (those yellow blotches are the bullets' models), the bullets' models spawn on the right as they should, but they have no pitch.

8HHrTib.png

However, when I fire downward (the bullet is in the far lower-left corner), the bullet's model spawns on the left. It still has no pitch.

Posted

Are you doing this for 1.7?

 

I'm doing something similar in 1.8, but I don't have trouble with bullets,

because I don't want them to become visible.

It's for 1.7.10. Also, fixed up your grammar and spelling .

Posted

ñaa not american

 

but i have a teory

you do your bullet using entity  fireball

 

I do not want to do that. Plus, I think my problem is in the render class, which can be found in the github repo.

Posted

how are you seting the starting position of  this bullet

 

i think you are using

DTGMod/tutorial/alex/Entity/EntityStdBullet.java

 

its tedios to read all your  clases loking for this single think

 

I've updated the OP to contain only the classes that are relevant.

Posted

Okay, I've fixed the problem with the bullet model's starting position changing on pitch. Now all I have to fix is the bullet model being horizontal all the time.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
  • Topics

×
×
  • Create New...

Important Information

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