Jump to content

Block acting like a player


Xillez

Recommended Posts

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
}

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

    • So, lately my modloader (curseforge) has been loading 162 mods instead of the 97 that my modpack only has, appart of that, when I try to join onto my public server the curseforge logs just starts spamming "OpenGL debug message: id=1280, source=API, type=ERROR, severity=HIGH, message='GL error GL_INVALID_ENUM'" and just freezes, my drivers are up to date, I've reinstalled curseforge, same with minecraft launcher, the java is updated, I've got enough ram and I got no viruses, Long after all this happened, my game could enter my online server and it didn't register as many mods, even my game was running at 40 fps, now I can't even play multiplayer, and when I try singleplayer, it goes about 20 fps to 10
    • It does but I'm struggling to see how to make it work in my recipe? (Its structure is the same as OP's, with a serializer subclass)
    • That looks pretty cool, nice!   Sure, so looking at that JSON file I posted, I pretty much made a record class for each "custom" data type in that JSON. The Input is a good example of why ``` "inputs": [ { "ingredient": { "item": "relativedimensions:aberrant_shard" }, "count": 8 } ], ``` So here's the inputs, it's an array, which we can use the Codec builder's builder.listOf to define an array. Each Item is of some arbitrary object with keys "ingredient" (which we know is an Ingredient) and a "count" which is an int. You don't have to have an intermediate class to map this to necessarily but I found that it's just easier to see the data that way, hence the 'ParticleReboundIngredient' represents one of these inputs.   Let me know if that makes sense or not. 
    • Pretty much, although all the recipes im planning to make on it are shapeless. The idea is that the chamber uses energy to "fuse" the items in each of the center slots together, in this case an ingot. The two slots at the sides are fuel. (A special kind of wood in this case). Here is an image of the interface just for reference (The center slot is the output)   As for the code- Can you elaborate a little bit on it? Seeing three different record classes has confused me a lot. (Elaborate as in why make them in three different records. I understand the code itself more or less)
    • Hello im trying to make a mod and the past few days GSON has almost killed me, when i export the mod and then launch it through minecraft launcher i get java.lang.NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)Lcom/google/gson/JsonElement; i have literally tried everything here is my build config   dependencies { minecraft("com.mojang:minecraft:1.8.9") mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") compileOnly("cc.polyfrost:oneconfig-1.8.9-forge:0.2.2-alpha+") shadowImpl("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-beta+") { isTransitive = false exclude(module = "gson") } shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") { isTransitive = false exclude(module = "gson") } annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT") shadowImpl("org.javassist:javassist:3.15.0-GA") { isTransitive = false exclude(module = "gson") } shadowImpl("com.neovisionaries:nv-i18n:1.28") { isTransitive = false exclude(module = "gson") } shadowImpl("org.apache.commons:commons-lang3:3.4") { isTransitive = false exclude(module = "gson") } shadowImpl("org.apache.httpcomponents:httpcore:4.4.5") { isTransitive = false exclude(module = "gson") } compileOnly("com.google.code.gson:gson:2.8.6") { isTransitive = false } configurations.all { resolutionStrategy { force("com.google.code.gson:gson:2.8.6") } } shadowImpl(fileTree( mapOf( "dir" to "libs", "include" to listOf("*.jar"), "exclude" to listOf( "asm", "asm-commons", "asm-tree", "gson", "unspecified", "nv-i18n" ) ) )) }  
  • Topics

×
×
  • Create New...

Important Information

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