diff --git a/src/main/java/io/icker/factions/FactionsMod.java b/src/main/java/io/icker/factions/FactionsMod.java index 8682d4dd..b97ad9ea 100644 --- a/src/main/java/io/icker/factions/FactionsMod.java +++ b/src/main/java/io/icker/factions/FactionsMod.java @@ -8,6 +8,7 @@ import io.icker.factions.command.CreateCommand; import io.icker.factions.command.DeclareCommand; import io.icker.factions.command.DisbandCommand; +import io.icker.factions.command.FriendlyFireCommand; import io.icker.factions.command.HomeCommand; import io.icker.factions.command.InfoCommand; import io.icker.factions.command.InviteCommand; @@ -98,6 +99,7 @@ private static void registerCommands( new CreateCommand(), new DeclareCommand(), new DisbandCommand(), + new FriendlyFireCommand(), new HomeCommand(), new InfoCommand(), new InviteCommand(), diff --git a/src/main/java/io/icker/factions/api/persistents/Faction.java b/src/main/java/io/icker/factions/api/persistents/Faction.java index 760b4116..bf18f292 100644 --- a/src/main/java/io/icker/factions/api/persistents/Faction.java +++ b/src/main/java/io/icker/factions/api/persistents/Faction.java @@ -45,6 +45,10 @@ public class Faction { @Field("Open") private boolean open; + /** Whether friendly fire is enabled for this faction (null = use global config) */ + @Field("FriendlyFire") + private Boolean friendlyFire; + @Field("Power") private int power; @@ -153,6 +157,10 @@ public boolean isOpen() { return open; } + public boolean isFriendlyFireEnabled() { + return friendlyFire != null ? friendlyFire : FactionsMod.CONFIG.FRIENDLY_FIRE; + } + public void setName(String name) { this.name = name; FactionEvents.MODIFY.invoker().onModify(this); @@ -178,6 +186,11 @@ public void setOpen(boolean open) { FactionEvents.MODIFY.invoker().onModify(this); } + public void setFriendlyFire(boolean enabled) { + this.friendlyFire = enabled; + FactionEvents.MODIFY.invoker().onModify(this); + } + public int adjustPower(int adjustment) { int maxPower = calculateMaxPower(); int newPower = Math.min(Math.max(0, power + adjustment), maxPower); diff --git a/src/main/java/io/icker/factions/command/FriendlyFireCommand.java b/src/main/java/io/icker/factions/command/FriendlyFireCommand.java new file mode 100644 index 00000000..791890ce --- /dev/null +++ b/src/main/java/io/icker/factions/command/FriendlyFireCommand.java @@ -0,0 +1,52 @@ +package io.icker.factions.command; + +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.tree.LiteralCommandNode; + +import io.icker.factions.api.persistents.Faction; +import io.icker.factions.util.Command; +import io.icker.factions.util.Message; + +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class FriendlyFireCommand implements Command { + private int execute(CommandContext context) throws CommandSyntaxException { + boolean enabled = BoolArgumentType.getBool(context, "enabled"); + + ServerCommandSource source = context.getSource(); + ServerPlayerEntity player = source.getPlayerOrThrow(); + + Faction faction = Command.getUser(player).getFaction(); + + faction.setFriendlyFire(enabled); + + new Message( + Text.translatable( + enabled + ? "factions.command.friendlyfire.success.enabled" + : "factions.command.friendlyfire.success.disabled")) + .format(enabled ? Formatting.GREEN : Formatting.RED) + .prependFaction(faction) + .send(player, false); + + return 1; + } + + public LiteralCommandNode getNode() { + return CommandManager.literal("friendlyfire") + .requires( + Requires.multiple( + Requires.hasPerms("factions.friendlyfire.toggle", 0), + Requires.isLeader())) + .then( + CommandManager.argument("enabled", BoolArgumentType.bool()) + .executes(this::execute)) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/io/icker/factions/core/FactionsManager.java b/src/main/java/io/icker/factions/core/FactionsManager.java index f2a29b62..fbc6db32 100644 --- a/src/main/java/io/icker/factions/core/FactionsManager.java +++ b/src/main/java/io/icker/factions/core/FactionsManager.java @@ -34,6 +34,7 @@ public class FactionsManager { public static void register() { ServerLifecycleEvents.SERVER_STARTED.register(FactionsManager::serverStarted); + ServerLifecycleEvents.SERVER_STOPPING.register(FactionsManager::serverStopping); FactionEvents.MODIFY.register(FactionsManager::factionModified); FactionEvents.MEMBER_JOIN.register(FactionsManager::memberChange); FactionEvents.MEMBER_LEAVE.register(FactionsManager::memberChange); diff --git a/src/main/java/io/icker/factions/core/InteractionManager.java b/src/main/java/io/icker/factions/core/InteractionManager.java index 191c1aa9..872d7f8f 100644 --- a/src/main/java/io/icker/factions/core/InteractionManager.java +++ b/src/main/java/io/icker/factions/core/InteractionManager.java @@ -262,7 +262,7 @@ private static ActionResult onUseInventory(PlayerEntity player, BlockPos pos, Wo } private static ActionResult isInvulnerableTo(Entity source, Entity target) { - if (!source.isPlayer() || FactionsMod.CONFIG.FRIENDLY_FIRE) return ActionResult.PASS; + if (!source.isPlayer()) return ActionResult.PASS; User sourceUser = User.get(source.getUuid()); User targetUser = User.get(target.getUuid()); @@ -274,6 +274,10 @@ private static ActionResult isInvulnerableTo(Entity source, Entity target) { Faction sourceFaction = sourceUser.getFaction(); Faction targetFaction = targetUser.getFaction(); + if (targetFaction.isFriendlyFireEnabled()) { + return ActionResult.PASS; + } + if (sourceFaction.equals(targetFaction)) { return ActionResult.SUCCESS; } diff --git a/src/main/java/io/icker/factions/core/ServerManager.java b/src/main/java/io/icker/factions/core/ServerManager.java index 8c0e05d3..b954c723 100644 --- a/src/main/java/io/icker/factions/core/ServerManager.java +++ b/src/main/java/io/icker/factions/core/ServerManager.java @@ -19,7 +19,7 @@ public static void register() { MiscEvents.ON_SAVE.register(ServerManager::save); } - private static void save(MinecraftServer server) { + public static void save(MinecraftServer server) { Claim.save(); Faction.save(); User.save(); diff --git a/src/main/java/io/icker/factions/ui/ModifyGui.java b/src/main/java/io/icker/factions/ui/ModifyGui.java index a0192ac4..8336f95e 100644 --- a/src/main/java/io/icker/factions/ui/ModifyGui.java +++ b/src/main/java/io/icker/factions/ui/ModifyGui.java @@ -73,6 +73,7 @@ public ModifyGui(ServerPlayerEntity player, Faction faction, @Nullable Runnable new ColorGui(player, faction, this::open); })); this.setSlot(5, buildOpenFactionButton(faction)); + this.setSlot(6, buildFriendlyFireButton(faction)); this.setSlot( 8, @@ -112,6 +113,26 @@ private GuiElementBuilder buildOpenFactionButton(Faction faction) { }); } + private GuiElementBuilder buildFriendlyFireButton(Faction faction) { + boolean enabled = faction.isFriendlyFireEnabled(); + return new GuiElementBuilder(Items.PLAYER_HEAD) + .setProfileSkinTexture( + enabled ? Icons.GUI_TESSERACT_RED : Icons.GUI_TESSERACT_BLUE) + .setName( + Text.translatable( + enabled + ? "factions.gui.modify.friendly_fire.enabled" + : "factions.gui.modify.friendly_fire.disabled")) + .addLoreLine( + Text.translatable("factions.gui.modify.friendly_fire.lore") + .formatted(Formatting.GRAY)) + .setCallback( + (index, clickType, actionType) -> { + faction.setFriendlyFire(!faction.isFriendlyFireEnabled()); + this.setSlot(index, buildFriendlyFireButton(faction)); + }); + } + private void execName(Faction faction) { InputGui inputGui = new InputGui(player); diff --git a/src/main/resources/data/factions/lang/en_us.json b/src/main/resources/data/factions/lang/en_us.json index fab12c2f..6eb12784 100644 --- a/src/main/resources/data/factions/lang/en_us.json +++ b/src/main/resources/data/factions/lang/en_us.json @@ -16,13 +16,11 @@ "factions.gui.admin.options.reload_dynmap": "Reload DynMap markers", "factions.gui.admin.options.reload_dynmap.lore": "Reloads DynMap markers.", "factions.gui.admin.options.reload_dynmap.success": "Reloaded DynMap markers", - "factions.gui.spoof.title": "Specify a player...", "factions.gui.spoof.default": "Player Name", "factions.gui.spoof.fail.invalid_name": "Invalid name %s!", "factions.gui.spoof.fail.no_player": "No such player %s!", "factions.gui.spoof.success": "Set spoof to player %s", - "factions.gui.power.setfaction.title": "Specify a faction...", "factions.gui.power.setfaction.default": "Faction Name", "factions.gui.power.setfaction.fail.no_faction": "No such faction!", @@ -34,7 +32,6 @@ "factions.gui.power.success.removed.admin": "Removed %d power", "factions.gui.power.success.added.faction": "Admin %s added %d power", "factions.gui.power.success.removed.faction": "Admin %s removed %d power", - "factions.gui.info.title": "Faction info", "factions.gui.info.owner": "Owner: ", "factions.gui.info.description": "Description: ", @@ -51,11 +48,9 @@ "factions.gui.info.enemies.some": "Enemy factions (%s): ", "factions.gui.info.settings": "Faction settings", "factions.gui.info.settings.lore": "Click to change settings", - "factions.gui.list.title": "Factions list", "factions.gui.list.entry.view_info": "Click to view faction info.", "factions.gui.list.entry.teleport": "Right-click to teleport to faction home.", - "factions.gui.members.title": "%s members list (%s)", "factions.gui.members.entry.unknown_player": "No info available", "factions.gui.members.entry.info.rank": "Rank: %s", @@ -74,7 +69,6 @@ "factions.gui.members.entry.manage.kick.confirm.no": "Go back", "factions.gui.members.entry.manage.kick.result.actor": "Kicked %s", "factions.gui.members.entry.manage.kick.result.subject": "You have been kicked from the faction by %s", - "factions.gui.modify.title": "Faction settings", "factions.gui.modify.change_name": "Change name", "factions.gui.modify.change_name.input.title": "Specify a name...", @@ -126,14 +120,17 @@ "factions.gui.modify.faction_type": "Faction type: %s", "factions.gui.modify.faction_type.public": "Public", "factions.gui.modify.faction_type.invite": "Invite only", - + "factions.gui.modify.friendly_fire.enabled": "Friendly Fire: Enabled", + "factions.gui.modify.friendly_fire.disabled": "Friendly Fire: Disabled", + "factions.gui.modify.friendly_fire.lore": "Click to toggle friendly fire for your faction", + "factions.command.friendlyfire.success.enabled": "Friendly fire has been enabled for your faction", + "factions.command.friendlyfire.success.disabled": "Friendly fire has been disabled for your faction", "factions.gui.generic.unknown_player": "{Unknown Player}", "factions.gui.generic.close": "Close", "factions.gui.generic.confirm": "Confirm", "factions.gui.generic.back": "Go back", "factions.gui.generic.next_page": "Next page", "factions.gui.generic.previous_page": "Previous page", - "factions.command.claim.list": "You have %s claim(s)", "factions.command.claim.add.fail.already_owned.single": "%s faction already owns this chunk", "factions.command.claim.add.fail.already_owned.single.your": "Your", @@ -156,12 +153,10 @@ "factions.command.claim.set_access_level.fail.min_level": "Cannot decrease access level as it is already at its minimum.", "factions.command.claim.set_access_level.fail.rank_too_low": "Cannot decrease access level from above your rank", "factions.command.claim.set_access_level.success": "Claim (%d, %d) changed to level %s by %s", - "factions.command.create.fail.blacklisted_name": "Cannot create a faction with this name as it is on the blacklist", "factions.command.create.fail.name_too_long": "Cannot create a faction with this name as it is too long", "factions.command.create.fail.name_taken": "Cannot create a faction as a one with that name already exists", "factions.command.create.success": "Successfully created faction", - "factions.command.declare.fail.nonexistent_faction": "Cannot change faction relationship with a faction that doesn't exist", "factions.command.declare.fail.own_faction": "Cannot use the declare command on your own faction", "factions.command.declare.fail.no_change": "That faction relationship has already been declared with this faction", @@ -172,12 +167,10 @@ "factions.command.declare.success.status.ally": "allies", "factions.command.declare.success.status.enemy": "enemies", "factions.command.declare.success.status.neutral": "neutral", - "factions.command.disband.fail.safe_not_empty": "Your faction safe isn't empty.", "factions.command.disband.fail.safe_not_empty.prompt": "\nContinue and move the items to your inventory", "factions.command.disband.fail.safe_not_empty.prompt.hover": "Click to confirm", "factions.command.disband.success": "%s disbanded the faction", - "factions.command.home.warp.fail.no_home": "No faction home set", "factions.command.home.warp.fail.no_world": "Cannot find dimension", "factions.command.home.warp.fail.no_claim": "Cannot warp home to an unclaimed chunk", @@ -185,10 +178,8 @@ "factions.command.home.warp.success": "Warped to faction home", "factions.command.home.fail.no_claim": "Cannot set home to an unclaimed chunk", "factions.command.home.set.success": "Home set to %.2f, %.2f, %.2f by %s", - "factions.command.info.fail.no_faction": "Command can only be used whilst in a faction", "factions.command.info.fail.nonexistent_faction": "Faction does not exist", - "factions.command.invite.list": "You have %s outgoing invite(s)", "factions.command.invite.add.fail.already_invited": "%s was already invited to your faction", "factions.command.invite.add.fail.already_member": "%s is already in your faction", @@ -197,25 +188,20 @@ "factions.command.invite.add.success.subject.hover": "Click to join", "factions.command.invite.remove.success": "%s is no longer invited to your faction", "factions.command.invite.remove.fail": "Could not find invite for %s", - "factions.command.join.fail.nonexistent_faction": "Cannot join faction as none exist with that name", "factions.command.join.fail.private_no_invite": "Cannot join faction as it is not open and you are not invited", "factions.command.join.fail.faction_full": "Cannot join faction as it is currently full", "factions.command.join.success": "%s joined", - "factions.command.kick.fail.self": "Cannot kick yourself", "factions.command.kick.fail.other_faction": "Cannot kick someone that is not in your faction", "factions.command.kick.fail.high_rank": "Cannot kick members with a higher of equivalent rank", "factions.command.kick.success.actor": "Kicked %s", "factions.command.kick.success.subject": "You have been kicked from the faction by %s", - "factions.command.leave.success.actor": "You have left this faction.", "factions.command.leave.success.subject": "%s left", - "factions.command.map.title": "Faction Map", "factions.command.map.you_wilderness": " ", "factions.command.map.you_owner": " %s", - "factions.command.members.fail.no_faction": "Command can only be used whilst in a faction", "factions.command.members.faction.nonexistent_faction": "Faction does not exist", "factions.command.members.faction.title": "Total Members: %s", @@ -223,44 +209,36 @@ "factions.command.members.faction.leaders": "Leaders (%s): %s", "factions.command.members.faction.commanders": "Commanders (%s): %s", "factions.command.members.faction.members": "Members (%s): %s", - "factions.command.modify.name.fail.blacklisted_name": "Cannot rename a faction to that name as it is on the blacklist", "factions.command.modify.name.fail.name_too_long": "Cannot rename a faction to this that as it is too long", "factions.command.modify.name.fail.name_taken": "A faction with that name already exists", "factions.command.modify.open.success": "Successfully updated faction to ", - "factions.command.permissions.change.fail.no_faction": "You must be in a faction and you must provide a valid faction", "factions.command.permissions.change.fail.invalid_permission": "Not a valid permission", "factions.command.permissions.change.fail.already_exists": "Could not change because the permission already exists", "factions.command.permissions.change.fail.doesnt_exist": "Could not change because the permission doesn't exist", "factions.command.permissions.change.success": "Successfully changed permissions", "factions.command.permissions.guest.fail.no_faction": "You must be in a faction", - "factions.command.permissions.list.title": "%s has the permissions: %s", "factions.command.permissions.list_guest.title": "Guests have the permissions: %s", - "factions.command.rank.guest": "guest", "factions.command.rank.member": "member", "factions.command.rank.commander": "commander", "factions.command.rank.leader": "leader", - "factions.command.rank.promote.fail.self": "You cannot promote yourself", "factions.command.rank.promote.fail.not_in_faction": "%s is not in your faction", "factions.command.rank.promote.fail.leader": "You cannot promote a Leader to Owner", "factions.command.rank.promote.fail.owner": "You cannot promote the Owner", "factions.command.rank.promote.success": "Promoted %s to %s", - "factions.command.rank.demote.fail.self": "You cannot demote yourself", "factions.command.rank.demote.fail.not_in_faction": "%s is not in your faction", "factions.command.rank.demote.fail.guest": "You cannot demote a Guest", "factions.command.rank.demote.fail.leader": "You cannot demote a Leader", "factions.command.rank.demote.fail.owner": "You cannot demote the Owner", "factions.command.rank.demote.success": "Demoted %s to %s", - "factions.command.rank.transfer.fail.self": "You cannot transfer ownership to yourself", "factions.command.rank.transfer.fail.not_in_faction": "%s is not in your faction", "factions.command.rank.transfer.success": "Transferred ownership to %s", - "factions.command.settings.chat": "Successfully set your chat preference", "factions.command.settings.chat.faction": "Faction", "factions.command.settings.chat.focus": "Focus", @@ -271,17 +249,14 @@ "factions.command.settings.sound.none": "None", "factions.command.settings.sound.warnings": "Warnings", "factions.command.settings.radar": "Successfully toggled claim radar", - "factions.chat.in_faction_symbol": "F", "factions.chat.faction_chat_when_not_in_faction": "You can't send a message to faction chat if you aren't in a faction.", "factions.chat.faction_chat_when_not_in_faction.hover": "Click to switch to global chat", - "factions.gui.safe.title": "%s's Safe", "factions.events.lose_power_by_death": "%s lost %d power from dying", "factions.events.get_power_by_tick": "%s gained %d power from surviving", "factions.events.no_enderchests_without_faction": "Cannot use enderchests when not in a faction", "factions.events.member_returns": "Welcome back %s!", - "factions.interactions.cannot_do": "Cannot %s here", "factions.interactions.name.break_blocks": "break blocks", "factions.interactions.name.use_blocks": "use blocks", @@ -290,20 +265,16 @@ "factions.interactions.name.attack_entities": "attack entities", "factions.interactions.name.use_entities": "use entities", "factions.interactions.name.use_inventory": "use inventory", - "factions.level.minecraft:overworld": "Overworld", "factions.level.minecraft:the_nether": "The Nether", "factions.level.minecraft:the_end": "The End", - "factions.events.autoclaim.fail": "Not enough faction power to claim chunk, autoclaim toggled off", "factions.events.autoclaim.success": "Chunk (%d, %d) claimed by %s", "factions.radar.wilderness": "Wilderness", - "factions.factionless": "[FACTIONLESS]", "factions.default_description": "No description set", "factions.default_motd": "No faction MOTD set", - "factions.papi.chat.global": "Global Chat", "factions.papi.chat.faction": "Faction Chat", "factions.papi.factionless": "FACTIONLESS" -} +} \ No newline at end of file