Skip to content

Commit

Permalink
MapText custom font support (#2596)
Browse files Browse the repository at this point in the history
* `MapText` custom font support

* Meta fixes

* Update meta example to modern tag
  • Loading branch information
tal5 committed Feb 14, 2024
1 parent 915219b commit d273f91
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 25 deletions.
Expand Up @@ -182,7 +182,7 @@ public void execute(ScriptEntry scriptEntry) {
}
if (text != null) {
DenizenMapRenderer dmr = DenizenMapManager.getDenizenRenderer(map);
dmr.addObject(new MapText(x.asString(), y.asString(), "true", false, text.asString(), null));
dmr.addObject(new MapText(x.asString(), y.asString(), "true", false, text.asString(), null, null, null, null));
dmr.hasChanged = true;
}
}
Expand Down
Expand Up @@ -60,17 +60,23 @@ public MapScriptContainer(YamlConfiguration configurationSection, String scriptC
// # Optionally add width/height numbers.
// width: 128
// height: 128
// # Specify a tag to show or hide custom content! Valid for all objects.
// # Note that all inputs other than 'type' for all objects support tags that will be dynamically reparsed per-player each time the map updates.
// visible: <player.name.contains_text[bob].not>
//
// 2:
// type: text
// # Specify any text to display. Color codes not permitted (unless you know how to format CraftMapCanvas byte-ID color codes).
// text: Hello <player.name>
// # Specify the color of the text as any valid ColorTag.
// color: red
// # Specify a tag to show or hide custom content! Valid for all objects.
// # Note that all inputs other than 'type' for all objects support tags that will be dynamically reparsed per-player each time the map updates.
// visible: <player.name.contains[bob].not>
//
// # | Optionally, specify the following additional options:
// # Specify a font to use, which allows using special characters/other languages the default font may not support.
// font: arial
// # Specify a text size (only available with a custom font).
// size: 18
// # Specify a style, as a list that contains either "bold", "italic", or both (only available with a custom font).
// style: bold|italic
// 3:
// type: cursor
// # Specify a cursor type
Expand Down Expand Up @@ -142,8 +148,8 @@ public void applyTo(MapView mapView) {
+ "' has no specified text!");
return;
}
String text = objectSection.getString("text");
added = new MapText(x, y, visible, shouldDebug(), text, objectSection.getString("color", "black"));
added = new MapText(x, y, visible, shouldDebug(), objectSection.getString("text"), objectSection.getString("color", "black"),
objectSection.getString("font"), objectSection.getString("size"), objectSection.getString("style"));
break;
case "cursor":
if (!objectSection.contains("cursor")) {
Expand Down
Expand Up @@ -72,32 +72,34 @@ public static void reloadMaps() {
List<String> objects = new ArrayList<>(objectsData.getKeys(false));
objects.sort(new NaturalOrderComparator());
for (String objectKey : objects) {
String type = objectsData.getString(objectKey + ".type").toUpperCase();
String xTag = objectsData.getString(objectKey + ".x");
String yTag = objectsData.getString(objectKey + ".y");
String visibilityTag = objectsData.getString(objectKey + ".visibility");
boolean debug = objectsData.getString(objectKey + ".debug", "false").equalsIgnoreCase("true");
ConfigurationSection objectConfig = objectsData.getConfigurationSection(objectKey);
String type = objectConfig.getString("type").toUpperCase();
String xTag = objectConfig.getString("x");
String yTag = objectConfig.getString("y");
String visibilityTag = objectConfig.getString("visibility");
boolean debug = objectConfig.getString("debug", "false").equalsIgnoreCase("true");
MapObject object = null;
switch (type) {
case "CURSOR":
object = new MapCursor(xTag, yTag, visibilityTag, debug, objectsData.getString(objectKey + ".direction"), objectsData.getString(objectKey + ".cursor"));
object = new MapCursor(xTag, yTag, visibilityTag, debug, objectConfig.getString("direction"), objectConfig.getString("cursor"));
break;
case "IMAGE":
String file = objectsData.getString(objectKey + ".image");
int width = objectsData.getInt(objectKey + ".width", 0);
int height = objectsData.getInt(objectKey + ".height", 0);
String file = objectConfig.getString("image");
int width = objectConfig.getInt("width", 0);
int height = objectConfig.getInt("height", 0);
object = new MapImage(renderer, xTag, yTag, visibilityTag, debug, file, width, height);
break;
case "TEXT":
object = new MapText(xTag, yTag, visibilityTag, debug, objectsData.getString(objectKey + ".text"), objectsData.getString(objectKey + ".color"));
object = new MapText(xTag, yTag, visibilityTag, debug, objectConfig.getString("text"), objectConfig.getString("color"),
objectConfig.getString("font"), objectConfig.getString("size"), objectConfig.getString("style"));
break;
case "DOT":
object = new MapDot(xTag, yTag, visibilityTag, debug, objectsData.getString(objectKey + ".radius"), objectsData.getString(objectKey + ".color"));
object = new MapDot(xTag, yTag, visibilityTag, debug, objectConfig.getString("radius"), objectConfig.getString("color"));
break;
}
if (object != null) {
object.worldCoordinates = objectsData.getString(objectKey + ".world_coordinates", "false").equalsIgnoreCase("true");
object.showPastEdge = objectsData.getString(objectKey + ".show_past_edge", "false").equalsIgnoreCase("true");
object.worldCoordinates = objectConfig.getString("world_coordinates", "false").equalsIgnoreCase("true");
object.showPastEdge = objectConfig.getString("show_past_edge", "false").equalsIgnoreCase("true");
renderer.addObject(object);
}
}
Expand Down
Expand Up @@ -2,24 +2,33 @@

import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizencore.objects.core.ColorTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.tags.TagContext;
import com.denizenscript.denizencore.tags.TagManager;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.denizenscript.denizencore.utilities.debugging.Debug;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapView;
import org.bukkit.map.MinecraftFont;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class MapText extends MapObject {

protected String textTag, colorTag;
protected String textTag, colorTag, fontTag, sizeTag, styleTag;
protected Map<UUID, String> playerTexts = new HashMap<>();

public MapText(String xTag, String yTag, String visibilityTag, boolean debug, String textTag, String colorTag) {
public MapText(String xTag, String yTag, String visibilityTag, boolean debug, String textTag, String colorTag, String fontTag, String sizeTag, String styleTag) {
super(xTag, yTag, visibilityTag, debug);
this.textTag = textTag;
this.colorTag = colorTag;
this.fontTag = fontTag;
this.sizeTag = sizeTag;
this.styleTag = styleTag;
}

@Override
Expand All @@ -42,6 +51,9 @@ public Map<String, Object> getSaveData() {
data.put("type", "TEXT");
data.put("text", textTag);
data.put("color", colorTag);
data.put("font", fontTag);
data.put("size", sizeTag);
data.put("style", styleTag);
return data;
}

Expand All @@ -52,9 +64,35 @@ public void render(MapView mapView, MapCanvas mapCanvas, PlayerTag player, UUID
playerTexts.put(uuid, tag(textTag, player));
}
ColorTag color = ColorTag.valueOf(colorTag == null ? "black" : tag(colorTag, player), getTagContext(player));
byte b = MapImage.matchColor(color.getAWTColor());
String text = ((char) 167) + Byte.toString(b) + ((char) 59) + getText(player);
mapCanvas.drawText(getX(player), getY(player), MinecraftFont.Font, text);
if (fontTag == null) {
byte b = MapImage.matchColor(color.getAWTColor());
String text = ((char) 167) + Byte.toString(b) + ((char) 59) + getText(player);
mapCanvas.drawText(getX(player), getY(player), MinecraftFont.Font, text);
return;
}
int style = Font.PLAIN;
if (styleTag != null) {
TagContext context = getTagContext(player);
ListTag styles = TagManager.tagObject(styleTag, context).asType(ListTag.class, context);
for (String styleStr : styles) {
String styleLower = CoreUtilities.toLowerCase(styleStr);
switch (styleLower) {
case "bold" -> style |= Font.BOLD;
case "italic" -> style |= Font.ITALIC;
}
}
}
int size = sizeTag != null ? TagManager.tagObject(sizeTag, getTagContext(player)).asElement().asInt() : 10;
BufferedImage image = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
graphics.setFont(new Font(tag(fontTag, player), style, size));
graphics.setColor(color.getAWTColor());
FontMetrics metrics = graphics.getFontMetrics();
int y = getY(player) + metrics.getAscent() - metrics.getDescent() - metrics.getLeading();
graphics.drawString(getText(player), getX(player), y);
graphics.dispose();
mapCanvas.drawImage(0, 0, image);

}
catch (Throwable ex) {
Debug.echoError(ex);
Expand Down

0 comments on commit d273f91

Please sign in to comment.