Skip to content
This repository has been archived by the owner on Apr 12, 2022. It is now read-only.

Commit

Permalink
Advancement Scripts and Commands
Browse files Browse the repository at this point in the history
Lacks additional testing, some polishing and some documentation. Also lacks commands for Score-type advancement criteria., but it's a start!
  • Loading branch information
Xenmai committed Feb 6, 2018
1 parent 2078a89 commit e39b046
Show file tree
Hide file tree
Showing 5 changed files with 345 additions and 1 deletion.
Expand Up @@ -26,6 +26,7 @@
import com.denizenscript.denizen2sponge.spongecommands.ExCommand;
import com.denizenscript.denizen2sponge.spongeevents.Denizen2SpongeLoadedEvent;
import com.denizenscript.denizen2sponge.spongeevents.Denizen2SpongeLoadingEvent;
import com.denizenscript.denizen2sponge.spongescripts.AdvancementScript;
import com.denizenscript.denizen2sponge.spongescripts.GameCommandScript;
import com.denizenscript.denizen2sponge.tags.handlers.*;
import com.denizenscript.denizen2sponge.tags.objects.*;
Expand Down Expand Up @@ -155,11 +156,13 @@ public void onServerStart(GamePreInitializationEvent event) {
Denizen2Core.register(new FeedCommand());
Denizen2Core.register(new GamemodeCommand());
Denizen2Core.register(new GiveCommand());
Denizen2Core.register(new GrantAdvancementCommand());
Denizen2Core.register(new HotbarCommand());
Denizen2Core.register(new KickCommand());
Denizen2Core.register(new NarrateCommand());
Denizen2Core.register(new PardonCommand());
Denizen2Core.register(new RemoveBossBarCommand());
Denizen2Core.register(new RevokeAdvancementCommand());
Denizen2Core.register(new TabListCommand());
Denizen2Core.register(new TakeCommand());
Denizen2Core.register(new TellCommand());
Expand Down Expand Up @@ -249,6 +252,7 @@ public void onServerStart(GamePreInitializationEvent event) {
Denizen2Core.register(new WorldTagBase());
// Sponge Script Types
Denizen2Core.register("command", GameCommandScript::new);
Denizen2Core.register("advancement", AdvancementScript::new);
// Tag Types
Denizen2Core.customSaveLoaders.put("BlockTypeTag", BlockTypeTag::getFor);
Denizen2Core.customSaveLoaders.put("CuboidTag", CuboidTag::getFor);
Expand Down
@@ -0,0 +1,66 @@
package com.denizenscript.denizen2sponge.commands.player;

import com.denizenscript.denizen2core.commands.AbstractCommand;
import com.denizenscript.denizen2core.commands.CommandEntry;
import com.denizenscript.denizen2core.commands.CommandQueue;
import com.denizenscript.denizen2core.utilities.debugging.ColorSet;
import com.denizenscript.denizen2core.utilities.debugging.Debug;
import com.denizenscript.denizen2sponge.tags.objects.PlayerTag;
import com.denizenscript.denizen2sponge.utilities.Utilities;
import org.spongepowered.api.advancement.Advancement;

public class GrantAdvancementCommand extends AbstractCommand {

// <--[command]
// @Since 0.4.0
// @Name grantadvancement
// @Arguments <player> <advancement id>
// @Short grants an advancement to a player.
// @Updated 2018/02/06
// @Group Player
// @Minimum 2
// @Maximum 2
// @Description
// Grants an advancement to a player.
// @Example
// # This example grants the advancement "iron_man" to the player.
// - grantadvancement <player> iron_man
// -->

@Override
public String getName() {
return "grantadvancement";
}

@Override
public String getArguments() {
return "<player> <advancement id>";
}

@Override
public int getMinimumArguments() {
return 2;
}

@Override
public int getMaximumArguments() {
return 2;
}

@Override
public void execute(CommandQueue queue, CommandEntry entry) {
PlayerTag player = PlayerTag.getFor(queue.error, entry.getArgumentObject(queue, 0));
String id = entry.getArgumentObject(queue, 1).toString();
Advancement advancement = (Advancement) Utilities.getTypeWithDefaultPrefix(Advancement.class, id);
if (advancement == null) {
Debug.error("There's no registered advancement that matches the specified id!");
return;
}
player.getOnline(queue.error).getProgress(advancement).grant();
if (queue.shouldShowGood()) {
queue.outGood("Granting advancement '" + ColorSet.emphasis + advancement.getId()
+ ColorSet.good + "' to player '" + ColorSet.emphasis + player.debug()
+ ColorSet.good + "'!");
}
}
}
@@ -0,0 +1,66 @@
package com.denizenscript.denizen2sponge.commands.player;

import com.denizenscript.denizen2core.commands.AbstractCommand;
import com.denizenscript.denizen2core.commands.CommandEntry;
import com.denizenscript.denizen2core.commands.CommandQueue;
import com.denizenscript.denizen2core.utilities.debugging.ColorSet;
import com.denizenscript.denizen2core.utilities.debugging.Debug;
import com.denizenscript.denizen2sponge.tags.objects.PlayerTag;
import com.denizenscript.denizen2sponge.utilities.Utilities;
import org.spongepowered.api.advancement.Advancement;

public class RevokeAdvancementCommand extends AbstractCommand {

// <--[command]
// @Since 0.4.0
// @Name revokeadvancement
// @Arguments <player> <advancement id>
// @Short revokes an advancement from a player.
// @Updated 2018/02/06
// @Group Player
// @Minimum 2
// @Maximum 2
// @Description
// Revokes an advancement from a player.
// @Example
// # This example revokes the advancement "iron_man" from the player.
// - revokeadvancement <player> iron_man
// -->

@Override
public String getName() {
return "revokeadvancement";
}

@Override
public String getArguments() {
return "<player> <advancement id>";
}

@Override
public int getMinimumArguments() {
return 2;
}

@Override
public int getMaximumArguments() {
return 2;
}

@Override
public void execute(CommandQueue queue, CommandEntry entry) {
PlayerTag player = PlayerTag.getFor(queue.error, entry.getArgumentObject(queue, 0));
String id = entry.getArgumentObject(queue, 1).toString();
Advancement advancement = (Advancement) Utilities.getTypeWithDefaultPrefix(Advancement.class, id);
if (advancement == null) {
Debug.error("There's no registered advancement that matches the specified id!");
return;
}
player.getOnline(queue.error).getProgress(advancement).revoke();
if (queue.shouldShowGood()) {
queue.outGood("Revoking advancement '" + ColorSet.emphasis + advancement.getId()
+ ColorSet.good + "' from player '" + ColorSet.emphasis + player.debug()
+ ColorSet.good + "'!");
}
}
}
@@ -0,0 +1,195 @@
package com.denizenscript.denizen2sponge.spongescripts;

import com.denizenscript.denizen2core.Denizen2Core;
import com.denizenscript.denizen2core.commands.CommandQueue;
import com.denizenscript.denizen2core.scripts.CommandScript;
import com.denizenscript.denizen2core.tags.AbstractTagObject;
import com.denizenscript.denizen2core.tags.objects.BooleanTag;
import com.denizenscript.denizen2core.tags.objects.IntegerTag;
import com.denizenscript.denizen2core.tags.objects.NumberTag;
import com.denizenscript.denizen2core.utilities.debugging.ColorSet;
import com.denizenscript.denizen2core.utilities.debugging.Debug;
import com.denizenscript.denizen2core.utilities.yaml.StringHolder;
import com.denizenscript.denizen2core.utilities.yaml.YAMLConfiguration;
import com.denizenscript.denizen2sponge.Denizen2Sponge;
import com.denizenscript.denizen2sponge.tags.objects.FormattedTextTag;
import com.denizenscript.denizen2sponge.tags.objects.ItemTypeTag;
import com.denizenscript.denizen2sponge.utilities.Utilities;
import com.flowpowered.math.vector.Vector2d;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.advancement.*;
import org.spongepowered.api.advancement.criteria.AdvancementCriterion;
import org.spongepowered.api.advancement.criteria.ScoreAdvancementCriterion;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.advancement.AdvancementTreeEvent;
import org.spongepowered.api.event.game.GameRegistryEvent;

import java.util.HashMap;
import java.util.Optional;

public class AdvancementScript extends CommandScript {

public static HashMap<String, AdvancementScript> currentAdvancementScripts = new HashMap<>();

// <--[explanation]
// @Since 0.4.0
// @Name Advancement Scripts
// @Group Script Types
// @Description
// An advancement script is a script that adds new advancements to the server.
// It is identified with the type "advancement".
// Expected keys: id (string), name (string, optional), criteria (map), display
// (advancement type), title (FormattedTextTag), description (FormattedTextTag),
// announce (boolean), show_toast (boolean), hidden (boolean), icon (item type),
// parent (id, only for children advancements), tree_id (string, only for root
// advancements), tree_name (string, only for root advancements, optional),
// position_x (number), and position_y (number).
// TODO: Add "Related information" such as criteria formatting, advancement types and examples.
// -->

public AdvancementScript(String name, YAMLConfiguration section) {
super(name, section);
}

@Override
public boolean isExecutable(String section) {
return false;
}

@Override
public boolean init() {
if (super.init()) {
register();
return true;
}
return false;
}

public Advancement advancement;

public AdvancementTree tree = null;

public Vector2d position;

public void register() {
Sponge.getEventManager().registerListeners(Denizen2Sponge.instance, this);
String id = contents.getString("id");
if (Denizen2Core.getImplementation().generalDebug()) {
Debug.good("Registering advancement script " + ColorSet.emphasis + id
+ ColorSet.good + " to Denizen2Sponge...");
}
Advancement.Builder builder = Advancement.builder().id(id);
if (contents.contains("name")) {
builder.name(contents.getString("name"));
}
AdvancementCriterion criterion = AdvancementCriterion.EMPTY;
YAMLConfiguration criteria = contents.getConfigurationSection("criteria");
for (StringHolder strh : criteria.getKeys(false)) {
String critNumber = strh.low;
String critName = criteria.getString(critNumber + ".name");
AdvancementCriterion.BaseBuilder<?, ?> toAdd = AdvancementCriterion.builder().name(critName);
if (criteria.contains(critName + ".score")) {
boolean score = BooleanTag.getFor(Debug::error,
criteria.getString(critName + ".score")).getInternal();
if (score) {
IntegerTag goal = IntegerTag.getFor(Debug::error,
criteria.getString(critName + ".goal"));
((ScoreAdvancementCriterion.Builder) toAdd).goal((int) goal.getInternal());
}
}
criterion = criterion.and(toAdd.build());
}
builder.criterion(criterion);
String typeId = contents.getString("display");
Optional<AdvancementType> type = Sponge.getRegistry().getType(AdvancementType.class, typeId);
if (!type.isPresent()) {
Debug.error("The display specified is not a valid advancement type!");
return;
}
DisplayInfo.Builder info = DisplayInfo.builder().type(type.get());
AbstractTagObject title = Denizen2Core.splitToArgument(
contents.getString("title"), false, false, Debug::error)
.parse(new CommandQueue(), new HashMap<>(), getDebugMode(), Debug::error);
if (title instanceof FormattedTextTag) {
info.title(((FormattedTextTag) title).getInternal());
}
else {
info.title(Denizen2Sponge.parseColor(title.toString()));
}
AbstractTagObject desc = Denizen2Core.splitToArgument(
contents.getString("description"), false, false, Debug::error)
.parse(new CommandQueue(), new HashMap<>(), getDebugMode(), Debug::error);
if (desc instanceof FormattedTextTag) {
info.title(((FormattedTextTag) desc).getInternal());
}
else {
info.title(Denizen2Sponge.parseColor(desc.toString()));
}
BooleanTag announce = BooleanTag.getFor(Debug::error, contents.getString("announce"));
info.announceToChat(announce.getInternal());
BooleanTag show = BooleanTag.getFor(Debug::error, contents.getString("show_toast"));
info.showToast(show.getInternal());
BooleanTag hidden = BooleanTag.getFor(Debug::error, contents.getString("hidden"));
info.hidden(hidden.getInternal());
ItemTypeTag icon = ItemTypeTag.getFor(Debug::error, contents.getString("icon"));
info.icon(icon.getInternal());
builder.displayInfo(info.build());
if (criteria.contains("parent")) {
String parentId = contents.getString("parent");
Advancement parent = (Advancement) Utilities.getTypeWithDefaultPrefix(Advancement.class, parentId);
if (parent == null) {
Debug.error("There's no registered advancement for the parent id specified!");
return;
}
builder.parent(parent);
advancement = builder.build();
}
else {
advancement = builder.build();
String treeId = contents.getString("tree_id");
AdvancementTree.Builder treeBuilder = AdvancementTree.builder().id(treeId);
if (contents.contains("tree_name")) {
treeBuilder.name(contents.getString("tree_name"));
}
if (contents.contains("tree_background")) {
treeBuilder.background(contents.getString("tree_background"));
}
treeBuilder.rootAdvancement(advancement);
tree = treeBuilder.build();
}
currentAdvancementScripts.put(id, this);
NumberTag x = NumberTag.getFor(Debug::error, contents.getString("x_position"));
NumberTag y = NumberTag.getFor(Debug::error, contents.getString("y_position"));
position = new Vector2d(x.getInternal(), y.getInternal());
}

public boolean isTreeRoot() {
return tree != null;
}

@Listener
public void onRegisterAdvancementTrees(GameRegistryEvent.Register<AdvancementTree> event) {
if (isTreeRoot()) {
event.register(tree);
Debug.good("Registering advancement tree '" + tree.getId() + "' to Sponge...");
}
}

@Listener
public void onRegisterAdvancements(GameRegistryEvent.Register<Advancement> event) {
event.register(advancement);
Debug.good("Registering advancement '" + advancement.getId() + "' to Sponge...");
}

@Listener
public void onGenerateTreeLayout(AdvancementTreeEvent.GenerateLayout event) {
if (isTreeRoot() && event.getTree() == tree) {
for (TreeLayoutElement element : event.getLayout().getElements()) {
Vector2d pos = currentAdvancementScripts
.get(Utilities.getIdWithoutDefaultPrefix(element.getAdvancement().getId())).position;
element.setPosition(pos);
}
Debug.good("Updating layout for tree '" + tree.getId() + "'...");
}
}
}
Expand Up @@ -40,7 +40,16 @@ public static boolean flagIsValidAndNotExpired(Action<String> error, MapTag flag
}

public static String getIdWithoutDefaultPrefix(String id) {
return id.startsWith("minecraft:") ? id.substring("minecraft:".length()) : id;
if (id.startsWith("minecraft")) {
return id.substring("minecraft:".length());
}
if (id.startsWith("sponge")) {
return id.substring("sponge:".length());
}
if (id.startsWith("denizen2sponge")) {
return id.substring("denizen2sponge:".length());
}
return id;
}

public static Object getTypeWithDefaultPrefix(Class clazz, String name) {
Expand All @@ -53,6 +62,10 @@ public static Object getTypeWithDefaultPrefix(Class clazz, String name) {
return opt.get();
}
opt = Sponge.getRegistry().getType(clazz, "sponge:" + name);
if (opt.isPresent()) {
return opt.get();
}
opt = Sponge.getRegistry().getType(clazz, "denizen2sponge:" + name);
return opt.orElse(null);
}
}

0 comments on commit e39b046

Please sign in to comment.