Merge branch 'master' into 1.15
# Conflicts: # src/main/java/carpet/mixins/ServerPlayNetworkHandler_scarpetEventsMixin.java # src/main/java/carpet/script/CarpetExpression.java
This commit is contained in:
commit
dc9532cf05
24 files changed
+1695
-655
No files matched your search
@@ -100,7 +100,7 @@ import static java.lang.Math.sqrt;
|
||||
/**
|
||||
* <h1>Minecraft specific API and <code>scarpet</code> language add-ons and commands</h1>
|
||||
* <p>Here is the gist of the Minecraft related functions. Otherwise the CarpetScript could live without Minecraft.</p>
|
||||
* <h2>Dimension issues</h2>
|
||||
* <h2>Dimension warning</h2>
|
||||
* <p>One note, which is important is that most of the calls for entities and blocks
|
||||
* would refer to the current dimension of the caller, meaning, that if we for example
|
||||
* list all the players using <code>player('all')</code> function, if a player is in the
|
||||
@@ -109,7 +109,8 @@ import static java.lang.Math.sqrt;
|
||||
* refer to the overworld blocks and entities.
|
||||
* In case you would want to run commands across all dimensions, just run three of them, using
|
||||
* <code>/execute in overworld/the_nether/the_end run script run ...</code> and query
|
||||
* players using <code>player('*')</code>, which only returns players in current dimension.</p>
|
||||
* players using <code>player('*')</code>, which only returns players in current dimension, or use
|
||||
* <code>in_dimension(expr)</code> function.</p>
|
||||
*/
|
||||
public class CarpetExpression
|
||||
{
|
||||
@@ -348,7 +349,7 @@ public class CarpetExpression
|
||||
* <h1>Blocks / World API</h1>
|
||||
* <div style="padding-left: 20px; border-radius: 5px 45px; border:1px solid grey;">
|
||||
* <h2>Specifying blocks</h2>
|
||||
* <h3><code>block(x, y, z), block(state)</code></h3>
|
||||
* <h3><code>block(x, y, z), block(l(x,y,z)), block(state)</code></h3>
|
||||
* <p>Returns either a block from specified location, or block with a specific state
|
||||
* (as used by <code>/setblock</code> command), so allowing for block properties, block entity data etc.
|
||||
* Blocks otherwise can be referenced everywhere by its simple string name, but its only used in its default state</p>
|
||||
@@ -401,6 +402,8 @@ public class CarpetExpression
|
||||
* place_item('piston,x,y,z,'down') // places a piston facing down
|
||||
* place_item('carrot',x,y,z) // attempts to plant a carrot plant. Returns true if could place carrots at that position.
|
||||
* </pre>
|
||||
* <h3><code>biome(pos)</code></h3>
|
||||
* <p>returns biome at that block position.</p>
|
||||
* <h3><code>set_biome(pos, biome_name)</code></h3>
|
||||
* <p>changes biome at that block position.</p>
|
||||
* <h3><code>update(pos)</code></h3>
|
||||
@@ -998,6 +1001,16 @@ public class CarpetExpression
|
||||
return (_c, _t) -> res;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("biome", -1, (c, t, lv) -> {
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParams(cc, lv, 0);
|
||||
ServerWorld world = cc.s.getWorld();
|
||||
BlockPos pos = locator.block.getPos();
|
||||
Biome biome = world.getBiome(pos);
|
||||
Value res = new StringValue(biome.getTranslationKey().replaceFirst("^biome\\.minecraft\\.", ""));
|
||||
return (_c, _t) -> res;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("set_biome", -1, (c, t, lv) ->
|
||||
{
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
@@ -1179,6 +1192,8 @@ public class CarpetExpression
|
||||
Value nbtValue = lv.get(inventoryLocator.offset+3).evalValue(c);
|
||||
if (nbtValue instanceof NBTSerializableValue)
|
||||
nbt = ((NBTSerializableValue)nbtValue).getCompoundTag();
|
||||
else if (nbtValue instanceof NullValue)
|
||||
nbt = null;
|
||||
else
|
||||
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
||||
}
|
||||
@@ -1241,7 +1256,7 @@ public class CarpetExpression
|
||||
if (inventoryLocator == null)
|
||||
return (_c, _t) -> Value.NULL;
|
||||
if (lv.size() <= inventoryLocator.offset)
|
||||
throw new InternalExpressionException("inventory_set requires at least an item to be removed");
|
||||
throw new InternalExpressionException("inventory_remove requires at least an item to be removed");
|
||||
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).evalValue(c).getString());
|
||||
int amount = 1;
|
||||
if (lv.size() > inventoryLocator.offset+1)
|
||||
@@ -1464,9 +1479,11 @@ public class CarpetExpression
|
||||
* <h3><code>query(e,'age')</code></h3>
|
||||
* <p>Age, in ticks, of the entity, i.e. how long it existed.</p>
|
||||
* <h3><code>query(e,'item')</code></h3>
|
||||
* <p>Name of the item if its an item entity, <code>null</code> otherwise</p>
|
||||
* <p>The item triple (name, count, nbt) if its an item entity, <code>null</code> otherwise</p>
|
||||
* <h3><code>query(e,'count')</code></h3>
|
||||
* <p>Number of items in a stack from item entity, <code>null</code> otherwise</p>
|
||||
* <h3><code>query(e,'pickup_delay')</code></h3>
|
||||
* <p>Retrieves pickup delay timeout for an item entity, <code>null</code> otherwise</p>
|
||||
* <h3><code>query(e,'is_baby')</code></h3>
|
||||
* <p>Boolean, true if its a baby.</p>
|
||||
* <h3><code>query(e,'target')</code></h3>
|
||||
@@ -1528,10 +1545,9 @@ public class CarpetExpression
|
||||
* that corresponds to the path. For specification of <code>path</code> attribute, consult
|
||||
* vanilla <code>/data get entity</code> command.</p>
|
||||
* <p>Note that calls to <code>nbt</code> are considerably more expensive comparing to other
|
||||
* calls in Minecraft API, and should only be used when there is no other option. Also returned
|
||||
* NBT is just a string to any retrieval of information post can currently only be done with matching
|
||||
* operator <code>~</code>. With time we are hoping not to support the <code>'nbt'</code> call better,
|
||||
* but rather to fill the API, so that <code>'nbt'</code> calls are not needed</p>
|
||||
* calls in Minecraft API, and should only be used when there is no other option. Returned value is of type <code>nbt</code>,
|
||||
* which can be further manipulated with nbt type objects via <code>get, put, has, delete</code>, so try to use API calls
|
||||
* first for that.</p>
|
||||
* <h2>Entity Modification</h2>
|
||||
* <p>Like with entity querying, entity modifications happen through one function. Most position and movements
|
||||
* modifications don't work currently on players as their position is controlled by clients.</p>
|
||||
@@ -1557,7 +1573,8 @@ public class CarpetExpression
|
||||
* <h3><code>modify(e, 'accelerate', x, y, z), modify(e, 'accelerate', l(x, y, z) )</code></h3>
|
||||
* <p>Adds a vector to the motion vector. Most realistic way to apply a force to an entity.</p>
|
||||
* <h3><code>modify(e, 'custom_name'), modify(e, 'custom_name', name )</code></h3>
|
||||
* <p>Sets a custom name for an entity. Removes a custom name if the argument is <code>null</code></p>
|
||||
* <h3><code>modify(e,'pickup_delay')</code></h3>
|
||||
* <p>Sets a custom pickup delay if the entity argument is an item entity</p>
|
||||
* <h3><code>modify(e, 'dismount')</code></h3>
|
||||
* <p>Dismounts riding entity.</p>
|
||||
* <h3><code>modify(e, 'mount', other)</code></h3>
|
||||
@@ -1576,6 +1593,44 @@ public class CarpetExpression
|
||||
* <p>Sets AI to stay around the home position, within <code>distance</code> blocks from it. <code>distance</code>
|
||||
* defaults to 16 blocks. <code>null</code> removes it. <i>May</i> not work fully with mobs that have this AI built in, like
|
||||
* Villagers.</p>
|
||||
*
|
||||
* <h2>Entity Events</h2>
|
||||
* <p>There is a number of events that happen to entities that you can attach your own code to in the form of event
|
||||
* handlers. The event handler is any function that runs in your package that accepts certain expected parameters, which
|
||||
* you can expand with your own arguments. When it comes to the moment when the given command needs to be executed, it
|
||||
* does so providing that number of arguments it accepts is equal number of event arguments, and extra arguments passed when
|
||||
* defining the callback with <code>entity_event</code></p>
|
||||
* <p>The following events can be handled by entities. </p>
|
||||
* <ul>
|
||||
* <li><code>'on_tick'</code>: executes every tick right before entity is ticked in the game. Required arguments: <code>entity</code></li>
|
||||
* <li><code>'on_death'</code>: executes once when a living entity dies. Required arguments: <code>entity, reason</code></li>
|
||||
* <li><code>'on_removed'</code>: execute once when an entity is removed. Required arguments: <code>entity</code></li>
|
||||
* <li><code>'on_damaged'</code>: executed every time a living entity is about to receive damage. Required arguments: <code>entity, amount, source, attacking_entity</code></li>
|
||||
* </ul>
|
||||
* <p>It doesn't mean that all entity types will have a chance to
|
||||
* execute a given event, but entities will not error when you will attach inapplicable event to it.</p>
|
||||
* <h3><code>entity_event(e, event, call_name, args...)</code></h3>
|
||||
* <p>Attaches specific function from the current package to be called upon the <code>event</code>, with extra <code>args</code>
|
||||
* curried to the original required arguments for the event handler</p>
|
||||
* <pre>
|
||||
* protect_villager(entity, amount, source, source_entity, healing_player) ->
|
||||
* (
|
||||
* if(source_entity && source_entity~'type' != 'player',
|
||||
* modify(entity, 'health', amount + entity~'health' );
|
||||
* particle('end_rod', pos(entity)+l(0,3,0));
|
||||
* print(str('%s healed thanks to %s', entity, healing_player))
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* __on_player_interacts_with_entity(player, entity, hand) ->
|
||||
* (
|
||||
* if (entity~'type' == 'villager',
|
||||
* entity_event(entity, 'on_damage', 'protect_villager', player~'name')
|
||||
* )
|
||||
* )
|
||||
* </pre>
|
||||
* <p>In this case this will protect a villager from entity damage (zombies, etc.) except players by granting all the health
|
||||
* back to the villager after being harmed.</p>
|
||||
* </div>
|
||||
*/
|
||||
|
||||
@@ -1673,8 +1728,12 @@ public class CarpetExpression
|
||||
boolean hasTag = false;
|
||||
if (lv.size() > position.offset)
|
||||
{
|
||||
hasTag = true;
|
||||
tag = new NBTSerializableValue(lv.get(position.offset).evalValue(c).getString()).getCompoundTag();
|
||||
NBTSerializableValue v = NBTSerializableValue.parseString(lv.get(position.offset).evalValue(c).getString());
|
||||
if (v != null)
|
||||
{
|
||||
hasTag = true;
|
||||
tag = v.getCompoundTag();
|
||||
}
|
||||
}
|
||||
tag.putString("id", entityId.toString());
|
||||
Vec3d vec3d = position.vec;
|
||||
@@ -2104,6 +2163,12 @@ public class CarpetExpression
|
||||
y = miny;
|
||||
z = minz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
return String.format("rect[(%d,%d,%d),..,(%d,%d,%d)]",minx, miny, minz, maxx, maxy, maxz);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -2195,6 +2260,12 @@ public class CarpetExpression
|
||||
curradius = 0;
|
||||
curpos = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
return String.format("diamond[(%d,%d,%d),%d,0]",cx, cy, cz, width);
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -2251,6 +2322,12 @@ public class CarpetExpression
|
||||
curpos = 0;
|
||||
curheight = -height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
return String.format("diamond[(%d,%d,%d),%d,%d]",cx, cy, cz, width, height);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -2286,8 +2363,8 @@ public class CarpetExpression
|
||||
* <h2>System function</h2>
|
||||
* <h3><code>nbt(expr)</code></h3>
|
||||
* <p>Treats the argument as a nbt serializable string and returns its nbt value.
|
||||
* In case nbt is not in a correct nbt compound tag format, the execution of a script will stop with an error,
|
||||
* whenever that tag is used.</p>
|
||||
* In case nbt is not in a correct nbt compound tag format, it will return <code>null</code> value.</p>
|
||||
* <p>Consult section about container operations in <code>Expression</code> to learn about possible operations on nbt values.</p>
|
||||
* <h3><code>print(expr)</code></h3>
|
||||
* <p>Displays the result of the expression to the chat. Overrides default <code>scarpet</code> behaviour of
|
||||
* sending everyting to stderr.</p>
|
||||
@@ -2307,11 +2384,11 @@ public class CarpetExpression
|
||||
* loop(1000,tick(100)) // runs the game twice as slow for 1000 ticks
|
||||
* </pre>
|
||||
* <h3><code>current_dimension()</code></h3>
|
||||
* <p>Returns current dimension that scripts run in.</p>
|
||||
* <p>Returns current dimension that the script runs in.</p>
|
||||
* <h3><code>in_dimension(smth, expr)</code></h3>
|
||||
* <p>Evaluates the expression <code>expr</code> with different dimension execution context. <code>smth</code> can
|
||||
* be an entity, world-localized block, so not <code>block('stone')</code>, or a string representing a dimension like:
|
||||
* <code>'nether'</code>, <code>'end'</code> or <code>'overworld'</code>.</p>
|
||||
* <code>'nether'</code>, <code>'the_nether'</code>, <code>'end'</code> or <code>'overworld'</code>, etc.</p>
|
||||
* <h3><code>schedule(delay, function, args...)</code></h3>
|
||||
* <p>Schedules a user defined function to run with a specified <code>delay</code> ticks of delay.
|
||||
* Scheduled functions run at the end of the tick, and they will run in order they were scheduled.</p>
|
||||
@@ -2608,7 +2685,9 @@ public class CarpetExpression
|
||||
Value v = lv.get(0).evalValue(c);
|
||||
if (v instanceof NBTSerializableValue)
|
||||
return (cc, tt) -> v;
|
||||
Value ret = new NBTSerializableValue(v.getString());
|
||||
Value ret = NBTSerializableValue.parseString(v.getString());
|
||||
if (ret == null)
|
||||
return LazyValue.NULL;
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
@@ -3005,22 +3084,25 @@ public class CarpetExpression
|
||||
* <h2></h2>
|
||||
* <h3>Event list</h3>
|
||||
* <p>Here is a list of events that can be handled by scarpet. This list includes prefixes required by modules to
|
||||
* autoload them, but you can add any function to any event if it had required parameters:</p>
|
||||
* autoload them, but you can add any function to any event if it accepts required number of parameters:</p>
|
||||
* <pre>
|
||||
* __on_tick() // can access blocks and entities in the overworld
|
||||
* __on_tick_nether() // can access blocks and entities in the nether
|
||||
* __on_tick_ender() // can access blocks and entities in the end
|
||||
*
|
||||
* // player specific callbacks
|
||||
* __on_player_uses_item(player, item_tuple, hand) // right click action
|
||||
* __on_player_releases_item(player, item_tuple, hand) // client action (e.g. bow)
|
||||
* __on_player_finishes_using_item(player, item_tuple, hand)) // server action (e.g. food), called item is from before it is used.
|
||||
* __on_player_clicks_block(player, block, face) // left click attack on a block
|
||||
* __on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec)
|
||||
* __on_player_breaks_block(player, block) // called after block is broken (the caller receives previous blockstate)
|
||||
* __on_player_interacts_with_entity(player, entity, hand)
|
||||
* __on_player_attacks_entity(player, entity)
|
||||
* __on_player_rides(player, forward, strafe, jumping, sneaking)
|
||||
* __on_player_jumps(player)
|
||||
* __on_player_deploys_elytra(player)
|
||||
* __on_player_wakes_up(player)
|
||||
* __on_player_rides(player, forward, strafe, jumping, sneaking)
|
||||
* __on_player_uses_item(player, item_tuple, hand)
|
||||
* __on_player_clicks_block(player, block, face)
|
||||
* __on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec)
|
||||
* __on_player_breaks_block(player, block)
|
||||
* __on_player_interacts_with_entity(player, entity, hand)
|
||||
* __on_player_attacks_entity(player, entity)
|
||||
* __on_player_starts_sneaking(player)
|
||||
* __on_player_stops_sneaking(player)
|
||||
* __on_player_starts_sprinting(player)
|
||||
@@ -3028,7 +3110,10 @@ public class CarpetExpression
|
||||
* </pre>
|
||||
* <h3><code>/script event</code> command</h3>
|
||||
* <p>used to display current events and bounded functions. use <code>add_to</code> ro register new event, or <code>remove_from</code>
|
||||
* to unbind a specific function from an event.</p>
|
||||
* to unbind a specific function from an event. Function to be bounded to an event needs to have the same
|
||||
* number of parameters as the action is attempting to bind to (see list above). All calls in modules
|
||||
* loaded via <code>/script load</code> that have functions listed above will be automatically bounded and unbounded when
|
||||
* script is unloaded.</p>
|
||||
* </div>
|
||||
*/
|
||||
public void gameEventsSystem()
|
||||
|
||||
Reference in new issue
Block a user