Added speaker sending messages to local players including an anti-spam

This commit is contained in:
Unknown 2020-04-24 21:46:43 +02:00 committed by unknown
parent cc20769d94
commit 6567376e4b
19 changed files with 453 additions and 0 deletions
src/main
java/cr0s/warpdrive
resources/assets/warpdrive

View file

@ -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"));

View file

@ -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());
}
}

View file

@ -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() );
}
}

View file

@ -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() {

View file

@ -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;

View file

@ -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 }
}
}
}

View file

@ -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 }
}
}
}

View file

@ -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 }
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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é

View file

@ -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

View file

@ -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 Ядро энантиоморфного реактора

View file

@ -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=高级对称反应堆核心

View file

@ -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 核反應堆核

View file

@ -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")

View file

@ -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