Revert "Removing experimental/unstable/untested/debug stuff"

This reverts commit b76ec1d361.
This commit is contained in:
LemADEC 2014-08-27 17:52:47 +02:00
parent b76ec1d361
commit 2d2a8a12c4
20 changed files with 3956 additions and 6 deletions

File diff suppressed because it is too large Load diff

View file

@ -3,14 +3,11 @@ WarpDrive
A warp drive mod for minecraft
See mcmod.info for credits
Minecraft forum:
http://www.minecraftforum.net/topic/1938578-164-warpdrive-mod-ships-space-lasers
Mod Showcase:
https://www.youtube.com/watch?v=9pUSZPEMc1g
http://www.twitch.tv/pyrostasis/c/4571421
Wiki:
http://wiki.kubach.tk/
@ -19,9 +16,9 @@ Installation
============
1. Download fresh build: http://kubach.tk/1.6.4/WarpDrive.zip
2. Download fresh Core build: http://kubach.tk/1.6.4/WarpDriveCore.jar
3. Install last version of IC2, Applied Energistics, CoFHCore and Computer Craft
3. Install last version of IC2 and Computer Craft
Contact Us
==========
=============
* Visit our IRC channel on EsperNet: irc://chaos.esper.net/WarpDrive
* Or PM me: http://www.minecraftforum.net/user/1133830-anon1644/
* Or PM me: http://www.minecraftforum.net/user/1133830-anon1644/

View file

@ -82,14 +82,21 @@ public class WarpDrive implements LoadingCallback {
public static Block cloakCoilBlock;
public static Block transporterBlock;
public static Block reactorMonitorBlock;
public static Block powerReactorBlock;
public static Block powerLaserBlock;
public static Block powerStoreBlock;
public static Block airBlock;
public static Block gasBlock;
public static Block iridiumBlock;
public static Block transportBeaconBlock;
public static Block chunkLoaderBlock;
public static BlockDecorative decorativeBlock;
public static Item reactorLaserFocusItem;
public static ItemWarpComponent componentItem;
public static ItemWarpUpgrade upgradeItem;
public static EnumArmorMaterial armorMaterial = EnumHelper.addArmorMaterial("WARP", 5, new int[]{1, 3, 2, 1}, 15);
public static ItemWarpArmor helmetItem;
@ -146,6 +153,7 @@ public class WarpDrive implements LoadingCallback {
@SideOnly(Side.CLIENT)
@EventHandler
public void init(FMLInitializationEvent event) {
// FIXME FMLInterModComms.sendMessage("Waila", "register", "cr0s.WarpDrive.client.WailaHandler.callbackRegister");
}
public static void print(String out) {
@ -272,12 +280,45 @@ public class WarpDrive implements LoadingCallback {
GameRegistry.registerBlock(cloakCoilBlock, "cloakCoilBlock");
// TRANSPORTER
transporterBlock = new BlockTransporter(WarpDriveConfig.transporterID,Material.rock);
GameRegistry.registerBlock(transporterBlock, "transporter");
GameRegistry.registerTileEntity(TileEntityTransporter.class,"transporter");
// REACTOR MONITOR
reactorMonitorBlock = new BlockLaserReactorMonitor(WarpDriveConfig.reactorMonitorID, Material.rock);
GameRegistry.registerBlock(reactorMonitorBlock, "reactorMonitor");
GameRegistry.registerTileEntity(TileEntityLaserReactorMonitor.class,"reactorMonitor");
// TRANSPORT BEACON
transportBeaconBlock = new BlockTransportBeacon(WarpDriveConfig.transportBeaconID);
GameRegistry.registerBlock(transportBeaconBlock, "transportBeacon");
// POWER REACTOR, LASER, STORE
powerReactorBlock = new BlockPowerReactor(WarpDriveConfig.powerReactorID);
GameRegistry.registerBlock(powerReactorBlock,"powerReactor");
GameRegistry.registerTileEntity(TileEntityPowerReactor.class, "powerReactor");
powerLaserBlock = new BlockPowerLaser(WarpDriveConfig.powerLaserID);
GameRegistry.registerBlock(powerLaserBlock, "powerLaser");
GameRegistry.registerTileEntity(TileEntityPowerLaser.class, "powerLaser");
powerStoreBlock = new BlockPowerStore(WarpDriveConfig.powerStoreID);
GameRegistry.registerBlock(powerStoreBlock,"powerStore");
GameRegistry.registerTileEntity(TileEntityPowerStore.class, "powerStore");
// CHUNK LOADER
chunkLoaderBlock = new BlockChunkLoader(WarpDriveConfig.chunkLoaderID);
GameRegistry.registerBlock(chunkLoaderBlock, "chunkLoader");
GameRegistry.registerTileEntity(TileEntityChunkLoader.class, "chunkLoader");
// DECORATIVE
decorativeBlock = new BlockDecorative(WarpDriveConfig.decorativeID);
GameRegistry.registerBlock(decorativeBlock, ItemBlockDecorative.class, "decorative");
// REACTOR LASER FOCUS
reactorLaserFocusItem = new ItemReactorLaserFocus(WarpDriveConfig.reactorLaserFocusID);
GameRegistry.registerItem(reactorLaserFocusItem, "reactorLaserFocus");
@ -292,6 +333,9 @@ public class WarpDrive implements LoadingCallback {
airCanisterItem = new ItemWarpAirCanister(WarpDriveConfig.airCanisterID);
GameRegistry.registerItem(airCanisterItem, "airCanisterFull");
upgradeItem = new ItemWarpUpgrade(WarpDriveConfig.upgradeID);
GameRegistry.registerItem(upgradeItem, "upgrade");
proxy.registerEntities();
ForgeChunkManager.setForcedChunkLoadingCallback(instance, instance);
@ -337,6 +381,8 @@ public class WarpDrive implements LoadingCallback {
private static void initVanillaRecipes() {
componentItem.registerRecipes();
decorativeBlock.initRecipes();
upgradeItem.initRecipes();
//WarpCore
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(warpCore), false, "ipi", "ici", "idi",
@ -449,6 +495,42 @@ public class WarpDrive implements LoadingCallback {
'r', Item.redstone,
'n', Item.goldNugget));
//Power Laser
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(powerLaserBlock), false, "iii", "ilg", "ici",
'i', Item.ingotIron,
'g', Block.glass,
'c', componentItem.getIS(5),
'l', componentItem.getIS(3)));
//Power Reactor
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(powerReactorBlock), false, "ipi", "gog", "ici",
'i', Item.ingotIron,
'g', Block.glass,
'o', componentItem.getIS(4),
'c', componentItem.getIS(5),
'p', componentItem.getIS(6)));
//Power Store
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(powerStoreBlock), false, "ipi", "isi", "ici",
'i', Item.ingotIron,
's', componentItem.getIS(7),
'c', componentItem.getIS(5),
'p', componentItem.getIS(6)));
//Transport Beacon
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(transportBeaconBlock), false, " e ", "ldl", " s ",
'e', Item.enderPearl,
'l', "dyeBlue",
'd', Item.diamond,
's', Item.stick));
//Chunk Loader
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(chunkLoaderBlock), false, "ipi", "ici", "ifi",
'i', Item.ingotIron,
'p', componentItem.getIS(6),
'c', componentItem.getIS(0),
'f', componentItem.getIS(5)));
//Helmet
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(helmetItem), false, "iii", "iwi", "gcg",
'i', Item.ingotIron,
@ -459,13 +541,16 @@ public class WarpDrive implements LoadingCallback {
private static void initAETERecipes() {
ItemStack redstoneEnergycell = GameRegistry.findItemStack("ThermalExpansion", "cellReinforced", 1);
ItemStack resonantEnergycell = GameRegistry.findItemStack("ThermalExpansion", "cellResonant", 1);
ItemStack bucketEnder = GameRegistry.findItemStack("ThermalExpansion", "bucketEnder", 1);
ItemStack fluixCrystal = WarpDriveConfig.getAEMaterial("matFluxCrystal");
ItemStack quantumEntangledSingularity = WarpDriveConfig.getAEMaterial("matQuantumEntangledSingularity");
ItemStack vibrantQuartzGlass = WarpDriveConfig.getAEBlock("blkQuartzLamp");
vibrantQuartzGlass.setItemDamage(4);
ItemStack antimatter = GameRegistry.findItemStack("ResonantInduction|Atomic", "antimatter", 1);
antimatter.setItemDamage(0);
ItemStack floppy = GameRegistry.findItemStack("ComputerCraft", "disk", 1);
ItemStack ultimateLappack = new ItemStack(WarpDriveConfig.GS_ultimateLappack, 1, 1);
// top = advancedCircuit, redstoneEnergycell, advancedCircuit
// middle = fluix crystal, advancedMachine, fluix crystal
@ -485,6 +570,29 @@ public class WarpDrive implements LoadingCallback {
'c', WarpDriveConfig.getIC2Item("advancedCircuit"),
'o', floppy,
'f', fluixCrystal);
// top = Iridium plate, Resonant Energycell, Iridium plate
// middle = Singularity, 125 milligram antimatter, Singularity
// bottom = Iridium plate, Ultimate lappack, Iridium plate
GameRegistry.addRecipe(new ItemStack(powerReactorBlock), "iri", "sas", "ili",
'i', WarpDriveConfig.getIC2Item("iridiumPlate"),
's', quantumEntangledSingularity,
'a', antimatter,
'l', ultimateLappack,
'r', resonantEnergycell);
// top = Advanced circuit, Advanced alloy, Advanced alloy
// middle = Advanced circuit, Warp drive laser, Vibrant quartz glass
// bottom = Advanced circuit, Certus quartz tank, Advanced alloy
ItemStack isMiningLaserBlock = new ItemStack(miningLaserBlock.blockID, 1, 0);
ItemStack isCertusQuartzTank = new ItemStack(WarpDriveConfig.AEExtra_certusQuartzTank.blockID, 1, 0);
GameRegistry.addRecipe(new ItemStack(powerLaserBlock), "caa", "czg", "cta",
'c', WarpDriveConfig.getIC2Item("advancedCircuit"),
'a', WarpDriveConfig.getIC2Item("advancedAlloy"),
'z', isMiningLaserBlock,
't', isCertusQuartzTank,
'g', vibrantQuartzGlass);
}
private static void initIC2Recipes() {
@ -622,6 +730,7 @@ public class WarpDrive implements LoadingCallback {
event.registerServerCommand(new SpaceTpCommand());
event.registerServerCommand(new InvisibleCommand());
event.registerServerCommand(new JumpgateCommand());
event.registerServerCommand(new DebugCommand());
}
public Ticket registerChunkLoadTE(WarpChunkTE te, boolean refreshLoading) {

View file

@ -43,8 +43,15 @@ public class WarpDriveConfig
public static int cloakCoreID;
public static int cloakCoilID;
public static int laserTreeFarmID;
public static int transporterID;
public static int transportBeaconID;
public static int reactorLaserFocusID;
public static int reactorMonitorID;
public static int powerReactorID;
public static int powerLaserID;
public static int powerStoreID;
public static int chunkLoaderID;
public static int decorativeID;
// Items
public static int componentID;
@ -447,7 +454,14 @@ public class WarpDriveConfig
cloakCoreID = config.getBlock("cloakcore", 517).getInt();
cloakCoilID = config.getBlock("cloakcoil", 518).getInt();
laserTreeFarmID = config.getBlock("lasertreefarm", 519).getInt();
transporterID = config.getBlock("transporter", 520).getInt();
transportBeaconID = config.getBlock("transportBeacon", 521).getInt();
reactorMonitorID = config.getBlock("reactorMonitor", 522).getInt();
powerLaserID = config.getBlock("powerLaser", 523).getInt();
powerReactorID = config.getBlock("powerReactor", 524).getInt();
powerStoreID = config.getBlock("powerStore", 525).getInt();
chunkLoaderID = config.getBlock("chunkLoader", 526).getInt();
decorativeID = config.getBlock("decorative",527).getInt();
reactorLaserFocusID = config.getItem("reactorLaserFocus", 8700).getInt();
componentID = config.getItem("component", 8701).getInt();

View file

@ -0,0 +1,98 @@
package cr0s.WarpDrive.block;
import java.util.List;
import cpw.mods.fml.common.registry.GameRegistry;
import cr0s.WarpDrive.WarpDrive;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraftforge.oredict.ShapedOreRecipe;
public class BlockDecorative extends Block
{
public static enum decorativeTypes { Plain , Energized , Network };
private ItemStack[] isCache = new ItemStack[decorativeTypes.values().length];
private Icon[] iconBuffer = new Icon[decorativeTypes.values().length];
public BlockDecorative(int par1)
{
super(par1, Material.iron);
setHardness(0.5f);
setStepSound(Block.soundMetalFootstep);
setCreativeTab(WarpDrive.warpdriveTab);
}
public boolean isValidDamage(int damage)
{
return damage >= 0 && damage < decorativeTypes.values().length;
}
@Override
public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
for(decorativeTypes val: decorativeTypes.values())
par3List.add(new ItemStack(par1, 1, val.ordinal()));
}
@Override
public void registerIcons(IconRegister ir)
{
for(decorativeTypes val: decorativeTypes.values())
iconBuffer[val.ordinal()] = ir.registerIcon("warpdrive:decorative" + val.toString());
}
@Override
public Icon getIcon(int side, int damage)
{
if(isValidDamage(damage))
return iconBuffer[damage];
return iconBuffer[0];
}
@Override
public int damageDropped(int damage)
{
return damage;
}
public ItemStack getIS(int damage)
{
if(!isValidDamage(damage))
return null;
if(isCache[damage] == null)
isCache[damage] = getISNoCache(damage);
return isCache[damage];
}
public ItemStack getISNoCache(int damage, int amount)
{
if(!isValidDamage(damage))
return null;
return new ItemStack(WarpDrive.decorativeBlock,amount,damage);
}
public ItemStack getISNoCache(int damage)
{
return getISNoCache(damage,1);
}
public void initRecipes()
{
GameRegistry.addRecipe(new ShapedOreRecipe(getISNoCache(0,8),false, "sss","scs","sss",
's', Block.stone,
'c', WarpDrive.componentItem.getIS(0)));
GameRegistry.addRecipe(new ShapedOreRecipe(getISNoCache(2,8),false, "sss","scs","sss",
's', getIS(0),
'c', WarpDrive.componentItem.getIS(5)));
}
}

View file

@ -0,0 +1,57 @@
package cr0s.WarpDrive.block;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cr0s.WarpDrive.WarpDrive;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public class BlockTransportBeacon extends Block {
public BlockTransportBeacon(int par1) {
super(par1, Material.iron);
setHardness(0.5F);
setStepSound(Block.soundMetalFootstep);
setCreativeTab(WarpDrive.warpdriveTab);
setUnlocalizedName("warpdrive.blocks.transportBeacon");
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) {
return null;
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister) {
this.blockIcon = par1IconRegister.registerIcon("warpdrive:transportBeacon");
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public boolean renderAsNormalBlock() {
return false;
}
@Override
public int getRenderType() {
return 2;
}
@Override
public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) {
float f = 0.065F;
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.6F, 0.5F + f);
return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
}
}

View file

@ -0,0 +1,40 @@
package cr0s.WarpDrive.block;
import java.util.List;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
public class ItemBlockDecorative extends ItemBlock
{
public ItemBlockDecorative(int par1)
{
super(par1);
setHasSubtypes(true);
setUnlocalizedName("warpdrive.block.decorative");
}
@Override
public int getMetadata (int damage)
{
return damage;
}
@Override
public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
for(int i = 0; i < BlockDecorative.decorativeTypes.values().length;i++)
par3List.add(new ItemStack(par1,1,i));
}
@Override
public String getUnlocalizedName(ItemStack itemstack)
{
if(itemstack == null)
return getUnlocalizedName();
return "tile.warpdrive.decorative." + BlockDecorative.decorativeTypes.values()[itemstack.getItemDamage()].toString();
}
}

View file

@ -0,0 +1,151 @@
package cr0s.WarpDrive.command;
import cpw.mods.fml.common.FMLCommonHandler;
import cr0s.WarpDrive.WarpDriveConfig;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
/*
* /wdebug <dimension> <coordinates> <blockId> <Metadata> <actions>
*/
public class DebugCommand extends CommandBase
{
@Override
public String getCommandName()
{
return "wdebug";
}
@Override
public int getRequiredPermissionLevel()
{
return 2;
}
@Override
public String getCommandUsage(ICommandSender par1ICommandSender)
{
return "/" + getCommandName() + " <dimension> <x> <y> <z> <blockId> <Metadata> <action><action>...\n"
+ "dimension: 0/world, 2/space, 3/hyperspace\n"
+ "coordinates: x,y,z\n"
+ "action: I(nvalidate), V(alidate), A(set air), R(emoveEntity), P(setBlock), S(etEntity)";
}
@Override
public void processCommand(ICommandSender icommandsender, String[] params)
{
EntityPlayerMP player = (EntityPlayerMP)icommandsender;
if(params.length > 6 )
{
int dim, x, y, z, blockId, metadata;
String actions;
try
{
String par = params[0].toLowerCase();
if (par.equals("world") || par.equals("overworld") || par.equals("0"))
{
dim = 0;
}
else if (par.equals("nether") || par.equals("thenether") || par.equals("-1"))
{
dim = -1;
}
else if (par.equals("s") || par.equals("space"))
{
dim = WarpDriveConfig.G_SPACE_DIMENSION_ID;
}
else if (par.equals("h") || par.equals("hyper") || par.equals("hyperspace"))
{
dim = WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID;
}
else
{
dim = Integer.parseInt(par);
}
x = Integer.parseInt(params[1]);
y = Integer.parseInt(params[2]);
z = Integer.parseInt(params[3]);
blockId = Integer.parseInt(params[4]);
metadata = Integer.parseInt(params[5]);
actions = params[6];
}
catch (Exception e)
{
e.printStackTrace();
player.addChatMessage(getCommandUsage(icommandsender));
return;
}
notifyAdmins(icommandsender, "/" + getCommandName() + " " + dim + " " + x + "," + y + "," + z + " " + blockId + ":" + metadata + " " + actions);
World worldObj = DimensionManager.getWorld(dim);
TileEntity te = worldObj.getBlockTileEntity(x, y, z);
notifyAdmins(icommandsender, "[" + getCommandName() + "] In dimension " + worldObj.getProviderName() + " - " + worldObj.getWorldInfo().getWorldName() + ", Current block is " + worldObj.getBlockId(x, y, z) + ":" + worldObj.getBlockMetadata(x, y, z) + ", tile entity is " + ((te == null) ? "undefined" : "defined"));
String side = FMLCommonHandler.instance().getEffectiveSide().isClient() ? "Client":"Server";
// I(nvalidate), V(alidate), A(set air), R(emoveEntity), P(setBlock), S(etEntity)
boolean bReturn = false;
for (char ch: actions.toUpperCase().toCharArray()) {
switch (ch) {
case 'I':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": invalidating");
if (te != null) {
te.invalidate();
}
break;
case 'V':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": validating");
if (te != null) {
te.validate();
}
break;
case 'A':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": setting to Air");
bReturn = worldObj.setBlockToAir(x, y, z);
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": returned " + bReturn);
break;
case 'R':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": remove entity");
worldObj.removeBlockTileEntity(x, y, z);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": set block " + x + ", " + y + ", " + z + " to " + blockId + ":" + metadata);
bReturn = worldObj.setBlock(x, y, z, blockId, metadata, ch - '0');
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": returned " + bReturn);
break;
case 'P':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": set block " + x + ", " + y + ", " + z + " to " + blockId + ":" + metadata);
bReturn = worldObj.setBlock(x, y, z, blockId, metadata, 2);
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": returned " + bReturn);
break;
case 'S':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": set entity");
worldObj.setBlockTileEntity(x, y, z, te);
break;
case 'C':
notifyAdmins(icommandsender, "[" + getCommandName() + "] " + side + ": update containing block info");
if (te != null) {
te.updateContainingBlockInfo();
}
break;
}
}
}
else
{
player.addChatMessage(getCommandUsage(icommandsender));
}
}
}

View file

@ -0,0 +1,137 @@
package cr0s.WarpDrive.item;
import java.util.List;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cr0s.WarpDrive.WarpDrive;
import cr0s.WarpDrive.data.EnumUpgradeTypes;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraftforge.oredict.ShapedOreRecipe;
public class ItemWarpUpgrade extends Item
{
private ItemStack[] isCache = new ItemStack[EnumUpgradeTypes.values().length];
private Icon[] iconBuffer = new Icon[EnumUpgradeTypes.values().length];
public ItemWarpUpgrade(int par1)
{
super(par1);
setHasSubtypes(true);
setUnlocalizedName("warpdrive.upgrade.Malformed");
setCreativeTab(WarpDrive.warpdriveTab);
}
private boolean isValidDamage(int damage)
{
return damage >= 0 && damage < EnumUpgradeTypes.values().length;
}
public ItemStack getIS(int damage)
{
if(!isValidDamage(damage))
return null;
if(isCache[damage] == null)
isCache[damage] = getISNoCache(damage);
return isCache[damage];
}
public ItemStack getISNoCache(int damage)
{
if(!isValidDamage(damage))
return null;
return new ItemStack(WarpDrive.upgradeItem,1,damage);
}
@Override
public String getUnlocalizedName(ItemStack is)
{
if(is == null)
return null;
int damage = is.getItemDamage();
if(isValidDamage(damage))
return "item.warpdrive.upgrade." + EnumUpgradeTypes.values()[damage].toString();
return null;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
for(int i=0;i<EnumUpgradeTypes.values().length;i++)
par3List.add(getIS(i));
}
@Override
public void addInformation(ItemStack is, EntityPlayer pl, List list, boolean par4)
{
if(is == null)
return;
int damage = is.getItemDamage();
if(damage == EnumUpgradeTypes.Energy.ordinal())
list.add("Increases the max energy of the machine");
else if(damage == EnumUpgradeTypes.Power.ordinal())
list.add( "Decreases the power usage of the machine");
else if(damage == EnumUpgradeTypes.Speed.ordinal())
list.add( "Increases the speed of the machine");
else if(damage == EnumUpgradeTypes.Range.ordinal())
list.add( "Increases the range of the machine");
}
public void initRecipes()
{
GameRegistry.addRecipe(new ShapedOreRecipe(getIS(EnumUpgradeTypes.Energy.ordinal()),false,"c","e","r",
'c', WarpDrive.componentItem.getIS(0),
'e', WarpDrive.componentItem.getIS(7),
'r', Item.redstone));
GameRegistry.addRecipe(new ShapedOreRecipe(getIS(EnumUpgradeTypes.Power.ordinal()),false,"c","e","r",
'c', WarpDrive.componentItem.getIS(0),
'e', WarpDrive.componentItem.getIS(6),
'r', Item.redstone));
GameRegistry.addRecipe(new ShapedOreRecipe(getIS(EnumUpgradeTypes.Speed.ordinal()),false,"c","e","r",
'c', WarpDrive.componentItem.getIS(0),
'e', Item.sugar,
'r', Item.redstone));
GameRegistry.addRecipe(new ShapedOreRecipe(getIS(EnumUpgradeTypes.Range.ordinal()),false,"c","e","r",
'c', WarpDrive.componentItem.getIS(0),
'e', WarpDrive.transportBeaconBlock,
'r', Item.redstone));
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister ir)
{
for(EnumUpgradeTypes val : EnumUpgradeTypes.values())
{
iconBuffer[val.ordinal()] = ir.registerIcon("warpdrive:upgrade" + val.toString());
}
}
@Override
@SideOnly(Side.CLIENT)
public Icon getIconFromDamage(int damage)
{
if(damage >= 0 && damage < EnumUpgradeTypes.values().length)
return iconBuffer[damage];
return iconBuffer[0];
}
}

View file

@ -0,0 +1,37 @@
package cr0s.WarpDrive.machines;
import cr0s.WarpDrive.machines.WarpBlockContainer;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
public class BlockChunkLoader extends WarpBlockContainer
{
Icon iconBuffer;
public BlockChunkLoader(int par1)
{
super(par1);
setUnlocalizedName("warpdrive.machines.ChunkLoader");
}
@Override
public TileEntity createNewTileEntity(World world)
{
return new TileEntityChunkLoader();
}
@Override
public void registerIcons(IconRegister ir)
{
iconBuffer = ir.registerIcon("warpdrive:chunkLoader");
}
@Override
public Icon getIcon(int side, int damage)
{
return iconBuffer;
}
}

View file

@ -0,0 +1,63 @@
package cr0s.WarpDrive.machines;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
public class BlockPowerLaser extends WarpBlockContainer {
static Icon[] iconBuffer = new Icon[16];
public BlockPowerLaser(int id) {
super(id);
setUnlocalizedName("warpdrive.power.Laser");
setResistance(100.0F);
}
@Override
public TileEntity createNewTileEntity(World world) {
return new TileEntityPowerLaser();
}
private static boolean isActive(int side, int meta) {
if (side == 3 && meta == 1) {
return true;
}
if (side == 2 && meta == 2) {
return true;
}
if (side == 4 && meta == 4) {
return true;
}
if (side == 5 && meta == 3) {
return true;
}
return false;
}
@Override
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int meta) {
if (side == 0 || side == 1) {
return iconBuffer[0];
}
if(isActive(side,meta)) {
return iconBuffer[2];
}
return iconBuffer[1];
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister) {
iconBuffer[0] = par1IconRegister.registerIcon("warpdrive:powerLaserTopBottom");
iconBuffer[1] = par1IconRegister.registerIcon("warpdrive:powerLaserSides");
iconBuffer[2] = par1IconRegister.registerIcon("warpdrive:powerLaserActive");
}
}

View file

@ -0,0 +1,70 @@
package cr0s.WarpDrive.machines;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
public class BlockPowerReactor extends WarpBlockContainer {
Icon[] iconBuffer = new Icon[17];
public BlockPowerReactor(int id) {
super(id);
setUnlocalizedName("warpdrive.power.Reactor");
}
@Override
public TileEntity createNewTileEntity(World world) {
return new TileEntityPowerReactor();
}
@Override
public void breakBlock(World w,int x,int y,int z, int oid,int om) {
super.breakBlock(w, x, y, z, oid, om);
int[] xo = {-2, 2, 0, 0};
int[] zo = { 0, 0,-2, 2};
for(int i = 0; i < 4; i++) {
TileEntity te = w.getBlockTileEntity(x+xo[i], y, z+zo[i]);
if(te instanceof TileEntityPowerLaser) {
((TileEntityPowerLaser)te).unlink();
}
}
}
@Override
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int meta) {
if (side == 0 || side == 1) {
return iconBuffer[16];
}
if (meta >= 0 && meta < 16) {
return iconBuffer[meta];
}
return iconBuffer[0];
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister) {
iconBuffer[16] = par1IconRegister.registerIcon("warpdrive:reactorTB");
iconBuffer[0] = par1IconRegister.registerIcon("warpdrive:reactorSide00");
iconBuffer[1] = par1IconRegister.registerIcon("warpdrive:reactorSide01");
iconBuffer[2] = par1IconRegister.registerIcon("warpdrive:reactorSide02");
iconBuffer[3] = par1IconRegister.registerIcon("warpdrive:reactorSide03");
iconBuffer[4] = par1IconRegister.registerIcon("warpdrive:reactorSide10");
iconBuffer[5] = par1IconRegister.registerIcon("warpdrive:reactorSide11");
iconBuffer[6] = par1IconRegister.registerIcon("warpdrive:reactorSide12");
iconBuffer[7] = par1IconRegister.registerIcon("warpdrive:reactorSide13");
iconBuffer[8] = par1IconRegister.registerIcon("warpdrive:reactorSide20");
iconBuffer[9] = par1IconRegister.registerIcon("warpdrive:reactorSide21");
iconBuffer[10] = par1IconRegister.registerIcon("warpdrive:reactorSide22");
iconBuffer[11] = par1IconRegister.registerIcon("warpdrive:reactorSide23");
iconBuffer[12] = par1IconRegister.registerIcon("warpdrive:reactorSide30");
iconBuffer[13] = par1IconRegister.registerIcon("warpdrive:reactorSide31");
iconBuffer[14] = par1IconRegister.registerIcon("warpdrive:reactorSide32");
iconBuffer[15] = par1IconRegister.registerIcon("warpdrive:reactorSide33");
}
}

View file

@ -0,0 +1,54 @@
package cr0s.WarpDrive.machines;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
public class BlockPowerStore extends WarpBlockContainer {
private Icon iconBuffer;
public BlockPowerStore(int par1) {
super(par1);
setUnlocalizedName("warpdrive.power.Store");
}
@Override
public TileEntity createNewTileEntity(World world) {
return new TileEntityPowerStore();
}
@Override
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int meta) {
return iconBuffer;
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister) {
iconBuffer = par1IconRegister.registerIcon("warpdrive:powerStore");
}
/**
* Called upon block activation (right click on the block.)
*/
@Override
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) {
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
return false;
}
WarpEnergyTE te = (WarpEnergyTE)par1World.getBlockTileEntity(par2, par3, par4);
if (te != null && (par5EntityPlayer.getHeldItem() == null)) {
par5EntityPlayer.addChatMessage(te.getStatus());
return true;
}
return false;
}
}

View file

@ -0,0 +1,47 @@
package cr0s.WarpDrive.machines;
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cr0s.WarpDrive.WarpDrive;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
public class BlockTransporter extends WarpBlockContainer {
private Icon[] iconBuffer;
public BlockTransporter(int par1, Material par2Material) {
super(par1, par2Material);
setUnlocalizedName("warpdrive.machines.Transporter");
}
@Override
public TileEntity createNewTileEntity(World world) {
return new TileEntityTransporter();
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister) {
iconBuffer = new Icon[3];
// Solid textures
iconBuffer[0] = par1IconRegister.registerIcon("warpdrive:transporterBottom");
iconBuffer[1] = par1IconRegister.registerIcon("warpdrive:transporterTop");
iconBuffer[2] = par1IconRegister.registerIcon("warpdrive:transporterSide");
}
@Override
public Icon getIcon(int side, int metadata) {
if (side == 0 || side == 1) {
return iconBuffer[side];
}
return iconBuffer[2];
}
}

View file

@ -0,0 +1,257 @@
package cr0s.WarpDrive.machines;
import java.util.Map;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.chunk.Chunk;
import cr0s.WarpDrive.data.EnumUpgradeTypes;
import cr0s.WarpDrive.WarpDrive;
import cr0s.WarpDrive.WarpDriveConfig;
import cr0s.WarpDrive.api.IUpgradable;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
public class TileEntityChunkLoader extends WarpChunkTE implements IPeripheral, IUpgradable
{
private boolean canLoad = false;
private boolean shouldLoad = false;
private boolean inited = false;
private ChunkCoordIntPair myChunk;
int negDX, posDX, negDZ, posDZ;
int area = 1;
private String[] methodArray = {
"energy",
"radius",
"bounds",
"active",
"upgrades",
"help"
};
{
negDX = 0;
negDZ = 0;
posDX = 0;
posDZ = 0;
}
@Override
public int getMaxEnergyStored()
{
return WarpDriveConfig.CL_MAX_ENERGY;
}
@Override
public boolean shouldChunkLoad()
{
return shouldLoad && canLoad;
}
@Override
public void updateEntity()
{
super.updateEntity();
if(!inited)
{
inited = true;
myChunk = worldObj.getChunkFromBlockCoords(xCoord, zCoord).getChunkCoordIntPair();
changedDistance();
}
if(shouldLoad)
{
canLoad = consumeEnergy(area * WarpDriveConfig.CL_RF_PER_CHUNKTICK, false);
}
else
{
canLoad = consumeEnergy(area * WarpDriveConfig.CL_RF_PER_CHUNKTICK, true);
}
}
private int clampDistance(int dis)
{
return clamp(dis,0,WarpDriveConfig.CL_MAX_DISTANCE);
}
private void changedDistance()
{
if(worldObj == null) {
return;
}
if (myChunk == null) {
Chunk aChunk = worldObj.getChunkFromBlockCoords(xCoord, zCoord);
if (aChunk != null) {
myChunk = aChunk.getChunkCoordIntPair();
} else {
return;
}
}
negDX = -clampDistance(negDX);
posDX = clampDistance(posDX);
negDZ = -clampDistance(negDZ);
posDZ = clampDistance(posDZ);
minChunk = new ChunkCoordIntPair(myChunk.chunkXPos+negDX,myChunk.chunkZPos+negDZ);
maxChunk = new ChunkCoordIntPair(myChunk.chunkXPos+posDX,myChunk.chunkZPos+posDZ);
area = (posDX - negDX + 1) * (posDZ - negDZ + 1);
refreshLoading(true);
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
negDX = nbt.getInteger("negDX");
negDZ = nbt.getInteger("negDZ");
posDX = nbt.getInteger("posDX");
posDZ = nbt.getInteger("posDZ");
changedDistance();
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setInteger("negDX", negDX);
nbt.setInteger("negDZ", negDZ);
nbt.setInteger("posDX", posDX);
nbt.setInteger("posDZ", posDZ);
}
@Override
public String getType()
{
return "warpdriveChunkloader";
}
@Override
public String[] getMethodNames()
{
return methodArray;
}
private String helpStr(Object[] args)
{
if(args.length == 1)
{
String m = args[0].toString().toLowerCase();
if(m.equals("energy"))
return WarpDrive.defEnergyStr;
else if(m.equals("radius"))
return "radius(int): sets the radius in chunks";
else if(m.equals("bounds"))
return "bounds(int,int,int,int): sets the bounds of chunks to load\nbounds(): returns the 4 bounds\nFormat is -X, +X, -Z, +Z";
else if(m.equals("active"))
return "active(): returns whether active or not\nactive(boolean): sets whether it should be active or not";
else if(m.equals("upgrades"))
return WarpDrive.defUpgradeStr;
}
return WarpDrive.defHelpStr;
}
@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws Exception
{
String meth = methodArray[method];
if(meth.equals("energy"))
return getEnergyObject();
else if(meth.equals("radius"))
{
if(arguments.length == 1)
{
int dist = toInt(arguments[0]);
negDX = dist;
negDZ = dist;
posDX = dist;
posDZ = dist;
changedDistance();
return new Object[] { true };
}
return new Object[] { false };
}
else if(meth.equals("bounds"))
{
if(arguments.length == 4)
{
negDX = toInt(arguments[0]);
posDX = toInt(arguments[1]);
negDZ = toInt(arguments[2]);
posDZ = toInt(arguments[3]);
changedDistance();
}
return new Object[] { negDX, posDX, negDZ, posDZ };
}
else if(meth.equals("active"))
{
if(arguments.length == 1)
shouldLoad = toBool(arguments[0]);
return new Object[] { shouldChunkLoad() };
}
else if(meth.equals("upgrades"))
{
return getUpgrades();
}
else if(meth.equals("help"))
{
return new Object[] {helpStr(arguments) };
}
return null;
}
@Override
public void attach(IComputerAccess computer)
{
}
@Override
public void detach(IComputerAccess computer)
{
}
@Override
public boolean equals(IPeripheral other)
{
return false;
}
@Override
public boolean takeUpgrade(EnumUpgradeTypes upgradeType, boolean simulate)
{
int max = 0;
if(upgradeType == EnumUpgradeTypes.Energy)
max = 2;
else if(upgradeType == EnumUpgradeTypes.Power)
max = 2;
if(max == 0)
return false;
if(upgrades.containsKey(upgradeType))
if(upgrades.get(upgradeType) >= max)
return false;
if(!simulate)
{
int c = 0;
if(upgrades.containsKey(upgradeType))
c = upgrades.get(upgradeType);
upgrades.put(upgradeType, c+1);
}
return true;
}
@Override
public Map<EnumUpgradeTypes, Integer> getInstalledUpgrades()
{
return upgrades;
}
}

View file

@ -0,0 +1,218 @@
package cr0s.WarpDrive.machines;
import cr0s.WarpDrive.api.IBlockUpdateDetector;
import cr0s.WarpDrive.data.Vector3;
import cr0s.WarpDrive.WarpDrive;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
public class TileEntityPowerLaser extends TileEntityAbstractLaser implements IPeripheral, IBlockUpdateDetector {
Vector3 myVec;
Vector3 reactorVec;
ForgeDirection side = ForgeDirection.UNKNOWN;
TileEntityParticleBooster booster;
TileEntityPowerReactor reactor;
boolean useLaser = false;
boolean doOnce = false;
String[] methodArray = {
"energy",
"hasReactor",
"side",
"sendLaser",
"help"
};
@Override
public boolean shouldChunkLoad() {
return false;
}
public TileEntityPowerReactor scanForReactor() {
reactor = null;
TileEntity te;
//I AM ON THE NORTH SIDE
side = ForgeDirection.UNKNOWN;
te = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord + 2);
if (te instanceof TileEntityPowerReactor && worldObj.isAirBlock(xCoord, yCoord, zCoord + 1)) {
side = ForgeDirection.NORTH;
reactor = (TileEntityPowerReactor) te;
}
//I AM ON THE SOUTH SIDE
te = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord - 2);
if (te instanceof TileEntityPowerReactor && worldObj.isAirBlock(xCoord, yCoord, zCoord - 1)) {
side = ForgeDirection.SOUTH;
reactor = (TileEntityPowerReactor) te;
}
//I AM ON THE WEST SIDE
te = worldObj.getBlockTileEntity(xCoord + 2, yCoord, zCoord);
if (te instanceof TileEntityPowerReactor && worldObj.isAirBlock(xCoord + 1, yCoord, zCoord)) {
side = ForgeDirection.WEST;
reactor = (TileEntityPowerReactor) te;
}
//I AM ON THE EAST SIDE
te = worldObj.getBlockTileEntity(xCoord - 2, yCoord, zCoord);
if (te instanceof TileEntityPowerReactor && worldObj.isAirBlock(xCoord - 1, yCoord, zCoord)) {
side = ForgeDirection.EAST;
reactor = (TileEntityPowerReactor) te;
}
setMetadata();
if (reactor != null) {
reactorVec = new Vector3(reactor).translate(0.5);
}
return reactor;
}
private void setMetadata() {
int metadata = 0;
if (side != ForgeDirection.UNKNOWN) {
metadata = side.ordinal() - 1;
}
if (getBlockMetadata() != metadata) {
worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, metadata, 3);
}
}
public TileEntityParticleBooster scanForBooster() {
booster = null;
TileEntity te;
te = worldObj.getBlockTileEntity(xCoord, yCoord + 1, zCoord);
if (te != null && te instanceof TileEntityParticleBooster) {
booster = (TileEntityParticleBooster)te;
}
te = worldObj.getBlockTileEntity(xCoord, yCoord - 1, zCoord);
if (te != null && te instanceof TileEntityParticleBooster) {
booster = (TileEntityParticleBooster)te;
}
return booster;
}
@Override
public void updateEntity() {
if (doOnce == false) {
scanForReactor();
scanForBooster();
myVec = new Vector3(this).translate(0.5);
doOnce = true;
}
if (useLaser == true) {
WarpDrive.sendLaserPacket(worldObj, myVec, reactorVec, 0.1F, 0.2F, 1.0F, 25, 50, 100);
useLaser = false;
}
}
public void unlink() {
side = ForgeDirection.UNKNOWN;
setMetadata();
}
@Override
public void updatedNeighbours() {
scanForBooster();
scanForReactor();
}
private void laserReactor(int energy) {
if (energy <= 0) {
return;
}
scanForBooster();
scanForReactor();
if(booster == null)
return;
if(reactor == null)
return;
if (booster.consumeEnergy(energy, false)) {
// WarpDrive.debugPrint("ReactorLaser on " + side.toString() +" side sending " + amount);
useLaser = true;
reactor.decreaseInstability(side, energy);
}
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public String getType() {
return "warpdriveReactorLaser";
}
@Override
public String[] getMethodNames() {
return methodArray;
}
private static String helpStr(Object[] args) {
if (args.length > 0) {
String arg = args[0].toString().toLowerCase();
if (arg.equals("energy")) {
return WarpDrive.defEnergyStr;
} else if(arg.equals("hasReactor")) {
return "hasReactor(): returns true if the laser can see a reactor and false otherwise";
} else if(arg.equals("sendlaser")) {
return "sendLaser(int): sends a laser of energy int to the reactor";
} else if(arg.equals("side")) {
return "side(): returns 0-3 depending on which side of the reactor its on";
}
}
return WarpDrive.defHelpStr;
}
@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws Exception {
String methodName = methodArray[method];
if (methodName.equals("energy")) {
scanForBooster();
if (booster == null) {
return new Object[] { 0,0 };
} else {
return new Object[] { booster.getEnergyStored(), booster.getMaxEnergyStored() };
}
} else if (methodName.equals("hasReactor")) {
return new Object[] { scanForReactor() != null };
} else if (methodName.equals("sendLaser")) {
if (arguments.length >= 1) {
laserReactor(toInt(arguments[0]));
}
} else if (methodName.equals("help")) {
return new Object[] {helpStr(arguments)};
} else if (methodName.equals("side")) {
return new Object[] { side.ordinal() - 2 };
}
return null;
}
@Override
public void attach(IComputerAccess computer) {
}
@Override
public void detach(IComputerAccess computer) {
}
@Override
public boolean equals(IPeripheral other) {
return other == this;
}
}

View file

@ -0,0 +1,543 @@
package cr0s.WarpDrive.machines;
import java.util.HashMap;
import java.util.Random;
import java.util.Set;
import cpw.mods.fml.common.FMLCommonHandler;
import cr0s.WarpDrive.WarpDrive;
import cr0s.WarpDrive.WarpDriveConfig;
import cr0s.WarpDrive.api.IBlockUpdateDetector;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
public class TileEntityPowerReactor extends WarpEnergyTE implements IPeripheral, IBlockUpdateDetector {
private int containedEnergy = 0;
// generation & instability is 'per tick'
private static final int PR_MIN_GENERATION = 4;
private static final int PR_MAX_GENERATION = 64000;
private static final double PR_MIN_INSTABILITY = 0.004D;
private static final double PR_MAX_INSTABILITY = 0.060D;
// explosion parameters
private static final int PR_MAX_EXPLOSION_RADIUS = 6;
private static final double PR_MAX_EXPLOSION_REMOVAL_CHANCE = 0.1D;
// laser stabilization is per shot
// target is to consume 10% max output power every second, hence 2.5% per side
// laser efficiency is 33% at 16% power (target spot), 50% at 24% power, 84% at 50% power, etc.
// 10% * 20 * PR_MAX_GENERATION / (4 * 0.16) => ~200kRF => ~ max laser energy
private static final double PR_MAX_LASER_ENERGY = 200000.0D;
private static final double PR_MAX_LASER_EFFECT = PR_MAX_INSTABILITY * 20 / 0.33D;
private int tickCount = 0;
private double[] instabilityValues = { 0.0D, 0.0D, 0.0D, 0.0D }; // no instability = 0, explosion = 100
private float lasersReceived = 0;
private int lastGenerationRate = 0;
private int releasedThisTick = 0; // amount of energy released during current tick update
private int releasedThisCycle = 0; // amount of energy released during current cycle
private int releasedLastCycle = 0;
private boolean hold = true; // hold updates and power output until reactor is controlled (i.e. don't explode on chunk-loading while computer is booting)
private boolean active = false;
private static final int MODE_DONT_RELEASE = 0;
private static final int MODE_MANUAL_RELEASE = 1;
private static final int MODE_RELEASE_ABOVE = 2;
private static final int MODE_RELEASE_AT_RATE = 3;
private static final String[] MODE_STRING = {"OFF", "MANUAL", "ABOVE", "RATE"};
private int releaseMode = 0;
private int releaseRate = 0;
private int releaseAbove = 0;
private boolean init = false;
private String[] methodArray = {
"getActive",
"setActive", // boolean
"energy", // returns energy, maxenergy
"instability", // returns ins0,1,2,3
"release", // releases all energy
"releaseRate", // releases energy when more than arg0 is produced
"releaseAbove", // releases any energy above arg0 amount
"help" // returns help on arg0 function
};
private HashMap<Integer,IComputerAccess> connectedComputers = new HashMap<Integer,IComputerAccess>();
private void increaseInstability(ForgeDirection from, boolean isNatural) {
if (canOutputEnergy(from) || hold) {
return;
}
int side = from.ordinal() - 2;
if (containedEnergy > WarpDriveConfig.PR_TICK_TIME * PR_MIN_GENERATION * 100) {
double amountToIncrease = WarpDriveConfig.PR_TICK_TIME * Math.max(PR_MIN_INSTABILITY, PR_MAX_INSTABILITY * Math.pow((worldObj.rand.nextDouble() * containedEnergy) / WarpDriveConfig.PR_MAX_ENERGY, 0.1));
//WarpDrive.debugPrint("InsInc" + amountToIncrease);
instabilityValues[side] += amountToIncrease * (isNatural ? 1.0D : 0.25D);
} else {
double amountToDecrease = WarpDriveConfig.PR_TICK_TIME * Math.max(PR_MIN_INSTABILITY, instabilityValues[side] * 0.02D);
instabilityValues[side] = Math.max(0.0D, instabilityValues[side] - amountToDecrease);
}
}
private void increaseInstability(boolean isNatural) {
increaseInstability(ForgeDirection.NORTH, isNatural);
increaseInstability(ForgeDirection.SOUTH, isNatural);
increaseInstability(ForgeDirection.EAST, isNatural);
increaseInstability(ForgeDirection.WEST, isNatural);
}
public void decreaseInstability(ForgeDirection from, int energy) {
if (canOutputEnergy(from)) {
return;
}
// laser is active => start updating reactor
hold = false;
int amount = convertInternalToRF(energy);
if (amount <= 1) {
return;
}
lasersReceived = Math.min(10.0F, lasersReceived + 1F / WarpDriveConfig.PR_MAX_LASERS);
double nospamFactor = 1.0;
if (lasersReceived > 1.0F) {
nospamFactor = 0.5;
worldObj.newExplosion((Entity) null, xCoord + from.offsetX, yCoord + from.offsetY, zCoord + from.offsetZ, 1, false, false);
// increaseInstability(from, false);
// increaseInstability(false);
}
double normalisedAmount = Math.min(1.0D, Math.max(0.0D, amount / PR_MAX_LASER_ENERGY)); // 0.0 to 1.0
double baseLaserEffect = 0.5D + 0.5D * Math.cos(Math.PI - (1.0D + Math.log10(0.1D + 0.9D * normalisedAmount)) * Math.PI); // 0.0 to 1.0
double randomVariation = 0.8D + 0.4D * worldObj.rand.nextDouble(); // ~1.0
double amountToRemove = PR_MAX_LASER_EFFECT * baseLaserEffect * randomVariation * nospamFactor;
int side = from.ordinal() - 2;
/*
if (side == 3) WarpDrive.debugPrint("Instability on " + from.toString() + " decreased by " + String.format("%.1f", amountToRemove) + "/" + String.format("%.1f", PR_MAX_LASER_EFFECT)
+ " after consuming " + amount + "/" + PR_MAX_LASER_ENERGY + " lasersReceived is " + String.format("%.1f", lasersReceived) + " hence nospamFactor is " + nospamFactor);
/**/
instabilityValues[side] = Math.max(0, instabilityValues[side] - amountToRemove);
updateSideTextures();
}
private void generateEnergy() {
double stabilityOffset = 0.5;
for(int i = 0; i < 4; i++) {
stabilityOffset *= Math.max(0.01D, instabilityValues[i] / 100.0D);
}
//WarpDrive.debugPrint("INSOFF" + stabilityOffset);
if (active) {// producing, instability increase output, you want to take the risk
int amountToGenerate = (int)Math.ceil( WarpDriveConfig.PR_TICK_TIME * (0.5D + stabilityOffset) * (PR_MIN_GENERATION + PR_MAX_GENERATION * Math.pow(containedEnergy / (double) WarpDriveConfig.PR_MAX_ENERGY, 0.6D)));
containedEnergy = Math.min(containedEnergy + amountToGenerate, WarpDriveConfig.PR_MAX_ENERGY);
lastGenerationRate = amountToGenerate / WarpDriveConfig.PR_TICK_TIME;
} else {// decaying over 20s without producing power, you better have power for those lasers
int amountToDecay = (int)( WarpDriveConfig.PR_TICK_TIME * (1.0D - stabilityOffset) * (PR_MIN_GENERATION + containedEnergy * 0.01D) );
containedEnergy = Math.max(0, containedEnergy - amountToDecay);
lastGenerationRate = 0;
}
}
@Override
public void updateEntity() {
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
return;
}
super.updateEntity();
releasedThisTick = 0;
lasersReceived = Math.max(0.0F, lasersReceived - 0.05F);
tickCount++;
if (tickCount < WarpDriveConfig.PR_TICK_TIME) {
return;
}
tickCount = 0;
releasedLastCycle = releasedThisCycle;
releasedThisCycle = 0;
if (!init) {
init = true;
updatedNeighbours();
}
updateSideTextures();
// unstable at all time
if (shouldExplode()) {
explode();
}
increaseInstability(true);
generateEnergy();
sendEvent("reactorPulse", new Object[] { lastGenerationRate });
}
private void explode() {
// remove blocks randomly up to x blocks around (breaking whatever protection is there)
double normalizedEnergy = containedEnergy / (double)WarpDriveConfig.PR_MAX_ENERGY;
int radius = (int) Math.round(PR_MAX_EXPLOSION_RADIUS * Math.pow(normalizedEnergy, 0.125));
double c = PR_MAX_EXPLOSION_REMOVAL_CHANCE * Math.pow(normalizedEnergy, 0.125);
WarpDrive.debugPrint(this + " Explosion radius is " + radius + ", Chance of removal is " + c);
if (radius > 1) {
for(int x = xCoord - radius; x <= xCoord + radius; x++) {
for(int y = yCoord - radius; y <= yCoord + radius; y++) {
for(int z = zCoord - radius; z <= zCoord + radius; z++) {
if (z != zCoord || y != yCoord || x != xCoord) {
if (worldObj.rand.nextDouble() < c) {
worldObj.setBlockToAir(x, y, z);
}
}
}
}
}
}
// remove reactor
worldObj.setBlockToAir(xCoord, yCoord, zCoord);
// set a few TnT augmented around reactor
for (int i = 0; i < 3; i++) {
worldObj.newExplosion((Entity) null,
xCoord + worldObj.rand.nextInt(3) - 0.5D,
yCoord + worldObj.rand.nextInt(3) - 0.5D,
zCoord + worldObj.rand.nextInt(3) - 0.5D,
4.0F + worldObj.rand.nextInt(3),
true, true);
}
}
private void updateSideTextures() {
double maxInstability = 0.0D;
for (Double ins:instabilityValues) {
if (ins > maxInstability) {
maxInstability = ins;
}
}
int instabilityNibble = (int) Math.max(0, Math.min(3, Math.round( maxInstability / 25.0D)));
int energyNibble = (int) Math.max(0, Math.min(3, Math.round(4.0D * containedEnergy / WarpDriveConfig.PR_MAX_ENERGY)));
int metadata = 4 * instabilityNibble + energyNibble;
if (getBlockMetadata() != metadata) {
worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, metadata, 3);
}
}
private boolean shouldExplode() {
boolean exploding = false;
for(int i = 0; i < 4; i++) {
exploding = exploding || (instabilityValues[i] >= 100);
}
exploding &= worldObj.rand.nextBoolean();
if (exploding && worldObj.rand.nextBoolean()) {
active = false;
WarpDrive.print(this + String.format(" Explosion trigerred, Instability is [%.2f, %.2f, %.2f, %.2f], Energy stored is %d, Laser received is %.2f, %s", new Object[] {
instabilityValues[0], instabilityValues[1], instabilityValues[2], instabilityValues[3],
this.containedEnergy,
this.lasersReceived,
this.active ? "ACTIVE" : "INACTIVE" }));
}
return exploding;
}
//Takes the arguments passed by function call and returns an appropriate string
private static String helpStr(Object[] args) {
if (args.length > 0) {
String arg = args[0].toString().toLowerCase();
if (arg.equals("getactive")) {
return "getActive(): returns true if the reactor is active and false otherwise";
} else if (arg.equals("setactive")) {
return "setActive(bool): activates the reactor if passed true and deactivates if passed false";
} else if (arg.equals("energy")) {
return WarpDrive.defEnergyStr;
} else if (arg.equals("instability")) {
return "instability(): returns the 4 instability values (100 is the point when the reactor explodes)";
} else if (arg.equals("release")) {
return "release(bool): sets the reactor to output all energy or disables outputting of energy";
} else if (arg.equals("releaserate")) {
return "releaseRate(int): sets the reactor to try to release exactly int/tick";
} else if (arg.equals("releaseabove")) {
return "releaseAbove(int): releases all energy above stored int";
}
}
return WarpDrive.defHelpStr;
}
@Override
public void updatedNeighbours() {
TileEntity te;
super.updatedNeighbours();
int[] xo = { 0, 0,-2, 2};
int[] zo = { 2,-2, 0, 0};
for(int i = 0; i < 4; i++) {
te = worldObj.getBlockTileEntity(xCoord + xo[i], yCoord, zCoord + zo[i]);
if (te instanceof TileEntityPowerLaser) {
((TileEntityPowerLaser)te).scanForReactor();
}
}
}
//COMPUTER INTERFACES
@Override
public String getType() {
return "warpdriveReactor";
}
@Override
public String[] getMethodNames() {
return methodArray;
}
@Override
public void attach(IComputerAccess computer) {
int id = computer.getID();
connectedComputers.put(id, computer);
if (WarpDriveConfig.G_LUA_SCRIPTS != WarpDriveConfig.LUA_SCRIPTS_NONE) {
computer.mount("/power", ComputerCraftAPI.createResourceMount(WarpDrive.class, "warpdrive", "lua/power"));
computer.mount("/warpupdater", ComputerCraftAPI.createResourceMount(WarpDrive.class, "warpdrive", "lua/common/updater"));
if (WarpDriveConfig.G_LUA_SCRIPTS == WarpDriveConfig.LUA_SCRIPTS_ALL) {
computer.mount("/startup", ComputerCraftAPI.createResourceMount(WarpDrive.class, "warpdrive", "lua/power/startup"));
}
}
}
@Override
public void detach(IComputerAccess computer) {
int id = computer.getID();
if (connectedComputers.containsKey(id)) {
connectedComputers.remove(id);
}
}
@Override
public boolean equals(IPeripheral other) {
return other == this;
}
@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws Exception {
// computer is alive => start updating reactor
hold = false;
String methodName = methodArray[method];
if (methodName.equals("getActive")) {
if (releaseMode == MODE_DONT_RELEASE || releaseMode == MODE_MANUAL_RELEASE) {
return new Object[] { active, MODE_STRING[releaseMode], 0 };
} else if (releaseMode == MODE_RELEASE_ABOVE) {
return new Object[] { active, MODE_STRING[releaseMode], releaseAbove };
} else {
return new Object[] { active, MODE_STRING[releaseMode], releaseRate };
}
} else if (methodName.equals("setActive")) {
boolean activate = false;
try {
activate = toBool(arguments[0]);
} catch(Exception e) {
throw new Exception("Function expects an boolean value");
}
if (active && !activate) {
sendEvent("reactorDeactivation", null);
} else if(!active && activate) {
sendEvent("reactorActivation", null);
}
active = activate;
} else if (methodName.equals("energy")) {
return new Object[] { containedEnergy, WarpDriveConfig.PR_MAX_ENERGY, releasedLastCycle / WarpDriveConfig.PR_TICK_TIME };
} else if (methodName.equals("instability")) {
Object[] retVal = new Object[4];
for(int i = 0; i < 4; i++) {
retVal[i] = instabilityValues[i];
}
return retVal;
} else if(methodName.equals("release")) {
boolean doRelease = false;
if (arguments.length > 0) {
try {
doRelease = toBool(arguments[0]);
} catch(Exception e) {
throw new Exception("Function expects an boolean value");
}
releaseMode = doRelease ? MODE_MANUAL_RELEASE : MODE_DONT_RELEASE;
releaseAbove = 0;
releaseRate = 0;
}
return new Object[] { releaseMode != MODE_DONT_RELEASE };
} else if(methodName.equals("releaseRate")) {
int rate = -1;
try {
rate = toInt(arguments[0]);
} catch(Exception e) {
throw new Exception("Function expects an integer value");
}
if (rate <= 0) {
releaseMode = MODE_DONT_RELEASE;
releaseRate = 0;
} else {
/* releaseAbove = (int)Math.ceil(Math.pow(rate, 1.0 / 0.6));
WarpDrive.debugPrint("releaseAbove " + releaseAbove);
releaseMode = MODE_RELEASE_ABOVE;/**/
// player has to adjust it
releaseRate = rate;
releaseMode = MODE_RELEASE_AT_RATE;
}
return new Object[] { MODE_STRING[releaseMode], releaseRate };
} else if(methodName.equals("releaseAbove")) {
int above = -1;
try {
above = toInt(arguments[0]);
} catch(Exception e) {
throw new Exception("Function expects an integer value");
}
if (above <= 0) {
releaseMode = 0;
releaseAbove = MODE_DONT_RELEASE;
} else {
releaseMode = MODE_RELEASE_ABOVE;
releaseAbove = above;
}
return new Object[] { MODE_STRING[releaseMode], releaseAbove };
} else if (methodName.equals("debugLaser")) {
//WarpDrive.debugPrint("debugMethod");
int side = toInt(arguments[0]);
int amount = toInt(arguments[1]);
ForgeDirection d;
if (side == 0) {
d = ForgeDirection.NORTH;
} else if (side == 1) {
d = ForgeDirection.SOUTH;
} else if (side == 2) {
d = ForgeDirection.WEST;
} else if (side == 3) {
d = ForgeDirection.EAST;
} else {
d = ForgeDirection.UP;
}
if (amount < containedEnergy) {
containedEnergy -= amount;
decreaseInstability(d,amount);
}
} else if (methodName.equals("help")) {
return new Object[] { helpStr(arguments) };
}
return null;
}
private void sendEvent(String eventName, Object[] arguments) {
// WarpDrive.debugPrint("" + this + " Sending event '" + eventName + "'");
Set<Integer> keys = connectedComputers.keySet();
for(Integer key:keys) {
IComputerAccess comp = connectedComputers.get(key);
comp.queueEvent(eventName, arguments);
}
}
// POWER INTERFACES
@Override
public int getPotentialEnergyOutput() {
if (hold) {// still loading/booting => hold output
return 0;
}
int capacity = Math.max(0, 2 * lastGenerationRate - releasedThisTick);
if (releaseMode == MODE_MANUAL_RELEASE) {
return convertRFtoInternal(Math.min(Math.max(0, containedEnergy ), capacity));
} else if (releaseMode == MODE_RELEASE_ABOVE) {
return convertRFtoInternal(Math.min(Math.max(0, containedEnergy - releaseAbove), capacity));
} else if (releaseMode == MODE_RELEASE_AT_RATE) {
int remainingRate = Math.max(0, releaseRate - releasedThisTick);
return convertRFtoInternal(Math.min(Math.max(0, containedEnergy ), Math.min(remainingRate, capacity)));
}
return 0;
}
@Override
public boolean canOutputEnergy(ForgeDirection from) {
if (from.equals(ForgeDirection.UP) || from.equals(ForgeDirection.DOWN)) {
return true;
}
return false;
}
@Override
protected void energyOutputDone(int energyOutput) {
int energyOutput_RF = convertInternalToRF(energyOutput);
containedEnergy -= energyOutput_RF;
if (containedEnergy < 0) {
containedEnergy = 0;
}
releasedThisTick += energyOutput_RF;
releasedThisCycle += energyOutput_RF;
}
@Override
public int getEnergyStored() {
return convertRFtoInternal(containedEnergy);
}
@Override
public int getMaxEnergyStored() {
return convertRFtoInternal(WarpDriveConfig.PR_MAX_ENERGY);
}
// Forge overrides
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setInteger("energy", containedEnergy);
nbt.setInteger("releaseMode", releaseMode);
nbt.setInteger("releaseRate", releaseRate);
nbt.setInteger("releaseAbove", releaseAbove);
nbt.setDouble("i0", instabilityValues[0]);
nbt.setDouble("i1", instabilityValues[1]);
nbt.setDouble("i2", instabilityValues[2]);
nbt.setDouble("i3", instabilityValues[3]);
nbt.setBoolean("active", active);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
containedEnergy = nbt.getInteger("energy");
releaseMode = nbt.getInteger("releaseMode");
releaseRate = nbt.getInteger("releaseRate");
releaseAbove = nbt.getInteger("releaseAbove");
instabilityValues[0] = nbt.getDouble("i0");
instabilityValues[1] = nbt.getDouble("i1");
instabilityValues[2] = nbt.getDouble("i2");
instabilityValues[3] = nbt.getDouble("i3");
active = nbt.getBoolean("active");
}
@Override
public String toString() {
return String.format("%s \'%s\' @ \'%s\' %.2f, %.2f, %.2f", new Object[] {
getClass().getSimpleName(),
this.connectedComputers == null ? "~NULL~" : this.connectedComputers,
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
Double.valueOf(xCoord), Double.valueOf(yCoord), Double.valueOf(zCoord)});
}
}

View file

@ -0,0 +1,73 @@
package cr0s.WarpDrive.machines;
import cr0s.WarpDrive.WarpDriveConfig;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraftforge.common.ForgeDirection;
public class TileEntityPowerStore extends WarpEnergyTE implements IPeripheral {
private String[] methodArray = {
"energy"
};
@Override
public int getPotentialEnergyOutput() {
return getEnergyStored();
}
@Override
protected void energyOutputDone(int energyOutput) {
consumeEnergy(energyOutput, false);
}
@Override
public int getMaxEnergyStored() {
return WarpDriveConfig.PS_MAX_ENERGY;
}
@Override
public boolean canInputEnergy(ForgeDirection from) {
return true;
}
@Override
public boolean canOutputEnergy(ForgeDirection to) {
return true;
}
// ComputerCraft
@Override
public String getType() {
return "warpdrivePowerStore";
}
@Override
public String[] getMethodNames() {
return methodArray;
}
@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws Exception {
String methodName = methodArray[method];
if (methodName == "energy") {
return getEnergyObject();
}
return null;
}
@Override
public void attach(IComputerAccess computer) {
// nothing to see here
}
@Override
public void detach(IComputerAccess computer) {
// nothing to see here
}
@Override
public boolean equals(IPeripheral other) {
return this == other;
}
}

View file

@ -0,0 +1,497 @@
package cr0s.WarpDrive.machines;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import cr0s.WarpDrive.api.IUpgradable;
import cr0s.WarpDrive.data.EnumUpgradeTypes;
import cr0s.WarpDrive.data.Vector3;
import cr0s.WarpDrive.WarpDrive;
import cr0s.WarpDrive.WarpDriveConfig;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.DamageSource;
import net.minecraftforge.common.ForgeDirection;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IPeripheral;
public class TileEntityTransporter extends WarpEnergyTE implements IPeripheral, IUpgradable
{
private double scanRange=2;
private int scanDist = 4;
private double beaconEffect = 0;
private double powerBoost = 1;
private double baseLockStrength=-1;
private double lockStrengthMul = 1;
private boolean isLocked=false;
private final static Vector3 centreOnMe = new Vector3(0.5D, 1.0D, 0.5D);
private Vector3 sourceVec = new Vector3();
private Vector3 destVec = new Vector3();
private TeleporterDamage teleDam = new TeleporterDamage("teleporter");
private String[] methodArray = {
"source",
"dest",
"lock",
"release",
"lockStrength",
"energize",
"energy",
"powerBoost",
"energyCost",
"upgrades",
"help" };
@Override
public void updateEntity() {
super.updateEntity();
if(isLocked) {
if(lockStrengthMul > 0.8) {
lockStrengthMul *= 0.995;
} else {
lockStrengthMul*= 0.98;
}
}
}
// IPeripheral overrides
@Override
public String getType() {
return "transporter";
}
private static String helpStr(Object[] function) {
if (function != null && function.length > 0) {
String fun = function[0].toString().toLowerCase();
if(fun.equals("source")) {
if(WarpDriveConfig.TR_RELATIVE_COORDS) {
return "source(x,y,z): sets the coordinates (relative to the transporter) to teleport from\ndest(): returns the relative x,y,z coordinates of the source";
} else {
return "source(x,y,z): sets the absolute coordinates to teleport from\ndest(): returns the x,y,z coordinates of the source";
}
} else if(fun.equals("dest")) {
if(WarpDriveConfig.TR_RELATIVE_COORDS) {
return "dest(x,y,z): sets the coordinates (relative to the transporter) to teleport to\ndest(): returns the relative x,y,z coordinates of the destination";
} else {
return "dest(x,y,z): sets the absolute coordinates to teleport to\ndest(): returns the x,y,z coordinates of the destination";
}
} else if(fun.equals("lock")) {
return "lock(): locks the source and dest coordinates in and returns the lock strength (float)";
} else if(fun.equals("release")) {
return "release(): releases the current lock";
} else if(fun.equals("lockstrength")) {
return "lockStrength(): returns the current lock strength (float)";
} else if(fun.equals("energize")) {
return "energize(): attempts to teleport all entities at source to dest. Returns the number of entities transported (-1 indicates a problem).";
} else if(fun.equals("powerboost")) {
return "powerBoost(boostAmount): sets the level of power to use (1 being default), returns the level of power\npowerBoost(): returns the level of power";
} else if(fun.equals("energycost")) {
return "energyCost(): returns the amount of energy it will take for a single entity to transport with the current settings";
} else if(fun.equals("upgrades")) {
return WarpDrive.defUpgradeStr;
} else if(fun.equals("energy")) {
return WarpDrive.defEnergyStr;
}
}
return WarpDrive.defHelpStr;
}
@Override
public String[] getMethodNames() {
return methodArray;
}
private Object[] setVec3(boolean src,Object... arguments) {
Vector3 vec = src ? sourceVec : destVec;
if (vec == null) {
Vector3 sV = WarpDriveConfig.TR_RELATIVE_COORDS ? new Vector3(this) : new Vector3(0,0,0);
if(src)
sourceVec = sV;
else
destVec = sV;
vec = src ? sourceVec : destVec;
}
try {
if (arguments.length >= 3) {
unlock();
vec.x = toDouble(arguments[0]);
vec.y = toDouble(arguments[1]);
vec.z = toDouble(arguments[2]);
} else if(arguments.length == 1) {
unlock();
if(WarpDriveConfig.TR_RELATIVE_COORDS) {
vec.x = centreOnMe.x;
vec.y = centreOnMe.y;
vec.z = centreOnMe.z;
} else {
vec.x = xCoord + centreOnMe.x;
vec.y = yCoord + centreOnMe.y;
vec.z = zCoord + centreOnMe.z;
}
}
} catch(NumberFormatException e) {
return setVec3(src,"this");
}
return new Object[] { vec.x, vec.y, vec.z };
}
@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws Exception {
String methodName = methodArray[method];
if (methodName.equals("energy")) {
return new Object[] { getEnergyStored(), getMaxEnergyStored() };
} else if (methodName.equals("source")) {
return setVec3(true,arguments);
} else if (methodName.equals("dest")) {
return setVec3(false,arguments);
} else if (methodName.equals("lock")) {
return new Object[] { lock(sourceVec, destVec) };
} else if (methodName.equals("release")) {
unlock();
return null;
} else if (methodName.equals("lockStrength")) {
return new Object[] { getLockStrength() };
} else if (methodName.equals("energize")) {
return new Object[] { energize () };
} else if (methodName.equals("powerBoost")) {
try {
if (arguments.length >= 1) {
powerBoost = clamp(toDouble(arguments[0]),1,WarpDriveConfig.TR_MAX_BOOST_MUL);
}
} catch(NumberFormatException e) {
powerBoost = 1;
}
return new Object[] { powerBoost };
} else if (methodName.equals("energyCost")) {
return new Object[] { energyCost() };
} else if (methodName.equals("help")) {
return new Object[] { helpStr(arguments) };
}
return null;
}
private Integer energyCost() {
if (sourceVec != null && destVec != null) {
return (int) Math.ceil(Math.pow(3, powerBoost - 1) * WarpDriveConfig.TR_EU_PER_METRE * sourceVec.distanceTo(destVec));
}
return null;
}
private int energize() {
if (isLocked) {
int count = 0;
double ls = getLockStrength();
WarpDrive.debugPrint("LS:" + getLockStrength());
ArrayList<Entity> entitiesToTransport = findEntities(sourceVec, ls);
Integer energyReq = energyCost();
if (energyReq == null) {
return -1;
}
Vector3 modDest = destVec.clone().translate(centreOnMe);
for(Entity ent : entitiesToTransport) {
WarpDrive.debugPrint("" + this + " Handling entity " + ent.getEntityName());
if (consumeEnergy(energyReq, false)) {
WarpDrive.debugPrint("" + this + " Energy taken");
inflictNegativeEffect(ent, ls);
transportEnt(ent, modDest);
count++;
} else {
break;
}
}
return count;
}
return -1;
}
private void transportEnt(Entity ent, Vector3 dest) {
if (ent instanceof EntityLivingBase) {
EntityLivingBase livingEnt = (EntityLivingBase) ent;
if (WarpDriveConfig.TR_RELATIVE_COORDS) {
livingEnt.setPositionAndUpdate(xCoord+dest.x, yCoord+dest.y, zCoord+dest.z);
} else {
livingEnt.setPositionAndUpdate(dest.x, dest.y, dest.z);
}
} else {
if (WarpDriveConfig.TR_RELATIVE_COORDS) {
ent.setPosition(xCoord+dest.x, yCoord+dest.y, zCoord+dest.z);
} else {
ent.setPosition(dest.x, dest.y, dest.z);
}
}
}
private void inflictNegativeEffect(Entity ent, double lockStrength) {
double value = Math.random() + lockStrength;
WarpDrive.debugPrint("TRANSPORTER INFLICTION: " + value);
if (value < 0.1) {
ent.attackEntityFrom(teleDam, 1000);
}
if (value < 0.2) {
ent.attackEntityFrom(teleDam, 10);
}
if (value < 0.5) {
ent.attackEntityFrom(teleDam, 1);
}
}
private double beaconScan(int xV, int yV, int zV)
{
WarpDrive.debugPrint("BeaconScan:" + xV + ","+yV + "," + zV);
double beacon = 0;
int beaconCount = 0;
int xL = xV - scanDist;
int xU = xV + scanDist;
int yL = yV - scanDist;
int yU = yV + scanDist;
int zL = zV - scanDist;
int zU = zV + scanDist;
for(int x=xL;x<=xU;x++)
{
for(int y=yL;y<=yU;y++)
{
if(y < 0 || y > 254) {
continue;
}
for(int z=zL;z<=zU;z++)
{
if(worldObj.getBlockId(x, y, z) != WarpDriveConfig.transportBeaconID) {
continue;
}
double dist = 1 + Math.abs(x - xV) + Math.abs(y - yV) + Math.abs(z - zV);
beaconCount++;
if (worldObj.getBlockMetadata(x, y, z) == 0) {
beacon += 1/dist;
} else {
beacon -= 1/dist;
}
}
}
}
if (beaconCount > 0) {
beacon /= Math.sqrt(beaconCount);
}
return beacon;
}
private double beaconScan(Vector3 s, Vector3 d)
{
s = absoluteVector(s);
d = absoluteVector(d);
return beaconScan(toInt(s.x), toInt(s.y), toInt(s.z)) + beaconScan(toInt(d.x), toInt(d.y), toInt(d.z));
}
private Vector3 absoluteVector(Vector3 a)
{
if(WarpDriveConfig.TR_RELATIVE_COORDS)
return a.clone().translate(new Vector3(this));
else
return a;
}
private double calculatePower(Vector3 d)
{
Vector3 myCoords;
if(WarpDriveConfig.TR_RELATIVE_COORDS)
myCoords = centreOnMe;
else
myCoords = new Vector3(this).translate(centreOnMe);
return calculatePower(myCoords,d);
}
private static double calculatePower(Vector3 s, Vector3 d)
{
double dist = s.distanceTo(d);
return clamp(Math.pow(Math.E, -dist / 300), 0, 1);
}
private static double min(double... ds)
{
double curMin = Double.MAX_VALUE;
for(double d: ds)
curMin = Math.min(curMin, d);
return curMin;
}
private double getLockStrength() {
if (isLocked) {
double upgradeBoost = 1;
if (upgrades.containsKey(EnumUpgradeTypes.Range))
upgradeBoost = Math.pow(1.2, upgrades.get(EnumUpgradeTypes.Range));
return clamp(baseLockStrength * lockStrengthMul * Math.pow(2, powerBoost-1) * upgradeBoost * (1 + beaconEffect), 0, 1);
}
return -1;
}
private void unlock() {
isLocked = false;
baseLockStrength = 0;
}
private double lock(Vector3 source,Vector3 dest) {
if (source != null && dest != null) {
double basePower = min(calculatePower(source), calculatePower(dest), calculatePower(source,dest));
beaconEffect = beaconScan(source, dest);
WarpDrive.debugPrint("BEACON:" + beaconEffect);
baseLockStrength = basePower;
lockStrengthMul = 1;
isLocked = true;
WarpDrive.debugPrint(baseLockStrength + "," + getLockStrength());
return getLockStrength();
} else {
unlock();
return 0;
}
}
private AxisAlignedBB getAABB() {
Vector3 tS = new Vector3(this);
Vector3 bS = new Vector3(this);
Vector3 scanPos = new Vector3( scanRange/2, 2, scanRange/2);
Vector3 scanNeg = new Vector3(-scanRange/2,-1,-scanRange/2);
if(WarpDriveConfig.TR_RELATIVE_COORDS) {
tS.translate(sourceVec).translate(scanPos);
bS.translate(sourceVec).translate(scanNeg);
} else {
tS = sourceVec.clone().translate(scanPos);
bS = sourceVec.clone().translate(scanNeg);
}
return AxisAlignedBB.getBoundingBox(bS.x,bS.y,bS.z,tS.x,tS.y,tS.z);
}
private ArrayList<Entity> findEntities(Vector3 source, double lockStrength) {
AxisAlignedBB bb = getAABB();
WarpDrive.debugPrint("Transporter:" +bb.toString());
List data = worldObj.getEntitiesWithinAABBExcludingEntity(null, bb);
ArrayList<Entity> output = new ArrayList<Entity>(data.size());
for(Object ent : data) {
if (lockStrength >= 1 || worldObj.rand.nextDouble() < lockStrength) {// If weak lock, don't transport
WarpDrive.debugPrint("" + this + " Entity '" + ent.toString() + "' found and added");
if (ent instanceof Entity) {
output.add((Entity) ent);
}
} else {
WarpDrive.debugPrint("" + this + " Entity '" + ent.toString() + "' discarded");
}
}
return output;
}
@Override
public void attach(IComputerAccess computer) {}
@Override
public void detach(IComputerAccess computer) {}
@Override
public int getMaxEnergyStored() {
int max = WarpDriveConfig.TR_MAX_ENERGY;
if (upgrades.containsKey(EnumUpgradeTypes.Energy)) {
max = (int) Math.floor(max * Math.pow(1.2, upgrades.get(EnumUpgradeTypes.Energy)));
}
return max;
}
@Override
public boolean canInputEnergy(ForgeDirection from) {
if (from == ForgeDirection.UP) {
return false;
}
return true;
}
@Override
public int getMaxSafeInput() {
return Integer.MAX_VALUE;
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setDouble("powerBoost", powerBoost);
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
powerBoost = tag.getDouble("powerBoost");
}
class TeleporterDamage extends DamageSource {
protected TeleporterDamage(String par1Str) {
super(par1Str);
}
@Override
public ChatMessageComponent getDeathMessage(EntityLivingBase e) {
String mess = "";
if(e instanceof EntityPlayer || e instanceof EntityPlayerMP) {
mess = ((EntityPlayer) e).username + " was killed by a teleporter malfunction";
} else {
mess = e.getEntityName() + " was killed by a teleporter malfunction";
}
WarpDrive.debugPrint(mess);
return ChatMessageComponent.createFromText(mess);
}
}
@Override
public boolean equals(IPeripheral other) {
return other == this;
}
@Override
public boolean takeUpgrade(EnumUpgradeTypes upgradeType, boolean simulate)
{
int max = 0;
if(upgradeType == EnumUpgradeTypes.Energy)
max = 2;
else if(upgradeType == EnumUpgradeTypes.Power)
max = 4;
else if(upgradeType == EnumUpgradeTypes.Range)
max = 4;
if(max == 0)
return false;
if(upgrades.containsKey(upgradeType))
if(upgrades.get(upgradeType) >= max)
return false;
if(!simulate)
{
int c = 0;
if(upgrades.containsKey(upgradeType))
c = upgrades.get(upgradeType);
upgrades.put(upgradeType, c+1);
}
return true;
}
@Override
public Map<EnumUpgradeTypes,Integer> getInstalledUpgrades()
{
return upgrades;
}
}

View file

@ -5,6 +5,7 @@ import cr0s.WarpDrive.WarpDrive;
import cr0s.WarpDrive.api.IBlockUpdateDetector;
import cr0s.WarpDrive.api.IUpgradable;
import cr0s.WarpDrive.data.EnumUpgradeTypes;
import cr0s.WarpDrive.item.ItemWarpUpgrade;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
@ -35,6 +36,44 @@ public abstract class WarpBlockContainer extends BlockContainer {
}
}
/* FIXME untested
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int par6, float par7, float par8, float par9)
{
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
return false;
}
boolean hasResponse = false;
TileEntity te = world.getBlockTileEntity(x, y, z);
if(te != null && te instanceof IUpgradable)
{
IUpgradable upgradable = (IUpgradable)te;
ItemStack is = player.inventory.getCurrentItem();
if(is != null)
{
Item i = is.getItem();
if(i instanceof ItemWarpUpgrade)
{
if(upgradable.takeUpgrade(EnumUpgradeTypes.values()[is.getItemDamage()],false))
{
if(!player.capabilities.isCreativeMode)
player.inventory.decrStackSize(player.inventory.currentItem, 1);
player.addChatMessage("Upgrade accepted");
}
else
{
player.addChatMessage("Upgrade declined");
}
hasResponse = true;
}
}
}
return hasResponse;
}
/**/
@Override
public void onNeighborBlockChange(World w, int x, int y, int z, int b) {
super.onNeighborBlockChange(w, x, y, z, b);