package joshie.progression.criteria.rewards; import com.google.common.collect.Lists; import joshie.progression.Progression; import joshie.progression.api.criteria.*; import joshie.progression.api.special.DisplayMode; import joshie.progression.api.special.ICustomDescription; import joshie.progression.api.special.IHasFilters; import joshie.progression.api.special.ISpecialFieldProvider; import joshie.progression.gui.fields.ItemFilterField; import joshie.progression.gui.filters.FilterTypeEntity; import joshie.progression.gui.filters.FilterTypeLocation; import joshie.progression.helpers.EntityHelper; import joshie.progression.lib.WorldLocation; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.Teleporter; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.DimensionManager; import java.util.ArrayList; import java.util.List; @ProgressionRule(name="teleport", color=0xFFDDDDDD, icon="minecraft:ender_pearl") public class RewardTeleport extends RewardBase implements ICustomDescription, IHasFilters, ISpecialFieldProvider { public List<IFilterProvider> locations = new ArrayList(); public List<IFilterProvider> targets = new ArrayList(); public boolean defaultToPlayer = true; protected transient IField field; public RewardTeleport() { field = new ItemFilterField("locations", this); } @Override public String getDescription() { return Progression.translate(getProvider().getUnlocalisedName() + ".description") + " \n" + field.getField(); } @Override public List<IFilterProvider> getAllFilters() { List<IFilterProvider> list = Lists.newArrayList(); list.addAll(locations); list.addAll(targets); return list; } @Override public IFilterType getFilterForField(String fieldName) { if (fieldName.equals("targets")) return FilterTypeEntity.INSTANCE; return FilterTypeLocation.INSTANCE; } @Override public void addSpecialFields(List<IField> fields, DisplayMode mode) { fields.add(new ItemFilterField("locations", this)); fields.add(new ItemFilterField("targets", this)); } @Override public void reward(EntityPlayerMP thePlayer) { boolean notteleported = true; for (int i = 0; i < 10 && notteleported; i++) { WorldLocation location = WorldLocation.getRandomLocationFromFilters(locations, thePlayer); if (location != null) { IFilter filter = EntityHelper.getFilter(targets, thePlayer); if (filter != null) { List<EntityLivingBase> entities = (List<EntityLivingBase>) filter.getRandom(thePlayer); if (entities.size() == 0 && defaultToPlayer) entities.add(thePlayer); for (EntityLivingBase entity : entities) { World world = DimensionManager.getWorld(location.dimension); int dimension = location.dimension; if (world == null) continue; //NO!!!! if (entity.dimension != dimension) { //From RFTools MinecraftServer server = entity.worldObj.getMinecraftServer(); WorldServer worldServer = server.worldServerForDimension(dimension); int oldDimension = entity.worldObj.provider.getDimension(); BlockPos pos = new BlockPos(location.pos); if (entity instanceof EntityPlayer) { ((EntityPlayerMP)entity).addExperienceLevel(0); //Fix levels worldServer.getMinecraftServer().getPlayerList().transferPlayerToDimension(((EntityPlayerMP)entity), dimension, new DimensionTeleportation(worldServer, new BlockPos(location.pos))); } else entity.changeDimension(dimension); entity.setPositionAndUpdate(pos.getX() + 0.5D, pos.getY() + 1, pos.getZ() + 0.5D); if (oldDimension == 1) { entity.setPositionAndUpdate(pos.getX() + 0.5D, pos.getY() + 1, pos.getZ() + 0.5D); world.spawnEntityInWorld(entity); world.updateEntityWithOptionalForce(entity, false); } notteleported = false; } else { BlockPos pos = new BlockPos(location.pos); if (world.isBlockLoaded(pos)) { if (isValidLocation(world, pos)) { notteleported = false; entity.setPositionAndUpdate(pos.getX() + 0.5D, pos.getY() + 1, pos.getZ() + 0.5D); } } } } } } } } //Helper Methods private boolean isValidLocation(World world, BlockPos pos) { IBlockState floorState = world.getBlockState(pos); IBlockState feetState = world.getBlockState(pos.up()); IBlockState headState = world.getBlockState(pos.up(2)); Material floor = floorState.getBlock().getMaterial(floorState); Material feet = feetState.getBlock().getMaterial(feetState); Material head = headState.getBlock().getMaterial(headState); if (feet.blocksMovement()) return false; if (head.blocksMovement()) return false; if (floor.isLiquid() || feet.isLiquid() || head.isLiquid()) return false; return floor.blocksMovement(); } public static class DimensionTeleportation extends Teleporter { private final WorldServer world; private final BlockPos pos; public DimensionTeleportation(WorldServer world, BlockPos pos) { super(world); this.world = world; this.pos = pos; } @Override public void placeInPortal(Entity entity, float rotationYaw) { world.getBlockState(pos); entity.setPositionAndUpdate(pos.getX() + 0.5D, pos.getY() + 1, pos.getZ() + 0.5D); entity.motionX = 0.0f; entity.motionY = 0.0f; entity.motionZ = 0.0f; } } }