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:
Electroblob77
2019-08-18 00:04:18 +01:00
parent 2680d02304
commit f37812be3e
1564 changed files with 47652 additions and 12984 deletions
@@ -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);
}
}