Added forcefield projector and upgrades (wip)
Implemented projector with fusion and various shapes/upgrades Wip support for translation/rotation, dome, upgrades, camouflage, damage effects
This commit is contained in:
parent
a120fa3ab5
commit
45e0dcb8bf
21 changed files with 2260 additions and 69 deletions
|
@ -5,6 +5,8 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import cr0s.warpdrive.block.forcefield.*;
|
||||
import cr0s.warpdrive.item.*;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
|
@ -40,6 +42,7 @@ import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
|||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
|
||||
import cr0s.warpdrive.block.BlockAirGenerator;
|
||||
import cr0s.warpdrive.block.BlockChunkLoader;
|
||||
import cr0s.warpdrive.block.BlockLaser;
|
||||
|
@ -110,14 +113,9 @@ import cr0s.warpdrive.data.StarMapRegistry;
|
|||
import cr0s.warpdrive.event.ClientHandler;
|
||||
import cr0s.warpdrive.event.LivingHandler;
|
||||
import cr0s.warpdrive.event.WorldHandler;
|
||||
import cr0s.warpdrive.item.ItemAirCanisterFull;
|
||||
import cr0s.warpdrive.item.ItemComponent;
|
||||
import cr0s.warpdrive.item.ItemHelmet;
|
||||
import cr0s.warpdrive.item.ItemIC2reactorLaserFocus;
|
||||
import cr0s.warpdrive.item.ItemUpgrade;
|
||||
import cr0s.warpdrive.item.ItemTuningFork;
|
||||
import cr0s.warpdrive.network.PacketHandler;
|
||||
import cr0s.warpdrive.render.ClientCameraHandler;
|
||||
import cr0s.warpdrive.render.RenderBlockForceField;
|
||||
import cr0s.warpdrive.render.RenderBlockStandard;
|
||||
import cr0s.warpdrive.render.RenderOverlayCamera;
|
||||
import cr0s.warpdrive.world.BiomeSpace;
|
||||
|
@ -165,6 +163,8 @@ public class WarpDrive implements LoadingCallback {
|
|||
public static Block blockHighlyAdvancedMachine;
|
||||
public static Block blockTransportBeacon;
|
||||
public static Block blockChunkLoader;
|
||||
public static Block blockForceField;
|
||||
public static Block blockProjector;
|
||||
public static BlockDecorative blockDecorative;
|
||||
public static Block[] blockHulls_plain;
|
||||
public static Block[] blockHulls_glass;
|
||||
|
@ -175,6 +175,8 @@ public class WarpDrive implements LoadingCallback {
|
|||
public static ItemComponent itemComponent;
|
||||
public static ItemUpgrade itemUpgrade;
|
||||
public static ItemTuningFork itemTuningRod;
|
||||
public static ItemForceFieldShape itemForceFieldShape;
|
||||
public static BlockForceFieldUpgrade blockForceFieldUpgrade;
|
||||
|
||||
public static final ArmorMaterial armorMaterial = EnumHelper.addArmorMaterial("WARP", 18, new int[] { 2, 6, 5, 2 }, 9);
|
||||
public static ItemHelmet itemHelmet;
|
||||
|
@ -188,8 +190,10 @@ public class WarpDrive implements LoadingCallback {
|
|||
public static DamageWarm damageWarm;
|
||||
|
||||
public static BiomeGenBase spaceBiome;
|
||||
public SpaceWorldGenerator spaceWorldGenerator;
|
||||
public HyperSpaceWorldGenerator hyperSpaceWorldGenerator;
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private SpaceWorldGenerator spaceWorldGenerator;
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private HyperSpaceWorldGenerator hyperSpaceWorldGenerator;
|
||||
|
||||
public static Field fieldBlockHardness = null;
|
||||
|
||||
|
@ -206,7 +210,8 @@ public class WarpDrive implements LoadingCallback {
|
|||
public static CloakManager cloaks;
|
||||
public static CamerasRegistry cameras;
|
||||
|
||||
public static WarpDrivePeripheralHandler peripheralHandler = null;
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private static WarpDrivePeripheralHandler peripheralHandler = null;
|
||||
|
||||
public static Logger logger;
|
||||
|
||||
|
@ -223,6 +228,9 @@ public class WarpDrive implements LoadingCallback {
|
|||
|
||||
RenderBlockStandard.renderId = RenderingRegistry.getNextAvailableRenderId();
|
||||
RenderingRegistry.registerBlockHandler(RenderBlockStandard.instance);
|
||||
|
||||
RenderBlockForceField.renderId = RenderingRegistry.getNextAvailableRenderId();
|
||||
RenderingRegistry.registerBlockHandler(RenderBlockForceField.instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,6 +376,7 @@ public class WarpDrive implements LoadingCallback {
|
|||
GameRegistry.registerBlock(blockIC2reactorLaserMonitor, "blockIC2reactorLaserMonitor");
|
||||
GameRegistry.registerTileEntity(TileEntityIC2reactorLaserMonitor.class, MODID + ":blockIC2reactorLaserMonitor");
|
||||
}
|
||||
|
||||
// TRANSPORT BEACON
|
||||
blockTransportBeacon = new BlockTransportBeacon();
|
||||
|
||||
|
@ -391,6 +400,29 @@ public class WarpDrive implements LoadingCallback {
|
|||
GameRegistry.registerBlock(blockChunkLoader, "blockChunkLoader");
|
||||
GameRegistry.registerTileEntity(TileEntityChunkLoader.class, MODID + ":blockChunkLoader");
|
||||
|
||||
for(byte tier = 1; tier <= 3; tier++) {
|
||||
// FORCE FIELD
|
||||
blockForceField = new BlockForceField(tier);
|
||||
GameRegistry.registerBlock(blockForceField, "blockForceField" + tier);
|
||||
GameRegistry.registerTileEntity(TileEntityForceField.class, MODID + ":blockForceField" + tier);
|
||||
|
||||
// FORCE FIELD PROJECTOR
|
||||
blockProjector = new BlockProjector(tier);
|
||||
GameRegistry.registerBlock(blockProjector, "blockProjector" + tier);
|
||||
GameRegistry.registerTileEntity(TileEntityProjector.class, MODID + ":blockProjector" + tier);
|
||||
/* TODO
|
||||
// FORCE FIELD CORE
|
||||
blockForceFieldCore = new BlockForceFieldCore(tier);
|
||||
GameRegistry.registerBlock(blockProjector, "blockForceFieldCore" + tier);
|
||||
GameRegistry.registerTileEntity(TileEntityForceFieldCore.class, MODID + ":blockForceFieldCore" + tier);
|
||||
*/
|
||||
}
|
||||
/* TODO
|
||||
// SECURITY STATION
|
||||
blockSecurityStation = new BlockSecurityStation();
|
||||
GameRegistry.registerBlock(blockSecurityStation, "blockSecurityStation");
|
||||
GameRegistry.registerTileEntity(TileEntitySecurityStation.class, MODID + ":blockSecurityStation");
|
||||
*/
|
||||
// DECORATIVE
|
||||
blockDecorative = new BlockDecorative();
|
||||
GameRegistry.registerBlock(blockDecorative, ItemBlockDecorative.class, "blockDecorative");
|
||||
|
@ -430,10 +462,19 @@ public class WarpDrive implements LoadingCallback {
|
|||
GameRegistry.registerItem(itemUpgrade, "itemUpgrade");
|
||||
}
|
||||
|
||||
// TOOL ITEMS
|
||||
itemTuningRod = new ItemTuningFork();
|
||||
GameRegistry.registerItem(itemTuningRod, "itemTuningRod");
|
||||
|
||||
// FORCEFIELD UPGRADES
|
||||
itemForceFieldShape = new ItemForceFieldShape();
|
||||
GameRegistry.registerItem(itemForceFieldShape, "itemForceFieldShape");
|
||||
|
||||
blockForceFieldUpgrade = new BlockForceFieldUpgrade();
|
||||
GameRegistry.registerBlock(blockForceFieldUpgrade, ItemBlockForceFieldUpgrade.class, "blockForceFieldUpgrade");
|
||||
GameRegistry.registerTileEntity(TileEntityForceFieldUpgrade.class, MODID + ":blockForceFieldUpgrade");
|
||||
|
||||
// DAMAGE SOURCES
|
||||
damageAsphyxia = new DamageAsphyxia();
|
||||
damageCold = new DamageCold();
|
||||
damageLaser = new DamageLaser();
|
||||
|
|
12
src/main/java/cr0s/warpdrive/api/IEffector.java
Normal file
12
src/main/java/cr0s/warpdrive/api/IEffector.java
Normal file
|
@ -0,0 +1,12 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Created by LemADEC on 16/05/2016.
|
||||
*/
|
||||
public interface IEffector {
|
||||
void onEntityCollided(World world, final int x, final int y, final int z, Entity entity);
|
||||
}
|
26
src/main/java/cr0s/warpdrive/api/IForceFieldUpgrade.java
Normal file
26
src/main/java/cr0s/warpdrive/api/IForceFieldUpgrade.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Created by LemADEC on 16/05/2016.
|
||||
*/
|
||||
public interface IForceFieldUpgrade {
|
||||
// Unique name for this upgrade category
|
||||
String getUpgradeKey();
|
||||
|
||||
// Bonus give to this upgrade category (can be positive or negative)
|
||||
int getUpgradeValue();
|
||||
|
||||
// Maximum speed of this upgrade in blocks per projector update
|
||||
// 0.3 to 30 blocks per upgrade ?
|
||||
float getMaxScanSpeed(final String upgradeKey, final int upgradeCount);
|
||||
float getMaxPlaceSpeed(final String upgradeKey, final int upgradeCount);
|
||||
|
||||
// Energy impacts of this upgrade
|
||||
float getStartupEnergyCost(final String upgradeKey, final int upgradeCount);
|
||||
float getScanEnergyCost(final String upgradeKey, final int upgradeCount);
|
||||
float getPlaceEnergyCost(final String upgradeKey, final int upgradeCount);
|
||||
}
|
18
src/main/java/cr0s/warpdrive/api/IShapeProvider.java
Normal file
18
src/main/java/cr0s/warpdrive/api/IShapeProvider.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import cr0s.warpdrive.data.ForceFieldSetup;
|
||||
import cr0s.warpdrive.data.VectorI;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IShapeProvider {
|
||||
|
||||
/**
|
||||
* Return a collection of coordinates to all blocks in a shape.
|
||||
* Rotation will be applied afterward by callee.
|
||||
* Warning: this is a threaded call, do NOT access world object during this call!
|
||||
* Boolean is true when it's the perimeter, false when it's the interior
|
||||
*/
|
||||
Map<VectorI, Boolean> getVertexes(ForceFieldSetup forceFieldSetup);
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IEffector;
|
||||
import cr0s.warpdrive.api.IDamageReceiver;
|
||||
import cr0s.warpdrive.block.BlockAbstractContainer;
|
||||
import cr0s.warpdrive.block.hull.BlockHullGlass;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.ForceFieldSetup;
|
||||
import cr0s.warpdrive.data.PermissionNode;
|
||||
import cr0s.warpdrive.data.Vector3;
|
||||
import cr0s.warpdrive.render.RenderBlockForceField;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockGlass;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class BlockForceField extends BlockAbstractContainer implements IDamageReceiver {
|
||||
@SideOnly(Side.CLIENT)
|
||||
private IIcon[] icons;
|
||||
private int tier;
|
||||
private static final float BOUNDING_TOLERANCE = 0.05F;
|
||||
|
||||
public BlockForceField(final int tier) {
|
||||
super(Material.glass);
|
||||
this.tier = tier;
|
||||
setHardness(WarpDriveConfig.HULL_HARDNESS[tier - 1]);
|
||||
setResistance(WarpDriveConfig.HULL_BLAST_RESISTANCE[tier - 1] * 5 / 3);
|
||||
setStepSound(Block.soundTypeCloth);
|
||||
setCreativeTab(WarpDrive.creativeTabWarpDrive);
|
||||
setBlockName("warpdrive.forcefield.block" + tier);
|
||||
setBlockTextureName("warpdrive:forcefield/forcefield");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int metadata) {
|
||||
return new TileEntityForceField();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer entityPlayer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMobilityFlag() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int side, int metadata) {
|
||||
return icons[metadata % 16];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int quantityDropped(Random random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canSilkHarvest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void getSubBlocks(Item item, CreativeTabs creativeTab, List list) {
|
||||
/* Hide in NEI
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
list.add(new ItemStack(item, 1, i));
|
||||
}
|
||||
/**/
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister iconRegister) {
|
||||
icons = new IIcon[16];
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
icons[i] = iconRegister.registerIcon(getTextureName() + "_" + i);
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int getRenderBlockPass() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int getRenderType() {
|
||||
return RenderBlockForceField.renderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) {
|
||||
if (world.isAirBlock(x, y, z)) {
|
||||
return true;
|
||||
}
|
||||
ForgeDirection direction = ForgeDirection.getOrientation(side).getOpposite();
|
||||
Block sideBlock = world.getBlock(x, y, z);
|
||||
if (sideBlock instanceof BlockGlass || sideBlock instanceof BlockHullGlass || sideBlock instanceof BlockForceField) {
|
||||
return world.getBlockMetadata(x, y, z)
|
||||
!= world.getBlockMetadata(x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ);
|
||||
}
|
||||
return !world.isSideSolid(x, y, z, direction, false);
|
||||
}
|
||||
|
||||
protected TileEntityProjector getProjector(World world, int x, int y, int z) {
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (tileEntity instanceof TileEntityForceField) {
|
||||
return ((TileEntityForceField) tileEntity).getProjector();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ForceFieldSetup getForceFieldSetup(World world, int x, int y, int z) {
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (tileEntity instanceof TileEntityForceField) {
|
||||
return ((TileEntityForceField) tileEntity).getForceFieldSetup();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer entityPlayer) {
|
||||
ForceFieldSetup forceFieldSetup = getForceFieldSetup(world, x, y, z);
|
||||
if (forceFieldSetup != null) {
|
||||
for (IEffector effector : forceFieldSetup.getEffectors()) {
|
||||
effector.onEntityCollided(world, x, y, z, entityPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
|
||||
ForceFieldSetup forceFieldSetup = getForceFieldSetup(world, x, y, z);
|
||||
if (forceFieldSetup != null) {
|
||||
List<EntityPlayer> entities = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 0.9D, z + 1));
|
||||
|
||||
for (EntityPlayer entityPlayer : entities) {
|
||||
if (entityPlayer != null && entityPlayer.isSneaking()) {
|
||||
if ( entityPlayer.capabilities.isCreativeMode
|
||||
|| forceFieldSetup.isAccessGranted(entityPlayer, PermissionNode.SNEAK_THROUGH)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AxisAlignedBB.getBoundingBox(
|
||||
x + BOUNDING_TOLERANCE, y + BOUNDING_TOLERANCE, z + BOUNDING_TOLERANCE,
|
||||
x + 1 - BOUNDING_TOLERANCE, y + 1 - BOUNDING_TOLERANCE, z + 1 - BOUNDING_TOLERANCE);
|
||||
}
|
||||
|
||||
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) {
|
||||
if (world.isRemote) {
|
||||
return;
|
||||
}
|
||||
|
||||
ForceFieldSetup forceFieldSetup = getForceFieldSetup(world, x, y, z);
|
||||
if (forceFieldSetup != null) {
|
||||
for (IEffector effector : forceFieldSetup.getEffectors()) {
|
||||
effector.onEntityCollided(world, x, y, z, entity);
|
||||
}
|
||||
|
||||
if (entity instanceof EntityLiving && new Vector3(x, y, z).translate(0.5F).distanceTo_square(entity) < 0.4D) {
|
||||
boolean hasPermission = false;
|
||||
|
||||
List<EntityPlayer> entities = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 0.9D, z + 1));
|
||||
for (EntityPlayer entityPlayer : entities) {
|
||||
if (entityPlayer != null && entityPlayer.isSneaking()) {
|
||||
if ( entityPlayer.capabilities.isCreativeMode
|
||||
|| forceFieldSetup.isAccessGranted(entityPlayer, PermissionNode.SNEAK_THROUGH)) {
|
||||
hasPermission = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// always slowdown
|
||||
((EntityLiving) entity).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20, 1));
|
||||
|
||||
if (!hasPermission) {
|
||||
((EntityLiving) entity).addPotionEffect(new PotionEffect(Potion.confusion.id, 80, 3));
|
||||
entity.attackEntityFrom(WarpDrive.damageShock, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int colorMultiplier(IBlockAccess blockAccess, int x, int y, int z) {
|
||||
TileEntity tileEntity = blockAccess.getTileEntity(x, y, z);
|
||||
if (tileEntity instanceof TileEntityForceField) {
|
||||
ForceFieldSetup forceFieldSetup = ((TileEntityForceField)tileEntity).getForceFieldSetup();
|
||||
if (forceFieldSetup != null) {
|
||||
Block blockCamouflage = forceFieldSetup.getCamouflageBlock();
|
||||
if (blockCamouflage != null) {
|
||||
try {
|
||||
return blockCamouflage.colorMultiplier(blockAccess, x, y, z);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.colorMultiplier(blockAccess, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue(IBlockAccess blockAccess, int x, int y, int z) {
|
||||
TileEntity tileEntity = blockAccess.getTileEntity(x, y, z);
|
||||
if (tileEntity instanceof TileEntityForceField) {
|
||||
ForceFieldSetup forceFieldSetup = ((TileEntityForceField)tileEntity).getForceFieldSetup();
|
||||
if (forceFieldSetup != null) {
|
||||
Block blockCamouflage = forceFieldSetup.getCamouflageBlock();
|
||||
if (blockCamouflage != null) {
|
||||
try {
|
||||
return blockCamouflage.getLightValue(blockAccess, x, y, z);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBlockHardness(World world, int x, int y, int z, DamageSource damageSource, int damageParameter, Vector3 damageDirection, int damageLevel) {
|
||||
return WarpDriveConfig.HULL_HARDNESS[tier - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int applyDamage(World world, int x, int y, int z, DamageSource damageSource, int damageParameter, Vector3 damageDirection, int damageLevel) {
|
||||
ForceFieldSetup forceFieldSetup = getForceFieldSetup(world, x, y, z);
|
||||
if (forceFieldSetup != null) {
|
||||
return forceFieldSetup.applyDamages(world, x, y, z, damageSource, damageParameter, damageDirection, damageLevel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.block.BlockAbstractContainer;
|
||||
import cr0s.warpdrive.data.EnumForceFieldUpgrade;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockForceFieldUpgrade extends BlockAbstractContainer {
|
||||
@SideOnly(Side.CLIENT)
|
||||
private final IIcon[] icons;
|
||||
|
||||
public BlockForceFieldUpgrade() {
|
||||
super(Material.iron);
|
||||
isRotating = false;
|
||||
setBlockName("warpdrive.forcefield.upgrade");
|
||||
setBlockTextureName("warpdrive:forcefield/upgrade");
|
||||
|
||||
icons = new IIcon[EnumForceFieldUpgrade.length];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(Item item, CreativeTabs creativeTabs, List list) {
|
||||
for (EnumForceFieldUpgrade enumForceFieldUpgrade : EnumForceFieldUpgrade.values()) {
|
||||
list.add(new ItemStack(item, 1, enumForceFieldUpgrade.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBlockIcons(IIconRegister iconRegister) {
|
||||
for (EnumForceFieldUpgrade enumForceFieldUpgrade : EnumForceFieldUpgrade.values()) {
|
||||
icons[enumForceFieldUpgrade.ordinal()] = iconRegister.registerIcon("warpdrive:forcefield/upgrade" + "_" + enumForceFieldUpgrade.unlocalizedName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIcon getIcon(int side, int damage) {
|
||||
if (damage >= 0 && damage < EnumForceFieldUpgrade.length) {
|
||||
return icons[damage];
|
||||
}
|
||||
return icons[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(int damage) {
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
|
||||
if (world.isRemote) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (!(tileEntity instanceof TileEntityForceFieldUpgrade)) {
|
||||
return false;
|
||||
}
|
||||
TileEntityForceFieldUpgrade tileEntityForceFieldUpgrade = (TileEntityForceFieldUpgrade) tileEntity;
|
||||
ItemStack itemStackHeld = entityPlayer.getHeldItem();
|
||||
|
||||
if (itemStackHeld == null) {
|
||||
WarpDrive.addChatMessage(entityPlayer, tileEntityForceFieldUpgrade.getStatus());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int metadata) {
|
||||
return new TileEntityForceFieldUpgrade();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canSilkHarvest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer entityPlayer) {
|
||||
return null; // FIXME
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.block.BlockAbstractContainer;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.EnumForceFieldShape;
|
||||
import cr0s.warpdrive.item.ItemForceFieldShape;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class BlockProjector extends BlockAbstractContainer {
|
||||
@SideOnly(Side.CLIENT)
|
||||
private IIcon[] icons;
|
||||
protected byte tier;
|
||||
|
||||
public BlockProjector(final byte tier) {
|
||||
super(Material.iron);
|
||||
isRotating = true;
|
||||
this.tier = tier;
|
||||
setHardness(WarpDriveConfig.HULL_HARDNESS[tier - 1]);
|
||||
setResistance(WarpDriveConfig.HULL_BLAST_RESISTANCE[tier - 1] * 5 / 3);
|
||||
setBlockName("warpdrive.forcefield.projector" + tier);
|
||||
setBlockTextureName("warpdrive:forcefield/projector");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBlockIcons(IIconRegister iconRegister) {
|
||||
icons = new IIcon[11];
|
||||
icons[ 0] = iconRegister.registerIcon("warpdrive:forcefield/projectorSide_notConnected");
|
||||
icons[ 1] = iconRegister.registerIcon("warpdrive:forcefield/projectorSide_connectedNotPowered");
|
||||
icons[ 2] = iconRegister.registerIcon("warpdrive:forcefield/projectorSide_connectedPowered");
|
||||
icons[ 3] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_none");
|
||||
icons[ 4] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_sphere");
|
||||
icons[ 5] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_cylinder_h");
|
||||
icons[ 6] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_cylinder_v");
|
||||
icons[ 7] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_cube");
|
||||
icons[ 8] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_plane");
|
||||
icons[ 9] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_tube");
|
||||
icons[10] = iconRegister.registerIcon("warpdrive:forcefield/projectorShape_tunnel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) {
|
||||
int metadata = world.getBlockMetadata(x, y, z);
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (tileEntity == null || !(tileEntity instanceof TileEntityProjector)) {
|
||||
return icons[0];
|
||||
}
|
||||
|
||||
if (side == (metadata & 7) || (((TileEntityProjector)tileEntity).isDoubleSided && ForgeDirection.OPPOSITES[side] == (metadata & 7))) {
|
||||
return icons[3 + ((TileEntityProjector)tileEntity).getShape().ordinal()];
|
||||
} else if (((TileEntityProjector)tileEntity).isConnected) {
|
||||
if (((TileEntityProjector)tileEntity).isPowered) {
|
||||
return icons[2];
|
||||
} else {
|
||||
return icons[1];
|
||||
}
|
||||
}
|
||||
|
||||
return icons[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIcon getIcon(int side, int metadata) {
|
||||
return side == 3 ? icons[4] : icons[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
|
||||
if (world.isRemote) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (!(tileEntity instanceof TileEntityProjector)) {
|
||||
return false;
|
||||
}
|
||||
TileEntityProjector tileEntityProjector = (TileEntityProjector) tileEntity;
|
||||
ItemStack itemStackHeld = entityPlayer.getHeldItem();
|
||||
int metadata = world.getBlockMetadata(x, y, z);
|
||||
|
||||
if (itemStackHeld == null) {
|
||||
if (entityPlayer.isSneaking()) {
|
||||
if (tileEntityProjector.getShape() != EnumForceFieldShape.NONE) {
|
||||
if (side == (metadata & 7) || (tileEntityProjector.isDoubleSided && ForgeDirection.OPPOSITES[side] == (metadata & 7))) {
|
||||
// dismount the shape item(s)
|
||||
ItemStack itemStackDrop = ItemForceFieldShape.getItemStackNoCache(tileEntityProjector.getShape(), tileEntityProjector.isDoubleSided ? 2 : 1);
|
||||
EntityItem entityItem = new EntityItem(world, entityPlayer.posX, entityPlayer.posY + 0.5D, entityPlayer.posZ, itemStackDrop);
|
||||
entityItem.delayBeforeCanPickup = 0;
|
||||
world.spawnEntityInWorld(entityItem);
|
||||
|
||||
tileEntityProjector.setShape(EnumForceFieldShape.NONE);
|
||||
} else {
|
||||
// wrong side TODO
|
||||
WarpDrive.addChatMessage(entityPlayer, tileEntityProjector.getStatus());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// no shape to dismount TODO
|
||||
WarpDrive.addChatMessage(entityPlayer, tileEntityProjector.getStatus());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
WarpDrive.addChatMessage(entityPlayer, tileEntityProjector.getStatus());
|
||||
return true;
|
||||
}
|
||||
} else if (itemStackHeld.getItem() instanceof ItemForceFieldShape) {
|
||||
if (side == (metadata & 7) || (((TileEntityProjector) tileEntity).isDoubleSided && ForgeDirection.OPPOSITES[side] == (metadata & 7))) {
|
||||
// validate quantity
|
||||
if (itemStackHeld.stackSize < (tileEntityProjector.isDoubleSided ? 2 : 1)) {
|
||||
// not enough shape items TODO
|
||||
WarpDrive.addChatMessage(entityPlayer, ((TileEntityProjector) tileEntity).getStatus());
|
||||
return true;
|
||||
}
|
||||
|
||||
// update player inventory
|
||||
itemStackHeld.stackSize -= tileEntityProjector.isDoubleSided ? 2 : 1;
|
||||
|
||||
// dismount the shape item(s)
|
||||
if (tileEntityProjector.getShape() != EnumForceFieldShape.NONE) {
|
||||
ItemStack itemStackDrop = ItemForceFieldShape.getItemStackNoCache(tileEntityProjector.getShape(), tileEntityProjector.isDoubleSided ? 2 : 1);
|
||||
EntityItem entityItem = new EntityItem(world, entityPlayer.posX, entityPlayer.posY + 0.5D, entityPlayer.posZ, itemStackDrop);
|
||||
entityItem.delayBeforeCanPickup = 0;
|
||||
world.spawnEntityInWorld(entityItem);
|
||||
}
|
||||
|
||||
// mount the new shape item(s)
|
||||
tileEntityProjector.setShape(EnumForceFieldShape.get(itemStackHeld.getItemDamage()));
|
||||
} else {
|
||||
// wrong side TODO
|
||||
WarpDrive.addChatMessage(entityPlayer, ((TileEntityProjector) tileEntity).getStatus());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int metadata) {
|
||||
return new TileEntityProjector();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canSilkHarvest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer entityPlayer) {
|
||||
return null; // FIXME
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.data.DecorativeType;
|
||||
import cr0s.warpdrive.data.EnumForceFieldUpgrade;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemBlockForceFieldUpgrade extends ItemBlock {
|
||||
private static ItemStack[] itemStackCache;
|
||||
|
||||
public ItemBlockForceFieldUpgrade(Block block) {
|
||||
super(block);
|
||||
setHasSubtypes(true);
|
||||
setUnlocalizedName("warpdrive.forcefield.upgrade");
|
||||
itemStackCache = new ItemStack[EnumForceFieldUpgrade.length];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetadata(int damage) {
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems(Item item, CreativeTabs creativeTab, List list) {
|
||||
for(EnumForceFieldUpgrade enumForceFieldUpgrade : EnumForceFieldUpgrade.values()) {
|
||||
list.add(new ItemStack(item, 1, enumForceFieldUpgrade.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName(ItemStack itemStack) {
|
||||
int damage = itemStack.getItemDamage();
|
||||
if (damage >= 0 && damage < EnumForceFieldUpgrade.length) {
|
||||
return getUnlocalizedName() + "." + EnumForceFieldUpgrade.get(damage).unlocalizedName;
|
||||
}
|
||||
return getUnlocalizedName();
|
||||
}
|
||||
|
||||
public static ItemStack getItemStack(EnumForceFieldUpgrade enumForceFieldUpgrade) {
|
||||
if (enumForceFieldUpgrade != null) {
|
||||
int damage = enumForceFieldUpgrade.ordinal();
|
||||
if (itemStackCache[damage] == null) {
|
||||
itemStackCache[damage] = new ItemStack(WarpDrive.itemComponent, 1, damage);
|
||||
}
|
||||
return itemStackCache[damage];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getItemStackNoCache(EnumForceFieldUpgrade enumForceFieldUpgrade, int amount) {
|
||||
return new ItemStack(WarpDrive.blockForceFieldUpgrade, amount, enumForceFieldUpgrade.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List list, boolean advancedItemTooltips) {
|
||||
super.addInformation(itemStack, entityPlayer, list, advancedItemTooltips);
|
||||
|
||||
String tooltipName1 = getUnlocalizedName(itemStack) + ".tooltip";
|
||||
if (StatCollector.canTranslate(tooltipName1)) {
|
||||
WarpDrive.addTooltip(list, StatCollector.translateToLocalFormatted(tooltipName1));
|
||||
}
|
||||
|
||||
String tooltipName2 = getUnlocalizedName() + ".tooltip";
|
||||
if ((!tooltipName1.equals(tooltipName2)) && StatCollector.canTranslate(tooltipName2)) {
|
||||
WarpDrive.addTooltip(list, StatCollector.translateToLocalFormatted(tooltipName2));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBeamFrequency;
|
||||
import cr0s.warpdrive.block.TileEntityAbstractEnergy;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.ForceFieldRegistry;
|
||||
import cr0s.warpdrive.data.Vector3;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import li.cil.oc.api.machine.Arguments;
|
||||
import li.cil.oc.api.machine.Callback;
|
||||
import li.cil.oc.api.machine.Context;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
/**
|
||||
* Created by LemADEC on 16/05/2016.
|
||||
*/
|
||||
public class TileEntityAbstractForceField extends TileEntityAbstractEnergy implements IBeamFrequency {
|
||||
// persistent properties
|
||||
protected int beamFrequency = -1;
|
||||
public boolean isEnabled = true;
|
||||
|
||||
// computed properties
|
||||
protected Vector3 vRGB;
|
||||
protected boolean isConnected = true;
|
||||
|
||||
public TileEntityAbstractForceField() {
|
||||
super();
|
||||
|
||||
addMethods(new String[]{
|
||||
"enable",
|
||||
"beamFrequency"
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFirstUpdateTick() {
|
||||
if (beamFrequency >= 0 && beamFrequency <= IBeamFrequency.BEAM_FREQUENCY_MAX) {
|
||||
ForceFieldRegistry.updateInRegistry(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEntity() {
|
||||
super.updateEntity();
|
||||
|
||||
// Frequency is not set
|
||||
isConnected = beamFrequency > 0 && beamFrequency <= IBeamFrequency.BEAM_FREQUENCY_MAX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
ForceFieldRegistry.removeFromRegistry(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnload() {
|
||||
super.onChunkUnload();
|
||||
// reload chunks as needed?
|
||||
// ForceFieldRegistry.removeFromRegistry(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeamFrequency() {
|
||||
return beamFrequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeamFrequency(final int parBeamFrequency) {
|
||||
if (beamFrequency != parBeamFrequency && (parBeamFrequency <= BEAM_FREQUENCY_MAX) && (parBeamFrequency > 0)) {
|
||||
if (WarpDriveConfig.LOGGING_VIDEO_CHANNEL) {
|
||||
WarpDrive.logger.info(this + " Beam frequency set from " + beamFrequency + " to " + parBeamFrequency);
|
||||
}
|
||||
if (worldObj != null) {
|
||||
ForceFieldRegistry.removeFromRegistry(this);
|
||||
}
|
||||
beamFrequency = parBeamFrequency;
|
||||
vRGB = IBeamFrequency.getBeamColor(beamFrequency);
|
||||
}
|
||||
if (worldObj != null) {
|
||||
ForceFieldRegistry.updateInRegistry(this);
|
||||
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getBeamFrequencyStatus() {
|
||||
if (beamFrequency < 0) {
|
||||
return StatCollector.translateToLocalFormatted("warpdrive.beamFrequency.statusLine.invalid",
|
||||
beamFrequency);
|
||||
} else {
|
||||
return StatCollector.translateToLocalFormatted("warpdrive.beamFrequency.statusLine.valid",
|
||||
beamFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return StatCollector.translateToLocalFormatted("warpdrive.guide.prefix",
|
||||
getBlockType().getLocalizedName())
|
||||
+ getBeamFrequencyStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
super.readFromNBT(tag);
|
||||
setBeamFrequency(tag.getInteger("beamFrequency"));
|
||||
isEnabled = tag.getBoolean("isEnabled");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound tag) {
|
||||
super.writeToNBT(tag);
|
||||
tag.setInteger("beamFrequency", beamFrequency);
|
||||
tag.setBoolean("isEnabled", isEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet getDescriptionPacket() {
|
||||
NBTTagCompound tagCompound = new NBTTagCompound();
|
||||
writeToNBT(tagCompound);
|
||||
tagCompound.setBoolean("isConnected", isConnected);
|
||||
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tagCompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) {
|
||||
NBTTagCompound tagCompound = packet.func_148857_g();
|
||||
readFromNBT(tagCompound);
|
||||
isConnected = tagCompound.getBoolean("isConnected");
|
||||
}
|
||||
|
||||
// OpenComputer callback methods
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] enable(Context context, Arguments arguments) throws Exception {
|
||||
return enable(argumentsOCtoCC(arguments));
|
||||
}
|
||||
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] beamFrequency(Context context, Arguments arguments) {
|
||||
if (arguments.count() == 1) {
|
||||
setBeamFrequency(arguments.checkInteger(0));
|
||||
}
|
||||
return new Integer[] { beamFrequency };
|
||||
}
|
||||
|
||||
public Object[] enable(Object[] arguments) throws Exception {
|
||||
if (arguments.length == 1) {
|
||||
boolean enable;
|
||||
try {
|
||||
enable = toBool(arguments[0]);
|
||||
} catch (Exception exception) {
|
||||
throw new Exception("Function expects a boolean value");
|
||||
}
|
||||
isEnabled = enable;
|
||||
}
|
||||
return new Object[] { isEnabled };
|
||||
}
|
||||
|
||||
// ComputerCraft IPeripheral methods implementation
|
||||
@Override
|
||||
@Optional.Method(modid = "ComputerCraft")
|
||||
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
|
||||
String methodName = getMethodName(method);
|
||||
|
||||
try {
|
||||
switch (methodName) {
|
||||
case "enable":
|
||||
return enable(arguments);
|
||||
|
||||
case "beamFrequency":
|
||||
if (arguments.length == 1) {
|
||||
setBeamFrequency(toInt(arguments[0]));
|
||||
}
|
||||
return new Integer[]{ beamFrequency };
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
return new String[] { exception.getMessage() };
|
||||
}
|
||||
|
||||
return super.callMethod(computer, context, method, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s Beam \'%d\' @ \'%s\' (%d %d %d)", getClass().getSimpleName(),
|
||||
beamFrequency, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), xCoord, yCoord, zCoord);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cr0s.warpdrive.block.TileEntityAbstractBase;
|
||||
import cr0s.warpdrive.data.ForceFieldSetup;
|
||||
import cr0s.warpdrive.data.VectorI;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
/**
|
||||
* Created by LemADEC on 16/05/2016.
|
||||
*/
|
||||
public class TileEntityForceField extends TileEntityAbstractBase {
|
||||
private VectorI vProjector;
|
||||
// cache parameters used for rendering, force projector check for others
|
||||
private int cache_beamFrequency;
|
||||
private ItemStack cache_itemStackCamouflage;
|
||||
private int gracePeriod_calls = 1;
|
||||
|
||||
@Override
|
||||
public boolean canUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
super.readFromNBT(tag);
|
||||
if (tag.hasKey("projector")) {
|
||||
vProjector = VectorI.readFromNBT(tag.getCompoundTag("projector"));
|
||||
cache_beamFrequency = tag.getInteger("beamFrequency");
|
||||
if (tag.hasKey("projector")) {
|
||||
try {
|
||||
cache_itemStackCamouflage = ItemStack.loadItemStackFromNBT(tag.getCompoundTag("camouflage"));
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
cache_itemStackCamouflage = null;
|
||||
}
|
||||
} else {
|
||||
vProjector = null;
|
||||
cache_beamFrequency = -1;
|
||||
cache_itemStackCamouflage = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound tagCompound) {
|
||||
super.writeToNBT(tagCompound);
|
||||
if (vProjector != null) {
|
||||
tagCompound.setTag("projector", vProjector.writeToNBT(new NBTTagCompound()));
|
||||
tagCompound.setInteger("beamFrequency", cache_beamFrequency);
|
||||
if (cache_itemStackCamouflage != null) {
|
||||
tagCompound.setTag("camouflage", cache_itemStackCamouflage.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet getDescriptionPacket() {
|
||||
NBTTagCompound tagCompound = new NBTTagCompound();
|
||||
writeToNBT(tagCompound);
|
||||
|
||||
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, -1, tagCompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) {
|
||||
NBTTagCompound tagCompound = packet.func_148857_g();
|
||||
readFromNBT(tagCompound);
|
||||
// worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); // TODO is it needed?
|
||||
}
|
||||
|
||||
public void setProjector(final VectorI vectorI) {
|
||||
vProjector = vectorI;
|
||||
ForceFieldSetup forceFieldSetup = getForceFieldSetup();
|
||||
if (forceFieldSetup != null) {
|
||||
cache_beamFrequency = forceFieldSetup.beamFrequency;
|
||||
cache_itemStackCamouflage = forceFieldSetup.itemStackCamouflage;
|
||||
}
|
||||
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
||||
}
|
||||
|
||||
public TileEntityProjector getProjector() {
|
||||
if (vProjector != null) {
|
||||
TileEntity tileEntity = vProjector.getTileEntity(worldObj);
|
||||
if (tileEntity instanceof TileEntityProjector) {
|
||||
TileEntityProjector tileEntityProjector = (TileEntityProjector) tileEntity;
|
||||
if (worldObj.isRemote || tileEntityProjector.isPartOfForceField(new VectorI(this))) {
|
||||
return tileEntityProjector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!worldObj.isRemote) {
|
||||
gracePeriod_calls--;
|
||||
if (gracePeriod_calls < 0) {
|
||||
worldObj.setBlockToAir(xCoord, yCoord, zCoord);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ForceFieldSetup getForceFieldSetup() {
|
||||
TileEntityProjector tileEntityProjector = getProjector();
|
||||
if (tileEntityProjector == null) {
|
||||
return null;
|
||||
}
|
||||
return tileEntityProjector.getForceFieldSetup();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cr0s.warpdrive.api.IForceFieldUpgrade;
|
||||
import cr0s.warpdrive.data.EnumForceFieldUpgrade;
|
||||
|
||||
/**
|
||||
* Created by LemADEC on 16/05/2016.
|
||||
*/
|
||||
public class TileEntityForceFieldUpgrade extends TileEntityAbstractForceField implements IForceFieldUpgrade {
|
||||
public TileEntityForceFieldUpgrade() {
|
||||
super();
|
||||
|
||||
peripheralName = "warpdriveForceFieldUpgrade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpgradeKey() {
|
||||
return isEnabled ? EnumForceFieldUpgrade.get(getBlockMetadata()).unlocalizedName : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUpgradeValue() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxScanSpeed(final String upgradeKey, final int upgradeCount) {
|
||||
return 10.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxPlaceSpeed(final String upgradeKey, final int upgradeCount) {
|
||||
return 10.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStartupEnergyCost(final String upgradeKey, final int upgradeCount) {
|
||||
return 100.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getScanEnergyCost(final String upgradeKey, final int upgradeCount) {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPlaceEnergyCost(final String upgradeKey, final int upgradeCount) {
|
||||
return 10.0F;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,502 @@
|
|||
package cr0s.warpdrive.block.forcefield;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IShapeProvider;
|
||||
import cr0s.warpdrive.config.*;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.data.*;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Created by LemADEC on 16/05/2016.
|
||||
*/
|
||||
public class TileEntityProjector extends TileEntityAbstractForceField {
|
||||
private static final int PROJECTOR_MAX_ENERGY_STORED = 100000;
|
||||
private static final int PROJECTOR_COOLDOWN_TICKS = 200;
|
||||
private static final int PROJECTOR_PROJECTION_UPDATE_TICKS = 8;
|
||||
private static final int PROJECTOR_SOUND_UPDATE_TICKS = Integer.MAX_VALUE; // TODO
|
||||
private static final int PROJECTOR_SCAN_MAX_BLOCKS_PER_UPDATE = 200;
|
||||
private static final int PROJECTOR_PLACE_MAX_BLOCKS_PER_UPDATE = 100;
|
||||
|
||||
// persistent properties
|
||||
public boolean isDoubleSided = true;
|
||||
private byte tier = -1;
|
||||
private EnumForceFieldShape shape = EnumForceFieldShape.NONE;
|
||||
|
||||
// computed properties
|
||||
private int cooldownTicks;
|
||||
private int updateTicks;
|
||||
protected boolean isPowered = true;
|
||||
private final boolean enableSound = false;
|
||||
|
||||
// allow only one computation at a time
|
||||
private static final AtomicBoolean isGlobalThreadRunning = new AtomicBoolean(false);
|
||||
// computation is ongoing for this specific tile
|
||||
private final AtomicBoolean isThreadRunning = new AtomicBoolean(false);
|
||||
// parameters have changed, new computation is required
|
||||
private final AtomicBoolean isDirty = new AtomicBoolean(true);
|
||||
|
||||
private Set<VectorI> calculated_interiorField = null;
|
||||
private Set<VectorI> calculated_forceField = null;
|
||||
private Iterator<VectorI> iteratorForcefield = null;
|
||||
|
||||
// currently placed forcefields
|
||||
private final Set<VectorI> vForceFields = new HashSet<>();
|
||||
|
||||
public TileEntityProjector() {
|
||||
super();
|
||||
|
||||
peripheralName = "warpdriveForceFieldProjector";
|
||||
addMethods(new String[]{
|
||||
"status" // isConnected, isPowered, shape
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFirstUpdateTick() {
|
||||
super.onFirstUpdateTick();
|
||||
tier = ((BlockProjector) getBlockType()).tier;
|
||||
cooldownTicks = worldObj.rand.nextInt(PROJECTOR_PROJECTION_UPDATE_TICKS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEntity() {
|
||||
super.updateEntity();
|
||||
|
||||
// Frequency is not set
|
||||
if (!isConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Powered ?
|
||||
int energyRequired;
|
||||
energyRequired = getEnergyRequired();
|
||||
isPowered = getEnergyStored() >= energyRequired;
|
||||
|
||||
boolean isEnabledAndValid = isEnabled && isValid();
|
||||
boolean isOn = isEnabledAndValid && cooldownTicks <= 0 && isPowered;
|
||||
if (isOn) {
|
||||
consumeEnergy(energyRequired, false);
|
||||
cooldownTicks = 0;
|
||||
|
||||
updateTicks++;
|
||||
if (!worldObj.isRemote) {
|
||||
if (updateTicks > PROJECTOR_PROJECTION_UPDATE_TICKS) {
|
||||
updateTicks = 0;
|
||||
if (!isCalculated()) {
|
||||
calculateForceField();
|
||||
} else {
|
||||
projectForceField();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO add some animation
|
||||
if (updateTicks > PROJECTOR_SOUND_UPDATE_TICKS) {
|
||||
if (enableSound) {
|
||||
worldObj.playSoundEffect(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, "projecting", 1.0F, 0.85F + 0.15F * worldObj.rand.nextFloat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!worldObj.isRemote) {
|
||||
destroyForceField(false);
|
||||
if (cooldownTicks > 0) {
|
||||
cooldownTicks--;
|
||||
} else if (isEnabledAndValid) {
|
||||
cooldownTicks = PROJECTOR_COOLDOWN_TICKS;
|
||||
String msg = "We're running out of power captain, reduce our consumption or get that scottish engineer to boost our power!";
|
||||
|
||||
AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBox(xCoord - 10, yCoord - 10, zCoord - 10, xCoord + 10, yCoord + 10, zCoord + 10);
|
||||
List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
|
||||
|
||||
System.out.println(this + " messageToPlayersNearby: " + msg);
|
||||
for (Entity entity : list) {
|
||||
if (entity == null || (!(entity instanceof EntityPlayer)) || entity instanceof FakePlayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WarpDrive.addChatMessage((EntityPlayer) entity, "[Projector] " + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
destroyForceField(true);
|
||||
}
|
||||
|
||||
private int getEnergyRequired() {
|
||||
return 6 + 2 * tier;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return getShape() != EnumForceFieldShape.NONE;
|
||||
}
|
||||
|
||||
public boolean isCalculated() {
|
||||
return !isDirty.get() && !isThreadRunning.get();
|
||||
}
|
||||
|
||||
private void calculateForceField() {
|
||||
if ((!worldObj.isRemote) && isValid()) {
|
||||
if (!isGlobalThreadRunning.getAndSet(true)) {
|
||||
isThreadRunning.set(true);
|
||||
isDirty.set(false);
|
||||
iteratorForcefield = null;
|
||||
calculated_interiorField = null;
|
||||
calculated_forceField = null;
|
||||
vForceFields.clear();
|
||||
|
||||
new ThreadCalculation(this).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void calculation_done(Set<VectorI> interiorField, Set<VectorI> forceField) {
|
||||
if (interiorField == null || forceField == null) {
|
||||
calculated_interiorField = new HashSet<>(0);
|
||||
calculated_forceField = new HashSet<>(0);
|
||||
} else {
|
||||
calculated_interiorField = interiorField;
|
||||
calculated_forceField = forceField;
|
||||
}
|
||||
isThreadRunning.set(false);
|
||||
isGlobalThreadRunning.set(false);
|
||||
}
|
||||
|
||||
public boolean isPartOfForceField(VectorI vector) {
|
||||
if (!isEnabled || !isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (!isCalculated()) {
|
||||
return true;
|
||||
}
|
||||
// only consider the forcefield itself
|
||||
return calculated_forceField.contains(vector);
|
||||
}
|
||||
|
||||
private Set<VectorI> getInteriorPoints() {
|
||||
if (!isCalculated()) {
|
||||
throw new ConcurrentModificationException("Calculation ongoing...");
|
||||
}
|
||||
return calculated_interiorField;
|
||||
}
|
||||
|
||||
private void projectForceField() {
|
||||
if (worldObj.isRemote || (!isCalculated())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ForceFieldSetup forceFieldSetup = getForceFieldSetup();
|
||||
int scanCount = 0;
|
||||
int scanSpeed = Math.min(calculated_forceField.size(), PROJECTOR_SCAN_MAX_BLOCKS_PER_UPDATE);
|
||||
int constructionCount = 0;
|
||||
int constructionSpeed = Math.min(forceFieldSetup.getProjectionSpeed(), PROJECTOR_PLACE_MAX_BLOCKS_PER_UPDATE);
|
||||
|
||||
boolean hasDisintegration = forceFieldSetup.disintegrationLevel > 0;
|
||||
|
||||
Set<TileEntityProjector> projectors = new HashSet<>();
|
||||
if (forceFieldSetup.hasFusion) {
|
||||
for (TileEntity tileEntity : ForceFieldRegistry.getTileEntities(getBeamFrequency())) {
|
||||
if ( (tileEntity instanceof TileEntityProjector)
|
||||
&& (tileEntity != this)
|
||||
&& (((TileEntityProjector) tileEntity).worldObj == worldObj)
|
||||
&& (((TileEntityProjector) tileEntity).isEnabled)
|
||||
&& (((TileEntityProjector) tileEntity).isValid())
|
||||
&& (((TileEntityProjector) tileEntity).isCalculated())) {
|
||||
projectors.add((TileEntityProjector) tileEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorI vector;
|
||||
Block block;
|
||||
boolean noFusion;
|
||||
|
||||
while (scanCount < scanSpeed && constructionCount < constructionSpeed) {
|
||||
if (iteratorForcefield == null || !iteratorForcefield.hasNext()) {
|
||||
iteratorForcefield = calculated_forceField.iterator();
|
||||
}
|
||||
scanCount++;
|
||||
|
||||
vector = iteratorForcefield.next();
|
||||
|
||||
if (!worldObj.blockExists(vector.x, vector.y, vector.z) || !worldObj.getChunkFromBlockCoords(vector.x, vector.z).isChunkLoaded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
block = vector.getBlock(worldObj);
|
||||
noFusion = true;
|
||||
|
||||
if (forceFieldSetup.hasFusion) {
|
||||
for (TileEntityProjector projector : projectors) {
|
||||
if (projector.getInteriorPoints().contains(vector)) {
|
||||
noFusion = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (noFusion) {
|
||||
// TODO: check area protection
|
||||
// MFR laser is unbreakable and replaceable
|
||||
// Liquid, vine and snow are replaceable
|
||||
if ( (block == null) || (block == Blocks.tallgrass) || (block == Blocks.deadbush)
|
||||
|| Dictionary.BLOCKS_EXPANDABLE.contains(block)
|
||||
|| (hasDisintegration && (block.getBlockHardness(worldObj, vector.x, vector.y, vector.z) != -1.0F))
|
||||
|| (!hasDisintegration && block.isReplaceable(worldObj, vector.x, vector.y, vector.z))) {
|
||||
|
||||
if ((block != WarpDrive.blockForceField) && (!vector.equals(this))) {
|
||||
float energyConsumed = 0;
|
||||
// if (forceFieldSetup.disintegrationLevel > 0) {
|
||||
// TODO break the block
|
||||
// TODO store result in chest or drop it?
|
||||
// } else if (forceFieldSetup.hasStabilize) {
|
||||
// TODO collect from chest
|
||||
// TODO place block (ItemBlock.place?)
|
||||
// } else if (forceFieldSetup.hasPump) {
|
||||
|
||||
// } else if (forceFieldSetup.temperatureLevel != 0 && forceFieldSetup.hasWorldInteraction) {
|
||||
// TODO glass <> sandstone <> sand <> gravel <> cobblestone <> stone <> obsidian
|
||||
// TODO ice <> snow <> water <> air > fire
|
||||
// TODO obsidian < lava
|
||||
// } else {
|
||||
energyConsumed = 1; // TODO
|
||||
worldObj.setBlock(vector.x, vector.y, vector.z, WarpDrive.blockForceField, 0, 2);
|
||||
|
||||
TileEntity tileEntity = worldObj.getTileEntity(vector.x, vector.y, vector.z);
|
||||
if (tileEntity instanceof TileEntityForceField) {
|
||||
((TileEntityForceField) tileEntity).setProjector(new VectorI(this));
|
||||
}
|
||||
|
||||
vForceFields.add(vector);
|
||||
// }
|
||||
if (energyConsumed > 0) {
|
||||
constructionCount++;
|
||||
consumeEnergy(Math.round(energyConsumed), false);
|
||||
} else {
|
||||
consumeEnergy(Math.round(1), false); // TODO
|
||||
}
|
||||
}
|
||||
} else if (block == WarpDrive.blockForceField && !vForceFields.contains(vector)) {
|
||||
TileEntity tileEntity = worldObj.getTileEntity(vector.x, vector.y, vector.z);
|
||||
if (tileEntity instanceof TileEntityForceField && (((TileEntityForceField) tileEntity).getProjector() == this)) {
|
||||
vForceFields.add(vector);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (block == WarpDrive.blockForceField) {
|
||||
if (((BlockForceField) block).getProjector(worldObj, vector.x, vector.y, vector.z) == this) {
|
||||
worldObj.setBlockToAir(vector.x, vector.y, vector.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyForceField(boolean isChunkLoading) {
|
||||
if ((!worldObj.isRemote) && (!vForceFields.isEmpty())) {
|
||||
for (Iterator<VectorI> iterator = vForceFields.iterator(); iterator.hasNext();) {
|
||||
VectorI vector = iterator.next();
|
||||
if (!isChunkLoading) {
|
||||
if (!(worldObj.blockExists(vector.x, vector.y, vector.z))) {// chunk is not loaded, skip it
|
||||
continue;
|
||||
}
|
||||
if (!worldObj.getChunkFromBlockCoords(vector.x, vector.z).isChunkLoaded) {// chunk is unloading, skip it
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Block block = vector.getBlock(worldObj);
|
||||
|
||||
if (block == WarpDrive.blockForceField) {
|
||||
worldObj.setBlockToAir(vector.x, vector.y, vector.z);
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if ((!worldObj.isRemote) && isCalculated() && isChunkLoading) {
|
||||
for (VectorI vector : calculated_forceField) {
|
||||
Block block = vector.getBlock(worldObj);
|
||||
|
||||
if (block == WarpDrive.blockForceField) {
|
||||
TileEntity tileEntity = worldObj.getTileEntity(vector.x, vector.y, vector.z);
|
||||
if (tileEntity instanceof TileEntityForceField && (((TileEntityForceField) tileEntity).getProjector() == this)) {
|
||||
worldObj.setBlockToAir(vector.x, vector.y, vector.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IShapeProvider getShapeProvider() {
|
||||
return WarpDrive.itemForceFieldShape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeamFrequency() {
|
||||
return beamFrequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeamFrequency(final int parBeamFrequency) {
|
||||
super.setBeamFrequency(parBeamFrequency);
|
||||
isDirty.set(true);
|
||||
if (worldObj != null) {
|
||||
destroyForceField(false);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return StatCollector.translateToLocalFormatted("warpdrive.guide.prefix",
|
||||
getBlockType().getLocalizedName())
|
||||
+ getBeamFrequencyStatus();
|
||||
// TODO add energy info
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
super.readFromNBT(tag);
|
||||
isDoubleSided = tag.getBoolean("isDoubleSided");
|
||||
tier = tag.getByte("tier");
|
||||
setShape(EnumForceFieldShape.get(tag.getByte("shape")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound tag) {
|
||||
super.writeToNBT(tag);
|
||||
tag.setBoolean("isDoubleSided", isDoubleSided);
|
||||
tag.setByte("tier", tier);
|
||||
tag.setByte("shape", (byte) getShape().ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet getDescriptionPacket() {
|
||||
NBTTagCompound tagCompound = new NBTTagCompound();
|
||||
writeToNBT(tagCompound);
|
||||
tagCompound.setBoolean("isPowered", isPowered);
|
||||
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tagCompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) {
|
||||
NBTTagCompound tagCompound = packet.func_148857_g();
|
||||
readFromNBT(tagCompound);
|
||||
isPowered = tagCompound.getBoolean("isPowered");
|
||||
}
|
||||
|
||||
public ForceFieldSetup getForceFieldSetup() {
|
||||
return new ForceFieldSetup(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, tier, beamFrequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxEnergyStored() {
|
||||
return PROJECTOR_MAX_ENERGY_STORED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInputEnergy(ForgeDirection from) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public EnumForceFieldShape getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
public void setShape(EnumForceFieldShape shape) {
|
||||
this.shape = shape;
|
||||
isDirty.set(true);
|
||||
if (worldObj != null) {
|
||||
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
||||
destroyForceField(false);
|
||||
}
|
||||
}
|
||||
|
||||
private class ThreadCalculation extends Thread {
|
||||
private final TileEntityProjector projector;
|
||||
|
||||
public ThreadCalculation(TileEntityProjector projector) {
|
||||
this.projector = projector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Set<VectorI> vPerimeterBlocks = null;
|
||||
Set<VectorI> vInteriorBlocks = null;
|
||||
|
||||
// calculation start is done synchronously, by caller
|
||||
try {
|
||||
if (projector.isValid()) {
|
||||
ForceFieldSetup forceFieldSetup = projector.getForceFieldSetup();
|
||||
if (WarpDriveConfig.LOGGING_FORCEFIELD) {
|
||||
WarpDrive.logger.info("Calculation started for " + projector);
|
||||
}
|
||||
|
||||
// create HashSets
|
||||
VectorI vScale = forceFieldSetup.vMax.clone().subtract(forceFieldSetup.vMin);
|
||||
vInteriorBlocks = new HashSet<>(vScale.x * vScale.y * vScale.z);
|
||||
vPerimeterBlocks = new HashSet<>(2 * vScale.x * vScale.y + 2 * vScale.x * vScale.z + 2 * vScale.y * vScale.z);
|
||||
|
||||
// compute interior fields to remove overlapping parts
|
||||
for (Map.Entry<VectorI, Boolean> entry : forceFieldSetup.shapeProvider.getVertexes(forceFieldSetup).entrySet()) {
|
||||
VectorI vPosition = entry.getKey();
|
||||
if (forceFieldSetup.isDoubleSided || vPosition.y >= yCoord) {
|
||||
if ((forceFieldSetup.rotationYaw != 0) || (forceFieldSetup.rotationPitch != 0)) {
|
||||
vPosition.rotateByAngle(forceFieldSetup.rotationYaw, forceFieldSetup.rotationPitch);
|
||||
}
|
||||
|
||||
vPosition.translate(forceFieldSetup.vTranslation);
|
||||
|
||||
if (vPosition.y > 0 && vPosition.y <= projector.worldObj.getHeight()) {
|
||||
if (entry.getValue()) {
|
||||
vPerimeterBlocks.add(vPosition);
|
||||
} else {
|
||||
vInteriorBlocks.add(vPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compute forcefield itself
|
||||
if (forceFieldSetup.isInverted) {
|
||||
// inverted mode => same as interior before fusion => need to be fully cloned
|
||||
vPerimeterBlocks = new HashSet<>(vInteriorBlocks);
|
||||
}
|
||||
|
||||
if (WarpDriveConfig.LOGGING_FORCEFIELD) {
|
||||
WarpDrive.logger.info(projector + " Calculation done: "
|
||||
+ vInteriorBlocks.size() + " blocks inside, including " + vPerimeterBlocks.size() + " blocks to place");
|
||||
}
|
||||
} else {
|
||||
if (WarpDriveConfig.LOGGING_FORCEFIELD) {
|
||||
WarpDrive.logger.info(projector + " Calculation aborted");
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
vInteriorBlocks = null;
|
||||
vPerimeterBlocks = null;
|
||||
exception.printStackTrace();
|
||||
WarpDrive.logger.error(projector + " Calculation failed");
|
||||
}
|
||||
|
||||
projector.calculation_done(vInteriorBlocks, vPerimeterBlocks);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -133,6 +133,8 @@ public class WarpDriveConfig {
|
|||
public static boolean LOGGING_DICTIONARY = false;
|
||||
public static boolean LOGGING_STARMAP = false;
|
||||
public static boolean LOGGING_BREAK_PLACE = false;
|
||||
public static boolean LOGGING_FORCEFIELD = false;
|
||||
public static boolean LOGGING_FORCEFIELD_REGISTRY = false;
|
||||
|
||||
// Planets
|
||||
public static Planet[] PLANETS = null;
|
||||
|
@ -340,6 +342,7 @@ public class WarpDriveConfig {
|
|||
public static void onFMLpreInitialization(final String stringConfigDirectory) {
|
||||
// create mod folder
|
||||
configDirectory = new File(stringConfigDirectory, WarpDrive.MODID);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
configDirectory.mkdir();
|
||||
if (!configDirectory.isDirectory()) {
|
||||
throw new RuntimeException("Unable to create config directory " + configDirectory);
|
||||
|
@ -419,6 +422,8 @@ public class WarpDriveConfig {
|
|||
LOGGING_DICTIONARY = config.get("logging", "enable_dictionary_logs", LOGGING_DICTIONARY, "Dictionary logs, enable it to dump blocks hardness and blast resistance at boot").getBoolean(true);
|
||||
LOGGING_STARMAP = config.get("logging", "enable_starmap_logs", LOGGING_STARMAP, "Starmap logs, enable it to dump starmap registry updates").getBoolean(false);
|
||||
LOGGING_BREAK_PLACE = config.get("logging", "enable_break_place_logs", LOGGING_BREAK_PLACE, "Detailed break/place event logs to help debug the mod, enable it before reporting a bug").getBoolean(false);
|
||||
LOGGING_FORCEFIELD = config.get("logging", "enable_forcefield_logs", LOGGING_FORCEFIELD, "Detailed forcefield logs to help debug the mod, enable it before reporting a bug").getBoolean(false);
|
||||
LOGGING_FORCEFIELD_REGISTRY = config.get("logging", "enable_forcefield_registry_logs", LOGGING_FORCEFIELD_REGISTRY, "ForceField registry logs, enable it to dump forcefield registry updates").getBoolean(false);
|
||||
|
||||
// Planets
|
||||
{
|
||||
|
@ -854,11 +859,8 @@ public class WarpDriveConfig {
|
|||
|
||||
public static void onFMLPostInitialization() {
|
||||
// unpack default XML files if none are defined
|
||||
File[] files = configDirectory.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File file_notUsed, String name) {
|
||||
return name.endsWith(".xml");
|
||||
}
|
||||
File[] files = configDirectory.listFiles((file_notUsed, name) -> {
|
||||
return name.endsWith(".xml");
|
||||
});
|
||||
if (files.length == 0) {
|
||||
for (String defaultXMLfilename : defaultXMLfilenames) {
|
||||
|
|
35
src/main/java/cr0s/warpdrive/data/EnumForceFieldShape.java
Normal file
35
src/main/java/cr0s/warpdrive/data/EnumForceFieldShape.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum EnumForceFieldShape {
|
||||
NONE ("none"),
|
||||
SPHERE ("sphere"),
|
||||
CYLINDER_H ("cylinder_h"),
|
||||
CYLINDER_V ("cylinder_v"),
|
||||
CUBE ("cube"),
|
||||
PLANE ("plane"),
|
||||
TUBE ("tube"),
|
||||
TUNNEL ("tunnel");
|
||||
|
||||
public final String unlocalizedName;
|
||||
|
||||
// cached values
|
||||
public static final int length;
|
||||
private static final HashMap<Integer, EnumForceFieldShape> ID_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
length = EnumForceFieldShape.values().length;
|
||||
for (EnumForceFieldShape enumForceFieldShape : values()) {
|
||||
ID_MAP.put(enumForceFieldShape.ordinal(), enumForceFieldShape);
|
||||
}
|
||||
}
|
||||
|
||||
EnumForceFieldShape(String unlocalizedName) {
|
||||
this.unlocalizedName = unlocalizedName;
|
||||
}
|
||||
|
||||
public static EnumForceFieldShape get(final int damage) {
|
||||
return ID_MAP.get(damage);
|
||||
}
|
||||
}
|
49
src/main/java/cr0s/warpdrive/data/EnumForceFieldUpgrade.java
Normal file
49
src/main/java/cr0s/warpdrive/data/EnumForceFieldUpgrade.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum EnumForceFieldUpgrade {
|
||||
NONE ("none" , false, false),
|
||||
BREAK ("break" , false, true ),
|
||||
CAMOUFLAGE ("camouflage" , false, true ),
|
||||
COOL ("cool" , true , true ),
|
||||
FUSION ("fusion" , true , true ),
|
||||
MUTE ("mute" , true , false),
|
||||
RANGE ("range" , true , true ),
|
||||
ROTATION ("rotation" , true , false),
|
||||
SHOCK ("shock" , true , true ),
|
||||
SPEED ("speed" , true , true ),
|
||||
STABILIZE ("stabilize" , false, true ),
|
||||
THICKNESS ("thickness" , true , true ),
|
||||
TRANSLATION ("translation" , true , false),
|
||||
WARM ("warm" , true , true ),
|
||||
// reserved 13
|
||||
// reserved 14
|
||||
// reserved 15
|
||||
;
|
||||
|
||||
public final String unlocalizedName;
|
||||
public final boolean allowAsItem;
|
||||
public final boolean allowAsBlock;
|
||||
|
||||
// cached values
|
||||
public static final int length;
|
||||
private static final HashMap<Integer, EnumForceFieldUpgrade> ID_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
length = EnumForceFieldUpgrade.values().length;
|
||||
for (EnumForceFieldUpgrade forceFieldShapeType : values()) {
|
||||
ID_MAP.put(forceFieldShapeType.ordinal(), forceFieldShapeType);
|
||||
}
|
||||
}
|
||||
|
||||
EnumForceFieldUpgrade(final String unlocalizedName, final boolean allowAsItem, final boolean allowAsBlock) {
|
||||
this.unlocalizedName = unlocalizedName;
|
||||
this.allowAsItem = allowAsItem;
|
||||
this.allowAsBlock = allowAsBlock;
|
||||
}
|
||||
|
||||
public static EnumForceFieldUpgrade get(final int damage) {
|
||||
return ID_MAP.get(damage);
|
||||
}
|
||||
}
|
105
src/main/java/cr0s/warpdrive/data/ForceFieldRegistry.java
Normal file
105
src/main/java/cr0s/warpdrive/data/ForceFieldRegistry.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBeamFrequency;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.WorldServer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Registry of all known forcefield in the loaded worlds, grouped by frequency
|
||||
*
|
||||
* @author LemADEC
|
||||
*/
|
||||
public class ForceFieldRegistry {
|
||||
private static final int FORCE_FIELD_REGISTRY_DEFAULT_ENTRIES_PER_FREQUENCY = 10;
|
||||
private static final HashMap<Integer, HashSet<GlobalPosition>> registry = new HashMap<>();
|
||||
|
||||
public static Set<TileEntity> getTileEntities(final int beamFrequency) {
|
||||
Set<TileEntity> setEntries = new HashSet<>();
|
||||
Set<GlobalPosition> setGlobalPositions = registry.get(beamFrequency);
|
||||
if (setGlobalPositions == null) {
|
||||
return setEntries;
|
||||
}
|
||||
for (Iterator<GlobalPosition> iterator = setGlobalPositions.iterator(); iterator.hasNext();) {
|
||||
GlobalPosition globalPosition = iterator.next();
|
||||
WorldServer world = globalPosition.getWorldServerIfLoaded();
|
||||
if (world != null) {
|
||||
TileEntity tileEntity = world.getTileEntity(globalPosition.x, globalPosition.y, globalPosition.z);
|
||||
if ((tileEntity instanceof IBeamFrequency) && ((IBeamFrequency)tileEntity).getBeamFrequency() == beamFrequency) {
|
||||
setEntries.add(tileEntity);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// world isn't loaded or block no longer exist => remove from registry
|
||||
iterator.remove();
|
||||
if (WarpDriveConfig.LOGGING_FORCEFIELD_REGISTRY) {
|
||||
printRegistry("removed");
|
||||
}
|
||||
}
|
||||
|
||||
return setEntries;
|
||||
}
|
||||
|
||||
public static boolean isInRegistry(final int beamFrequency) {
|
||||
return !getTileEntities(beamFrequency).isEmpty();
|
||||
}
|
||||
|
||||
public static void updateInRegistry(IBeamFrequency tileEntity) {
|
||||
assert(tileEntity instanceof TileEntity);
|
||||
|
||||
HashSet<GlobalPosition> setGlobalPositions = registry.get(tileEntity.getBeamFrequency());
|
||||
if (setGlobalPositions == null) {
|
||||
setGlobalPositions = new HashSet<>(FORCE_FIELD_REGISTRY_DEFAULT_ENTRIES_PER_FREQUENCY);
|
||||
}
|
||||
for (Iterator<GlobalPosition> iterator = setGlobalPositions.iterator(); iterator.hasNext();) {
|
||||
GlobalPosition globalPosition = iterator.next();
|
||||
if (globalPosition.equals(tileEntity)) {
|
||||
// already registered
|
||||
return;
|
||||
}
|
||||
}
|
||||
// not found => add
|
||||
setGlobalPositions.add(new GlobalPosition((TileEntity)tileEntity));
|
||||
registry.put(tileEntity.getBeamFrequency(), setGlobalPositions);
|
||||
if (WarpDriveConfig.LOGGING_FORCEFIELD_REGISTRY) {
|
||||
printRegistry("added");
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeFromRegistry(IBeamFrequency tileEntity) {
|
||||
assert(tileEntity instanceof TileEntity);
|
||||
|
||||
Set<GlobalPosition> setGlobalPositions = registry.get(tileEntity.getBeamFrequency());
|
||||
if (setGlobalPositions == null) {
|
||||
// noting to remove
|
||||
return;
|
||||
}
|
||||
for (Iterator<GlobalPosition> iterator = setGlobalPositions.iterator(); iterator.hasNext();) {
|
||||
GlobalPosition globalPosition = iterator.next();
|
||||
if (globalPosition.equals(tileEntity)) {
|
||||
// found it, remove and exit
|
||||
iterator.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// not found => ignore it
|
||||
}
|
||||
|
||||
public static void printRegistry(final String trigger) {
|
||||
WarpDrive.logger.info("Forcefield registry (" + registry.size() + " entries after " + trigger + "):");
|
||||
|
||||
for (Map.Entry<Integer, HashSet<GlobalPosition>> entry : registry.entrySet()) {
|
||||
String message = "";
|
||||
for (GlobalPosition globalPosition : entry.getValue()) {
|
||||
if (!message.isEmpty()) {
|
||||
message += ", ";
|
||||
}
|
||||
message += globalPosition.dimensionId + ": " + globalPosition.x + " " + globalPosition.y + " " + globalPosition.z;
|
||||
}
|
||||
WarpDrive.logger.info("- " + entry.getValue().size() + " entries at frequency " + entry.getKey() + ": " + message);
|
||||
}
|
||||
}
|
||||
}
|
138
src/main/java/cr0s/warpdrive/data/ForceFieldSetup.java
Normal file
138
src/main/java/cr0s/warpdrive/data/ForceFieldSetup.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import cr0s.warpdrive.api.IEffector;
|
||||
import cr0s.warpdrive.api.IForceFieldUpgrade;
|
||||
import cr0s.warpdrive.api.IShapeProvider;
|
||||
import cr0s.warpdrive.block.forcefield.TileEntityProjector;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ForceFieldSetup extends GlobalPosition {
|
||||
public int beamFrequency;
|
||||
public byte tier;
|
||||
public ItemStack itemStackCamouflage;
|
||||
private Block blockCamouflage_cache;
|
||||
private static final List<Integer> ALLOWED_RENDER_TYPES = Arrays.asList(0, 1, 4, 5, 6, 8, 7, 12, 13, 14, 16, 17, 20, 23, 29, 30, 31, 39);
|
||||
private final HashMap<String, Integer> upgrades = new HashMap<>(EnumForceFieldUpgrade.length);
|
||||
|
||||
// TODO
|
||||
public Set<TileEntityProjector> projectors = new HashSet<>();
|
||||
public Set<IEffector> effectors = new HashSet<>();
|
||||
public int disintegrationLevel;
|
||||
public int temperatureLevel;
|
||||
public boolean hasStabilize;
|
||||
public boolean isInverted = false;
|
||||
public boolean hasFusion;
|
||||
|
||||
// Projector provided properties
|
||||
public float rotationYaw;
|
||||
public float rotationPitch;
|
||||
public VectorI vTranslation = new VectorI(0, 0, 0);
|
||||
public VectorI vMin = new VectorI(-8, -8, -8);
|
||||
public VectorI vMax = new VectorI(8, 8, 8);
|
||||
public IShapeProvider shapeProvider;
|
||||
public EnumForceFieldShape enumForceFieldShape;
|
||||
public boolean isDoubleSided = true;
|
||||
public float thickness = 1.0F;
|
||||
|
||||
public ForceFieldSetup(final int dimensionId, final int x, final int y, final int z, final byte tier, final int beamFrequency) {
|
||||
super(dimensionId, x, y, z);
|
||||
this.tier = tier;
|
||||
this.beamFrequency = beamFrequency;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public Collection<IEffector> getEffectors() {
|
||||
return effectors;
|
||||
}
|
||||
|
||||
public boolean isAccessGranted(EntityPlayer entityPlayer, PermissionNode permissionNode) {
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
public static boolean isValidCamouflage(ItemStack itemStack) {
|
||||
if (itemStack != null && itemStack.stackSize > 0 && itemStack.getItem() instanceof ItemBlock) {
|
||||
Block block = Block.getBlockFromItem(itemStack.getItem());
|
||||
return ALLOWED_RENDER_TYPES.contains(block.getRenderType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Block getCamouflageBlock() {
|
||||
if (blockCamouflage_cache != null) {
|
||||
return blockCamouflage_cache;
|
||||
}
|
||||
if (isValidCamouflage(itemStackCamouflage)) {
|
||||
blockCamouflage_cache = Block.getBlockFromItem(itemStackCamouflage.getItem());
|
||||
return blockCamouflage_cache;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
Set<TileEntity> tileEntities = ForceFieldRegistry.getTileEntities(beamFrequency);
|
||||
|
||||
for (TileEntity tileEntity : tileEntities) {
|
||||
// only consider same dimension
|
||||
if (tileEntity.getWorldObj().provider.dimensionId != dimensionId) {
|
||||
continue;
|
||||
}
|
||||
// projectors
|
||||
if (tileEntity instanceof TileEntityProjector) {
|
||||
TileEntityProjector projector = (TileEntityProjector) tileEntity;
|
||||
if (tileEntity.xCoord == x && tileEntity.yCoord == y && tileEntity.zCoord == z) {
|
||||
shapeProvider = projector.getShapeProvider();
|
||||
enumForceFieldShape = projector.getShape();
|
||||
isDoubleSided = projector.isDoubleSided;
|
||||
vTranslation = new VectorI(projector);
|
||||
// TODO vMin = projector.vMin;
|
||||
// TODO vMax = projector.vMax;
|
||||
} else {
|
||||
if ((((TileEntityProjector) tileEntity).isEnabled)
|
||||
&& (((TileEntityProjector) tileEntity).isCalculated())
|
||||
&& (((TileEntityProjector) tileEntity).isValid())) {
|
||||
projectors.add((TileEntityProjector) tileEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
// block upgrades
|
||||
if (tileEntity instanceof IForceFieldUpgrade) {
|
||||
String upgradeKey = ((IForceFieldUpgrade)tileEntity).getUpgradeKey();
|
||||
if (!upgradeKey.isEmpty()) {
|
||||
Integer count = upgrades.get(upgradeKey);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
upgrades.put(upgradeKey, count + ((IForceFieldUpgrade)tileEntity).getUpgradeValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasFusion = upgrades.containsKey(EnumForceFieldUpgrade.FUSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s @ DIM%d (%d %d %d) (%d %d %d) -> (%d %d %d)",
|
||||
getClass().getSimpleName(), dimensionId,
|
||||
x, y, z,
|
||||
vMin.x, vMin.y, vMin.z,
|
||||
vMax.x, vMax.y, vMax.z);
|
||||
}
|
||||
|
||||
public int applyDamages(World world, int x, int y, int z, DamageSource damageSource, int damageParameter, Vector3 damageDirection, int damageLevel) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getProjectionSpeed() {
|
||||
return 1; // TODO
|
||||
}
|
||||
}
|
33
src/main/java/cr0s/warpdrive/data/PermissionNode.java
Normal file
33
src/main/java/cr0s/warpdrive/data/PermissionNode.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum PermissionNode {
|
||||
NONE ("None"),
|
||||
ENABLE ("Enable"),
|
||||
OPEN_GUI ("OpenGUI"),
|
||||
MODIFY ("Modify"),
|
||||
SNEAK_THROUGH ("SneakThrough"),
|
||||
;
|
||||
|
||||
public final String unlocalizedName;
|
||||
|
||||
// cached values
|
||||
public static final int length;
|
||||
private static final HashMap<Integer, PermissionNode> ID_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
length = PermissionNode.values().length;
|
||||
for (PermissionNode permissionNode : values()) {
|
||||
ID_MAP.put(permissionNode.ordinal(), permissionNode);
|
||||
}
|
||||
}
|
||||
|
||||
PermissionNode(String unlocalizedName) {
|
||||
this.unlocalizedName = unlocalizedName;
|
||||
}
|
||||
|
||||
public static PermissionNode get(final int id) {
|
||||
return ID_MAP.get(id);
|
||||
}
|
||||
}
|
|
@ -2,8 +2,9 @@ package cr0s.warpdrive.item;
|
|||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IShapeProvider;
|
||||
import cr0s.warpdrive.data.ComponentType;
|
||||
import cr0s.warpdrive.data.ForceFieldShapeType;
|
||||
import cr0s.warpdrive.data.ForceFieldSetup;
|
||||
import cr0s.warpdrive.data.EnumForceFieldShape;
|
||||
import cr0s.warpdrive.data.VectorI;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
@ -12,25 +13,25 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class ItemForceFieldShape extends Item implements IShapeProvider {
|
||||
private IIcon[] icons;
|
||||
private final IIcon[] icons;
|
||||
private static ItemStack[] itemStackCache;
|
||||
|
||||
public ItemForceFieldShape() {
|
||||
super();
|
||||
setHasSubtypes(true);
|
||||
setUnlocalizedName("warpdrive.forcefield.shapeProvider");
|
||||
setUnlocalizedName("warpdrive.forcefield.shape");
|
||||
setCreativeTab(WarpDrive.creativeTabWarpDrive);
|
||||
|
||||
icons = new IIcon[ForceFieldShapeType.length];
|
||||
itemStackCache = new ItemStack[ComponentType.length];
|
||||
icons = new IIcon[EnumForceFieldShape.length];
|
||||
itemStackCache = new ItemStack[EnumForceFieldShape.length];
|
||||
}
|
||||
|
||||
public static ItemStack getItemStack(ComponentType componentType) {
|
||||
if (componentType != null) {
|
||||
int damage = componentType.ordinal();
|
||||
public static ItemStack getItemStack(EnumForceFieldShape enumForceFieldShape) {
|
||||
if (enumForceFieldShape != null) {
|
||||
int damage = enumForceFieldShape.ordinal();
|
||||
if (itemStackCache[damage] == null) {
|
||||
itemStackCache[damage] = new ItemStack(WarpDrive.itemComponent, 1, damage);
|
||||
}
|
||||
|
@ -39,29 +40,29 @@ public class ItemForceFieldShape extends Item implements IShapeProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getItemStackNoCache(ComponentType componentType, int amount) {
|
||||
return new ItemStack(WarpDrive.itemComponent, amount, componentType.ordinal());
|
||||
public static ItemStack getItemStackNoCache(EnumForceFieldShape enumForceFieldShape, int amount) {
|
||||
return new ItemStack(WarpDrive.itemForceFieldShape, amount, enumForceFieldShape.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerIcons(IIconRegister par1IconRegister) {
|
||||
for(ComponentType componentType : ComponentType.values()) {
|
||||
icons[componentType.ordinal()] = par1IconRegister.registerIcon("warpdrive:component" + componentType.unlocalizedName);
|
||||
for(EnumForceFieldShape enumForceFieldShape : EnumForceFieldShape.values()) {
|
||||
icons[enumForceFieldShape.ordinal()] = par1IconRegister.registerIcon("warpdrive:forcefield/shape_" + enumForceFieldShape.unlocalizedName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName(ItemStack itemStack) {
|
||||
int damage = itemStack.getItemDamage();
|
||||
if (damage >= 0 && damage < ComponentType.length) {
|
||||
return "item.warpdrive.crafting." + ComponentType.get(damage).unlocalizedName;
|
||||
if (damage >= 0 && damage < EnumForceFieldShape.length) {
|
||||
return getUnlocalizedName() + "." + EnumForceFieldShape.get(damage).unlocalizedName;
|
||||
}
|
||||
return getUnlocalizedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIcon getIconFromDamage(int damage) {
|
||||
if (damage >= 0 && damage < ComponentType.length) {
|
||||
if (damage >= 0 && damage < EnumForceFieldShape.length) {
|
||||
return icons[damage];
|
||||
}
|
||||
return icons[0];
|
||||
|
@ -69,51 +70,163 @@ public class ItemForceFieldShape extends Item implements IShapeProvider {
|
|||
|
||||
@Override
|
||||
public void getSubItems(Item item, CreativeTabs creativeTab, List list) {
|
||||
for(ComponentType componentType : ComponentType.values()) {
|
||||
list.add(new ItemStack(item, 1, componentType.ordinal()));
|
||||
for(EnumForceFieldShape enumForceFieldShape : EnumForceFieldShape.values()) {
|
||||
list.add(new ItemStack(item, 1, enumForceFieldShape.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
// For empty air canister
|
||||
@Override
|
||||
public boolean canContainAir(ItemStack itemStack) {
|
||||
return (itemStack.getItem() instanceof ItemForceFieldShape && itemStack.getItemDamage() == ComponentType.AIR_CANISTER.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAir(ItemStack itemStack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack fullDrop(ItemStack itemStack) {
|
||||
if (canContainAir(itemStack)) {
|
||||
return WarpDrive.itemAirCanisterFull.fullDrop(itemStack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack emptyDrop(ItemStack itemStack) {
|
||||
if (canContainAir(itemStack)) {
|
||||
return WarpDrive.itemAirCanisterFull.emptyDrop(itemStack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List list, boolean advancedItemTooltips) {
|
||||
super.addInformation(itemStack, entityPlayer, list, advancedItemTooltips);
|
||||
|
||||
String tooltip = "";
|
||||
switch (ComponentType.get(itemStack.getItemDamage())) {
|
||||
case AIR_CANISTER:
|
||||
tooltip += StatCollector.translateToLocalFormatted("item.warpdrive.crafting.AirCanisterEmpty.tooltip");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
String tooltipName1 = getUnlocalizedName(itemStack) + ".tooltip";
|
||||
if (StatCollector.canTranslate(tooltipName1)) {
|
||||
WarpDrive.addTooltip(list, StatCollector.translateToLocalFormatted(tooltipName1));
|
||||
}
|
||||
|
||||
WarpDrive.addTooltip(list, tooltip);
|
||||
String tooltipName2 = getUnlocalizedName() + ".tooltip";
|
||||
if ((!tooltipName1.equals(tooltipName2)) && StatCollector.canTranslate(tooltipName2)) {
|
||||
WarpDrive.addTooltip(list, StatCollector.translateToLocalFormatted(tooltipName2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<VectorI, Boolean> getVertexes(ForceFieldSetup forceFieldSetup) {
|
||||
VectorI vScale = forceFieldSetup.vMax.clone().translateBack(forceFieldSetup.vMin);
|
||||
Map<VectorI, Boolean> mapVertexes = new HashMap<>(vScale.x * vScale.y * vScale.z);
|
||||
int radius;
|
||||
int thickness;
|
||||
int radiusInterior2;
|
||||
int radiusPerimeter2;
|
||||
VectorI vCenter;
|
||||
switch(forceFieldSetup.enumForceFieldShape) {
|
||||
case SPHERE:
|
||||
radius = forceFieldSetup.vMax.y;
|
||||
radiusInterior2 = Math.round((radius - forceFieldSetup.thickness) * (radius - forceFieldSetup.thickness));
|
||||
radiusPerimeter2 = Math.round((radius + forceFieldSetup.thickness) * (radius + forceFieldSetup.thickness));
|
||||
vCenter = new VectorI(0, 0, 0);
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
int y2 = (y - vCenter.y) * (y - vCenter.y);
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
int x2 = (x - vCenter.x) * (x - vCenter.x);
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
int z2 = (z - vCenter.z) * (z - vCenter.z);
|
||||
if (x2 + y2 + z2 <= radiusPerimeter2) {
|
||||
mapVertexes.put(new VectorI(x, y, z), x2 + y2 + z2 >= radiusInterior2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CYLINDER_H:
|
||||
radius = Math.round((forceFieldSetup.vMax.y + forceFieldSetup.vMax.z) / 2);
|
||||
radiusInterior2 = Math.round((radius - forceFieldSetup.thickness) * (radius - forceFieldSetup.thickness));
|
||||
radiusPerimeter2 = Math.round((radius + forceFieldSetup.thickness) * (radius + forceFieldSetup.thickness));
|
||||
vCenter = new VectorI(0, 0, 0);
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
int y2 = (y - vCenter.y) * (y - vCenter.y);
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
int z2 = (z - vCenter.z) * (z - vCenter.z);
|
||||
if (y2 + z2 <= radiusPerimeter2) {
|
||||
boolean isPerimeter = y2 + z2 >= radiusInterior2;
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CYLINDER_V:
|
||||
radius = Math.round((forceFieldSetup.vMax.x + forceFieldSetup.vMax.y) / 2);
|
||||
radiusInterior2 = Math.round((radius - forceFieldSetup.thickness) * (radius - forceFieldSetup.thickness));
|
||||
radiusPerimeter2 = Math.round((radius + forceFieldSetup.thickness) * (radius + forceFieldSetup.thickness));
|
||||
vCenter = new VectorI(0, 0, 0);
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
int x2 = (x - vCenter.x) * (x - vCenter.x);
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
int y2 = (y - vCenter.y) * (y - vCenter.y);
|
||||
if (x2 + y2 <= radiusPerimeter2) {
|
||||
boolean isPerimeter = x2 + y2 >= radiusInterior2;
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TUBE:
|
||||
radius = Math.round((forceFieldSetup.vMax.x + forceFieldSetup.vMax.z) / 2);
|
||||
radiusInterior2 = Math.round((radius - forceFieldSetup.thickness) * (radius - forceFieldSetup.thickness));
|
||||
radiusPerimeter2 = Math.round((radius + forceFieldSetup.thickness) * (radius + forceFieldSetup.thickness));
|
||||
vCenter = new VectorI(0, 0, 0);
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
int x2 = (x - vCenter.x) * (x - vCenter.x);
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
int z2 = (z - vCenter.z) * (z - vCenter.z);
|
||||
if (x2 + z2 <= radiusPerimeter2) {
|
||||
boolean isPerimeter = x2 + z2 >= radiusInterior2;
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CUBE:
|
||||
thickness = Math.round(forceFieldSetup.thickness);
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
boolean yFace = Math.abs(y - forceFieldSetup.vMin.y) <= thickness
|
||||
|| Math.abs(y - forceFieldSetup.vMax.y) <= thickness;
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
boolean xFace = Math.abs(x - forceFieldSetup.vMin.x) <= thickness
|
||||
|| Math.abs(x - forceFieldSetup.vMax.x) <= thickness;
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
boolean zFace = Math.abs(z - forceFieldSetup.vMin.z) <= thickness
|
||||
|| Math.abs(z - forceFieldSetup.vMax.z) <= thickness;
|
||||
mapVertexes.put(new VectorI(x, y, z), xFace || yFace || zFace);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PLANE:
|
||||
thickness = Math.round(forceFieldSetup.thickness);
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
boolean yFace = Math.abs(y - forceFieldSetup.vMin.y) <= thickness
|
||||
|| Math.abs(y - forceFieldSetup.vMax.y) <= thickness;
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
mapVertexes.put(new VectorI(x, y, z), yFace);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TUNNEL:
|
||||
thickness = Math.round(forceFieldSetup.thickness);
|
||||
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
|
||||
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
|
||||
boolean xFace = Math.abs(x - forceFieldSetup.vMin.x) <= thickness
|
||||
|| Math.abs(x - forceFieldSetup.vMax.x) <= thickness;
|
||||
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
|
||||
boolean isPerimeter = xFace
|
||||
|| Math.abs(z - forceFieldSetup.vMin.z) <= thickness
|
||||
|| Math.abs(z - forceFieldSetup.vMax.z) <= thickness;
|
||||
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return mapVertexes;
|
||||
}
|
||||
}
|
114
src/main/java/cr0s/warpdrive/render/RenderBlockForceField.java
Normal file
114
src/main/java/cr0s/warpdrive/render/RenderBlockForceField.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
package cr0s.warpdrive.render;
|
||||
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cr0s.warpdrive.block.forcefield.TileEntityForceField;
|
||||
import cr0s.warpdrive.data.ForceFieldSetup;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
// wrapper to native classes to renderId is non-zero so we don't render faces when player camera is inside the block
|
||||
public class RenderBlockForceField implements ISimpleBlockRenderingHandler {
|
||||
public static int renderId = 0;
|
||||
public static RenderBlockForceField instance = new RenderBlockForceField();
|
||||
|
||||
@Override
|
||||
public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) {
|
||||
// not supposed to happen
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (!(tileEntity instanceof TileEntityForceField)) {
|
||||
return false;
|
||||
}
|
||||
ForceFieldSetup forceFieldSetup = ((TileEntityForceField)tileEntity).getForceFieldSetup();
|
||||
if (forceFieldSetup == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int renderType = -1;
|
||||
Block blockCamouflage = forceFieldSetup.getCamouflageBlock();
|
||||
if (blockCamouflage != null) {
|
||||
renderType = blockCamouflage.getRenderType();
|
||||
}
|
||||
|
||||
if (renderType >= 0) {
|
||||
try {
|
||||
if (blockCamouflage != null) {
|
||||
renderer.setRenderBoundsFromBlock(blockCamouflage);
|
||||
}
|
||||
|
||||
switch (renderType) {
|
||||
case 1 :
|
||||
renderer.renderCrossedSquares(block, x, y, z);
|
||||
break;
|
||||
case 4 :
|
||||
renderer.renderBlockLiquid(block, x, y, z);
|
||||
break;
|
||||
case 5 :
|
||||
renderer.renderBlockRedstoneWire(block, x, y, z);
|
||||
break;
|
||||
case 6 :
|
||||
renderer.renderBlockCrops(block, x, y, z);
|
||||
break;
|
||||
case 7 :
|
||||
renderer.renderBlockDoor(block, x, y, z);
|
||||
break;
|
||||
case 12 :
|
||||
renderer.renderBlockLever(block, x, y, z);
|
||||
break;
|
||||
case 13 :
|
||||
renderer.renderBlockCactus(block, x, y, z);
|
||||
break;
|
||||
case 14 :
|
||||
renderer.renderBlockBed(block, x, y, z);
|
||||
break;
|
||||
case 16 :
|
||||
renderer.renderPistonBase(block, x, y, z, false);
|
||||
break;
|
||||
case 17 :
|
||||
renderer.renderPistonExtension(block, x, y, z, true);
|
||||
break;
|
||||
case 20 :
|
||||
renderer.renderBlockVine(block, x, y, z);
|
||||
break;
|
||||
case 23 :
|
||||
renderer.renderBlockLilyPad(block, x, y, z);
|
||||
break;
|
||||
case 29 :
|
||||
renderer.renderBlockTripWireSource(block, x, y, z);
|
||||
break;
|
||||
case 30 :
|
||||
renderer.renderBlockTripWire(block, x, y, z);
|
||||
break;
|
||||
case 31 :
|
||||
renderer.renderBlockLog(block, x, y, z);
|
||||
break;
|
||||
case 39 :
|
||||
renderer.renderBlockQuartz(block, x, y, z);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} catch(Exception exception) {
|
||||
renderer.renderBlockAsItem(blockCamouflage, forceFieldSetup.itemStackCamouflage.getItemDamage(), 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender3DInInventory(int modelId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderId() {
|
||||
return renderId;
|
||||
}
|
||||
}
|
|
@ -32,10 +32,20 @@ item.warpdrive.crafting.BoneCharcoal.name=Bone Charcoal
|
|||
item.warpdrive.crafting.ActivatedCarbon.name=Activated Carbon
|
||||
item.warpdrive.crafting.LaserMediumEmpty.name=Laser Medium (empty)
|
||||
|
||||
item.warpdrive.energy.IC2reactorLaserFocus.name=IC2 Reactor Laser Focus
|
||||
item.warpdrive.armor.AirCanisterFull.name=Air Canister
|
||||
item.warpdrive.armor.Helmet.name=Warp Helmet
|
||||
|
||||
item.warpdrive.energy.IC2reactorLaserFocus.name=IC2 Reactor Laser Focus
|
||||
|
||||
item.warpdrive.forcefield.shape.none.name=No shape
|
||||
item.warpdrive.forcefield.shape.sphere.name=Sphere shape
|
||||
item.warpdrive.forcefield.shape.cylinder_h.name=Horizontal cylinder shape
|
||||
item.warpdrive.forcefield.shape.cylinder_v.name=Vertical cylinder shape
|
||||
item.warpdrive.forcefield.shape.cube.name=Cube shape
|
||||
item.warpdrive.forcefield.shape.plane.name=Plane shape
|
||||
item.warpdrive.forcefield.shape.tube.name=Tube shape
|
||||
item.warpdrive.forcefield.shape.tunnel.name=Tunnel shape
|
||||
|
||||
item.warpdrive.upgrade.Power.name=Power Upgrade
|
||||
item.warpdrive.upgrade.Speed.name=Speed Upgrade
|
||||
item.warpdrive.upgrade.Range.name=Range Upgrade
|
||||
|
@ -96,6 +106,26 @@ tile.warpdrive.energy.EnanReactorLaser.name=Enantiomorphic Reactor Stabilization
|
|||
tile.warpdrive.energy.EnergyBank.name=Anuic Energy Bank
|
||||
tile.warpdrive.energy.IC2ReactorLaserMonitor.name=IC2 Reactor Laser Monitor
|
||||
|
||||
tile.warpdrive.forcefield.block.name=Forcefield
|
||||
tile.warpdrive.forcefield.projector1.name=Basic Forcefield Projector
|
||||
tile.warpdrive.forcefield.projector2.name=Advanced Forcefield Projector
|
||||
tile.warpdrive.forcefield.projector3.name=Superior Forcefield Projector
|
||||
|
||||
tile.warpdrive.forcefield.upgrade.none.name=No upgrade
|
||||
tile.warpdrive.forcefield.upgrade.break.name=Block breaker upgrade
|
||||
tile.warpdrive.forcefield.upgrade.camouflage.name=Camouflage upgrade
|
||||
tile.warpdrive.forcefield.upgrade.cool.name=Cooling upgrade
|
||||
tile.warpdrive.forcefield.upgrade.fusion.name=Fusion upgrade
|
||||
tile.warpdrive.forcefield.upgrade.mute.name=Muting upgrade
|
||||
tile.warpdrive.forcefield.upgrade.range .name=Range upgrade
|
||||
tile.warpdrive.forcefield.upgrade.rotation.name=Rotation upgrade
|
||||
tile.warpdrive.forcefield.upgrade.shock.name=Shock upgrade
|
||||
tile.warpdrive.forcefield.upgrade.speed.name=Speed upgrade
|
||||
tile.warpdrive.forcefield.upgrade.stabilize.name=Stabilization upgrade
|
||||
tile.warpdrive.forcefield.upgrade.thickness.name=Thickness upgrade
|
||||
tile.warpdrive.forcefield.upgrade.translation.name=Translation upgrade
|
||||
tile.warpdrive.forcefield.upgrade.warm.name=Heating upgrade
|
||||
|
||||
tile.warpdrive.movement.Lift.name=Lift
|
||||
tile.warpdrive.movement.ShipController.name=Ship Controller
|
||||
tile.warpdrive.movement.ShipCore.name=Ship Core
|
||||
|
|
Loading…
Add table
Reference in a new issue