Added speaker sending messages to local players including an anti-spam
This commit is contained in:
parent
cc20769d94
commit
6567376e4b
19 changed files with 453 additions and 0 deletions
src/main
java/cr0s/warpdrive
resources/assets/warpdrive
blockstates
lang
lua.ComputerCraft/warpdriveSpeaker
lua.OpenComputers/warpdriveSpeaker
textures/blocks/detection
|
@ -44,12 +44,14 @@ import cr0s.warpdrive.block.detection.BlockCloakingCore;
|
|||
import cr0s.warpdrive.block.detection.BlockMonitor;
|
||||
import cr0s.warpdrive.block.detection.BlockRadar;
|
||||
import cr0s.warpdrive.block.detection.BlockSiren;
|
||||
import cr0s.warpdrive.block.detection.BlockSpeaker;
|
||||
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.detection.TileEntitySiren;
|
||||
import cr0s.warpdrive.block.detection.TileEntitySpeaker;
|
||||
import cr0s.warpdrive.block.energy.BlockCapacitor;
|
||||
import cr0s.warpdrive.block.energy.BlockEnanReactorCore;
|
||||
import cr0s.warpdrive.block.energy.BlockEnanReactorLaser;
|
||||
|
@ -275,6 +277,7 @@ public class WarpDrive {
|
|||
public static Block blockRadar;
|
||||
public static Block[] blockSirenIndustrial;
|
||||
public static Block[] blockSirenMilitary;
|
||||
public static Block[] blockSpeaker;
|
||||
public static Block blockWarpIsolation;
|
||||
|
||||
// energy blocks and items
|
||||
|
@ -472,10 +475,12 @@ public class WarpDrive {
|
|||
|
||||
blockSirenIndustrial = new Block[EnumTier.length];
|
||||
blockSirenMilitary = new Block[EnumTier.length];
|
||||
blockSpeaker = new Block[EnumTier.length];
|
||||
for(final EnumTier enumTier : EnumTier.nonCreative()) {
|
||||
final int index = enumTier.getIndex();
|
||||
blockSirenIndustrial[index] = new BlockSiren("siren_industrial." + enumTier.getName(), enumTier, true);
|
||||
blockSirenMilitary[index] = new BlockSiren("siren_military." + enumTier.getName(), enumTier, false);
|
||||
blockSpeaker[index] = new BlockSpeaker("speaker." + enumTier.getName(), enumTier);
|
||||
}
|
||||
blockWarpIsolation = new BlockWarpIsolation("warp_isolation", EnumTier.BASIC);
|
||||
|
||||
|
@ -1047,6 +1052,7 @@ public class WarpDrive {
|
|||
GameRegistry.registerTileEntity(TileEntityShipCore.class, new ResourceLocation(WarpDrive.MODID, "ship_core"));
|
||||
GameRegistry.registerTileEntity(TileEntityShipScanner.class, new ResourceLocation(WarpDrive.MODID, "ship_scanner"));
|
||||
GameRegistry.registerTileEntity(TileEntitySiren.class, new ResourceLocation(WarpDrive.MODID, "siren"));
|
||||
GameRegistry.registerTileEntity(TileEntitySpeaker.class, new ResourceLocation(WarpDrive.MODID, "speaker"));
|
||||
GameRegistry.registerTileEntity(TileEntityTransporterBeacon.class, new ResourceLocation(WarpDrive.MODID, "transporter_beacon"));
|
||||
GameRegistry.registerTileEntity(TileEntityTransporterCore.class, new ResourceLocation(WarpDrive.MODID, "transporter_core"));
|
||||
GameRegistry.registerTileEntity(TileEntityWeaponController.class, new ResourceLocation(WarpDrive.MODID, "weapon_controller"));
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package cr0s.warpdrive.block.detection;
|
||||
|
||||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.api.WarpDriveText;
|
||||
import cr0s.warpdrive.block.BlockAbstractRotatingContainer;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.EnumTier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public class BlockSpeaker extends BlockAbstractRotatingContainer {
|
||||
|
||||
public BlockSpeaker(final String registryName, final EnumTier enumTier) {
|
||||
super(registryName, enumTier, Material.IRON);
|
||||
|
||||
setTranslationKey("warpdrive.detection.speaker" + "." + enumTier.getName());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(@Nonnull final World world, final int metadata) {
|
||||
return new TileEntitySpeaker();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void addInformation(@Nonnull final ItemStack itemStack, @Nullable final World world,
|
||||
@Nonnull final List<String> list, @Nullable final ITooltipFlag advancedItemTooltips) {
|
||||
super.addInformation(itemStack, world, list, advancedItemTooltips);
|
||||
|
||||
final int range = MathHelper.floor(WarpDriveConfig.SPEAKER_RANGE_BLOCKS_BY_TIER[enumTier.getIndex()]);
|
||||
final String unlocalizedName_withoutTier = getTranslationKey().replace("." + enumTier.getName(), "");
|
||||
Commons.addTooltip(list, new TextComponentTranslation(unlocalizedName_withoutTier + ".tooltip.usage",
|
||||
new WarpDriveText(Commons.getStyleValue(), range) ).getFormattedText());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package cr0s.warpdrive.block.detection;
|
||||
|
||||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.api.WarpDriveText;
|
||||
import cr0s.warpdrive.block.TileEntityAbstractMachine;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import li.cil.oc.api.machine.Arguments;
|
||||
import li.cil.oc.api.machine.Callback;
|
||||
import li.cil.oc.api.machine.Context;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
|
||||
public class TileEntitySpeaker extends TileEntityAbstractMachine {
|
||||
|
||||
// persistent properties
|
||||
// (none)
|
||||
|
||||
// computed properties
|
||||
private final float rateDecayPerTick = WarpDriveConfig.SPEAKER_RATE_MAX_MESSAGES / (float) WarpDriveConfig.SPEAKER_RATE_PERIOD_TICKS;
|
||||
private AxisAlignedBB aabbRange = null;
|
||||
private float rateMessaging = 0.0F;
|
||||
private final Queue<String> messagesToSpeak = new LinkedList<>();
|
||||
|
||||
public TileEntitySpeaker() {
|
||||
super();
|
||||
|
||||
peripheralName = "warpdriveSpeaker";
|
||||
addMethods(new String[] {
|
||||
"speak"
|
||||
});
|
||||
CC_scripts = Collections.singletonList("speak");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFirstUpdateTick() {
|
||||
super.onFirstUpdateTick();
|
||||
|
||||
final float range = WarpDriveConfig.SPEAKER_RANGE_BLOCKS_BY_TIER[enumTier.getIndex()];
|
||||
aabbRange = new AxisAlignedBB(
|
||||
pos.getX() - range, pos.getY() - range, pos.getZ() - range,
|
||||
pos.getX() + range + 1.0D, pos.getY() + range + 1.0D, pos.getZ() + range + 1.0D );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
rateMessaging = Math.max(0.0F, rateMessaging - rateDecayPerTick);
|
||||
if ( isEnabled
|
||||
&& !messagesToSpeak.isEmpty()
|
||||
&& rateMessaging + 1.0F < WarpDriveConfig.SPEAKER_RATE_MAX_MESSAGES ) {
|
||||
final String messageRaw = messagesToSpeak.remove();
|
||||
final ITextComponent messageFormatted = new WarpDriveText(null, messageRaw);
|
||||
final List<EntityPlayerMP> playersInRange = world.getEntitiesWithinAABB(EntityPlayerMP.class, aabbRange, entityPlayerMP -> entityPlayerMP != null
|
||||
&& entityPlayerMP.isEntityAlive()
|
||||
&& !entityPlayerMP.isSpectator() );
|
||||
for (final EntityPlayerMP entityPlayerMP : playersInRange) {
|
||||
entityPlayerMP.sendMessage(messageFormatted);
|
||||
}
|
||||
rateMessaging++;
|
||||
}
|
||||
}
|
||||
|
||||
// Common OC/CC methods
|
||||
public Object[] speak(final Object[] arguments) {
|
||||
int size = messagesToSpeak.size();
|
||||
if (arguments.length == 1) {
|
||||
if (size >= WarpDriveConfig.SPEAKER_QUEUE_MAX_MESSAGES) {
|
||||
return new Object[] { false, "You're speaking too fast... breath!" };
|
||||
}
|
||||
messagesToSpeak.add(Commons.toString(arguments[0]));
|
||||
size++;
|
||||
}
|
||||
return new Object[] { true, size };
|
||||
}
|
||||
|
||||
// OpenComputers callback methods
|
||||
@Callback(direct = true)
|
||||
@Optional.Method(modid = "opencomputers")
|
||||
public Object[] speak(final Context context, final Arguments arguments) {
|
||||
return speak(OC_convertArgumentsAndLogCall(context, arguments));
|
||||
}
|
||||
|
||||
// ComputerCraft IPeripheral methods
|
||||
@Override
|
||||
@Optional.Method(modid = "computercraft")
|
||||
protected Object[] CC_callMethod(@Nonnull final String methodName, @Nonnull final Object[] arguments) {
|
||||
switch (methodName) {
|
||||
case "speak":
|
||||
return speak(arguments);
|
||||
}
|
||||
|
||||
return super.CC_callMethod(methodName, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s %s %s messages queued",
|
||||
getClass().getSimpleName(),
|
||||
Commons.format(world, pos),
|
||||
messagesToSpeak.size() );
|
||||
}
|
||||
}
|
|
@ -1339,6 +1339,22 @@ public class Recipes {
|
|||
WarpDrive.blockSirenMilitary[EnumTier.SUPERIOR.getIndex()], " I ", "ISI", " I ",
|
||||
'I', "gemDiamond",
|
||||
'S', WarpDrive.blockSirenMilitary[EnumTier.ADVANCED.getIndex()] ));
|
||||
|
||||
// Speakers
|
||||
WarpDrive.register(new ShapedOreRecipe(groupMachines,
|
||||
WarpDrive.blockSpeaker[EnumTier.BASIC.getIndex()], "BBB", "rDr", "rCr",
|
||||
'B', ItemComponent.getItemStack(EnumComponentType.BIOFIBER),
|
||||
'r', rubber,
|
||||
'D', ItemComponent.getItemStack(EnumComponentType.DIAMOND_CRYSTAL),
|
||||
'C', ItemComponent.getItemStack(EnumComponentType.COMPUTER_INTERFACE) ));
|
||||
WarpDrive.register(new ShapedOreRecipe(groupMachines,
|
||||
WarpDrive.blockSpeaker[EnumTier.ADVANCED.getIndex()], " I ", "ISI", " I ",
|
||||
'I', "ingotGold",
|
||||
'S', WarpDrive.blockSpeaker[EnumTier.BASIC.getIndex()] ));
|
||||
WarpDrive.register(new ShapedOreRecipe(groupMachines,
|
||||
WarpDrive.blockSpeaker[EnumTier.SUPERIOR.getIndex()], " I ", "ISI", " I ",
|
||||
'I', "gemDiamond",
|
||||
'S', WarpDrive.blockSpeaker[EnumTier.ADVANCED.getIndex()] ));
|
||||
}
|
||||
|
||||
private static void initEnergy() {
|
||||
|
|
|
@ -313,6 +313,12 @@ public class WarpDriveConfig {
|
|||
// Siren
|
||||
public static float[] SIREN_RANGE_BLOCKS_BY_TIER = { 0.0F, 32.0F, 64.0F, 128.0F };
|
||||
|
||||
// Speaker
|
||||
public static float[] SPEAKER_RANGE_BLOCKS_BY_TIER = { 0.0F, 16.0F, 32.0F, 64.0F };
|
||||
public static float SPEAKER_QUEUE_MAX_MESSAGES = 12;
|
||||
public static float SPEAKER_RATE_MAX_MESSAGES = 3;
|
||||
public static int SPEAKER_RATE_PERIOD_TICKS = 60;
|
||||
|
||||
// Ship Scanner
|
||||
public static int SS_MAX_DEPLOY_RADIUS_BLOCKS = 100;
|
||||
public static int SS_SEARCH_INTERVAL_TICKS = 20;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "minecraft:cube_directional",
|
||||
"textures": {
|
||||
"particle": "warpdrive:blocks/detection/speaker-side",
|
||||
"down" : "warpdrive:blocks/detection/speaker-side",
|
||||
"up" : "warpdrive:blocks/detection/speaker-side",
|
||||
"north" : "warpdrive:blocks/detection/speaker-front",
|
||||
"south" : "warpdrive:blocks/detection/speaker-side",
|
||||
"west" : "warpdrive:blocks/detection/speaker-side",
|
||||
"east" : "warpdrive:blocks/detection/speaker-side"
|
||||
},
|
||||
"transform": "forge:default-block"
|
||||
},
|
||||
"variants": {
|
||||
"normal": [{}],
|
||||
"inventory": [{}],
|
||||
"active": {
|
||||
"false": {
|
||||
|
||||
},
|
||||
"true": {
|
||||
|
||||
}
|
||||
},
|
||||
"facing": {
|
||||
"north": {},
|
||||
"south": { "y": 180 },
|
||||
"west" : { "y": 270 },
|
||||
"east" : { "y": 90 },
|
||||
"up" : { "x": -90 },
|
||||
"down" : { "x": 90 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "minecraft:cube_directional",
|
||||
"textures": {
|
||||
"particle": "warpdrive:blocks/detection/speaker-side",
|
||||
"down" : "warpdrive:blocks/detection/speaker-side",
|
||||
"up" : "warpdrive:blocks/detection/speaker-side",
|
||||
"north" : "warpdrive:blocks/detection/speaker-front",
|
||||
"south" : "warpdrive:blocks/detection/speaker-side",
|
||||
"west" : "warpdrive:blocks/detection/speaker-side",
|
||||
"east" : "warpdrive:blocks/detection/speaker-side"
|
||||
},
|
||||
"transform": "forge:default-block"
|
||||
},
|
||||
"variants": {
|
||||
"normal": [{}],
|
||||
"inventory": [{}],
|
||||
"active": {
|
||||
"false": {
|
||||
|
||||
},
|
||||
"true": {
|
||||
|
||||
}
|
||||
},
|
||||
"facing": {
|
||||
"north": {},
|
||||
"south": { "y": 180 },
|
||||
"west" : { "y": 270 },
|
||||
"east" : { "y": 90 },
|
||||
"up" : { "x": -90 },
|
||||
"down" : { "x": 90 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "minecraft:cube_directional",
|
||||
"textures": {
|
||||
"particle": "warpdrive:blocks/detection/speaker-side",
|
||||
"down" : "warpdrive:blocks/detection/speaker-side",
|
||||
"up" : "warpdrive:blocks/detection/speaker-side",
|
||||
"north" : "warpdrive:blocks/detection/speaker-front",
|
||||
"south" : "warpdrive:blocks/detection/speaker-side",
|
||||
"west" : "warpdrive:blocks/detection/speaker-side",
|
||||
"east" : "warpdrive:blocks/detection/speaker-side"
|
||||
},
|
||||
"transform": "forge:default-block"
|
||||
},
|
||||
"variants": {
|
||||
"normal": [{}],
|
||||
"inventory": [{}],
|
||||
"active": {
|
||||
"false": {
|
||||
|
||||
},
|
||||
"true": {
|
||||
|
||||
}
|
||||
},
|
||||
"facing": {
|
||||
"north": {},
|
||||
"south": { "y": 180 },
|
||||
"west" : { "y": 270 },
|
||||
"east" : { "y": 90 },
|
||||
"up" : { "x": -90 },
|
||||
"down" : { "x": 90 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=Weiterentwickelte Luftschu
|
|||
tile.warpdrive.detection.siren_military.superior.name=Überlegene Luftschutzsirene
|
||||
tile.warpdrive.detection.siren_military.tooltip=Ausgelöst durch ein Redstone Signal.
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=Lässt einen Alarm bis zu %1$d m weit ertönen.
|
||||
tile.warpdrive.detection.speaker.basic.name=Basic Speaker
|
||||
tile.warpdrive.detection.speaker.advanced.name=Advanced Speaker
|
||||
tile.warpdrive.detection.speaker.superior.name=Superior Speaker
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Sends messages to players up to %1$d m away.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=Standard Enantiomorpher Reaktorkern
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=Weiterentwickelte Enantiomorpher Reaktorkern
|
||||
|
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=Advanced Air Raid Siren
|
|||
tile.warpdrive.detection.siren_military.superior.name=Superior Air Raid Siren
|
||||
tile.warpdrive.detection.siren_military.tooltip=Triggered by redstone
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=Sounds an alarm up to %1$d m away.
|
||||
tile.warpdrive.detection.speaker.basic.name=Basic Speaker
|
||||
tile.warpdrive.detection.speaker.advanced.name=Advanced Speaker
|
||||
tile.warpdrive.detection.speaker.superior.name=Superior Speaker
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Sends messages to players up to %1$d m away.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=Basic Enantiomorphic Reactor Core
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=Advanced Enantiomorphic Reactor Core
|
||||
|
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=Sirène de raid aérien av
|
|||
tile.warpdrive.detection.siren_military.superior.name=Sirène de raid aérien supérieure
|
||||
tile.warpdrive.detection.siren_military.tooltip=Déclenchement par redstone
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=Emet une alarme audible à %1$d m.
|
||||
tile.warpdrive.detection.speaker.basic.name=Haut-parleur basique
|
||||
tile.warpdrive.detection.speaker.advanced.name=Haut-parleur avancé
|
||||
tile.warpdrive.detection.speaker.superior.name=Haut-parleur supérieur
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Envoi des messages aux joueurs à moins de %1$d m.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=Noyau de réacteur Enantiomorphic basique
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=Noyau de réacteur Enantiomorphic avancé
|
||||
|
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=Geavanceerde Luchtsirene
|
|||
tile.warpdrive.detection.siren_military.superior.name=Superieure Luchtsirene
|
||||
tile.warpdrive.detection.siren_military.tooltip=Aangezet door redstone
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=Je kan deze Sirene vanaf %1$d m verderop horen.
|
||||
tile.warpdrive.detection.speaker.basic.name=Basic Speaker
|
||||
tile.warpdrive.detection.speaker.advanced.name=Advanced Speaker
|
||||
tile.warpdrive.detection.speaker.superior.name=Superior Speaker
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Sends messages to players up to %1$d m away.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=Normale Enantiomorfe Reactor Kern
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=Geavanceerde Enantiomorfe Reactor Kern
|
||||
|
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=Advanced Air Raid Siren
|
|||
tile.warpdrive.detection.siren_military.superior.name=Superior Air Raid Siren
|
||||
tile.warpdrive.detection.siren_military.tooltip=Triggered by redstone
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=Sounds an alarm up to %1$d m away.
|
||||
tile.warpdrive.detection.speaker.basic.name=Basic Speaker
|
||||
tile.warpdrive.detection.speaker.advanced.name=Advanced Speaker
|
||||
tile.warpdrive.detection.speaker.superior.name=Superior Speaker
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Sends messages to players up to %1$d m away.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=Basic Ядро энантиоморфного реактора
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=Advanced Ядро энантиоморфного реактора
|
||||
|
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=高级空袭警报器
|
|||
tile.warpdrive.detection.siren_military.superior.name=卓越空袭警报器
|
||||
tile.warpdrive.detection.siren_military.tooltip=红石触发
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=在%1$d米内能听到警报声。
|
||||
tile.warpdrive.detection.speaker.basic.name=Basic Speaker
|
||||
tile.warpdrive.detection.speaker.advanced.name=Advanced Speaker
|
||||
tile.warpdrive.detection.speaker.superior.name=Superior Speaker
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Sends messages to players up to %1$d m away.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=基础对称反应堆核心
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=高级对称反应堆核心
|
||||
|
|
|
@ -317,6 +317,10 @@ tile.warpdrive.detection.siren_military.advanced.name=進階空襲警報器
|
|||
tile.warpdrive.detection.siren_military.superior.name=高階空襲警報器
|
||||
tile.warpdrive.detection.siren_military.tooltip=由紅石觸發
|
||||
tile.warpdrive.detection.siren_military.tooltip.usage=距離%1$d格範圍内有空襲警報器發出了警報。
|
||||
tile.warpdrive.detection.speaker.basic.name=Basic Speaker
|
||||
tile.warpdrive.detection.speaker.advanced.name=Advanced Speaker
|
||||
tile.warpdrive.detection.speaker.superior.name=Superior Speaker
|
||||
tile.warpdrive.detection.speaker.tooltip.usage=Sends messages to players up to %1$d m away.
|
||||
|
||||
tile.warpdrive.energy.enan_reactor_core.basic.name=Basic 核反應堆核
|
||||
tile.warpdrive.energy.enan_reactor_core.advanced.name=Advanced 核反應堆核
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
if not term.isColor() then
|
||||
print("Advanced computer required")
|
||||
error()
|
||||
end
|
||||
|
||||
local sides = peripheral.getNames()
|
||||
local speakers = {}
|
||||
for _, side in pairs(sides) do
|
||||
if peripheral.getType(side) == "warpdriveSpeaker" then
|
||||
print("Wrapping " .. side)
|
||||
table.insert(speakers, peripheral.wrap(side))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local noExit = true
|
||||
local message = ""
|
||||
local args = {...}
|
||||
if #args == 0 or args[1] == "help" or args[1] == "?" then
|
||||
print("Usage: speak <message>")
|
||||
print()
|
||||
print("Queue up to 12 messages to send to living players.")
|
||||
print("Antispam will slow you down, be wise!")
|
||||
print()
|
||||
noExit = false
|
||||
else
|
||||
for index, arg in pairs(args) do
|
||||
if string.len(message) > 0 then
|
||||
message = message .. " "
|
||||
end
|
||||
if index > 0 then
|
||||
message = message .. arg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #speakers == 0 then
|
||||
term.setBackgroundColor(colors.red)
|
||||
term.setTextColor(colors.white)
|
||||
print("No speaker detected")
|
||||
|
||||
noExit = false
|
||||
end
|
||||
if noExit then
|
||||
for _, speaker in pairs(speakers) do
|
||||
speaker.speak(message)
|
||||
end
|
||||
print("Message sent")
|
||||
end
|
||||
|
||||
term.setBackgroundColor(colors.black)
|
||||
term.setTextColor(colors.white)
|
||||
|
||||
print()
|
||||
print("Program closed")
|
|
@ -0,0 +1,70 @@
|
|||
local component = require("component")
|
||||
local computer = require("computer")
|
||||
local term = require("term")
|
||||
|
||||
if not term.isAvailable() then
|
||||
computer.beep()
|
||||
os.exit()
|
||||
end
|
||||
if component.gpu.getDepth() < 4 then
|
||||
print("A tier 2 or higher GPU is required")
|
||||
os.exit()
|
||||
end
|
||||
|
||||
local speakers = {}
|
||||
for address, _ in component.list("warpdriveSpeaker", true) do
|
||||
print("Wrapping " .. address)
|
||||
table.insert(speakers, component.proxy(address))
|
||||
end
|
||||
|
||||
function textOut(x, y, text, fg, bg)
|
||||
if term.isAvailable() then
|
||||
local w, _ = component.gpu.getResolution()
|
||||
if w then
|
||||
component.gpu.setBackground(bg)
|
||||
component.gpu.setForeground(fg)
|
||||
component.gpu.set(x, y, text)
|
||||
component.gpu.setBackground(0x000000)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local noExit = true
|
||||
local message = ""
|
||||
local args = {...}
|
||||
if #args == 0 or args[1] == "help" or args[1] == "?" then
|
||||
print("Usage: speak <message>")
|
||||
print()
|
||||
print("Queue up to 12 messages to send to living players.")
|
||||
print("Antispam will slow you down, be wise!")
|
||||
print()
|
||||
noExit = false
|
||||
else
|
||||
for index, arg in pairs(args) do
|
||||
if string.len(message) > 0 then
|
||||
message = message .. " "
|
||||
end
|
||||
if index > 0 then
|
||||
message = message .. arg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #speakers == 0 then
|
||||
computer.beep()
|
||||
textOut(1, 2, "No speaker detected", 0xFFFFFF, 0xFF0000)
|
||||
|
||||
noExit = false
|
||||
end
|
||||
if noExit then
|
||||
for _, speaker in pairs(speakers) do
|
||||
speaker.speak(message)
|
||||
end
|
||||
print("Message sent")
|
||||
end
|
||||
|
||||
textOut(1, 1, "", 0xFFFFFF, 0x000000)
|
||||
|
||||
print()
|
||||
print("Program closed")
|
Binary file not shown.
After ![]() (image error) Size: 5.2 KiB |
Binary file not shown.
After ![]() (image error) Size: 3 KiB |
Loading…
Add table
Reference in a new issue