Merge remote-tracking branch '1.10/master' into 1.11.X

master
Bartek Bok 2017-12-17 14:20:32 +01:00
commit a824613401
No known key found for this signature in database
GPG Key ID: D4AB7344B821F0B5
8 changed files with 225 additions and 50 deletions

@ -1 +1 @@
Subproject commit 9c1e4505b8e290c59c910145f083f4a4b5a26b8a
Subproject commit 66c9249fd9abcbde7628a12721ece02bca23fcb7

View File

@ -1,5 +1,5 @@
mod_version=1.7.2
api_version=1.1
mod_version=1.7.3
api_version=1.2
opc_api_version=3.5-unstable
mc_version=1.11.2
forge_version=13.20.1.2386

View File

@ -67,6 +67,10 @@ public class Config {
@ConfigProperty(category = "dropblock", name = "specialBlockRules", comment = "Defines blocks that are handled specially by elevators. Entries are in form <modId>:<blockName>:<action> or id:<blockId>:<action>. Possible actions: abort (elevator can't pass block), increment (counts for elevatorMaxBlockPassCount limit) and ignore")
public static String[] elevatorRules = new String[0];
@OnLineModifiable
@ConfigProperty(category = "dropblock", name = "overrides", comment = "Use to configure blocks as elevators. Examples: 'minecraft:wool' - configure any wool as white elevator, 'minecraft:wool#color=light_blue;yellow' - configure lightblue wool as yellow elevator")
public static String[] elevatorOverrides = new String[0];
@OnLineModifiable
@ConfigProperty(category = "dropblock", name = "elevatorXpDrainRatio", comment = "XP consumed by elevator (total amount = ratio * distance)")
public static float elevatorXpDrainRatio = 0;

View File

@ -0,0 +1,48 @@
package openblocks.api;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.event.world.BlockEvent;
import openblocks.api.IElevatorBlock.PlayerRotation;
public class ElevatorCheckEvent extends BlockEvent {
public ElevatorCheckEvent(World world, BlockPos pos, IBlockState state, EntityPlayer player) {
super(world, pos, state);
this.player = player;
}
private final EntityPlayer player;
private EnumDyeColor color;
private IElevatorBlock.PlayerRotation rotation = PlayerRotation.NONE;
public EntityPlayer getPlayer() {
return player;
}
public EnumDyeColor getColor() {
return color;
}
public boolean isElevator() {
return color != null;
}
public void setColor(EnumDyeColor color) {
this.color = color;
}
public IElevatorBlock.PlayerRotation getRotation() {
return rotation;
}
public void setRotation(IElevatorBlock.PlayerRotation rotation) {
this.rotation = rotation;
}
}

View File

@ -12,11 +12,13 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import openblocks.Config;
import openblocks.OpenBlocks;
import openblocks.api.ElevatorCheckEvent;
import openblocks.api.IElevatorBlock;
import openblocks.api.IElevatorBlock.PlayerRotation;
import openblocks.events.ElevatorActionEvent;
@ -54,28 +56,41 @@ public class ElevatorActionHandler {
return true;
}
private static SearchResult findLevel(EntityPlayer player, World world, IBlockState thisBlockState, BlockPos pos, EnumFacing direction) {
Preconditions.checkArgument(direction == EnumFacing.UP
|| direction == EnumFacing.DOWN, "Must be either up or down... for now");
private static ElevatorCheckEvent checkIsElevator(EntityPlayer player, World world, BlockPos pos, IBlockState state) {
final ElevatorCheckEvent evt = new ElevatorCheckEvent(world, pos, state, player);
final IElevatorBlock thisElevatorBlock = (IElevatorBlock)thisBlockState.getBlock();
final EnumDyeColor thisColor = thisElevatorBlock.getColor(world, pos, thisBlockState);
final Block block = state.getBlock();
if (block instanceof IElevatorBlock) {
final IElevatorBlock elevatorBlock = (IElevatorBlock)block;
evt.setColor(elevatorBlock.getColor(world, pos, state));
evt.setRotation(elevatorBlock.getRotation(world, pos, state));
}
ElevatorBlockRules.instance.configureEvent(evt);
MinecraftForge.EVENT_BUS.post(evt);
return evt;
}
private static SearchResult findLevel(EntityPlayer player, World world, EnumDyeColor thisColor, BlockPos pos, EnumFacing searchDirection) {
Preconditions.checkArgument(searchDirection == EnumFacing.UP
|| searchDirection == EnumFacing.DOWN, "Must be either up or down... for now");
int blocksInTheWay = 0;
BlockPos searchPos = pos;
for (int i = 0; i < Config.elevatorTravelDistance; i++) {
searchPos = searchPos.offset(direction);
searchPos = searchPos.offset(searchDirection);
if (!world.isBlockLoaded(searchPos)) break;
if (world.isAirBlock(searchPos)) continue;
final IBlockState blockState = world.getBlockState(searchPos);
final Block block = blockState.getBlock();
final ElevatorCheckEvent elevatorCheckResult = checkIsElevator(player, world, searchPos, blockState);
if (block instanceof IElevatorBlock) {
final IElevatorBlock otherElevatorBlock = (IElevatorBlock)block;
final EnumDyeColor otherColor = otherElevatorBlock.getColor(world, searchPos, blockState);
if (elevatorCheckResult.isElevator()) {
final EnumDyeColor otherColor = elevatorCheckResult.getColor();
if (otherColor == thisColor && canTeleportPlayer(player, world, searchPos.up())) {
final PlayerRotation rotation = otherElevatorBlock.getRotation(world, searchPos, blockState);
final PlayerRotation rotation = elevatorCheckResult.getRotation();
return new SearchResult(searchPos, rotation);
}
}
@ -99,8 +114,8 @@ public class ElevatorActionHandler {
return null;
}
private static void activate(EntityPlayer player, World world, IBlockState state, BlockPos pos, EnumFacing dir) {
SearchResult result = findLevel(player, world, state, pos, dir);
private static void activate(EntityPlayer player, World world, EnumDyeColor color, BlockPos pos, EnumFacing dir) {
SearchResult result = findLevel(player, world, color, pos, dir);
if (result != null) {
boolean doTeleport = checkXpCost(player, result);
@ -144,29 +159,7 @@ public class ElevatorActionHandler {
@SubscribeEvent
public void onElevatorEvent(ElevatorActionEvent evt) {
final World world = evt.getWorld();
final IBlockState blockState = world.getBlockState(evt.blockPos);
if (!(blockState.getBlock() instanceof IElevatorBlock)) return;
if (evt.sender != null) {
if (evt.sender.isRiding()) return;
switch (evt.type) {
case JUMP:
activate(evt.sender, world, blockState, evt.blockPos, EnumFacing.UP);
break;
case SNEAK:
activate(evt.sender, world, blockState, evt.blockPos, EnumFacing.DOWN);
break;
}
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onPlayerMovement(PlayerMovementEvent evt) {
final EntityPlayer player = evt.getEntityPlayer();
final EntityPlayer player = evt.sender;
if (player == null) return;
final World world = player.world;
@ -175,10 +168,30 @@ public class ElevatorActionHandler {
final int x = MathHelper.floor(player.posX);
final int y = MathHelper.floor(player.getEntityBoundingBox().minY) - 1;
final int z = MathHelper.floor(player.posZ);
final BlockPos pos = new BlockPos(x, y, z);
final Block block = world.getBlockState(pos).getBlock();
final BlockPos blockPos = new BlockPos(x, y, z);
if (block instanceof IElevatorBlock) new ElevatorActionEvent(world.provider.getDimension(), pos, evt.type).sendToServer();
if (evt.sender != null) {
if (evt.sender.isRiding()) return;
final IBlockState blockState = world.getBlockState(blockPos);
final ElevatorCheckEvent elevatorCheckResult = checkIsElevator(evt.sender, world, blockPos, blockState);
if (elevatorCheckResult.isElevator()) {
switch (evt.type) {
case JUMP:
activate(evt.sender, world, elevatorCheckResult.getColor(), blockPos, EnumFacing.UP);
break;
case SNEAK:
activate(evt.sender, world, elevatorCheckResult.getColor(), blockPos, EnumFacing.DOWN);
break;
}
}
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onPlayerMovement(PlayerMovementEvent evt) {
new ElevatorActionEvent(evt.type).sendToServer();
}
}

View File

@ -1,17 +1,26 @@
package openblocks.common;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.command.CommandBase;
import net.minecraft.init.Blocks;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import openblocks.Config;
import openblocks.api.ElevatorCheckEvent;
import openblocks.api.IElevatorBlock.PlayerRotation;
import openmods.Log;
import openmods.colors.ColorMeta;
import openmods.config.properties.ConfigurationChange;
public class ElevatorBlockRules {
@ -26,6 +35,16 @@ public class ElevatorBlockRules {
INCREMENT
}
private static class ElevatorOverride {
public final EnumDyeColor color;
public final PlayerRotation rotation;
public ElevatorOverride(EnumDyeColor color, PlayerRotation rotation) {
this.color = color;
this.rotation = rotation;
}
}
private static final Map<String, Action> ACTIONS;
static {
@ -37,6 +56,8 @@ public class ElevatorBlockRules {
private Map<Block, Action> rules;
private Map<IBlockState, ElevatorOverride> overrides;
private Map<Block, Action> getRules() {
if (rules == null) {
rules = Maps.newIdentityHashMap();
@ -44,7 +65,7 @@ public class ElevatorBlockRules {
try {
tryAddRule(rules, entry);
} catch (Throwable t) {
Log.warn(t, "Invalid entry in map blacklist: %s", entry);
Log.warn(t, "Invalid entry in elevator actions: %s", entry);
}
}
}
@ -69,9 +90,64 @@ public class ElevatorBlockRules {
else Log.warn("Can't find block %s", entry);
}
private Map<IBlockState, ElevatorOverride> getOverrides() {
if (overrides == null) {
overrides = Maps.newIdentityHashMap();
for (String entry : Config.elevatorOverrides) {
try {
tryAddOverride(overrides, entry);
} catch (Throwable t) {
Log.warn(t, "Invalid entry in elevator overrides: %s", entry);
}
}
}
return overrides;
}
private static void tryAddOverride(Map<IBlockState, ElevatorOverride> overrides, String entry) throws Exception {
final List<String> parts = Splitter.on(';').splitToList(entry);
if (parts.size() == 0) return;
Preconditions.checkState(parts.size() == 1 || parts.size() == 2, "Each entry be either 'blockState' or 'blockState=color'");
final List<IBlockState> blockStates = parseBlockDesc(parts.get(0));
final EnumDyeColor color;
if (parts.size() == 2) {
final ColorMeta colorMeta = ColorMeta.fromName(parts.get(1));
color = colorMeta.vanillaEnum;
} else {
color = EnumDyeColor.WHITE;
}
for (IBlockState state : blockStates)
overrides.put(state, new ElevatorOverride(color, PlayerRotation.NONE));
}
private static List<IBlockState> parseBlockDesc(String blockDesc) throws Exception {
final List<String> blockDescParts = Splitter.on('#').splitToList(blockDesc);
final String blockId = blockDescParts.get(0);
Block block = Block.REGISTRY.getObject(new ResourceLocation(blockId));
if (block == Blocks.AIR) {
Log.warn("Can't find block %s", blockId);
return Collections.emptyList();
}
if (blockDescParts.size() == 1) {
return block.getBlockState().getValidStates();
} else {
final String stateDesc = blockDescParts.get(1);
return ImmutableList.of(CommandBase.convertArgToBlockState(block, stateDesc));
}
}
@SubscribeEvent
public void onReconfig(ConfigurationChange.Post evt) {
if (evt.check("dropblock", "specialBlockRules")) rules = null;
if (evt.check("dropblock", "overrides")) overrides = null;
}
private static boolean isPassable(IBlockState state) {
@ -85,4 +161,13 @@ public class ElevatorBlockRules {
return isPassable(state)? Action.IGNORE : Action.INCREMENT;
}
public void configureEvent(ElevatorCheckEvent evt) {
final Map<IBlockState, ElevatorOverride> overrides = getOverrides();
final ElevatorOverride elevatorOverride = overrides.get(evt.getState());
if (elevatorOverride != null) {
evt.setColor(elevatorOverride.color);
evt.setRotation(elevatorOverride.rotation);
}
}
}

View File

@ -1,19 +1,17 @@
package openblocks.events;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import openmods.events.network.BlockEventPacket;
import openmods.movement.PlayerMovementEvent;
import openmods.network.event.EventDirection;
import openmods.network.event.NetworkEvent;
import openmods.network.event.NetworkEventMeta;
@NetworkEventMeta(direction = EventDirection.C2S)
public class ElevatorActionEvent extends BlockEventPacket {
public class ElevatorActionEvent extends NetworkEvent {
public ElevatorActionEvent() {}
public ElevatorActionEvent(int dimension, BlockPos pos, PlayerMovementEvent.Type type) {
super(dimension, pos);
public ElevatorActionEvent(PlayerMovementEvent.Type type) {
this.type = type;
}
@ -21,13 +19,11 @@ public class ElevatorActionEvent extends BlockEventPacket {
@Override
protected void readFromStream(PacketBuffer input) {
super.readFromStream(input);
type = input.readEnumValue(PlayerMovementEvent.Type.class);
}
@Override
protected void writeToStream(PacketBuffer output) {
super.writeToStream(output);
output.writeEnumValue(type);
}
}

View File

@ -1,4 +1,33 @@
[
{
"version" : "1.7.3",
"sections" :
[
{
"title": "openblocks.gui.features",
"lines":
[
"Any block can be configured as elevator (see 'dropblock.overrides' in config)"
]
},
{
"title": "openblocks.gui.bugfixes",
"lines":
[
"Fix server slowdown when using block placer",
"Change big metal bar recipe to prevent conflicts",
"Fix random glitches and crashes"
]
},
{
"title" : "openblocks.gui.tweaks",
"lines" :
[
"Auto-anvil now accepts any items in both input slots"
]
}
]
},
{
"version" : "1.7.2",
"sections" :