That's one heck of a commit you've got there...
I may have got a bit behind with version control. A lot behind, in fact. Maybe I'll go back and split this sometime - then again, I probably won't. But hey, at least it's here!
This commit is contained in:
@@ -1,36 +1,41 @@
|
||||
package electroblob.wizardry.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import electroblob.wizardry.WizardData;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.packet.PacketCastSpell;
|
||||
import electroblob.wizardry.packet.PacketCastSpellAtPos;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.NumberInvalidException;
|
||||
import net.minecraft.command.PlayerNotFoundException;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.command.*;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.nbt.NBTException;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandCastSpell extends CommandBase {
|
||||
|
||||
/** The default number of ticks for which /cast will cast a continuous spell, if duration is not specified. */
|
||||
public static final int DEFAULT_CASTING_DURATION = 100;
|
||||
/** The minimum number of seconds for which /cast may cast a continuous spell. */
|
||||
public static final int MIN_CASTING_DURATION = 0;
|
||||
/** The maximum number of seconds for which /cast may cast a continuous spell. */
|
||||
public static final int MAX_CASTING_DURATION = 1000000;
|
||||
|
||||
@Override
|
||||
public String getName(){
|
||||
return Wizardry.settings.castCommandName;
|
||||
@@ -74,6 +79,8 @@ public class CommandCastSpell extends CommandBase {
|
||||
int i = 0;
|
||||
|
||||
EntityPlayerMP caster = null;
|
||||
Vec3d origin = null;
|
||||
EnumFacing direction = null;
|
||||
|
||||
try{
|
||||
caster = getCommandSenderAsPlayer(sender);
|
||||
@@ -85,12 +92,24 @@ public class CommandCastSpell extends CommandBase {
|
||||
Spell spell = Spell.get(arguments[i++]);
|
||||
|
||||
if(spell == null){
|
||||
throw new NumberInvalidException("commands." + Wizardry.MODID + ":cast.not_found", new Object[]{arguments[i - 1]});
|
||||
throw new NumberInvalidException("commands." + Wizardry.MODID + ":cast.not_found", arguments[i - 1]);
|
||||
}
|
||||
|
||||
boolean castAsOtherPlayer = false;
|
||||
|
||||
if(i < arguments.length){
|
||||
if(i + 3 < arguments.length){
|
||||
|
||||
Vec3d vec3d = sender.getPositionVector();
|
||||
CoordinateArg x = parseCoordinate(vec3d.x, arguments[i++], true);
|
||||
CoordinateArg y = parseCoordinate(vec3d.y, arguments[i++], 0, 256, false);
|
||||
CoordinateArg z = parseCoordinate(vec3d.z, arguments[i++], true);
|
||||
|
||||
origin = new Vec3d(x.getResult(), y.getResult(), z.getResult());
|
||||
|
||||
direction = EnumFacing.byName(arguments[i++]);
|
||||
if(direction == null) throw new NumberInvalidException("commands." + Wizardry.MODID + ":cast.invalid_direction", arguments[i - 1]);
|
||||
|
||||
}else if(i < arguments.length){
|
||||
try{
|
||||
// If the second argument is a player and is not the player that gave the command, the spell is cast
|
||||
// as the given player rather than the command sender, and there is a different chat readout.
|
||||
@@ -107,8 +126,31 @@ public class CommandCastSpell extends CommandBase {
|
||||
|
||||
// If, after this point, the player is still null, the sender must be a command block or the console and the
|
||||
// player must not have been specified, meaning an exception should be thrown.
|
||||
if(caster == null)
|
||||
throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
|
||||
if(caster == null && origin == null)
|
||||
throw new PlayerNotFoundException("commands." + Wizardry.MODID + ":cast.origin_not_specified");
|
||||
|
||||
int duration = DEFAULT_CASTING_DURATION;
|
||||
int seconds = duration/20;
|
||||
|
||||
if(spell.isContinuous){
|
||||
|
||||
if(i >= arguments.length) throw new CommandException("commands." + Wizardry.MODID + ":cast.duration_not_specified");
|
||||
|
||||
try{
|
||||
seconds = parseInt(arguments[i++]);
|
||||
}catch(NumberInvalidException e){
|
||||
// If no duration was found, assume it was unspecified
|
||||
i--;
|
||||
}
|
||||
|
||||
if(seconds < MIN_CASTING_DURATION){
|
||||
throw new NumberInvalidException("commands.generic.num.tooSmall", seconds, MIN_CASTING_DURATION);
|
||||
}else if(seconds > MAX_CASTING_DURATION){
|
||||
throw new NumberInvalidException("commands.generic.num.tooBig", seconds, MAX_CASTING_DURATION);
|
||||
}
|
||||
|
||||
duration = seconds * 20;
|
||||
}
|
||||
|
||||
SpellModifiers modifiers = new SpellModifiers();
|
||||
|
||||
@@ -136,64 +178,124 @@ public class CommandCastSpell extends CommandBase {
|
||||
|
||||
// ===== Spell casting =====
|
||||
|
||||
// If anything stops the spell working at this point, nothing else happens.
|
||||
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(caster, spell, modifiers, Source.COMMAND))){
|
||||
displayFailMessage(sender, spell);
|
||||
return;
|
||||
}
|
||||
if(origin != null){ // Positional
|
||||
|
||||
WizardData data = WizardData.get((EntityPlayer)caster);
|
||||
World world = sender.getEntityWorld();
|
||||
|
||||
if(spell.isContinuous){
|
||||
// If anything stops the spell working at this point, nothing else happens.
|
||||
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(Source.COMMAND, spell, world,
|
||||
origin.x, origin.y, origin.z, direction, modifiers))){
|
||||
if(server.sendCommandFeedback()) displayFailMessage(sender, spell);
|
||||
return;
|
||||
}
|
||||
|
||||
// Events for continuous spell casting via commands are dealt with in WizardData.
|
||||
if(spell.isContinuous){
|
||||
|
||||
if(data != null){
|
||||
if(data.isCasting()){
|
||||
data.stopCastingContinuousSpell();
|
||||
}else{
|
||||
if(spell.cast(world, origin.x, origin.y, origin.z, direction, 0, duration, modifiers)){
|
||||
|
||||
data.startCastingContinuousSpell(spell, modifiers);
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.COMMAND, spell, world, origin.x, origin.y, origin.z, direction, modifiers));
|
||||
|
||||
if(castAsOtherPlayer){
|
||||
sender.sendMessage(
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_remote_continuous",
|
||||
spell.getNameForTranslationFormatted(), caster.getName()));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_continuous",
|
||||
spell.getNameForTranslationFormatted()));
|
||||
SpellEmitter.add(spell, world, origin.x, origin.y, origin.z, direction, duration, modifiers);
|
||||
IMessage msg = new PacketCastSpellAtPos.Message(origin, direction, spell, modifiers, duration);
|
||||
WizardryPacketHandler.net.sendToDimension(msg, world.provider.getDimension());
|
||||
|
||||
if(server.sendCommandFeedback()){
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_position_continuous",
|
||||
spell.getNameForTranslationFormatted(), origin.x, origin.y, origin.z, seconds));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
if(spell.cast(world, origin.x, origin.y, origin.z, direction, 0, -1, modifiers)){
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.COMMAND, spell, world, origin.x, origin.y, origin.z, direction, modifiers));
|
||||
|
||||
if(spell.requiresPacket()){
|
||||
// Sends a packet to all players in dimension to tell them to spawn particles.
|
||||
// Only sent if the spell succeeded, because if the spell failed, you wouldn't
|
||||
// need to spawn any particles!
|
||||
IMessage msg = new PacketCastSpellAtPos.Message(origin, direction, spell, modifiers);
|
||||
WizardryPacketHandler.net.sendToDimension(msg, world.provider.getDimension());
|
||||
}
|
||||
|
||||
if(server.sendCommandFeedback()){
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_position",
|
||||
spell.getNameForTranslationFormatted(), origin.x, origin.y, origin.z));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}else{ // Player-based
|
||||
|
||||
// If anything stops the spell working at this point, nothing else happens.
|
||||
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(Source.COMMAND, spell, caster, modifiers))){
|
||||
if(server.sendCommandFeedback()) displayFailMessage(sender, spell);
|
||||
return;
|
||||
}
|
||||
|
||||
}else{
|
||||
if(spell.isContinuous){
|
||||
|
||||
if(spell.cast(caster.world, caster, EnumHand.MAIN_HAND, 0, modifiers)){
|
||||
WizardData data = WizardData.get(caster);
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(caster, spell, modifiers, Source.COMMAND));
|
||||
// Events/packets for continuous spell casting via commands are dealt with in WizardData.
|
||||
|
||||
if(spell.doesSpellRequirePacket()){
|
||||
// Sends a packet to all players in dimension to tell them to spawn particles.
|
||||
// Only sent if the spell succeeded, because if the spell failed, you wouldn't
|
||||
// need to spawn any particles!
|
||||
IMessage msg = new PacketCastSpell.Message(caster.getEntityId(), null, spell.id(), modifiers);
|
||||
WizardryPacketHandler.net.sendToDimension(msg, caster.world.provider.getDimension());
|
||||
if(data != null){
|
||||
if(data.isCasting()){
|
||||
data.stopCastingContinuousSpell(); // TODO: Where should this go now?
|
||||
}else{
|
||||
|
||||
data.startCastingContinuousSpell(spell, modifiers, duration);
|
||||
|
||||
if(server.sendCommandFeedback()){
|
||||
if(castAsOtherPlayer){
|
||||
sender.sendMessage(
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_remote_continuous",
|
||||
spell.getNameForTranslationFormatted(), caster.getName(), seconds));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_continuous",
|
||||
spell.getNameForTranslationFormatted(), seconds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(castAsOtherPlayer){
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_remote",
|
||||
spell.getNameForTranslationFormatted(), caster.getName()));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success",
|
||||
spell.getNameForTranslationFormatted()));
|
||||
}else{
|
||||
|
||||
if(spell.cast(caster.world, caster, EnumHand.MAIN_HAND, 0, modifiers)){
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.COMMAND, spell, caster, modifiers));
|
||||
|
||||
if(spell.requiresPacket()){
|
||||
// Sends a packet to all players in dimension to tell them to spawn particles.
|
||||
// Only sent if the spell succeeded, because if the spell failed, you wouldn't
|
||||
// need to spawn any particles!
|
||||
IMessage msg = new PacketCastSpell.Message(caster.getEntityId(), null, spell, modifiers);
|
||||
WizardryPacketHandler.net.sendToDimension(msg, caster.world.provider.getDimension());
|
||||
}
|
||||
|
||||
if(server.sendCommandFeedback()){
|
||||
if(castAsOtherPlayer){
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_remote",
|
||||
spell.getNameForTranslationFormatted(), caster.getName()));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success",
|
||||
spell.getNameForTranslationFormatted()));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
displayFailMessage(sender, spell);
|
||||
if(server.sendCommandFeedback()) displayFailMessage(sender, spell);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
package electroblob.wizardry.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import electroblob.wizardry.WizardData;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.event.DiscoverSpellEvent;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.NumberInvalidException;
|
||||
import net.minecraft.command.PlayerNotFoundException;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.command.*;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandDiscoverSpell extends CommandBase {
|
||||
|
||||
@Override
|
||||
@@ -92,7 +87,7 @@ public class CommandDiscoverSpell extends CommandBase {
|
||||
|
||||
if(spell == null){
|
||||
throw new NumberInvalidException("commands." + Wizardry.MODID + ":discoverspell.not_found",
|
||||
new Object[]{arguments[i - 1]});
|
||||
arguments[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,32 +105,32 @@ public class CommandDiscoverSpell extends CommandBase {
|
||||
if(player == null)
|
||||
throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
|
||||
|
||||
WizardData properties = WizardData.get(player);
|
||||
WizardData data = WizardData.get(player);
|
||||
|
||||
if(properties != null){
|
||||
if(data != null){
|
||||
if(clear){
|
||||
properties.spellsDiscovered.clear();
|
||||
sender.sendMessage(
|
||||
data.spellsDiscovered.clear();
|
||||
if(server.sendCommandFeedback()) sender.sendMessage(
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.clear", player.getName()));
|
||||
}else if(all){
|
||||
properties.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells));
|
||||
sender.sendMessage(
|
||||
data.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells));
|
||||
if(server.sendCommandFeedback()) sender.sendMessage(
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.all", player.getName()));
|
||||
}else{
|
||||
if(properties.hasSpellBeenDiscovered(spell)){
|
||||
properties.spellsDiscovered.remove(spell);
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.removespell",
|
||||
if(data.hasSpellBeenDiscovered(spell)){
|
||||
data.spellsDiscovered.remove(spell);
|
||||
if(server.sendCommandFeedback()) sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.removespell",
|
||||
spell.getNameForTranslationFormatted(), player.getName()));
|
||||
}else{
|
||||
if(!MinecraftForge.EVENT_BUS
|
||||
.post(new DiscoverSpellEvent(player, spell, DiscoverSpellEvent.Source.COMMAND))){
|
||||
properties.discoverSpell(spell);
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.addspell",
|
||||
data.discoverSpell(spell);
|
||||
if(server.sendCommandFeedback()) sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.addspell",
|
||||
spell.getNameForTranslationFormatted(), player.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
properties.sync();
|
||||
data.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
package electroblob.wizardry.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import electroblob.wizardry.WizardData;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.NumberInvalidException;
|
||||
import net.minecraft.command.PlayerNotFoundException;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.command.*;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -18,6 +11,8 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandSetAlly extends CommandBase {
|
||||
|
||||
@Override
|
||||
@@ -85,10 +80,12 @@ public class CommandSetAlly extends CommandBase {
|
||||
if(allyOf != sender && sender instanceof EntityPlayer
|
||||
&& !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){
|
||||
// Displays a chat message if a non-op tries to modify another player's allies.
|
||||
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation(
|
||||
"commands." + Wizardry.MODID + ":ally.permission");
|
||||
TextComponentTranslation2.getStyle().setColor(TextFormatting.RED);
|
||||
allyOf.sendMessage(TextComponentTranslation2);
|
||||
if(server.sendCommandFeedback()){
|
||||
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation(
|
||||
"commands." + Wizardry.MODID + ":ally.permission");
|
||||
TextComponentTranslation2.getStyle().setColor(TextFormatting.RED);
|
||||
allyOf.sendMessage(TextComponentTranslation2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,15 +99,17 @@ public class CommandSetAlly extends CommandBase {
|
||||
|
||||
if(allyOf == ally) throw new NumberInvalidException("commands." + Wizardry.MODID + ":ally.self");
|
||||
|
||||
if(WizardData.get(allyOf) != null){
|
||||
String string = WizardData.get(allyOf).toggleAlly(ally) ? "add" : "remove";
|
||||
if(executeAsOtherPlayer){
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":ally." + string + "ally",
|
||||
ally.getName(), allyOf.getName()));
|
||||
// In this case, the player whose allies have been modified is also notified.
|
||||
allyOf.sendMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName()));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName()));
|
||||
if(server.sendCommandFeedback()){
|
||||
if(WizardData.get(allyOf) != null){
|
||||
String string = WizardData.get(allyOf).toggleAlly(ally) ? "add" : "remove";
|
||||
if(executeAsOtherPlayer){
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":ally." + string + "ally",
|
||||
ally.getName(), allyOf.getName()));
|
||||
// In this case, the player whose allies have been modified is also notified.
|
||||
allyOf.sendMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName()));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package electroblob.wizardry.command;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import electroblob.wizardry.WizardData;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -18,6 +14,9 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class CommandViewAllies extends CommandBase {
|
||||
|
||||
@Override
|
||||
@@ -75,10 +74,12 @@ public class CommandViewAllies extends CommandBase {
|
||||
if(player != sender && sender instanceof EntityPlayer
|
||||
&& !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){
|
||||
// Displays a chat message if a non-op tries to view another player's allies.
|
||||
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation(
|
||||
"commands." + Wizardry.MODID + ":allies.permission");
|
||||
TextComponentTranslation2.getStyle().setColor(TextFormatting.RED);
|
||||
player.sendMessage(TextComponentTranslation2);
|
||||
if(server.sendCommandFeedback()){
|
||||
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation(
|
||||
"commands." + Wizardry.MODID + ":allies.permission");
|
||||
TextComponentTranslation2.getStyle().setColor(TextFormatting.RED);
|
||||
player.sendMessage(TextComponentTranslation2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -101,6 +102,7 @@ public class CommandViewAllies extends CommandBase {
|
||||
playerList = new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.none");
|
||||
}
|
||||
|
||||
// Ignore sendCommandFeedback here since that's the entire point of this command
|
||||
if(executeAsOtherPlayer){
|
||||
sender.sendMessage(
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list_other", player.getName(), playerList));
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
package electroblob.wizardry.command;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.SpellEmitterData;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
/**
|
||||
* A {@code SpellEmitter} represents a continuous spell being cast from a position via commands.
|
||||
*
|
||||
* @since Wizardry 4.2
|
||||
* @author Electroblob
|
||||
*/
|
||||
public class SpellEmitter implements ITickable {
|
||||
|
||||
protected final Spell spell;
|
||||
protected World world;
|
||||
protected final double x, y, z;
|
||||
protected final EnumFacing direction;
|
||||
protected final int duration;
|
||||
protected final SpellModifiers modifiers;
|
||||
|
||||
protected int castingTick = 0;
|
||||
protected boolean needsRemoving = false;
|
||||
|
||||
protected SpellEmitter(Spell spell, World world, double x, double y, double z, EnumFacing direction, int duration, SpellModifiers modifiers){
|
||||
this.spell = spell;
|
||||
this.world = world;
|
||||
this.duration = duration;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.direction = direction;
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
/** Marks this spell emitter to be removed next tick. */
|
||||
protected void markForRemoval(){
|
||||
this.needsRemoving = true;
|
||||
}
|
||||
|
||||
/** Returns whether this spell emitter is marked for removal. */
|
||||
public boolean needsRemoving(){
|
||||
return needsRemoving;
|
||||
}
|
||||
|
||||
/** Returns the {@link SpellCastEvent.Source} that should be used for events fired by this spell emitter. */
|
||||
protected SpellCastEvent.Source getSource(){
|
||||
return SpellCastEvent.Source.COMMAND;
|
||||
}
|
||||
|
||||
/** Sets this spell emitter's world. This should only be used on the client side when the world has not yet been
|
||||
* set, otherwise the world will not be changed and a warning will be printed to the console. */
|
||||
public void setWorld(World world){
|
||||
if(world.isRemote && this.world == null){
|
||||
this.world = world;
|
||||
}else{
|
||||
Wizardry.logger.warn("Tried to change the world for a spell emitter, this shouldn't happen!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
if(castingTick < duration){
|
||||
|
||||
if(!MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(getSource(), spell, world, x, y, z, direction, modifiers, castingTick))){
|
||||
|
||||
if(spell.cast(world, x, y, z, direction, castingTick, duration, modifiers)){
|
||||
if(castingTick == 0) MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(getSource(), spell, world, x, y, z, direction, modifiers));
|
||||
castingTick++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the time ran out or the spell failed, interrupt spell casting
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Finish(getSource(), spell, world, x, y, z, direction, modifiers, castingTick));
|
||||
spell.finishCasting(world, null, x, y, z, direction, duration, modifiers);
|
||||
markForRemoval();
|
||||
}
|
||||
|
||||
/** Writes this {@code SpellEmitter} to the given ByteBuf. */
|
||||
public void write(ByteBuf buf){
|
||||
buf.writeInt(spell.networkID());
|
||||
buf.writeDouble(x);
|
||||
buf.writeDouble(y);
|
||||
buf.writeDouble(z);
|
||||
buf.writeInt(direction.getIndex());
|
||||
// This is sent through as the duration, meaning castingTick always starts at zero client-side, which is
|
||||
// important for sounds to work correctly. As a consequence, the client's castingTick will be different to the
|
||||
// server value if the player changes dimension or re-logs. However, since this is pretty uncommon anyway I
|
||||
// think it's an ok compromise.
|
||||
buf.writeInt(duration - castingTick);
|
||||
modifiers.write(buf);
|
||||
}
|
||||
|
||||
/** Reads a {@code SpellEmitter} from the given ByteBuf and returns it. */
|
||||
public static SpellEmitter read(ByteBuf buf){
|
||||
|
||||
Spell spell = Spell.byNetworkID(buf.readInt());
|
||||
double x = buf.readDouble();
|
||||
double y = buf.readDouble();
|
||||
double z = buf.readDouble();
|
||||
EnumFacing direction = EnumFacing.byIndex(buf.readInt());
|
||||
int duration = buf.readInt();
|
||||
SpellModifiers modifiers = new SpellModifiers();
|
||||
modifiers.read(buf);
|
||||
|
||||
return new SpellEmitter(spell, null, x, y, z, direction, duration, modifiers);
|
||||
}
|
||||
|
||||
// INBTSerializable is annoying, it doesn't allow you to have final fields
|
||||
|
||||
/** Returns a new {@link NBTTagCompound} representing this {@code SpellEmitter}. */
|
||||
public NBTTagCompound toNBT(){
|
||||
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
|
||||
nbt.setInteger("spell", spell.metadata());
|
||||
nbt.setDouble("x", x);
|
||||
nbt.setDouble("y", y);
|
||||
nbt.setDouble("z", z);
|
||||
nbt.setInteger("direction", direction.getIndex());
|
||||
nbt.setInteger("duration", duration);
|
||||
nbt.setTag("modifiers", modifiers.toNBT());
|
||||
nbt.setInteger("castingTick", castingTick);
|
||||
|
||||
return nbt;
|
||||
}
|
||||
|
||||
/** Creates a new {@code SpellEmitter} from the given {@link NBTTagCompound} and returns it. */
|
||||
public static SpellEmitter fromNBT(World world, NBTTagCompound nbt){
|
||||
|
||||
Spell spell = Spell.byMetadata(nbt.getInteger("spell"));
|
||||
double x = nbt.getDouble("x");
|
||||
double y = nbt.getDouble("y");
|
||||
double z = nbt.getDouble("z");
|
||||
EnumFacing direction = EnumFacing.byIndex(nbt.getInteger("direction"));
|
||||
int duration = nbt.getInteger("duration");
|
||||
SpellModifiers modifiers = SpellModifiers.fromNBT(nbt.getCompoundTag("modifiers"));
|
||||
int castingTick = nbt.getInteger("castingTick");
|
||||
|
||||
SpellEmitter emitter = new SpellEmitter(spell, world, x, y, z, direction, duration, modifiers);
|
||||
emitter.castingTick = castingTick;
|
||||
return emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code SpellEmitter} and adds it to the list of active emitters in {@link SpellEmitterData}. <i>
|
||||
* This method does not perform any syncing.</i>
|
||||
*
|
||||
* @param spell The spell to be cast
|
||||
* @param world The world in which to cast the spell
|
||||
* @param x The x-coordinate of the spell origin
|
||||
* @param y The y-coordinate of the spell origin
|
||||
* @param z The z-coordinate of the spell origin
|
||||
* @param direction The direction to cast the spell in
|
||||
* @param duration The number of ticks to cast the spell for
|
||||
* @param modifiers The {@link SpellModifiers} for the spell
|
||||
*/
|
||||
public static void add(Spell spell, World world, double x, double y, double z, EnumFacing direction, int duration, SpellModifiers modifiers){
|
||||
if(spell.isContinuous){
|
||||
if(duration <= 0) Wizardry.logger.warn("Adding a spell emitter with negative or zero duration!");
|
||||
SpellEmitterData.get(world).add(new SpellEmitter(spell, world, x, y, z, direction, duration, modifiers));
|
||||
}else{
|
||||
Wizardry.logger.warn("Tried to add a non-continuous spell emitter for spell {}", spell.getRegistryName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user