Added sirens.
This commit is contained in:
parent
32cf54347c
commit
7a2b0008fe
12 changed files with 298 additions and 13 deletions
53
src/main/java/cr0s/warpdrive/SirenSound.java
Normal file
53
src/main/java/cr0s/warpdrive/SirenSound.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
||||
|
|
49
src/main/java/cr0s/warpdrive/block/detection/BlockSiren.java
Normal file
49
src/main/java/cr0s/warpdrive/block/detection/BlockSiren.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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}]}
|
||||
}
|
||||
|
|
BIN
src/main/resources/assets/warpdrive/sounds/siren_industrial.ogg
Normal file
BIN
src/main/resources/assets/warpdrive/sounds/siren_industrial.ogg
Normal file
Binary file not shown.
BIN
src/main/resources/assets/warpdrive/sounds/siren_raid.ogg
Normal file
BIN
src/main/resources/assets/warpdrive/sounds/siren_raid.ogg
Normal file
Binary file not shown.
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 |
Loading…
Reference in a new issue