diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..6f2713e7 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: McHorse # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/src/main/java/mchorse/metamorph/api/Morph.java b/src/main/java/mchorse/metamorph/api/Morph.java index ded317c6..0ce0ea4d 100644 --- a/src/main/java/mchorse/metamorph/api/Morph.java +++ b/src/main/java/mchorse/metamorph/api/Morph.java @@ -22,6 +22,11 @@ public Morph(AbstractMorph morph) this.morph = morph; } + public boolean isEmpty() + { + return this.morph == null; + } + public boolean set(AbstractMorph morph, boolean isRemote) { if (this.morph == null || !this.morph.canMerge(morph, isRemote)) diff --git a/src/main/java/mchorse/metamorph/api/MorphManager.java b/src/main/java/mchorse/metamorph/api/MorphManager.java index 9ab9f01d..4dff91cb 100644 --- a/src/main/java/mchorse/metamorph/api/MorphManager.java +++ b/src/main/java/mchorse/metamorph/api/MorphManager.java @@ -214,10 +214,13 @@ public AbstractMorph morphFromNBT(NBTTagCompound tag) if (this.factories.get(i).hasMorph(name)) { AbstractMorph morph = this.factories.get(i).getMorphFromNBT(tag); - - this.applySettings(morph); - - return morph; + + if (morph != null) + { + this.applySettings(morph); + + return morph; + } } } diff --git a/src/main/java/mchorse/metamorph/api/morphs/EntityMorph.java b/src/main/java/mchorse/metamorph/api/morphs/EntityMorph.java index 26505340..a9641b7e 100644 --- a/src/main/java/mchorse/metamorph/api/morphs/EntityMorph.java +++ b/src/main/java/mchorse/metamorph/api/morphs/EntityMorph.java @@ -499,7 +499,12 @@ protected void updateEntity(EntityLivingBase target) { if (this.settings.updates) { + if (!Metamorph.proxy.config.show_morph_idle_sounds) + { + this.entity.setSilent(true); + } this.entity.onUpdate(); + this.entity.setSilent(false); } } diff --git a/src/main/java/mchorse/metamorph/capabilities/morphing/Morphing.java b/src/main/java/mchorse/metamorph/capabilities/morphing/Morphing.java index b2c5c221..fe977988 100644 --- a/src/main/java/mchorse/metamorph/capabilities/morphing/Morphing.java +++ b/src/main/java/mchorse/metamorph/capabilities/morphing/Morphing.java @@ -4,6 +4,7 @@ import java.util.List; import mchorse.metamorph.Metamorph; +import mchorse.metamorph.api.Morph; import mchorse.metamorph.api.MorphManager; import mchorse.metamorph.api.morphs.AbstractMorph; import mchorse.metamorph.client.gui.elements.GuiSurvivalMorphs; @@ -35,7 +36,7 @@ public class Morphing implements IMorphing /** * Current used morph */ - private AbstractMorph morph; + private Morph morph = new Morph(); /** * Used for animation @@ -129,19 +130,19 @@ public AbstractMorph getPreviousMorph() @SideOnly(Side.CLIENT) public boolean renderPlayer(EntityPlayer player, double x, double y, double z, float yaw, float partialTick) { - if (this.morph == null && !this.isAnimating()) + if (this.morph.isEmpty() && !this.isAnimating()) { return false; } - if (this.morph == null && this.animation <= 10 || this.previousMorph == null && this.animation > 10) + if (this.morph.isEmpty() && this.animation <= 10 || this.previousMorph == null && this.animation > 10) { return false; } if (!this.isAnimating()) { - this.morph.render(player, x, y, z, yaw, partialTick); + this.morph.get().render(player, x, y, z, yaw, partialTick); return true; } @@ -167,7 +168,7 @@ public boolean renderPlayer(EntityPlayer player, double x, double y, double z, f GlStateManager.scale(1 - anim, 1 - anim, 1 - anim); } - this.morph.render(player, 0, 0, 0, yaw, partialTick); + this.morph.get().render(player, 0, 0, 0, yaw, partialTick); } else if (this.previousMorph != null) { @@ -261,7 +262,7 @@ public void setAcquiredMorphs(List morphs) @Override public AbstractMorph getCurrentMorph() { - return this.morph; + return this.morph.get(); } @Override @@ -280,23 +281,24 @@ public boolean setCurrentMorph(AbstractMorph morph, EntityPlayer player, boolean { if (player != null) { - if (this.morph == null) + if (this.morph.isEmpty()) { this.lastHealth = (float) player.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue(); } else { - this.morph.demorph(player); + this.morph.get().demorph(player); } } this.setMorph(morph, player == null ? false : player.world.isRemote); - if (player != null) + if (player != null && !this.morph.isEmpty()) { - this.setHealth(player, this.morph.settings.health); + AbstractMorph current = this.morph.get(); - this.morph.morph(player); + this.setHealth(player, current.settings.health); + current.morph(player); } return true; @@ -308,9 +310,9 @@ public boolean setCurrentMorph(AbstractMorph morph, EntityPlayer player, boolean @Override public void demorph(EntityPlayer player) { - if (player != null && this.morph != null) + if (player != null && !this.morph.isEmpty()) { - this.morph.demorph(player); + this.morph.get().demorph(player); } if (player != null) @@ -327,22 +329,23 @@ public void demorph(EntityPlayer player) */ protected void setMorph(AbstractMorph morph, boolean isRemote) { - if (this.morph == null || (this.morph != null && !this.morph.canMerge(morph, isRemote))) + AbstractMorph previous = this.morph.get(); + + if (this.morph.set(morph, isRemote)) { if (!Metamorph.proxy.config.disable_morph_animation) { this.animation = 20; } - this.previousMorph = this.morph; - this.morph = morph; + this.previousMorph = previous; } } @Override public boolean isMorphed() { - return this.morph != null; + return !this.morph.isEmpty(); } @Override @@ -385,11 +388,10 @@ public boolean remove(int index) public void copy(IMorphing morphing, EntityPlayer player) { this.acquiredMorphs.addAll(morphing.getAcquiredMorphs()); + if (morphing.getCurrentMorph() != null) { - NBTTagCompound morphNBT = new NBTTagCompound(); - morphing.getCurrentMorph().toNBT(morphNBT); - this.setCurrentMorph(MorphManager.INSTANCE.morphFromNBT(morphNBT), player, true); + this.setCurrentMorph(morphing.getCurrentMorph().clone(player.world.isRemote), player, true); } else { @@ -461,14 +463,16 @@ public void update(EntityPlayer player) player.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 1.0F, 1.0F); } - if (this.morph != null) + if (!this.morph.isEmpty()) { + AbstractMorph morph = this.morph.get(); + if (!Metamorph.proxy.config.disable_health) { - this.setMaxHealth(player, this.morph.settings.health); + this.setMaxHealth(player, morph.settings.health); } - this.morph.update(player, this); + morph.update(player, this); } } diff --git a/src/main/java/mchorse/metamorph/commands/CommandAcquireMorph.java b/src/main/java/mchorse/metamorph/commands/CommandAcquireMorph.java index f858623e..577a3800 100644 --- a/src/main/java/mchorse/metamorph/commands/CommandAcquireMorph.java +++ b/src/main/java/mchorse/metamorph/commands/CommandAcquireMorph.java @@ -93,7 +93,10 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args throw new CommandException("metamorph.error.acquire", args[1]); } - sender.sendMessage(new TextComponentTranslation("metamorph.success.acquire", args[0], args[1])); + if (sender.sendCommandFeedback()) + { + sender.sendMessage(new TextComponentTranslation("metamorph.success.acquire", args[0], args[1])); + } } /** diff --git a/src/main/java/mchorse/metamorph/commands/CommandMorph.java b/src/main/java/mchorse/metamorph/commands/CommandMorph.java index a08bd7c1..5217f33e 100644 --- a/src/main/java/mchorse/metamorph/commands/CommandMorph.java +++ b/src/main/java/mchorse/metamorph/commands/CommandMorph.java @@ -4,6 +4,7 @@ import mchorse.metamorph.api.MorphAPI; import mchorse.metamorph.api.MorphManager; +import mchorse.metamorph.api.morphs.AbstractMorph; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; @@ -69,17 +70,23 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args if (args.length < 2) { MorphAPI.demorph(player); - sender.sendMessage(new TextComponentTranslation("metamorph.success.demorph", args[0])); + + if (sender.sendCommandFeedback()) + { + sender.sendMessage(new TextComponentTranslation("metamorph.success.demorph", args[0])); + } } else { NBTTagCompound tag = null; + String mergedTagArgs = ""; if (args.length >= 3) { try { - tag = JsonToNBT.getTagFromJson(mergeArgs(args, 2)); + mergedTagArgs = mergeArgs(args, 2); + tag = JsonToNBT.getTagFromJson(mergedTagArgs); } catch (Exception e) { @@ -94,8 +101,20 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args tag.setString("Name", args[1]); - MorphAPI.morph(player, MorphManager.INSTANCE.morphFromNBT(tag), true); - sender.sendMessage(new TextComponentTranslation("metamorph.success.morph", args[0], args[1])); + AbstractMorph newMorph = MorphManager.INSTANCE.morphFromNBT(tag); + boolean morphFound = newMorph != null; + + if (!morphFound) + { + throw new CommandException("metamorph.error.morph.factory", args[0], args[1], mergedTagArgs); + } + + MorphAPI.morph(player, newMorph, true); + + if (sender.sendCommandFeedback()) + { + sender.sendMessage(new TextComponentTranslation("metamorph.success.morph", args[0], args[1])); + } } } diff --git a/src/main/java/mchorse/metamorph/config/MetamorphConfig.java b/src/main/java/mchorse/metamorph/config/MetamorphConfig.java index 84912b41..837cc73b 100644 --- a/src/main/java/mchorse/metamorph/config/MetamorphConfig.java +++ b/src/main/java/mchorse/metamorph/config/MetamorphConfig.java @@ -74,6 +74,11 @@ public class MetamorphConfig */ public boolean morph_in_tight_spaces; + /** + * Whether players make entity idle sounds when morphed + */ + public boolean show_morph_idle_sounds; + /* End of config options */ /** @@ -106,6 +111,7 @@ public void reload() this.disable_morph_disguise = this.config.getBoolean("disable_morph_disguise", cat, false, "Disables the ability of morphs labeled as 'hostile' to avoid being attacked by hostile mobs.", lang + "disable_morph_disguise"); this.acquire_immediately = this.config.getBoolean("acquire_immediately", cat, false, "Acquires morph immediately after player kills an entity instead of spawning a ghost", lang + "acquire_immediately"); this.morph_in_tight_spaces = this.config.getBoolean("morph_in_tight_spaces", cat, false, "Allows morphing even if it could cause suffocation and allow passing through walls", lang + "morph_in_tight_spaces"); + this.show_morph_idle_sounds = this.config.getBoolean("show_morph_idle_sounds", cat, true, "When enabled, morphed players make mob idle sounds", lang + "show_morph_idle_sounds"); this.config.getCategory(cat).setComment("General configuration of Metamorph mod"); diff --git a/src/main/java/mchorse/vanilla_pack/PlayerMorphFactory.java b/src/main/java/mchorse/vanilla_pack/PlayerMorphFactory.java index 4bea80eb..9a7ec85b 100644 --- a/src/main/java/mchorse/vanilla_pack/PlayerMorphFactory.java +++ b/src/main/java/mchorse/vanilla_pack/PlayerMorphFactory.java @@ -91,7 +91,7 @@ public AbstractMorph getMorphFromNBT(NBTTagCompound tag) player.fromNBT(tag); - return player; + return player.profile != null ? player : null; } return null; diff --git a/src/main/resources/assets/metamorph/lang/en_US.lang b/src/main/resources/assets/metamorph/lang/en_US.lang index 3a9ef9fa..62eb1144 100644 --- a/src/main/resources/assets/metamorph/lang/en_US.lang +++ b/src/main/resources/assets/metamorph/lang/en_US.lang @@ -68,6 +68,7 @@ metamorph.config.disable_morph_animation=Disable morph animation metamorph.config.disable_morph_disguise=Disable morph hostility metamorph.config.acquire_immediately=Acquire morph immediately metamorph.config.morph_in_tight_spaces=Allow morphing in tight spaces +metamorph.config.show_morph_idle_sounds=Show morph idle sounds # Commands metamorph.commands.morph=Morph command. This command is responsible for morphing player into specified morph.\n\n/morph [morph_name] [data_tag] @@ -76,6 +77,7 @@ metamorph.commands.metamorph=Metamorph server command. This command allows to ma metamorph.error.morph.not_player=Entity %s isn't not a player! metamorph.error.morph.nbt=Error occurred during data tag parsing:\n%s +metamorph.error.morph.factory=Could not morph into %2$s with given data tag metamorph.error.acquire=Couldn't acquire a morph by name %s! metamorph.success.morph=Player by username %s was successfully morphed into %s! metamorph.success.demorph=Player by username %s was successfully demorphed! @@ -90,4 +92,4 @@ morph.category.boss=Boss morphs morph.category.acquired=Your morphs morph.category.hostile=Hostile morphs morph.category.players=Player morphs -morph.category.modded=Morphs from %s \ No newline at end of file +morph.category.modded=Morphs from %s