Jump to content

[1.12.2] Dimension changing functions in block & command, but not from entity


Lyinginbedmon

Recommended Posts

I'm trying to make a magic spell that, when cast, transports the caster to the Nether. This is accomplished by creating a spell entity that then isolates its caster and changes their dimension. I've managed to create a command for debugging and a block that does the same thing on contact, but whilst all three use the exact same code (down to a single static function in the teleporter) on the exact same side with the same variables attempts to use the effect via the spell entity causes errors in the world that consequently results in a server crash. The command and block work perfectly, but the spell just crashes.

Teleporter function


    public static void teleportToDimension(EntityPlayer player, int dimension, double x, double y, double z)
    {
        if(!net.minecraftforge.common.ForgeHooks.onTravelToDimension(player, dimension)) return;
        int originDim = player.getEntityWorld().provider.getDimension();
        EntityPlayerMP playerMP = (EntityPlayerMP) player;
        MinecraftServer server = player.getEntityWorld().getMinecraftServer();
        WorldServer dimWorld = server.getWorld(dimension);
        player.addExperienceLevel(0);
        
        if(dimWorld == null || dimWorld.getMinecraftServer() == null) throw new IllegalArgumentException("Couldn't teleport to dimension "+dimension);
        
        dimWorld.getMinecraftServer().getPlayerList().transferPlayerToDimension(playerMP, dimension, new VOTeleporter(dimWorld, x, y, z));
        player.setPositionAndUpdate(x, y, z);
        
        // End teleport compensation
        if(originDim == 1)
        {
            player.setPositionAndUpdate(x, y, z);
            dimWorld.spawnEntity(player);
            dimWorld.updateEntityWithOptionalForce(player, false);
        }
    }

 

Spell code

	public void doEffectStart(Entity sourceEntity, Side onSide)
	{
		if(onSide == Side.SERVER)
		{
			EntityLivingBase caster = getCaster(sourceEntity);
			EntityLivingBase target = caster;
			if(target != null)
			{
				int previousDimension = target.dimension;
				if(target != null && canAffectEntity(sourceEntity, target) && previousDimension == sourceEntity.dimension)
				{
					if(target instanceof EntityPlayer)
					{
						int transferDimension = previousDimension == -1 ? 0 : -1;
				        VOTeleporter.teleportToDimension((EntityPlayer)target, transferDimension, target.posX, target.posY + 5D, target.posZ);
					}
				}
			}
		}
		
		sourceEntity.setDead();
	}

 

Command code

	public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException
	{
        if(args.length < 1) return;
        String s = args[0];
        int dim = 0;
        boolean dimFound = false;
        for(WorldServer dimension : DimensionManager.getWorlds())
        {
        	if(s.equalsIgnoreCase(dimension.provider.getDimensionType().getName()))
        	{
        		dim = dimension.provider.getDimension();
        		dimFound = true;
        		break;
        	}
        }
        
        if(!dimFound)
        {
	        try
	        {
	            dim = Integer.parseInt(s);
	            dimFound = true;
	        }
	        catch (NumberFormatException e)
	        {
	            sender.sendMessage(new TextComponentString(TextFormatting.RED + "Error parsing dimension!"));
	            return;
	        }
        }
        
        if(dimFound && sender instanceof EntityPlayer)
        {
        	VOTeleporter.teleportToDimension((EntityPlayer)sender, dim, sender.getPositionVector().x, sender.getPositionVector().y, sender.getPositionVector().z);
        	sender.sendMessage(new TextComponentString("Teleporting to dimension "+DimensionManager.getWorld(dim).provider.getDimensionType().getName()));
        }
	}

 

Block code

    public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn)
    {
        if(!worldIn.isRemote)
        {
	        VOTeleporter.teleportToDimension((EntityPlayer)entityIn, -1, entityIn.posX, entityIn.posY + 5D, entityIn.posZ);
        }
    }

 

Anyone know what's going on here? I'm at my wit's end trying to figure out what is creating the difference in operation.

Link to comment
Share on other sites

In theory I can just have the spell place an appropriately-tuned portal block at the head/feet of the target mob, but that raises possible issues of displacing blocks (and the reverse of avoiding doing so presents the issue of unreliable transport), so I'd really prefer a block-free solution to this spell problem.

Link to comment
Share on other sites

On 8/29/2019 at 4:26 AM, Lyinginbedmon said:

This is accomplished by creating a spell entity

Why do you need to create an entity though?

How is your spell casted?

 

Also please post your crash log.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

8 hours ago, DavidM said:

Why do you need to create an entity though?

How is your spell casted?

 

Also please post your crash log.

Spells are cast through items containing an ID to a specific spell in a registry, those items create a holder entity that references the spell in the registry to perform all of its effects. Several items contain multiple spells that can be selected and cast as necessary.


This particular spell (which does its thing in a single game tick and vanishes) could probably be contained solely within an item, but it's one of a large variety and assortment of different spells, many of which have more long-term effects, visuals, and post-casting interaction options. It's easier to create an inert holder entity than it is to implement an entire system of ongoing spell effects that mostly mirrors an entity anyways.

 

As for the crash report, the error doesn't seem to happen inside the the dimension code but specifically as a result of it, and only when used via an entity.

---- Minecraft Crash Report ----
// Hi. I'm Minecraft, and I'm a crashaholic.

Time: 8/27/19 9:32 PM
Description: Exception ticking world entities

java.lang.IndexOutOfBoundsException: Index: 25, Size: 25
	at java.util.ArrayList.rangeCheck(ArrayList.java:653)
	at java.util.ArrayList.remove(ArrayList.java:492)
	at net.minecraft.world.World.updateEntities(World.java:1959)
	at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:642)
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:840)
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741)
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590)
	at java.lang.Thread.run(Thread.java:745)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Server thread
Stacktrace:
	at java.util.ArrayList.rangeCheck(ArrayList.java:653)
	at java.util.ArrayList.remove(ArrayList.java:492)
	at net.minecraft.world.World.updateEntities(World.java:1959)
	at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:642)

-- Affected level --
Details:
	Level name: Testing
	All players: 0 total; []
	Chunk stats: ServerChunkCache: 625 Drop: 369
	Level seed: -2446296594359232719
	Level generator: ID 01 - flat, ver 0. Features enabled: false
	Level generator options: 3;minecraft:bedrock,2*minecraft:dirt,minecraft:grass;1;village
	Level spawn location: World: (-273,4,909), Chunk: (at 15,0,13 in -18,56; contains blocks -288,0,896 to -273,255,911), Region: (-1,1; contains chunks -32,32 to -1,63, blocks -512,0,512 to -1,255,1023)
	Level time: 8937689 game time, 6000 day time
	Level dimension: 0
	Level storage version: 0x04ABD - Anvil
	Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
	Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true
Stacktrace:
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:840)
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741)
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590)
	at java.lang.Thread.run(Thread.java:745)

-- System Details --
Details:
	Minecraft Version: 1.12.2
	Operating System: Windows 10 (amd64) version 10.0
	Java Version: 1.8.0_101, Oracle Corporation
	Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
	Memory: 1914570600 bytes (1825 MB) / 2392850432 bytes (2282 MB) up to 5652348928 bytes (5390 MB)
	JVM Flags: 0 total; 
	IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
	FML: MCP 9.42 Powered by Forge 14.23.2.2618 6 mods loaded, 6 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.2.2618.jar | None      |
	| UCHIJAAAA | forge     | 14.23.2.2618 | forgeSrc-1.12.2-14.23.2.2618.jar | None      |
	| UCHIJAAAA | varodd    | 5.0          | bin                              | None      |
	| UCHIJAAAA | baubles   | 1.5.2        | Baubles-1.12-1.5.2.jar           | 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['Player314'/49, l='Testing', x=-297.95, y=9.00, z=893.80]]
	Type: Integrated Server (map_client.txt)
	Is Modded: Definitely; Client brand changed to 'fml,forge'

 

Edited by Lyinginbedmon
Link to comment
Share on other sites

2 hours ago, Lyinginbedmon said:

As for the crash report, the error doesn't seem to happen inside the the dimension code but specifically as a result of it, and only when used via an entity.

It also seems that the error is caused when TileEntities are being removed. Do you have any TileEntities that override the onChunkUnload method?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

As far as I can see it's happening when Entities are being removed (at line 1959, just before tile entities, which start at line 1970). And the only thing removing an entity is the same code that works just fine in blocks and commands.

The greater codebase does have 1 reference to ChunkEvent.Unload (no overrides for it in custom tiles, nor any such tiles present in that test world) but that just removes tile entities in the target chunk from a separate registry that keeps track of containers.

Edited by Lyinginbedmon
Link to comment
Share on other sites

29 minutes ago, Lyinginbedmon said:

As far as I can see it's happening when Entities are being removed (at line 1959, just before tile entities, which start at line 1970).

Sorry have an older version of 1.12.2 on my computer. Does your spell entity override onEntityRemoved? Just as a suggestion remove the call to  setDead in your code.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

28 minutes ago, Animefan8888 said:

Sorry have an older version of 1.12.2 on my computer. Does your spell entity override onEntityRemoved? Just as a suggestion remove the call to  setDead in your code.

No, and given that there's numerous other spell effects that function near-identically (such as status effect buffs) I don't think it's the setDead call.

Suffice it to say that every other spell works fine without issue, every other use-case of the dimension code works fine without issue, it's specifically when the two cross.

Edited by Lyinginbedmon
Link to comment
Share on other sites

31 minutes ago, Lyinginbedmon said:

I don't think it's the setDead call.

I think it is. Because the error has to do with you removing that entity when changing directions.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

17 minutes ago, Lyinginbedmon said:

Is it purely to do with unloading chunks?

It has to be. My suggestion is to add the setDead call in the onUpdate method of the entity. And the onLoad if that exists for entities or not use an entity at all unless you plan for a visual effect to exist. 

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

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



×
×
  • Create New...

Important Information

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