Jump to content

Recommended Posts

Posted

Hey, I'm trying to make a block that can keep a mobspawner active when the player isn't there.

 

But for that I need to create a fake player that can activate the spawner. How can this be done?

 

Any help would be awsome :-)

 

Version: 1.7.10

 

package com.Xillez.blocks;

import java.util.Random;
import java.util.UUID;

import org.lwjgl.opengl.GL11;

import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.management.ItemInWorldManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityMobSpawner;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.common.util.ForgeDirection;

import com.Xillez.PIEntity.PIEntity;
import com.Xillez.lib.RefStrings;
import com.Xillez.main.MainRegistry;
import com.Xillez.tabs.UserTabs;
import com.Xillez.tileentity.TileEntityPIB;
import com.mojang.authlib.GameProfile;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class pIB extends Block
{
// ------------------------------------------- General Block Stuff
public IIcon common;
public IIcon front;
public IIcon top;

private Boolean firstRight = false;
private String playername = "";

public pIB(int i)
{
	super(Material.iron);
	this.setBlockName("pIB");
	this.setCreativeTab(UserTabs.piTab);
	this.setHarvestLevel("pickaxe", 1);
	this.setHardness(1.0F);
	this.setResistance(5.0F);
	this.setStepSound(Block.soundTypeMetal);

}

public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
    {
	float pixel = 1F/16F;

	float minX = 0;
	float maxX = 1;
	float minY = 0;
	float maxY = 1;
	float minZ = 0;
	float maxZ = 1;
	this.setBlockBounds(minX, minY, minZ, maxX, maxY, maxZ);

        return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ);
    }

public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int x, int y, int z)
    {
	float pixel = 1F/16F;

	float minX = 0;
	float maxX = 1;
	float minY = 0;
	float maxY = 1;
	float minZ = 0;
	float maxZ = 1;
	this.setBlockBounds(minX, minY, minZ, maxX, maxY, maxZ);

        return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ);
    }

public int getRenderType()
{
	return -1;
}

public boolean isOpaqueCube()
{
	return false;
}

public boolean renderAsNormalBlock()
{
	return false;
}

//At right click
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int par6, float par7, float par8, float par9)
    {
	TileEntity tileentity = world.getTileEntity(x, y, z);
	TileEntity spawner = world.getTileEntity(x, y-1, z);
	if (!firstRight)
	{
		if (spawner instanceof TileEntityMobSpawner)
		{
			player.attackEntityFrom(DamageSource.outOfWorld, Float.MAX_VALUE);
			firstRight = true;
		}
	}
	/*else
	{
		player.openGui(MainRegistry.modInstance, 0, world, x, y, z);
	}*/
        return false;
    }

public void registerBlockIcons(IIconRegister icon)
{
	/*common = icon.registerIcon(RefStrings.MODID + ":cpu_0");
	front = icon.registerIcon(RefStrings.MODID + ":cpu_1");
	top = icon.registerIcon(RefStrings.MODID + ":cpu_1");*/
}
@Override
public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack)
{
	int l = MathHelper.floor_double((double)(par5EntityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;

	if (l == 0)
	{
		par1World.setBlockMetadataWithNotify(par2, par3, par4, 2, 2);
	}

	if (l == 1)
	{
		par1World.setBlockMetadataWithNotify(par2, par3, par4, 5, 2);
	}

	if (l == 2)
	{
		par1World.setBlockMetadataWithNotify(par2, par3, par4, 3, 2);
	}

	if (l == 3)
	{
		par1World.setBlockMetadataWithNotify(par2, par3, par4, 4, 2);
	}

}

@Override
public IIcon getIcon(int side, int meta)
{
	return null; //side == 1 ? this.top : (side == 0 ? this.common : (side != meta ? this.common : this.front));
}

public TileEntity createNewTileEntity(World world, int i)
{
	return new TileEntityPIB();
}

public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_)
    {
        return Item.getItemFromBlock(initBlock.pIB);
    }

/*
Sides: 
- 0 = bottom
- 1 = top
- 2 = front
- 3 = back
- 4 = left
- 5 = right
*/

// ------------------------------------------- Block specific
}

Posted

Version?

 

In 1.9+ you have MobSpawnerBaseLogic, where magic happens:

    private boolean isActivated()
    {
        BlockPos blockpos = this.getSpawnerPosition();
        return this.getSpawnerWorld().isAnyPlayerWithinRangeAt((double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 0.5D, (double)blockpos.getZ() + 0.5D, (double)this.activatingRangeFromPlayer);
    }

 

#isActivated and World#isAnyPlayerWithinRangeAt are say - untouchable. Conclusion is that you ineed will need to simulate EntityPlayer for it to work nice OR you can replace all mob spawners' logic with you own extension of MobSpawnerBaseLogic with #updateSpawner overriden to do proper checks (not only players).

 

Simulating EntityPlayer was always pain in the ass, especially when you would (in this case) HAVE TO place it in World#playerEntities.

This would become quite a nightmare because 1st - "fake" player would have to be "NOT_SPECTATING" (for spawners to even work) and that would cause a lot of not-wanted oucomes.

 

Said that - the only real solution for me would be applying custom MobSpawnerBaseLogic to all mob spawners. Since there are only 2 extensions to that class - for block and for minecart, whole replacement would be limited to not-hard stuff.

 

Now how to do such replacement is quite tricky. For me - only viable approach is injecting with ASM and that would even allow you to simply add hook in #isActivated method itself. Without ASM you could try to Reflect and replace TileEntityMobSpawner#spawnerLogic whenever TileEntity appears. Now this is also tricky - whenever TileEntity would be added to world, yo uwould have to check agains type (if mob spawner) and replace field.

 

Following this logic - only thing left is to know how to catch loading TileEntity to world. I can have few guesses - use ChunkDataEvent.Load to scan and replace logic of loaded spawners, but idk if TileEnntities are alredy placed at the time of loading chunk (+ it would be server only replacement, which actually wouldn't bother you since your logic can be server only). Other idea would include maybe using WorldTickEvent to gather World#tickableTileEntities - check against mob spawners and reflacet/replace their logic. Or you could even simulate spawning logic without even using TileEntityMobSpawner#spawnerLogic. Your choice.

 

I said my piece, rest is for you (or others with ideas).

1.7.10 is no longer supported by forge, you are on your own.

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



×
×
  • Create New...

Important Information

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