Merge branch 'master' into 1.17
This commit is contained in:
commit
253604b34a
18 files changed
+381
-32
No files matched your search
@@ -73,6 +73,7 @@ public class CarpetSettings
|
||||
|
||||
/*
|
||||
These will be turned when events can be added / removed in code
|
||||
Then also gotta remember to remove relevant rules
|
||||
|
||||
@Rule(
|
||||
desc = "Turns on internal camera path tracing app",
|
||||
@@ -97,9 +98,29 @@ public class CarpetSettings
|
||||
appSource = "ai_tracker"
|
||||
)
|
||||
public static boolean commandAITracker = true;
|
||||
|
||||
@Rule(
|
||||
desc = "Enables /draw commands",
|
||||
extra = {
|
||||
"... allows for drawing simple shapes or",
|
||||
"other shapes which are sorta difficult to do normally"
|
||||
},
|
||||
appSource = "draw",
|
||||
category = {FEATURE, SCARPET, COMMAND}
|
||||
)
|
||||
public static String commandDraw = "true";
|
||||
|
||||
@Rule(
|
||||
desc = "Enables /distance command to measure in game distance between points",
|
||||
extra = "Also enables brown carpet placement action if 'carpets' rule is turned on as well",
|
||||
appSource = "distance",
|
||||
category = {FEATURE, SCARPET, COMMAND}
|
||||
)
|
||||
public static String commandDistance = "true";
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@Rule(desc = "Gbhs sgnf sadsgras fhskdpri!", category = EXPERIMENTAL)
|
||||
public static boolean superSecretSetting = false;
|
||||
|
||||
@@ -378,6 +399,7 @@ public class CarpetSettings
|
||||
@Rule(desc = "Enables /draw commands", extra = {"... allows for drawing simple shapes or","other shapes which are sorta difficult to do normally"}, category = COMMAND)
|
||||
public static String commandDraw = "true";
|
||||
|
||||
|
||||
@Rule(
|
||||
desc = "Enables /script command",
|
||||
extra = "An in-game scripting API for Scarpet programming language",
|
||||
|
||||
@@ -244,13 +244,13 @@ public class ScriptCommand
|
||||
suggests( (cc, bb) -> suggestMatching(CarpetServer.scriptServer.listAvailableModules(true),bb)).
|
||||
executes((cc) ->
|
||||
{
|
||||
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), true, false, null);
|
||||
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, true, false, false);
|
||||
return success?1:0;
|
||||
}).
|
||||
then(literal("global").
|
||||
executes((cc) ->
|
||||
{
|
||||
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), false, false, null);
|
||||
boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, false, false, false);
|
||||
return success?1:0;
|
||||
}
|
||||
)
|
||||
|
||||
@@ -268,6 +268,12 @@ public class CarpetEventServer
|
||||
};
|
||||
public static final Event NETHER_TICK = new Event("tick_nether", 0, true)
|
||||
{
|
||||
@Override
|
||||
public boolean deprecated()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick()
|
||||
{
|
||||
@@ -279,6 +285,11 @@ public class CarpetEventServer
|
||||
};
|
||||
public static final Event ENDER_TICK = new Event("tick_ender", 0, true)
|
||||
{
|
||||
@Override
|
||||
public boolean deprecated()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public void onTick()
|
||||
{
|
||||
@@ -804,6 +815,7 @@ public class CarpetEventServer
|
||||
{
|
||||
return handler.callList.size() > 0;
|
||||
}
|
||||
public boolean deprecated() {return false;}
|
||||
//stubs for calls just to ease calls in vanilla code so they don't need to deal with scarpet value types
|
||||
public void onTick() { }
|
||||
public void onChunkGenerated(ServerWorld world, Chunk chunk) { }
|
||||
@@ -900,10 +912,10 @@ public class CarpetEventServer
|
||||
|
||||
private boolean canAddEvent(Event event, ScriptHost host)
|
||||
{
|
||||
if (event.deprecated()) host.issueDeprecation(event.name+" event");
|
||||
return !(event.globalOnly && (host.perUser || host.parent != null));
|
||||
}
|
||||
|
||||
|
||||
public boolean removeEventFromCommand(ServerCommandSource source, String event, String funName)
|
||||
{
|
||||
Event ev = Event.getEvent(event, CarpetServer.scriptServer);
|
||||
|
||||
@@ -57,7 +57,10 @@ public class CarpetScriptHost extends ScriptHost
|
||||
public Map<Value, Value> appConfig;
|
||||
public Map<String, CommandArgument> appArgTypes;
|
||||
|
||||
private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent, Map<Value, Value> config, Map<String, CommandArgument> argTypes)
|
||||
Function<ServerCommandSource, Boolean> commandValidator;
|
||||
boolean isRuleApp;
|
||||
|
||||
private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent, Map<Value, Value> config, Map<String, CommandArgument> argTypes, Function<ServerCommandSource, Boolean> commandValidator, boolean isRuleApp)
|
||||
{
|
||||
super(code, perUser, parent);
|
||||
this.saveTimeout = 0;
|
||||
@@ -74,11 +77,13 @@ public class CarpetScriptHost extends ScriptHost
|
||||
}
|
||||
appConfig = config;
|
||||
appArgTypes = argTypes;
|
||||
this.commandValidator = commandValidator;
|
||||
this.isRuleApp = isRuleApp;
|
||||
}
|
||||
|
||||
public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source)
|
||||
public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source, Function<ServerCommandSource, Boolean> commandValidator, boolean isRuleApp)
|
||||
{
|
||||
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>());
|
||||
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>(), commandValidator, isRuleApp);
|
||||
// parse code and convert to expression
|
||||
if (module != null)
|
||||
{
|
||||
@@ -169,7 +174,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
@Override
|
||||
protected ScriptHost duplicate()
|
||||
{
|
||||
return new CarpetScriptHost(scriptServer, main, false, this, appConfig, appArgTypes);
|
||||
return new CarpetScriptHost(scriptServer, main, false, this, appConfig, appArgTypes, commandValidator, isRuleApp);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -739,4 +744,15 @@ public class CarpetScriptHost extends ScriptHost
|
||||
{
|
||||
return scriptServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean issueDeprecation(String feature)
|
||||
{
|
||||
if(super.issueDeprecation(feature))
|
||||
{
|
||||
Messenger.m(responsibleSource, "rb '"+feature+"' is deprecated and soon will be removed. Please consult the docs for their replacement");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,8 @@ public class CarpetScriptServer
|
||||
registerBuiltInScript(BundledModule.carpetNative("math", true));
|
||||
registerBuiltInScript(BundledModule.carpetNative("chunk_display", false));
|
||||
registerBuiltInScript(BundledModule.carpetNative("ai_tracker", false));
|
||||
registerBuiltInScript(BundledModule.carpetNative("draw_beta", false));
|
||||
registerBuiltInScript(BundledModule.carpetNative("distance_beta", false));
|
||||
}
|
||||
|
||||
public CarpetScriptServer(MinecraftServer server)
|
||||
@@ -101,7 +103,7 @@ public class CarpetScriptServer
|
||||
tickStart = 0L;
|
||||
stopAll = false;
|
||||
holyMoly = server.getCommandManager().getDispatcher().getRoot().getChildren().stream().map(CommandNode::getName).collect(Collectors.toSet());
|
||||
globalHost = CarpetScriptHost.create(this, null, false, null);
|
||||
globalHost = CarpetScriptHost.create(this, null, false, null, p -> true, false);
|
||||
}
|
||||
|
||||
public void initializeForWorld()
|
||||
@@ -117,7 +119,7 @@ public class CarpetScriptServer
|
||||
Messenger.m(server.getCommandSource(), "Auto-loading world scarpet apps");
|
||||
for (String moduleName: listAvailableModules(false))
|
||||
{
|
||||
addScriptHost(server.getCommandSource(), moduleName, true, true, null);
|
||||
addScriptHost(server.getCommandSource(), moduleName, null, true, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +170,7 @@ public class CarpetScriptServer
|
||||
{
|
||||
for (Module mi : bundledModuleData)
|
||||
{
|
||||
if (!mi.isLibrary()) moduleNames.add(mi.getName());
|
||||
if (!mi.isLibrary() && !mi.getName().endsWith("_beta")) moduleNames.add(mi.getName());
|
||||
}
|
||||
}
|
||||
File folder = server.getSavePath(WorldSavePath.ROOT).resolve("scripts").toFile();
|
||||
@@ -193,10 +195,11 @@ public class CarpetScriptServer
|
||||
return modules.get(name);
|
||||
}
|
||||
|
||||
public boolean addScriptHost(ServerCommandSource source, String name, boolean perPlayer, boolean autoload, Function<ServerCommandSource, Boolean> commandValidator)
|
||||
public boolean addScriptHost(ServerCommandSource source, String name, Function<ServerCommandSource, Boolean> commandValidator,
|
||||
boolean perPlayer, boolean autoload, boolean isRuleApp)
|
||||
{
|
||||
//TODO add per player modules to support player actions better on a server
|
||||
boolean isRuleApp = commandValidator != null;
|
||||
if (commandValidator == null) commandValidator = p -> true;
|
||||
long start = System.nanoTime();
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
boolean reload = false;
|
||||
@@ -212,7 +215,7 @@ public class CarpetScriptServer
|
||||
Messenger.m(source, "r Failed to add "+name+" app");
|
||||
return false;
|
||||
}
|
||||
CarpetScriptHost newHost = CarpetScriptHost.create(this, module, perPlayer, source);
|
||||
CarpetScriptHost newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp);
|
||||
if (newHost == null)
|
||||
{
|
||||
Messenger.m(source, "r Failed to add "+name+" app");
|
||||
@@ -434,13 +437,26 @@ public class CarpetScriptServer
|
||||
}
|
||||
}
|
||||
|
||||
static class TransferData
|
||||
{
|
||||
boolean perUser;
|
||||
Function<ServerCommandSource, Boolean> commandValidator;
|
||||
boolean isRuleApp;
|
||||
private TransferData(CarpetScriptHost host)
|
||||
{
|
||||
perUser = host.perUser;
|
||||
commandValidator = host.commandValidator;
|
||||
isRuleApp = host.isRuleApp;
|
||||
}
|
||||
}
|
||||
|
||||
public void reload(MinecraftServer server)
|
||||
{
|
||||
Map<String, Boolean> apps = new HashMap<>();
|
||||
modules.forEach((s, h) -> apps.put(s, h.perUser));
|
||||
Map<String, TransferData> apps = new HashMap<>();
|
||||
modules.forEach((s, h) -> apps.put(s, new TransferData(h)));
|
||||
apps.keySet().forEach(s -> removeScriptHost(server.getCommandSource(), s, false, false));
|
||||
CarpetEventServer.Event.clearAllBuiltinEvents();
|
||||
init();
|
||||
apps.forEach((s, pp) -> addScriptHost(server.getCommandSource(), s, pp, false, null));
|
||||
apps.forEach((s, data) -> addScriptHost(server.getCommandSource(), s,data.commandValidator, data.perUser,false, data.isRuleApp));
|
||||
}
|
||||
}
|
||||
@@ -366,7 +366,28 @@ public class Expression
|
||||
|
||||
public void alias(String copy, String original)
|
||||
{
|
||||
functions.put(copy, functions.get(original));
|
||||
ILazyFunction originalFunction = functions.get(original);
|
||||
functions.put(copy, new ILazyFunction()
|
||||
{
|
||||
@Override
|
||||
public int getNumParams()
|
||||
{
|
||||
return originalFunction.getNumParams();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean numParamsVaries()
|
||||
{
|
||||
return originalFunction.numParamsVaries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue lazyEval(Context c, Integer type, Expression expr, Tokenizer.Token token, List<LazyValue> lazyParams)
|
||||
{
|
||||
c.host.issueDeprecation(copy+"(...)");
|
||||
return originalFunction.lazyEval(c, type, expr, token, lazyParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.Value;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -34,6 +36,8 @@ public abstract class ScriptHost
|
||||
private final Map<Value, Object> locks = new ConcurrentHashMap<>();
|
||||
protected boolean inTermination = false;
|
||||
|
||||
private final Set<String> deprecations = new HashSet<>();
|
||||
|
||||
public Random getRandom(long aLong)
|
||||
{
|
||||
if (randomizers.size() > 1024)
|
||||
@@ -379,4 +383,14 @@ public abstract class ScriptHost
|
||||
{
|
||||
errorSnooper=null;
|
||||
}
|
||||
|
||||
public static final Logger DEPRECATION_LOG = LogManager.getLogger("Scarpet Deprecation Warnings");
|
||||
|
||||
public boolean issueDeprecation(String feature)
|
||||
{
|
||||
if (deprecations.contains(feature)) return false;
|
||||
deprecations.add(feature);
|
||||
DEPRECATION_LOG.warn("'"+feature+"' is deprecated and soon will be removed. Please consult the docs for their replacement");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -577,6 +577,7 @@ public class Auxiliary {
|
||||
|
||||
expression.addLazyFunction("seed", -1, (c, t, lv) -> {
|
||||
ServerCommandSource s = ((CarpetContext)c).s;
|
||||
c.host.issueDeprecation("seed()");
|
||||
Value ret = new NumericValue(s.getWorld().getSeed());
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
@@ -785,6 +786,7 @@ public class Auxiliary {
|
||||
boolean shared = false;
|
||||
if (lv.size()>0)
|
||||
{
|
||||
c.host.issueDeprecation("load_app_data(...) with arguments");
|
||||
file = recognizeResource(lv.get(0).evalValue(c));
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
@@ -807,6 +809,7 @@ public class Auxiliary {
|
||||
boolean shared = false;
|
||||
if (lv.size()>1)
|
||||
{
|
||||
c.host.issueDeprecation("store_app_data(...) with more than one argument");
|
||||
file = recognizeResource(lv.get(1).evalValue(c));
|
||||
if (lv.size() > 2)
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ public class Scoreboards {
|
||||
}
|
||||
String objectiveName = lv.get(0).evalValue(c).getString();
|
||||
ScoreboardObjective objective = scoreboard.getObjective(objectiveName);
|
||||
if (objective == null) throw new InternalExpressionException("Unknown objective: "+objectiveName);
|
||||
if (objective == null) return LazyValue.NULL;
|
||||
if (lv.size()==1)
|
||||
{
|
||||
Value ret = ListValue.wrap(scoreboard.getAllPlayerScores(objective).stream().map(s -> new StringValue(s.getPlayerName())).collect(Collectors.toList()));
|
||||
@@ -143,7 +143,7 @@ public class Scoreboards {
|
||||
}
|
||||
String objectiveString = target.getString();
|
||||
ScoreboardObjective objective = scoreboard.getObjective(objectiveString);
|
||||
if (objective == null) throw new InternalExpressionException("Objective doesn't exist: "+objectiveString);
|
||||
if (objective == null) return LazyValue.NULL;
|
||||
scoreboard.setObjectiveSlot(slot, objective);
|
||||
return (_c, _t) -> new NumericValue(slot);
|
||||
});
|
||||
|
||||
@@ -543,6 +543,7 @@ public class WorldAccess {
|
||||
// Deprecated, use loaded_status as more indicative
|
||||
expression.addLazyFunction("loaded_ep", -1, (c, t, lv) ->
|
||||
{
|
||||
c.host.issueDeprecation("loaded_ep(...)");
|
||||
BlockPos pos = BlockArgument.findIn((CarpetContext)c, lv, 0).block.getPos();
|
||||
Value retval = ((CarpetContext)c).s.getWorld().getChunkManager().shouldTickChunk(new ChunkPos(pos))?Value.TRUE : Value.FALSE;
|
||||
return (c_, t_) -> retval;
|
||||
@@ -739,11 +740,12 @@ public class WorldAccess {
|
||||
return (c_, t_) -> Value.FALSE;
|
||||
BlockState finalSourceBlockState = sourceBlockState;
|
||||
BlockPos targetPos = targetLocator.block.getPos();
|
||||
Boolean[] result = new Boolean[]{true};
|
||||
cc.s.getMinecraftServer().submitAndJoin( () ->
|
||||
{
|
||||
Clearable.clear(world.getBlockEntity(targetPos));
|
||||
world.setBlockState(targetPos, finalSourceBlockState, 2);
|
||||
if (finalData != null)
|
||||
boolean success = world.setBlockState(targetPos, finalSourceBlockState, 2);
|
||||
if (success && finalData != null)
|
||||
{
|
||||
BlockEntity be = world.getBlockEntity(targetPos);
|
||||
if (be != null)
|
||||
@@ -756,7 +758,9 @@ public class WorldAccess {
|
||||
be.markDirty();
|
||||
}
|
||||
}
|
||||
result[0] = success;
|
||||
});
|
||||
if (!result[0]) return LazyValue.FALSE;
|
||||
Value retval = new BlockValue(finalSourceBlockState, world, targetLocator.block.getPos());
|
||||
return (c_, t_) -> retval;
|
||||
});
|
||||
@@ -962,6 +966,7 @@ public class WorldAccess {
|
||||
// Deprecated for block_state()
|
||||
expression.addLazyFunction("property", -1, (c, t, lv) ->
|
||||
{
|
||||
c.host.issueDeprecation("property(...)");
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0);
|
||||
BlockState state = locator.block.getBlockState();
|
||||
if (lv.size() <= locator.offset)
|
||||
@@ -978,6 +983,7 @@ public class WorldAccess {
|
||||
// Deprecated for block_state()
|
||||
expression.addLazyFunction("block_properties", -1, (c, t, lv) ->
|
||||
{
|
||||
c.host.issueDeprecation("block_properties(...)");
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0);
|
||||
BlockState state = locator.block.getBlockState();
|
||||
StateManager<Block, BlockState> states = state.getBlock().getStateManager();
|
||||
|
||||
@@ -190,7 +190,7 @@ public class SettingsManager
|
||||
{
|
||||
if (rule.getBoolValue() || (rule.type == String.class && !rule.get().equals("false")))
|
||||
{
|
||||
CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, false, false, s -> canUseCommand(s, rule.get()));
|
||||
CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, s -> canUseCommand(s, rule.get()), false, false, true);
|
||||
} else {
|
||||
CarpetServer.scriptServer.removeScriptHost(source, rule.scarpetApp, false, true);
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ public abstract class Validator<T>
|
||||
return newValue;
|
||||
}
|
||||
@Override
|
||||
public String description() { return "Its a client command so can be issued when connecting to non-carpet servers. " +
|
||||
"In client-server setting it will only affect the executing player, so each player needs to type it" +
|
||||
public String description() { return "Its a client command so can be issued and potentially be effective when connecting to non-carpet/vanilla servers. " +
|
||||
"In these situations (on vanilla servers) it will only affect the executing player, so each player needs to type it" +
|
||||
" separately for the desired effect";}
|
||||
}
|
||||
|
||||
|
||||
@@ -638,14 +638,14 @@ save_as(file) ->
|
||||
//otherwise mojang will interpret 0.0d as 0i and fail to insert
|
||||
put(path_nbt:'points', point_nbt, _i);
|
||||
);
|
||||
store_app_data(path_nbt, file);
|
||||
write_file(file, 'nbt', path_nbt);
|
||||
'stored path as '+file;
|
||||
);
|
||||
|
||||
// loads path under the local file that
|
||||
load(file) ->
|
||||
(
|
||||
path_nbt = load_app_data(file);
|
||||
path_nbt = read_file(file, 'nbt');
|
||||
if (!path_nbt, exit('No path to load: '+file));
|
||||
new_points = map(get(path_nbt, 'points[]'), l(_:'pos[]', _:'duration', _:'type'));
|
||||
if (!new_points || first(new_points, length(_:0) != 5),
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import('math','_euclidean','_manhattan','_round');
|
||||
|
||||
__config()->{
|
||||
'commands'->{
|
||||
'from <start>'->'set_start',
|
||||
'from <start> to <end>'->'_calculate',
|
||||
'to <end>'->_(end_pos)->(_calculate(null,end_pos)),
|
||||
'toggle_line'->'_toggle_line'
|
||||
},
|
||||
'arguments' -> {
|
||||
'start' -> {'type' -> 'location'},
|
||||
'end' -> {'type' -> 'location'}
|
||||
}
|
||||
};
|
||||
|
||||
global_start=null;
|
||||
global_end=null;
|
||||
|
||||
global_show_line=false;
|
||||
|
||||
__mktp(pos) -> str('!/tp %.6f %.6f %.6f', pos);
|
||||
|
||||
set_start(pos)->(
|
||||
global_start = pos;
|
||||
global_end = null;
|
||||
print(player(),format('gi Initial point set to: ', 'g '+pos, __mktp(pos)))
|
||||
);
|
||||
|
||||
_toggle_line()->(
|
||||
global_show_line= !global_show_line;
|
||||
if(global_show_line,
|
||||
print('Toggled lines on');
|
||||
_draw_line()
|
||||
, // else
|
||||
print('Toggled lines off')
|
||||
);
|
||||
);
|
||||
|
||||
_calculate(start_pos, end_pos)->(
|
||||
if(start_pos!=null,
|
||||
set_start(start_pos);
|
||||
calculate(end_pos)
|
||||
, // else
|
||||
if(global_start,
|
||||
calculate(end_pos),
|
||||
print(player(),format('r There was no initial point for '+player()));
|
||||
set_start(end_pos)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
__on_player_places_block(player, item_tuple, hand, block) ->(
|
||||
if(block=='brown_carpet' && system_info('world_carpet_rules'):'carpets'=='true',
|
||||
effective_pos = pos(block)+[0.5, 0, 0.5];
|
||||
if(global_start==null||player~'sneaking',//wont complain for first carpet
|
||||
set_start(effective_pos),
|
||||
_calculate(null, effective_pos)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
calculate(end_pos)->(
|
||||
global_end = end_pos;
|
||||
manhattan = _round(_manhattan(global_start, global_end),0.001);//rounding to nearest 0.01 for precision, but not ridiculous decimal places
|
||||
spherical = _round(_euclidean(global_start, global_end), 0.001);
|
||||
//useful for chunk distances etc.
|
||||
cylindrical = _round(_euclidean(global_start, [global_end:0, global_start:1, global_end:2]), 0.001);
|
||||
|
||||
|
||||
print(player(),format(
|
||||
'w Distance between ',
|
||||
'c '+str('[%.1f, %.1f, %.1f]', global_start), __mktp(global_start),
|
||||
'w and ',
|
||||
'c '+str('[%.1f, %.1f, %.1f]', global_end), __mktp(global_end), 'w :\n',
|
||||
'w - Spherical: ', 'wb '+spherical+'\n',
|
||||
'w - Cylindrical: ', 'wb '+cylindrical+'\n',
|
||||
'w - Manhattan: ', 'wb '+manhattan
|
||||
));
|
||||
|
||||
schedule(0,'_draw_line');
|
||||
);
|
||||
|
||||
_draw_line()->(
|
||||
if(global_show_line,//It will always draw from the global positions, so it will turn on if there is a line
|
||||
if ( global_start && global_end,
|
||||
draw_shape('line',20,'from',global_start,'to',global_end, 'player',player());
|
||||
draw_shape('label',20,'pos',global_end,'text',_round(_euclidean(global_start,global_end),0.001));
|
||||
);
|
||||
schedule(20,'_draw_line')
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,142 @@
|
||||
import('math','_euclidean_sq','_vec_length');
|
||||
|
||||
__config() -> {
|
||||
'commands'->{
|
||||
'sphere <center> <radius> <block>'->['draw_sphere',null,true],
|
||||
'sphere <center> <radius> <block> replace <replacement>'->['draw_sphere',true],
|
||||
'ball <center> <radius> <block>'->['draw_sphere',null,false],
|
||||
'ball <center> <radius> <block> replace <replacement>'->['draw_sphere',false],
|
||||
'diamond <center> <radius> <block>'->['draw_diamond',null],
|
||||
'diamond <center> <radius> <block> replace <replacement>'->'draw_diamond',
|
||||
'pyramid <center> <radius> <height> <pointing> <orientation> <block> <hollow>'->['draw_pyramid',null, true],
|
||||
'pyramid <center> <radius> <height> <pointing> <orientation> <block> <hollow> replace <replacement>'->['draw_pyramid', true],
|
||||
'cone <center> <radius> <height> <pointing> <orientation> <block> <hollow>'->['draw_pyramid',null, false],
|
||||
'cone <center> <radius> <height> <pointing> <orientation> <block> <hollow> replace <replacement>'->['draw_pyramid', false],
|
||||
'cuboid <center> <radius> <height> <orientation> <block> <hollow>'->['draw_prism', null, true],
|
||||
'cuboid <center> <radius> <height> <orientation> <block> <hollow> replace <replacement>'->['draw_prism', true],
|
||||
'cylinder <center> <radius> <height> <orientation> <block> <hollow>'->['draw_prism', null, false],
|
||||
'cylinder <center> <radius> <height> <orientation> <block> <hollow> replace <replacement>'->['draw_prism', false]
|
||||
},
|
||||
'arguments'->{
|
||||
'center'->{'type'->'pos', 'loaded'->'true'},
|
||||
'radius'->{'type'->'int', 'suggest'->[], 'min'->0},//to avoid default suggestions
|
||||
'replacement'->{'type'->'block'},
|
||||
'height'->{'type'->'int', 'suggest'->[],'min'->0},
|
||||
'orientation'->{'type'->'term', 'suggest'->['x','y','z']},
|
||||
'pointing'->{'type'->'term','suggest'->['up','down']},
|
||||
'hollow'->{'type'->'term','suggest'->['hollow','solid']},
|
||||
},
|
||||
'scope'->'global'
|
||||
};
|
||||
|
||||
|
||||
//"Boilerplate" code
|
||||
|
||||
set_block(x, y, z, block, replacement)-> (
|
||||
if(block != block(x, y, z),
|
||||
without_updates( if (set([x, y, z],block),
|
||||
global_affected += [x, y, z];
|
||||
));
|
||||
);
|
||||
);
|
||||
|
||||
global_affected = [];
|
||||
|
||||
affected(player) -> (
|
||||
affected = length(global_affected);
|
||||
print(player,format('gi Filled ' + affected + ' blocks'));
|
||||
|
||||
if(system_info('world_carpet_rules'):'fillUpdates',
|
||||
for(global_affected,update(_));//updating if fillUpdates is true
|
||||
);
|
||||
|
||||
global_affected = [];
|
||||
affected
|
||||
);
|
||||
|
||||
length_sq(vec) -> reduce(vec, _a + _*_, 0);
|
||||
|
||||
fill_flat(pos, offset, dr, rectangle, orientation, block, hollow, replacement)->(
|
||||
r = floor(dr);
|
||||
drsq = dr^2;
|
||||
if(orientation=='x',
|
||||
scan(pos,0,-r,-r,
|
||||
if((!hollow && (rectangle || _y^2 + _z^2 <= drsq))||//if not hollow, vry simple
|
||||
(hollow && ((rectangle && (abs(_y) == r || abs(_z) ==r)) || //If hollow and it's a rectangle
|
||||
(!rectangle && (_y^2 + _z^2 <= drsq && (abs(_y)+1)^ 2 + (abs(_z)+1)^2 >= drsq)))),//If hollow and not rectangle
|
||||
set_block(_x+offset,_y,_z,block, replacement)
|
||||
)
|
||||
),
|
||||
orientation == 'y',
|
||||
scan(pos,-r,0,-r,
|
||||
if((!hollow && (rectangle || _x^2 + _z^2 <= drsq))||//if not hollow, vry simple
|
||||
(hollow && ((rectangle && (abs(_x) == r || abs(_z) ==r)) || //If hollow and it's a rectangle
|
||||
(!rectangle && (_x^2 + _z^2 <= drsq && (abs(_x)+1)^ 2 + (abs(_z)+1)^2 >= drsq)))),//If hollow and not rectangle
|
||||
set_block(_x,_y+offset,_z,block, replacement)
|
||||
)
|
||||
),
|
||||
orientation == 'z',
|
||||
scan(pos,-r,-r,0,
|
||||
if((!hollow && (rectangle || _y^2 + _x^2 <= drsq))||//if not hollow, vry simple
|
||||
(hollow && ((rectangle && (abs(_y) == r || abs(_x) ==r)) || //If hollow and it's a rectangle
|
||||
(!rectangle && (_y^2 + _x^2 <= drsq && (abs(_y)+1)^ 2 + (abs(_x)+1)^2 >= drsq)))),//If hollow and not rectangle
|
||||
set_block(_x,_y,_z+offset,block, replacement)
|
||||
)
|
||||
),
|
||||
print(player(),format('r Error while running command: orientation can only be "x", "y" or "z", '+orientation+' is invalid.'));
|
||||
global_affected = [];
|
||||
);
|
||||
);
|
||||
|
||||
//drawing commands
|
||||
|
||||
draw_sphere(centre, radius, block, replacement, hollow)->(
|
||||
scan(centre,[radius,radius,radius],
|
||||
l = length_sq([_x,_y,_z]-centre);
|
||||
if((l<=radius^2+radius) && (!hollow || l>=radius^2-radius),
|
||||
set_block(_x, _y, _z, block, replacement)
|
||||
)
|
||||
);
|
||||
|
||||
affected(player());
|
||||
);
|
||||
|
||||
draw_diamond(pos, radius, block, replacement)->(
|
||||
|
||||
c_for(r=0, r<radius, r+=1,
|
||||
y = r-radius+1;
|
||||
c_for(x=-r,x<=r,x+=1,
|
||||
z=r-abs(x);
|
||||
|
||||
set_block(pos:0+x,pos:1-y,pos:2+z, block, replacement);
|
||||
set_block(pos:0+x,pos:1-y,pos:2-z, block, replacement);
|
||||
set_block(pos:0+x,pos:1+y,pos:2+z, block, replacement);
|
||||
set_block(pos:0+x,pos:1+y,pos:2-z, block, replacement);
|
||||
)
|
||||
);
|
||||
|
||||
affected(player())
|
||||
);
|
||||
|
||||
draw_pyramid(pos, radius, height, pointing, orientation, block, fill_type, replacement, is_square)->(
|
||||
|
||||
hollow = fill_type=='hollow';
|
||||
pointup = pointing=='up';
|
||||
|
||||
for(range(height),
|
||||
r = if(pointup, radius - radius * _ / height -1, radius * _ / height);
|
||||
fill_flat(pos, _, r, is_square, orientation, block, if((pointup&&_==0)||(!pointup && _==height-1),false,hollow),replacement)//Always close bottom off
|
||||
);
|
||||
affected(player())
|
||||
);
|
||||
|
||||
draw_prism(pos, rad, height, orientation, block, fill_type, replacement, is_square)->(
|
||||
|
||||
hollow = fill_type =='hollow';
|
||||
radius = rad+0.5;
|
||||
|
||||
for(range(height),
|
||||
fill_flat(pos, _, radius, is_square, orientation, block, if(_==0 || _==height-1,false,hollow), replacement)//Always close ends off
|
||||
);
|
||||
affected(player())
|
||||
);
|
||||
@@ -1,3 +1,5 @@
|
||||
_euclidean_sq(vec1, vec2) -> reduce(vec1 - vec2, _a + _*_, 0);
|
||||
_euclidean(vec1, vec2) -> sqrt(reduce(vec1 - vec2, _a + _*_, 0));
|
||||
_vec_length(vec) -> sqrt(reduce(vec, _a + _*_, 0));
|
||||
_manhattan(vec1, vec2) -> reduce(vec1-vec2,_a+abs(_),0);
|
||||
_vec_length(vec) -> sqrt(reduce(vec, _a + _*_, 0));
|
||||
_round(num,precision) -> round(num/precision)*precision;
|
||||
Reference in new issue
Block a user