Skip to content

Commit

Permalink
Added a soulbound feature for items
Browse files Browse the repository at this point in the history
PR #286
  • Loading branch information
CraftedMods authored Oct 7, 2018
1 parent fe22316 commit aed730a
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 1.5.0-BETA
### General changes:
* Added a `soulbound` command which marks items as soulbound, preventing them from being dropped on death

### Deathcraft compatibility:
* Fixed a crash occurring when a player dies with empty inventory
Expand Down
43 changes: 35 additions & 8 deletions src/main/java/pvpmode/ChatUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,22 @@ public static void postLocalChatMessages (ICommandSender recipient, EnumChatForm
{
for (String line : message.split ("\n"))
{
ChatComponentText text = new ChatComponentText (line);
text.getChatStyle ().setColor (color);
recipient.addChatMessage (text);
ChatComponentText root = null;
for (String part : line.split ("§r"))
{
ChatComponentText text = new ChatComponentText (part);
text.getChatStyle ().setColor (color);
if (root == null)
{
root = text;
}
else
{
root.appendSibling (text);
}
}
if (root != null)
recipient.addChatMessage (root);
}
}
}
Expand Down Expand Up @@ -103,11 +116,25 @@ public static void postGlobalChatMessages (EnumChatFormatting color,
{
for (String line : message.split ("\n"))
{
ChatComponentText prefix = new ChatComponentText (
PvPMode.prefixGlobalMessages ? PvPMode.globalMessagePrefix : "");
ChatComponentText text = new ChatComponentText (line);
text.getChatStyle ().setColor (color);
PvPMode.cfg.sendChatMsg (prefix.appendSibling (text));
ChatComponentText root = null;
for (String part : line.split ("§r"))
{
ChatComponentText text = new ChatComponentText (part);
text.getChatStyle ().setColor (color);
if (root == null)
{
ChatComponentText prefix = new ChatComponentText (
PvPMode.prefixGlobalMessages ? PvPMode.globalMessagePrefix : "");
prefix.appendSibling (text);
root = prefix;
}
else
{
root.appendSibling (text);
}
}
if (root != null)
PvPMode.cfg.sendChatMsg (root);
}
}
}
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/pvpmode/PvPEventHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.*;
import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.*;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.entity.living.*;
import net.minecraftforge.event.entity.player.*;
import pvpmode.compatibility.events.*;
import pvpmode.compatibility.events.PartialItemDropEvent.Drop.Action;
import pvpmode.compatibility.events.PartialItemDropEvent.EnumInventory;
Expand Down Expand Up @@ -488,6 +491,55 @@ public void onCommandExecution (CommandEvent event)
}
}

private Map<EntityPlayer, Collection<ItemStack>> soulboundItems = new HashMap<> ();

@SubscribeEvent
public void onPlayerDrops (PlayerDropsEvent event)
{
if (PvPMode.soulboundItemsEnabled)
{
ListIterator<EntityItem> drops = event.drops.listIterator ();
while (drops.hasNext ())
{
ItemStack drop = drops.next ().getEntityItem ();
if (PvPUtils.isSoulbound (drop))
{
drops.remove ();
if (soulboundItems.containsKey (event.entityPlayer))
{
soulboundItems.put (event.entityPlayer, new ArrayList<> ());
}
soulboundItems.get (event.entityPlayer).add (drop);
}
}
}
}

@SubscribeEvent
public void onPlayerRespawn (PlayerRespawnEvent event)
{
if (PvPMode.soulboundItemsEnabled && soulboundItems.containsKey (event.player))
{
soulboundItems.get (event.player).forEach (event.player.inventory::addItemStackToInventory);
soulboundItems.remove (event.player);
}
}

@SubscribeEvent
public void onPartialItemLoss (PartialItemLossEvent event)
{
event.setCanceled (PvPMode.soulboundItemsEnabled && PvPUtils.isSoulbound (event.getStack ()));
}

// @SubscribeEvent
// public void onItemTooltip (ItemTooltipEvent event)
// {
// if (PvPUtils.isSoulbound (event.itemStack) && PvPMode.soulboundItemsEnabled)
// {
// event.toolTip.add (PvPMode.soulboundTooltip);
// }
// }TODO: clientside mod

public static void init ()
{
INSTANCE = new PvPEventHandler ();
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/pvpmode/PvPMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public class PvPMode
public static boolean announcePvPEnabledGlobally;
public static boolean announcePvPDisabledGlobally;

public static boolean soulboundItemsEnabled;
public static String soulboundTooltip;

public static final String MAIN_CONFIGURATION_CATEGORY = "MAIN";
public static final String CSV_COMBAT_LOGGING_CONFIGURATION_CATEGORY = "PVP_LOGGING_CSV";
public static final String PARTIAL_INVENTORY_LOSS_CONFIGURATION_CATEGORY = "PARTIAL_INVENTORY_LOSS";
Expand All @@ -74,6 +77,9 @@ public class PvPMode
public static PvPCommandConfig pvpconfigCommandInstance;
public static PvPCommandHelp pvphelpCommandInstance;
public static PvPCommandList pvplistCommandInstance;
public static SoulboundCommand soulboundCommandInstance;

public static final String DEFAULT_SOULBOUND_TOOLTIP = "\u00A7r\u00A78[\u00A75Soulbound\u00A7r\u00A78]";

@EventHandler
public void preinit (FMLPreInitializationEvent event) throws IOException
Expand Down Expand Up @@ -166,6 +172,13 @@ public void preinit (FMLPreInitializationEvent event) throws IOException
announcePvPDisabledGlobally = config.getBoolean ("Announce PvP Disabled Globally", MAIN_CONFIGURATION_CATEGORY,
false, "Sends a message to all players if PvP is disabled for a player.");

soulboundItemsEnabled = config.getBoolean ("Enable Soulbound Items",
MAIN_CONFIGURATION_CATEGORY, true,
"If true, the soulbound command of the PvP Mode Mod will be enabled and items marked as soulbound won't be dropped. If SuffixForge is present, the soulbound command will be disabled.");
soulboundTooltip = config.getString ("Soulbound Item Tooltip", MAIN_CONFIGURATION_CATEGORY,
DEFAULT_SOULBOUND_TOOLTIP,
"The tooltip shown for soulbound items. It musn't be blank. You can use the MC formatting codes to format the tooltip.");

config.addCustomCategoryComment (MAIN_CONFIGURATION_CATEGORY, "General configuration entries");
config.addCustomCategoryComment (CSV_COMBAT_LOGGING_CONFIGURATION_CATEGORY,
"Configuration entries related to the CSV combat logging handler");
Expand Down Expand Up @@ -203,6 +216,18 @@ public void preinit (FMLPreInitializationEvent event) throws IOException
"The configuration property 'Force Default PvP Mode' is set to true but 'Pvp Toggeling Enabled' is set to false, but required to be set to true.");
}

if (Loader.isModLoaded ("suffixforge"))
{
soulboundItemsEnabled = false;
FMLLog.info ("SuffixForge is present - the soulbound command will be disabled");
}

if (soulboundTooltip.trim ().isEmpty ())
{
soulboundTooltip = DEFAULT_SOULBOUND_TOOLTIP;
FMLLog.warning ("The soulbound tooltip is empty. A default one will be used.");
}

if (config.hasChanged ())
{
config.save ();
Expand Down Expand Up @@ -292,13 +317,19 @@ public void serverLoad (FMLServerStartingEvent event)
pvpadminCommandInstance = new PvPCommandAdmin ();
pvphelpCommandInstance = new PvPCommandHelp ();
pvpconfigCommandInstance = new PvPCommandConfig ();
soulboundCommandInstance = new SoulboundCommand ();

event.registerServerCommand (pvpCommandInstance);
event.registerServerCommand (pvplistCommandInstance);
event.registerServerCommand (pvpadminCommandInstance);
event.registerServerCommand (pvphelpCommandInstance);
event.registerServerCommand (pvpconfigCommandInstance);

if (soulboundItemsEnabled)
{
event.registerServerCommand (soulboundCommandInstance);// TODO: Can be done with the compatibility module
}

if (!compatibilityManager.areModulesLoaded ())
{
compatibilityManager.loadRegisteredModules ();
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/pvpmode/PvPUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -509,4 +509,10 @@ private static <K> K getUnmodifiableObject (K object)
return (K) deepUnmodifiableCollection ((Collection<?>) object);
return object;
}
}

public static boolean isSoulbound (ItemStack stack)
{
return stack.hasTagCompound () && stack.getTagCompound ().getBoolean ("SoulboundBool");
}

}
19 changes: 17 additions & 2 deletions src/main/java/pvpmode/command/PvPCommandHelp.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.*;
import java.util.function.Function;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Triple;

import net.minecraft.command.ICommandSender;
Expand Down Expand Up @@ -69,6 +70,8 @@ public void processCommand (ICommandSender sender, String[] args)
ChatUtils.blue (sender, "# Admin commands");
postShortCommandHelp (sender, PvPMode.pvpadminCommandInstance);
postShortCommandHelp (sender, PvPMode.pvpconfigCommandInstance);
if (PvPMode.soulboundItemsEnabled)
postShortCommandHelp (sender, PvPMode.soulboundCommandInstance);
ChatUtils.green (sender, "-------------------------");
}
else
Expand All @@ -91,6 +94,12 @@ public void processCommand (ICommandSender sender, String[] args)
case "pvphelp":
postLongCommandHelp (sender, PvPMode.pvphelpCommandInstance);
break;
case "soulbound":
if (PvPMode.soulboundItemsEnabled)
{
postLongCommandHelp (sender, PvPMode.soulboundCommandInstance);
break;
}
default:
ChatUtils.red (sender,
String.format ("The command \"%s\" doesn't exist or isn't a command of PvP Mode", command));
Expand Down Expand Up @@ -167,8 +176,14 @@ private void postCommandHelp (ICommandSender sender, String commandName, String
public List<?> addTabCompletionOptions (ICommandSender sender, String[] args)
{
if (args.length == 1)
return getListOfStringsMatchingLastWord (args, "pvp", "pvpadmin", "pvplist", "pvphelp",
"pvpconfig");
{
String[] commands =
{"pvp", "pvpadmin", "pvplist", "pvphelp",
"pvpconfig"};
if (PvPMode.soulboundItemsEnabled)
commands = ArrayUtils.add (commands, "soulbound");
return getListOfStringsMatchingLastWord (args, commands);
}
return null;
}
}
Loading

0 comments on commit aed730a

Please sign in to comment.