Skip to content

Commit

Permalink
Beacon fixes and Forge support
Browse files Browse the repository at this point in the history
  • Loading branch information
Guichaguri committed Mar 12, 2017
1 parent 99e5f59 commit 8bac624
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 52 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
build/
lib/
logs/
*.log
others/
out/
run/
Expand All @@ -10,3 +11,4 @@ BetterFps.iml
BetterFps.ipr
BetterFps.iws
gradlew*
src/main/resources/betterfps.srg
1 change: 1 addition & 0 deletions mappings.srg
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
CL: Minecraft net/minecraft/client/Minecraft
CL: World net/minecraft/world/World
CL: Chunk net/minecraft/world/chunk/Chunk
CL: Block net/minecraft/block/Block
CL: EntityPlayer net/minecraft/entity/player/EntityPlayer
CL: EntityPlayerSP net/minecraft/client/entity/EntityPlayerSP
CL: MathHelper net/minecraft/util/math/MathHelper
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/guichaguri/betterfps/api/IBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package guichaguri.betterfps.api;

import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

/**
* @author Guilherme Chaguri
*/
public interface IBlock {

/**
* Method added by Forge. Reimplemented for compatibility with it.
*/
boolean isBeaconBase(IBlockAccess worldObj, BlockPos pos, BlockPos beacon);

/**
* Method added by Forge. Reimplemented for compatibility with it.
*/
@Nullable
float[] getBeaconColorMultiplier(IBlockState state, World world, BlockPos pos, BlockPos beaconPos);

}
35 changes: 35 additions & 0 deletions src/main/java/guichaguri/betterfps/patches/block/BlockPatch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package guichaguri.betterfps.patches.block;

import guichaguri.betterfps.api.IBlock;
import guichaguri.betterfps.transformers.annotations.Copy;
import guichaguri.betterfps.transformers.annotations.Copy.Mode;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

/**
* @author Guilherme Chaguri
*/
public abstract class BlockPatch extends Block implements IBlock {
public BlockPatch(Material m) {
super(m);
}

@Copy(Mode.COPY)
@Override
public boolean isBeaconBase(IBlockAccess worldObj, BlockPos pos, BlockPos beacon) {
return this == Blocks.EMERALD_BLOCK || this == Blocks.GOLD_BLOCK || this == Blocks.DIAMOND_BLOCK || this == Blocks.IRON_BLOCK;
}

@Copy(Mode.COPY)
@Nullable
@Override
public float[] getBeaconColorMultiplier(IBlockState state, World world, BlockPos pos, BlockPos beaconPos) {
return null;
}
}
127 changes: 75 additions & 52 deletions src/main/java/guichaguri/betterfps/patches/block/FastBeacon.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package guichaguri.betterfps.patches.block;

import guichaguri.betterfps.api.IBlock;
import guichaguri.betterfps.transformers.Conditions;
import guichaguri.betterfps.transformers.annotations.Condition;
import guichaguri.betterfps.transformers.annotations.Copy;
import guichaguri.betterfps.transformers.annotations.Copy.Mode;
import java.util.Arrays;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStainedGlass;
import net.minecraft.block.BlockStainedGlassPane;
Expand Down Expand Up @@ -34,90 +34,90 @@ public abstract class FastBeacon extends TileEntityBeacon {
public void update() {
tickCount--;
if(tickCount == 100) {
updateEffects(pos.getX(), pos.getY(), pos.getZ());
addEffectsToPlayers();
} else if(tickCount <= 0) {
updateBeacon();
tickCount = 200;
}
}

/**
* Updates the beacon structure
*/
@Copy(Mode.REPLACE)
@Override
public void updateBeacon() {
// Updates everything, including player effects
public void updateSegmentColors() {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();

if(world.isRemote) {
updateGlassLayers(x, y, z);
} else {
updateActivation(x, y, z);
}
updateLevels(x, y, z);
updateEffects(x, y, z);
tickCount = 200;
}

/**
* Updates player effects
*/
@Copy(Mode.REPLACE)
@Override
public void updateSegmentColors() {
// Only updates the beacon structure
public void addEffectsToPlayers() {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
if(world.isRemote) {
updateGlassLayers(x, y, z);
} else {
updateActivation(x, y, z);
}
updateLevels(x, y, z);
}

@Copy(Mode.REPLACE)
@Override
public void addEffectsToPlayers() {
// Only updates player effects
updateEffects(pos.getX(), pos.getY(), pos.getZ());
}
if(isComplete && levels > 0 && !world.isRemote && primaryEffect != null) {

@Copy
private void updateEffects(int x, int y, int z) {
if((isComplete) && (levels > 0) && (!world.isRemote) && (primaryEffect != null)) {
int effectTicks = (9 + levels * 2) * 20;
int radius = (levels + 1) * 10;
byte effectLevel = 0;
if((levels >= 4) && (primaryEffect == secondaryEffect)) {
effectLevel = 1;
boolean hasSecondaryEffect = false;

if(levels >= 4) {
if(primaryEffect == secondaryEffect) {
effectLevel = 1;
} else {
hasSecondaryEffect = secondaryEffect != null;
}
}

AxisAlignedBB box = new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1);
box = box.expand(radius, radius, radius).addCoord(0.0D, world.getHeight(), 0.0D);
List<EntityPlayer> players = world.getEntitiesWithinAABB(EntityPlayer.class, box);

boolean hasSecondaryEffect = (levels >= 4) && (primaryEffect != secondaryEffect) && (secondaryEffect != null);
int effectTicks = (9 + levels * 2) * 20;

for(EntityPlayer player : players) {
for(EntityPlayer player : world.getEntitiesWithinAABB(EntityPlayer.class, box)) {
player.addPotionEffect(new PotionEffect(primaryEffect, effectTicks, effectLevel, true, true));

if(hasSecondaryEffect) {
player.addPotionEffect(new PotionEffect(secondaryEffect, effectTicks, 0, true, true));
}
}
}
}

/**
* Checks if the beacon should be active and searches for stained glass to color the beam
* Should be only called client-side. {@link #updateActivation} should be used on the server
*/
@Copy
private void updateGlassLayers(int x, int y, int z) {
// Checks if the beacon should be active and searches for stained glass to color the beam.
// Should be only called client-side
isComplete = true;
beamSegments.clear();
BeamSegment beam = new BeamSegment(EntitySheep.getDyeRgb(EnumDyeColor.WHITE));
float[] oldColor = null;

beamSegments.clear();
beamSegments.add(beam);
int height = world.getActualHeight();
for(int blockY = y + 1; blockY < height; blockY++) {
BlockPos pos = new BlockPos(x, blockY, z);
IBlockState state = world.getBlockState(pos);

isComplete = true;

for(int blockY = y + 1; blockY < world.getActualHeight(); blockY++) {

BlockPos blockPos = new BlockPos(x, blockY, z);
IBlockState state = world.getBlockState(blockPos);
Block b = state.getBlock();
float[] color;
float[] color = null;

if(b == Blocks.STAINED_GLASS) {
color = EntitySheep.getDyeRgb(state.getValue(BlockStainedGlass.COLOR));
} else if(b == Blocks.STAINED_GLASS_PANE) {
Expand All @@ -128,13 +128,25 @@ private void updateGlassLayers(int x, int y, int z) {
beamSegments.clear();
break;
}

// Forge Compatibility
float[] customColor = ((IBlock)b).getBeaconColorMultiplier(state, world, blockPos, pos);
if(customColor != null) color = customColor;
}

if(color == null) {
beam.incrementHeight();
continue;
}

if(oldColor != null) {
color = new float[]{(oldColor[0] + color[0]) / 2.0F, (oldColor[1] + color[1]) / 2.0F, (oldColor[2] + color[2]) / 2.0F};
color = new float[]{
(oldColor[0] + color[0]) / 2,
(oldColor[1] + color[1]) / 2,
(oldColor[2] + color[2]) / 2
};
}

if(Arrays.equals(color, oldColor)) {
beam.incrementHeight();
} else {
Expand All @@ -145,55 +157,66 @@ private void updateGlassLayers(int x, int y, int z) {
}
}

/**
* Checks if the beacon should be active
* Should be called only server-side. {@link #updateGlassLayers} should be used on the client
*/
@Copy
private void updateActivation(int x, int y, int z) {
// Checks if the beacon should be activate
// Should be called only server-side. updateGlassLayers do the trick on the client
isComplete = true;
int height = world.getActualHeight();
for(int blockY = y + 1; blockY < height; blockY++) {

for(int blockY = y + 1; blockY < world.getActualHeight(); blockY++) {

BlockPos pos = new BlockPos(x, blockY, z);
IBlockState state = world.getBlockState(pos);
Block b = state.getBlock();

if(b != Blocks.BEDROCK && state.getLightOpacity() >= 15) {
isComplete = false;
break;
}
}
}

/**
* Checks if the beacon should be active and how many levels it should have
*/
@Copy
private void updateLevels(int x, int y, int z) {
// Checks if the beacon should be active and how many levels it should have.
boolean isClient = world.isRemote;
int levelsOld = levels;

lvlLoop: for(int lvl = 1; lvl <= 4; lvl++) {
levels = lvl;
int blockY = y - lvl;
if(blockY < 0) break;

for(int blockX = x - lvl; blockX <= x + lvl; blockX++) {
for(int blockZ = z - lvl; blockZ <= z + lvl; blockZ++) {

BlockPos blockPos = new BlockPos(blockX, blockY, blockZ);
Block block = world.getBlockState(blockPos).getBlock();
// TODO make it work with Forge's isBeaconBase
if(block != Blocks.EMERALD_BLOCK && block != Blocks.GOLD_BLOCK && block != Blocks.DIAMOND_BLOCK && block != Blocks.IRON_BLOCK) {

// Forge Compatibility
if(!((IBlock)block).isBeaconBase(world, blockPos, pos)) {
levels--;
break lvlLoop;
}

}
}

// If it's a client, let's ignore all other layers
if(isClient) break;
}
if(levels == 0) {
this.isComplete = false;
isComplete = false;
}

if((!isClient) && (levels == 4) && (levelsOld < levels)) {
if(!isClient && levels == 4 && levelsOld < levels) {
// Give the full beacon achievement
AxisAlignedBB box = new AxisAlignedBB(x, y, z, x, y - 4, z).expand(10.0, 5.0, 10.0);
List<EntityPlayer> players = world.getEntitiesWithinAABB(EntityPlayer.class, box);
for(EntityPlayer player : players) {
for(EntityPlayer player : world.getEntitiesWithinAABB(EntityPlayer.class, box)) {
player.addStat(AchievementList.FULL_BEACON);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class PatcherTransformer implements IClassTransformer {
private static final Map<Mappings, String> patches = new HashMap<Mappings, String>();

static {
patches.put(Mappings.C_Block, "guichaguri/betterfps/patches/block/BlockPatch");

patches.put(Mappings.C_TileEntityHopper, "guichaguri/betterfps/patches/block/FastHopper");
patches.put(Mappings.C_BlockHopper, "guichaguri/betterfps/patches/block/FastHopperBlock");

Expand Down
1 change: 1 addition & 0 deletions src/main/java/guichaguri/betterfps/tweaker/Mappings.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public enum Mappings {
C_Minecraft(Type.CLASS, "Minecraft"),
C_World(Type.CLASS, "World"),
C_Chunk(Type.CLASS, "Chunk"),
C_Block(Type.CLASS, "Block"),
C_EntityPlayer(Type.CLASS, "EntityPlayer"),
C_EntityPlayerSP(Type.CLASS, "EntityPlayerSP"),
C_MathHelper(Type.CLASS, "MathHelper"),
Expand Down

0 comments on commit 8bac624

Please sign in to comment.