Added sirens.

This commit is contained in:
ClawmanCat 2016-08-15 20:08:14 +02:00
parent 32cf54347c
commit 7a2b0008fe
12 changed files with 298 additions and 13 deletions

View file

@ -0,0 +1,53 @@
package cr0s.warpdrive;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.MovingSound;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
public class SirenSound extends MovingSound {
ResourceLocation resource;
float range;
float x, y, z;
/**x, y and z are the position of the tile entity. the actual sound is broadcast from
xPosF, yPosF, zPosF, which is the location of the player.
The volume is adjusted according to the distance to x, y, z.
Why? Because Minecraft's sound system was not made for this kind of thing, and this
is the easiest way which:
1. Produces a sound audible from a specifiable range.
2. Produces a sound which decreases in volume the farther you get away from it.
3. Doesn't completely spazz out the instant you try to actually use it.*/
public SirenSound(ResourceLocation resource, float range, float x, float y, float z) {
super(resource);
this.resource = resource;
this.range = range;
this.x = x;
this.y = y;
this.z = z;
this.xPosF = x;
this.yPosF = y;
this.zPosF = z;
}
public void update() {
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
this.xPosF = (float) player.posX;
this.yPosF = (float) player.posY;
this.zPosF = (float) player.posZ;
if (player.getDistance(x, y, z) > range) {
this.volume = 0.0F;
} else {
this.volume = 1.0F - scaleTo((float) player.getDistance(x, y, z), 0.0F, range, 0.0F, 1.0F);
}
}
private float scaleTo(float num, float oldMin, float oldMax, float newMin, float newMax) {
return ((newMax - newMin)*(num - oldMin)) / (oldMax - oldMin) + newMin;
}
}

View file

@ -6,17 +6,23 @@ import java.util.UUID;
import com.mojang.authlib.GameProfile;
import cr0s.warpdrive.block.*;
import cr0s.warpdrive.block.detection.*;
import cr0s.warpdrive.block.forcefield.*;
import cr0s.warpdrive.block.hull.BlockHullStairs;
import cr0s.warpdrive.compat.CompatMekanism;
import cr0s.warpdrive.item.*;
import ic2.api.item.IC2Items;
import net.minecraft.block.Block;
import net.minecraft.block.BlockColored;
import net.minecraft.client.Minecraft;
import net.minecraft.command.ICommandSender;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.item.ItemDye;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
@ -53,16 +59,6 @@ import cr0s.warpdrive.block.collection.BlockLaserTreeFarm;
import cr0s.warpdrive.block.collection.BlockMiningLaser;
import cr0s.warpdrive.block.collection.TileEntityLaserTreeFarm;
import cr0s.warpdrive.block.collection.TileEntityMiningLaser;
import cr0s.warpdrive.block.detection.BlockCamera;
import cr0s.warpdrive.block.detection.BlockCloakingCoil;
import cr0s.warpdrive.block.detection.BlockCloakingCore;
import cr0s.warpdrive.block.detection.BlockMonitor;
import cr0s.warpdrive.block.detection.BlockRadar;
import cr0s.warpdrive.block.detection.BlockWarpIsolation;
import cr0s.warpdrive.block.detection.TileEntityCamera;
import cr0s.warpdrive.block.detection.TileEntityCloakingCore;
import cr0s.warpdrive.block.detection.TileEntityMonitor;
import cr0s.warpdrive.block.detection.TileEntityRadar;
import cr0s.warpdrive.block.energy.BlockEnanReactorCore;
import cr0s.warpdrive.block.energy.BlockEnanReactorLaser;
import cr0s.warpdrive.block.energy.BlockEnergyBank;
@ -126,7 +122,12 @@ public class WarpDrive implements LoadingCallback {
public static final String VERSION = "@version@";
public static final boolean isDev = VERSION.equals("@" + "version" + "@") || VERSION.contains("-dev");
public static GameProfile gameProfile = new GameProfile(UUID.nameUUIDFromBytes("[WarpDrive]".getBytes()), "[WarpDrive]");
public static Block blockSirenIndustrial;
public static Block blockSirenRaidBasic;
public static Block blockSirenRaidAdvanced;
public static Block blockSirenRaidSuperior;
public static Block blockShipCore;
public static Block blockShipController;
public static Block blockRadar;
@ -236,7 +237,35 @@ public class WarpDrive implements LoadingCallback {
// open access to Block.blockHardness
fieldBlockHardness = WarpDrive.getField(Block.class, "blockHardness", "field_149782_v");
// SIRENS
blockSirenIndustrial = new BlockSiren("siren_industrial", false, 32.0F);
blockSirenRaidBasic = new BlockSiren("siren_raid_basic", true, 32.0F);
blockSirenRaidAdvanced = new BlockSiren("siren_raid_advanced", true, 64.0F);
blockSirenRaidSuperior = new BlockSiren("siren_raid_superior", true, 128.0F);
GameRegistry.registerBlock(blockSirenIndustrial, "siren_industrial");
GameRegistry.registerBlock(blockSirenRaidBasic, "siren_raid_basic");
GameRegistry.registerBlock(blockSirenRaidAdvanced, "siren_raid_advanced");
GameRegistry.registerBlock(blockSirenRaidSuperior, "siren_raid_superior");
GameRegistry.addRecipe(new ItemStack(blockSirenIndustrial, 1), "ICI", "ICI", "NRN",
Character.valueOf('I'), new ItemStack(Blocks.planks, 1),
Character.valueOf('C'), new ItemStack(Items.iron_ingot, 1),
Character.valueOf('N'), new ItemStack(Blocks.noteblock, 1),
Character.valueOf('R'), new ItemStack(Items.redstone, 1));
GameRegistry.addRecipe(new ItemStack(blockSirenRaidBasic, 1), " I ", "ISI", " I ",
Character.valueOf('I'), new ItemStack(Items.iron_ingot, 1),
Character.valueOf('S'), new ItemStack(blockSirenIndustrial, 1));
GameRegistry.addRecipe(new ItemStack(blockSirenRaidAdvanced, 1), " I ", "ISI", " I ",
Character.valueOf('I'), new ItemStack(Items.gold_ingot, 1),
Character.valueOf('S'), new ItemStack(blockSirenRaidBasic, 1));
GameRegistry.addRecipe(new ItemStack(blockSirenRaidSuperior, 1), " I ", "ISI", " I ",
Character.valueOf('I'), new ItemStack(Items.diamond, 1),
Character.valueOf('S'), new ItemStack(blockSirenRaidAdvanced, 1));
GameRegistry.registerTileEntity(TileEntitySiren.class, MODID + ":tileEntitySiren");
// CORE CONTROLLER
blockShipController = new BlockShipController();

View file

@ -0,0 +1,49 @@
package cr0s.warpdrive.block.detection;
import cr0s.warpdrive.WarpDrive;
import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class BlockSiren extends Block implements ITileEntityProvider {
private boolean isRaidSiren;
private float range;
public BlockSiren(String name, boolean isRaidSiren, float range) {
super(Material.iron);
this.setBlockName(name);
this.isRaidSiren = isRaidSiren;
this.range = range;
this.setCreativeTab(WarpDrive.creativeTabWarpDrive);
this.setBlockTextureName("warpdrive:detection/" + name);
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
return new TileEntitySiren(this.unlocalizedName, isRaidSiren, range);
}
//Silences the siren if the block is destroyed.
//If this fails, the siren will still be stopped when it's invalidated.
@Override
public void onBlockPreDestroy(World world, int x, int y, int z, int meta) {
if (!world.isRemote) {
super.onBlockPreDestroy(world, x, y, z, meta);
return;
}
TileEntity te = world.getTileEntity(x, y, z);
if(te != null && te instanceof TileEntitySiren) {
TileEntitySiren siren = (TileEntitySiren) te;
if (siren.isPlaying()) {
siren.stopSound();
}
}
}
}

View file

@ -0,0 +1,147 @@
package cr0s.warpdrive.block.detection;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cr0s.warpdrive.SirenSound;
import cr0s.warpdrive.WarpDrive;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.ISound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
public class TileEntitySiren extends TileEntity {
private static final int COOLDOWN_LENGTH_TICKS = 5;
public enum SirenState {
STOPPED, STARTING, STARTED, STOPPING, COOLDOWN;
}
private SirenState state = SirenState.STOPPED;
private boolean isRaidSiren;
private String name;
private Object sound;
private float range;
private int cooldown = 0;
/* Because the SirenSound exists only on the client, but the Tile Entity itself
* also exists on the server, we cannot declare a SirenSound object directly, thus
* the sound object is declared as type Object. */
public TileEntitySiren(String name, boolean isRaidSiren, float range) {
super();
this.name = name;
this.range = range;
this.isRaidSiren = isRaidSiren;
}
@Override
public void updateEntity() {
super.updateEntity();
if (!this.hasWorldObj() || !worldObj.isRemote) return;
if (this.sound == null) this.setSound();
//Siren sound logic.
switch (this.state) {
case STOPPED:
if (this.isPowered() && !this.isPlaying()) {
this.startSound();
} else if (!this.isPowered() && this.isPlaying()) {
//Better safe than sorry.
this.stopSound();
}
break;
case STARTING:
if (this.isPlaying()) {
this.state = SirenState.STARTED;
}
break;
case STARTED:
if (this.isPowered()) {
if (!this.isPlaying()) this.startSound();
} else {
this.state = SirenState.STOPPING;
}
break;
case STOPPING:
this.stopSound();
this.cooldown = COOLDOWN_LENGTH_TICKS;
this.state = SirenState.COOLDOWN;
break;
case COOLDOWN:
if (cooldown > 0) {
cooldown--;
} else {
this.cooldown = 0;
this.state = SirenState.STOPPED;
}
break;
default:
this.stopSound();
this.state = SirenState.STOPPED;
break;
}
}
//Stops the siren when the chunk is unloaded.
@Override
public void onChunkUnload() {
if (worldObj.isRemote && this.isPlaying()) this.stopSound();
super.onChunkUnload();
}
//Stops the siren when the TileEntity object is destroyed.
//The siren should already be stopped by this point, but better safe than sorry.
@Override
public void invalidate() {
if (worldObj.isRemote && this.isPlaying()) this.stopSound();
super.invalidate();
}
//Create a new SirenSound object that the siren will use.
@SideOnly(Side.CLIENT)
private void setSound() {
String resource = WarpDrive.MODID + ":siren_" + (isRaidSiren ? "raid" : "industrial");
this.sound = new SirenSound(new ResourceLocation(resource), this.range, this.xCoord, this.yCoord, this.zCoord);
}
//Forces the siren to start playing its sound;
@SideOnly(Side.CLIENT)
public void startSound() {
try {
Minecraft.getMinecraft().getSoundHandler().playSound((ISound) sound);
this.state = SirenState.STARTING;
} catch (IllegalArgumentException e) {
/* If soundHandler.playSound() is called before the previous same ISound stops
* from a call to soundHandler.stopSound(), an IllegalArgumentException will
* be thrown. This happens when you spam the redstone trigger.
* We're trying to recover by forcing a stop. */
this.state = SirenState.STOPPING;
}
}
//Forces the siren to stop playing its sound.
@SideOnly(Side.CLIENT)
public void stopSound() {
Minecraft.getMinecraft().getSoundHandler().stopSound((ISound) sound);
}
//Checks if the siren is currently playing its sound.
@SideOnly(Side.CLIENT)
public boolean isPlaying() {
return Minecraft.getMinecraft().getSoundHandler().isSoundPlaying((ISound) sound);
}
//Checks if the siren is being powered by redstone.
public boolean isPowered() {
return worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord);
}
}

View file

@ -160,6 +160,11 @@ tile.warpdrive.building.ShipScanner.name=Ship Scanner
tile.warpdrive.collection.LaserTreeFarm.name=Laser Tree Farm
tile.warpdrive.collection.MiningLaser.name=Mining Laser
tile.siren_industrial.name=Industrial Siren
tile.siren_raid_basic.name=Basic Air Raid Siren
tile.siren_raid_advanced.name=Advanced Air Raid Siren
tile.siren_raid_superior.name=Superior Air Raid Siren
tile.warpdrive.detection.Camera.name=Camera
tile.warpdrive.detection.CloakingCoil.name=Cloaking Coil
tile.warpdrive.detection.CloakingCore.name=Cloaking Core

View file

@ -7,5 +7,7 @@
"lowlaser": {"category": "master","sounds": [{"name": "lowlaser","stream": false}]},
"cloak": {"category": "master","sounds": [{"name": "cloak","stream": false}]},
"decloak": {"category": "master","sounds": [{"name": "decloak","stream": false}]},
"projecting": {"category": "master","sounds": [{"name": "projecting","stream": false}]}
"projecting": {"category": "master","sounds": [{"name": "projecting","stream": false}]},
"siren_raid": {"category": "master","sounds": [{"name": "siren_raid","stream": true}]},
"siren_industrial": {"category": "master","sounds": [{"name": "siren_industrial","stream": true}]}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B