Merge remote-tracking branch '1.10/master' into 1.11.X
commit
a824613401
|
@ -1 +1 @@
|
|||
Subproject commit 9c1e4505b8e290c59c910145f083f4a4b5a26b8a
|
||||
Subproject commit 66c9249fd9abcbde7628a12721ece02bca23fcb7
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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" :
|
||||
|
|
Loading…
Reference in New Issue