added . operator, changed priorities of ~ and ., cleaned entity_event handler and docs, replaced default call function to space, added stacktrace to unknown exceptions, renamed event to 'on_damaged'
This commit is contained in:
1 parent
99af49661b
commit
aac313bbb3
4 files changed
+57
-12
No files matched your search
@@ -235,7 +235,7 @@ public class CarpetEventServer
|
||||
private ScheduledCall makeEventCall(CarpetContext cc, String function, List<Value> extraArgs, int argCount)
|
||||
{
|
||||
UserDefinedFunction udf = cc.host.globalFunctions.get(function);
|
||||
if (udf == null || (udf.getArguments().size()-extraArgs.size()) != argCount)
|
||||
if (udf == null || (udf.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argCount)
|
||||
{
|
||||
// call won't match arguments
|
||||
return null;
|
||||
@@ -389,11 +389,9 @@ public class CarpetEventServer
|
||||
}
|
||||
public ScheduledCall makeDamageCall(CarpetContext cc, String function, List<Value> extraArgs)
|
||||
{
|
||||
return makeEventCall(cc, function, extraArgs, 3);
|
||||
return makeEventCall(cc, function, extraArgs, 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void onEntityDeath(ScheduledCall call, Entity e, String reason)
|
||||
{
|
||||
call.execute( Arrays.asList( (c, t)-> new EntityValue(e), (c, t)-> new StringValue(reason)));
|
||||
|
||||
@@ -1586,6 +1586,43 @@ 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>
|
||||
*/
|
||||
|
||||
|
||||
@@ -309,6 +309,7 @@ import static java.lang.Math.min;
|
||||
public class Expression implements Cloneable
|
||||
{
|
||||
private static final Map<String, Integer> precedence = new HashMap<String,Integer>() {{
|
||||
put("attribute~.", 80);
|
||||
put("unary+-!", 60);
|
||||
put("exponent^", 40);
|
||||
put("multiplication*/%", 30);
|
||||
@@ -560,7 +561,8 @@ public class Expression implements Cloneable
|
||||
return new ExpressionException(e, token, "Your math is wrong, "+exc.getMessage());
|
||||
if (exc instanceof ExpressionException)
|
||||
return exc;
|
||||
return new ExpressionException(e, token, "Error while evaluating expression: "+exc.getMessage());
|
||||
exc.printStackTrace();
|
||||
return new ExpressionException(e, token, "Error while evaluating expression: "+exc);
|
||||
}
|
||||
|
||||
private void addUnaryOperator(String surface, boolean leftAssoc, Function<Value, Value> fun)
|
||||
@@ -912,7 +914,7 @@ public class Expression implements Cloneable
|
||||
public void UserDefinedFunctionsAndControlFlow() // public just to get the javadoc right
|
||||
{
|
||||
// artificial construct to handle user defined functions and function definitions
|
||||
addLazyFunction(".",-1, (c, t, lv) -> { // adjust based on c
|
||||
addLazyFunction(" ",-1, (c, t, lv) -> { // adjust based on c
|
||||
String name = lv.get(lv.size()-1).evalValue(c).getString();
|
||||
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
||||
if (t != Context.SIGNATURE) // just call the function
|
||||
@@ -1062,11 +1064,12 @@ public class Expression implements Cloneable
|
||||
* note, that commas and brackets are not operators, but behave like them:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Match, Get<code>~ .</code></li>
|
||||
* <li>Unary <code>+ - !</code></li>
|
||||
* <li>Exponent <code>^</code></li>
|
||||
* <li>Multiplication <code>* / %</code></li>
|
||||
* <li>Addition <code>+ -</code></li>
|
||||
* <li>Comparison <code>== != > >= <= < ~</code></li>
|
||||
* <li>Comparison <code>== != > >= <= <</code></li>
|
||||
* <li>Logical And<code>&&</code></li>
|
||||
* <li>Logical Or <code>||</code></li>
|
||||
* <li>Assignment <code>= += <></code></li>
|
||||
@@ -1140,8 +1143,14 @@ public class Expression implements Cloneable
|
||||
* null != false && run('kill gnembon') => 1 // gnembon dies, cheats allowed
|
||||
* </pre>
|
||||
*
|
||||
* <h3><code>Get, Accessor Operator .</code></h3>
|
||||
* <p>Operator version of the <code>get(...)</code> function to access elements of lists, nbts, and potentially other
|
||||
* containers. It is important to distinguish from <code>~</code> operator, which is a matching operator, meaning it
|
||||
* is expected to perform some extra computations to retrieve the result, while <code>.</code> should be
|
||||
* straightforward and immediate.</p>
|
||||
*
|
||||
* <h3><code>Matching Operator ~</code></h3>
|
||||
* <p>This operator should be understood as 'matches', or 'in'. For strings it matches the right operand as a regular
|
||||
* <p>This operator should be understood as 'matches', 'contains' or 'is_in'. For strings it matches the right operand as a regular
|
||||
* expression to the left one, returning the first match. This can be used to extract information from unparsed nbt's
|
||||
* in a more efficient way. For lists it checks if an element is in the list, and returns the index of that element,
|
||||
* or <code>null</code> if no such element was found, especially that the use of <code>first</code> function will not
|
||||
@@ -1161,7 +1170,7 @@ public class Expression implements Cloneable
|
||||
* <pre>
|
||||
* entities = entities_area('all',x,y,z,100,10,100);
|
||||
* sid = entities ~ 'Squid';
|
||||
* if(sid != null, run('execute as '+query(element(entities,sid),'id')+' run say I am here '+query(element(entities,sid),'pos') ) )
|
||||
* if(sid != null, run('execute as '+query(get(entities,sid),'id')+' run say I am here '+query(get(entities,sid),'pos') ) )
|
||||
* </pre>
|
||||
* <p>Or an example to find if a player has specific enchantment on a held axe (either hand) and get its level
|
||||
* (despite obvious lack of support for json NBT's):</p>
|
||||
@@ -1218,6 +1227,7 @@ public class Expression implements Cloneable
|
||||
*/
|
||||
public void Operators()
|
||||
{
|
||||
addBinaryOperator(".", precedence.get("attribute~."),true, Value::getElementAt);
|
||||
addBinaryOperator("+", precedence.get("addition+-"), true, Value::add);
|
||||
addBinaryOperator("-", precedence.get("addition+-"), true, Value::subtract);
|
||||
addBinaryOperator("*", precedence.get("multiplication*/%"), true, Value::multiply);
|
||||
@@ -1243,7 +1253,7 @@ public class Expression implements Cloneable
|
||||
return v2.getBoolean() ? ((cc, tt) -> v2) : LazyValue.FALSE;
|
||||
});
|
||||
|
||||
addBinaryOperator("~", precedence.get("compare>=><=<"), true, Value::in);
|
||||
addBinaryOperator("~", precedence.get("attribute~."), true, Value::in);
|
||||
|
||||
addBinaryOperator(">", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||
v1.compareTo(v2) > 0 ? Value.TRUE : Value.FALSE);
|
||||
@@ -2890,7 +2900,7 @@ public class Expression implements Cloneable
|
||||
}
|
||||
else // potentially unknown function or just unknown function
|
||||
{
|
||||
f = functions.get(".");
|
||||
f = functions.get(" ");
|
||||
p = new ArrayList<>();
|
||||
}
|
||||
// pop parameters off the stack until we hit the start of
|
||||
|
||||
@@ -728,6 +728,6 @@ public class EntityValue extends Value
|
||||
put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l));
|
||||
put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l));
|
||||
put("on_tick", (c, e, f, l) -> ((EntityInterface)e).setTickCallback(c, f, l));
|
||||
put("on_damage", (c, e, f, l) -> ((EntityInterface)e).setDamageCallback(c, f, l));
|
||||
put("on_damaged", (c, e, f, l) -> ((EntityInterface)e).setDamageCallback(c, f, l));
|
||||
}};
|
||||
}
|
||||
Reference in new issue
Block a user