Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 102 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,116 @@
# Damage Display

![Logo](./media/logo.png)

A Minecraft Spigot plugin that offers the possibility to keep track of damage dealt and received.
Spigot plugin that shows combat feedback: floating damage/heal numbers and action bar messages.

Requires **Java 21+** and a **26.2** Spigot-compatible server (`api-version: 26.2`).

## Features

- Floating `TextDisplay` holograms on damage (optional heal holograms)
- Action bar for damage dealt and damage taken
- Uses **final damage** (after armor/resistance), not raw damage
- Configurable `&` color formats, TextDisplay style, and rise motion
- Nearby-player gate, concurrent caps, viewer scoping
- `/dd toggle [actionbar|heals]` per-player preferences (YAML)
- GitHub Actions: PR tests + `v*` tag releases

## Installation

1. Download the latest release jar (or build with Maven)
2. Put it in your server `plugins/` folder
3. Restart the server
4. Edit `plugins/DamageDisplay/config.yml` and run `/dd reload`

## Commands

| Command | Permission | Description |
|---------|------------|-------------|
| `/dd help` | `damagedisplay.command.help` | List commands you can use |
| `/dd info` | `damagedisplay.command.info` | Show plugin version and config keys |
| `/dd toggle` | `damagedisplay.command.toggle` | Toggle action bar (same as `actionbar`) |
| `/dd toggle actionbar` | `damagedisplay.command.toggle` | Toggle action bar messages |
| `/dd toggle heals` | `damagedisplay.command.toggle` | Toggle heal holograms for yourself |
| `/dd reload` | `damagedisplay.command.reload` | Reload config and player prefs |

Aliases: `/damagedisplay`

## Permissions

| Permission | Default | Description |
|------------|---------|-------------|
| `damagedisplay.enabled` | true | See action bars and holograms |
| `damagedisplay.command.toggle` | true | Use `/dd toggle` |
| `damagedisplay.command.help` | op | Use `/dd help` |
| `damagedisplay.command.info` | op | Use `/dd info` |
| `damagedisplay.command.reload` | op | Use `/dd reload` |

## Configuration

`plugins/DamageDisplay/config.yml` (defaults below). Colors use legacy `&` codes. Placeholders: `{damage}`, `{cause}`, `{amount}`.

```yaml
actionbar:
damageDealt:
enabled: true
format: "&e★ Damage Dealt: &e{damage}"
damageReceived:
enabled: true
format: "&c☠ Damage Taken: &c{damage}&7 | &7{cause}"

displayText:
enabled: true
lingertime: 10
nearbyRange: 16
onlyFromPlayers: false
maxTotal: 64
maxPerChunk: 8
viewerScoped: true
format: "&c{damage}"
critFormat: "&6✴{damage}"
billboard: VERTICAL
shadow: true
seeThrough: false
background: true
textOpacity: 255
scale: 1.0
motion:
enabled: true
riseBlocks: 0.6

heals:
enabled: false
format: "&a+{amount}"
```

Player toggles are stored in `plugins/DamageDisplay/player-prefs.yml`. An old `cache.dat` is migrated automatically on first load.

## Build

# Features
![Damage Example Showcase](./media/damage_01.png)
- Show a [TextDisplay](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/TextDisplay.html) whenever an entity takes damage
- Send out ActionBar messages to players in regard to damage that has been taken.
- Display an ActionBar message whenever a player has dealt an amount of damage to an entity.
```bash
mvn clean package
```

# Installation
1. Download the latest version of the DamageDisplay plugin
2. Place the downloaded `.jar` file inside of your server's plugins directory
3. Restart your server
Jar: `target/DamageDisplay-<version>.jar`

# Usage
Whenever a player is going to take or deal an amount of damage, an ActionBar message is automatically going to be
shown to the player in question. There is also another case when an entity takes an amount of damage, that damage will
be displayed to anyone looking as a TextDisplay floating near the position that the damage has been taken at.
Tests: `mvn test`

# Permissions
## Releases

### damagedisplay.enabled
- Description: Enables the ActionBar messages for the player
- Default: True
Push a tag on `master`:

### damagedisplay.command.info
- Description: Enables the ActionBar messages for the player
- Default: True
```bash
git tag v1.2.0
git push origin v1.2.0
```

### damagedisplay.command.toggle
- Description: Enables the ActionBar messages for the player
- Default: True
CI runs tests, sets the Maven version from the tag, and publishes the jar on GitHub Releases.

### damagedisplay.command.reload
- Description: Grants permission to /dd reload which will reload the configuration file, so you won't have to reload it
- Default: False
## Support

### damagedisplay.command.help
- Description: Grants permission to /dd help
- Default: False
Bugs and PRs: [GitHub repository](https://github.com/JustKato/DamageDisplay).

# Support & Contribution
In regard to possible bugs that might show up, please open an issue on the [Github Repository](https://github.com/JustKato/DamageDisplay).
Contributions are more than welcome! Fork the repository, make your changes and submit a pull request.
## License

# License
This project is licensed under the [MIT License](./LICENSE)
[MIT License](./LICENSE)
17 changes: 17 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.11.4</junit.version>
<mockito.version>5.20.0</mockito.version>
<adventure.version>4.21.0</adventure.version>
</properties>
<url>https://danlegt.com</url>

Expand Down Expand Up @@ -50,6 +51,10 @@
<pattern>org.bstats</pattern>
<shadedPattern>com.danlegt.util</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori</pattern>
<shadedPattern>com.danlegt.adventure</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
Expand Down Expand Up @@ -94,6 +99,18 @@
<version>3.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>${adventure.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>${adventure.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,67 @@
package com.danlegt.damagedisplay.Commands;

import com.danlegt.damagedisplay.DamageDisplay;
import org.bukkit.ChatColor;
import com.danlegt.damagedisplay.Services.Messages;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;

import java.util.ArrayList;
import java.util.List;

public class CommandManager implements CommandExecutor {
public class CommandManager implements CommandExecutor, TabCompleter {

public static List<DDCommand> registeredCommands = List.of(
new InfoCommand(),
new ToggleCommand(),
new HelpCommand(),
new ReloadCommand()
public static final List<DDCommand> registeredCommands = List.of(
new InfoCommand(),
new ToggleCommand(),
new HelpCommand(),
new ReloadCommand()
);

private static final List<String> TOGGLE_OPTIONS = List.of("actionbar", "heals");

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0) {
sender.sendMessage(ChatColor.RED + "Usage: /dd <info|help|toggle|reload>");
sender.sendMessage(Messages.toLegacy("&cUsage: /dd <info|help|toggle|reload>"));
return true;
}

for ( var cmd: registeredCommands ) {
if ( cmd.getCommandLabel().equalsIgnoreCase(args[0]) ) {
for (var cmd : registeredCommands) {
if (cmd.getCommandLabel().equalsIgnoreCase(args[0])) {
return cmd.handleCommand(sender, command, label, args);
}
}

return false;
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 1) {
String prefix = args[0].toLowerCase();
List<String> completions = new ArrayList<>();
for (DDCommand cmd : registeredCommands) {
String cmdLabel = cmd.getCommandLabel();
if (cmdLabel.startsWith(prefix) && sender.hasPermission(cmd.getPermission())) {
completions.add(cmdLabel);
}
}
return completions;
}

if (args.length == 2 && args[0].equalsIgnoreCase("toggle")
&& sender.hasPermission("damagedisplay.command.toggle")) {
String prefix = args[1].toLowerCase();
List<String> completions = new ArrayList<>();
for (String option : TOGGLE_OPTIONS) {
if (option.startsWith(prefix)) {
completions.add(option);
}
}
return completions;
}

return List.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

public interface DDCommand {

public String getCommandLabel();
String getCommandLabel();

public boolean handleCommand(CommandSender sender, Command command, String label, String[] args);
String getPermission();

public String getDescription();
boolean handleCommand(CommandSender sender, Command command, String label, String[] args);

String getDescription();

}
21 changes: 14 additions & 7 deletions src/main/java/com/danlegt/damagedisplay/Commands/HelpCommand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.danlegt.damagedisplay.Commands;

import org.bukkit.ChatColor;
import com.danlegt.damagedisplay.Services.Messages;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;

Expand All @@ -10,18 +10,25 @@ public String getCommandLabel() {
return "help";
}

@Override
public String getPermission() {
return "damagedisplay.command.help";
}

@Override
public boolean handleCommand(CommandSender sender, Command command, String label, String[] args) {
if ( !sender.hasPermission("damagedisplay.command.help") ) {
sender.sendMessage(ChatColor.RED + "You do not have permission to use this command.");
if (!sender.hasPermission(getPermission())) {
sender.sendMessage(Messages.toLegacy("&cYou do not have permission to use this command."));
return true;
}

sender.sendMessage(ChatColor.GRAY + "====================");
CommandManager.registeredCommands.forEach( cmd -> {
sender.sendMessage(ChatColor.GOLD + "/dd " + cmd.getCommandLabel() + ChatColor.GRAY + " - " + ChatColor.RESET + cmd.getDescription());
sender.sendMessage(Messages.toLegacy("&8===================="));
CommandManager.registeredCommands.forEach(cmd -> {
if (sender.hasPermission(cmd.getPermission())) {
sender.sendMessage(Messages.toLegacy("&6/dd " + cmd.getCommandLabel() + " &7- &f" + cmd.getDescription()));
}
});
sender.sendMessage(ChatColor.GRAY + "====================");
sender.sendMessage(Messages.toLegacy("&8===================="));

return true;
}
Expand Down
35 changes: 17 additions & 18 deletions src/main/java/com/danlegt/damagedisplay/Commands/InfoCommand.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
package com.danlegt.damagedisplay.Commands;

import com.danlegt.damagedisplay.DamageDisplay;
import org.bukkit.ChatColor;
import com.danlegt.damagedisplay.Services.Messages;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;

import java.util.List;
import java.util.Objects;

public class InfoCommand implements DDCommand{
public class InfoCommand implements DDCommand {

@Override
public String getCommandLabel() {
return "info";
}

@Override
public String getPermission() {
return "damagedisplay.command.info";
}

@Override
public boolean handleCommand(CommandSender sender, Command command, String label, String[] args) {
if ( !sender.hasPermission("damagedisplay.command.info") ) {
sender.sendMessage(ChatColor.RED + "You do not have permission to use this command.");
if (!sender.hasPermission(getPermission())) {
sender.sendMessage(Messages.toLegacy("&cYou do not have permission to use this command."));
return true;
}

FileConfiguration config = DamageDisplay.me.getConfig();
sender.sendMessage(ChatColor.GREEN + "DamageDisplay (" + ChatColor.AQUA + DamageDisplay.me.getDescription().getVersion() + ChatColor.GREEN + ")");
sender.sendMessage(Messages.toLegacy(
"&aDamageDisplay (&b" + DamageDisplay.me.getDescription().getVersion() + "&a)"
));
for (String key : config.getKeys(true)) {
var val = config.get(key);
if ( val == null ) {
val = "";
Object val = config.get(key);
if (val == null) {
continue;
}

if ( val instanceof Boolean v) {
val = v ? "True" : "False";
}

if ( val instanceof String || val instanceof Integer || val instanceof Float || val instanceof Double ) {
sender.sendMessage(ChatColor.GOLD + key + ChatColor.GRAY + ": " + ChatColor.WHITE + config.get(key));
if (val instanceof Boolean || val instanceof String || val instanceof Number) {
sender.sendMessage(Messages.toLegacy("&6" + key + "&7: &f" + val));
}
}

Expand All @@ -47,5 +47,4 @@ public boolean handleCommand(CommandSender sender, Command command, String label
public String getDescription() {
return "Retrieve information about the plugin";
}

}
Loading
Loading