EssentialsX

EssentialsX

2M Downloads

Block-Based Teleportation Cost

waterlubber opened this issue ยท 3 comments

commented

Feature request

Description

There should be a configuration option for a per-block based teleport cost. For example, a player teleporting 500 blocks would pay more than one travelling 100 blocks. Ideally, it would have a permission node to exempt players from the cost, and perhaps per-warp rates or something like that.

In the configuration file, cost could either be linear (eg 10x, where x is the number of blocks) or exponential (x^1.4, for example). Ideally it would be polynomial and allow you to set your own function, however, this would be difficult to implement.

How the feature is useful

Server owners could allow players to teleport for convenience, but discourage the use of /tpa and similar commands to as a main form of transport. Short trips, like from someone's mine to one's house, are mostly for practical and convenience purposes. Having them cost less than a cross-world teleport encourages players to spend time building infrastructure projects, etc.

It also offers a way to balance the teleport commands, which some server admins may disable due to them being considered "overpowered."

Feasibility.
With the help of this reddit post, I hacked together this spaghetti mess. While code of this quality is obviously not suitable to include in Essentials (and it's why I didn't submit a PR -- I literally started learning Java yesterday), it shows that something like this could easily be done.

commented

Using javax.script it is possible to evaluate Javascript from a String. Using this you could potentially write a function in the config file and then evaluate it to get the cost.

A very simple implementation might look like this:

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

final ScriptEngineManager mgr = new ScriptEngineManager();
final ScriptEngine engine = mgr.getEngineByName("JavaScript");

public float getCommandCost(String name, float x) {
    String f = something; // read the formula from the config file using name
    engine.put("x", x); // X might refer to the ammount of blocks par example or something else
    
    try {
        return Float.parseFloat(engine.eval("f(x)"));
    catch (Exception e) {
        return default; // some default value read from the config file using name
    }
}

Now of course in this case we'd want the config to be backwards compatible and for most commands it probably won't even make sense to pass in a variable. So the config file might look somthing like this:

command-costs:
    normal: 100 // Just a normal definition for backwards compatability
    tp:
        function: "x^2" // The function that would be evaluated
        default: 10 // If it fails the default value to use

Advantages of implementing it this way is that you give the user a finegrained control over the cost (as you could in theory also put if statements in the function). Downsides are 1) a lot of work to implement 2) fragile, there will probably be a lot of edge cases 3) it only applies to very few commands (maybe even just the teleport commands).

I do think it's implementable, but I'd like to hear the opinion of @triagonal and/or @md678685.

commented

While this is certainly possible, I'm not sure this is the best fit for EssentialsX.

As this is a somewhat niche feature, I imagine most servers using it would want slightly different cost calculation formulae, and so @jvdoorn's approach makes some sense. However, for many users writing mathematical functions in a single line of JavaScript isn't particularly intuitive if you just want a simple per-block cost calculation.

A more intuitive implementation would be something like a per-block: <n>, possibly combined with a function: <linear/quadratic/exponential...> option to pick between some predefined formulae. The problem with this is that it sacrifices flexibility and forces servers that want a slightly different calculation to reimplement it themselves anyway, undermining the whole point of having this feature in EssentialsX.

Overall I can't see any implementation of this that would comfortably fit all EssentialsX users. You can already achieve this in a separate plugin using Bukkit's PlayerTeleportEvent, and for servers wishing to implement a per-block charge for teleportation, I'd recommend implementing it yourself for full control over the calculation.

commented

I'm going to go ahead and close this for now since it seems this isn't planned for inclusion. I'll agree that the custom function might be a little too much, but if a PR were opened for a simple linear cost, I'm sure that would be more than adequate for the majority of servers. If not, they should probably write their own plugin for their own specialised needs.