def builtin_slope_to_sprite_offset(name, args, pos): """ builtin function slope_to_sprite_offset(slope) @return sprite offset to use """ if len(args) != 1: raise generic.ScriptError(name + "() must have 1 parameter", pos) if isinstance(args[0], ConstantNumeric): generic.check_range(args[0].value, 0, 15, "Argument of '{}'".format(name), args[0].pos) # step 1: ((slope >= 0) & (slope <= 14)) * slope # This handles all non-steep slopes expr = nmlop.AND(nmlop.CMP_LE(args[0], 14, pos), nmlop.CMP_GE(args[0], 0, pos)) expr = nmlop.MUL(expr, args[0]) # Now handle the steep slopes separately # So add (slope == SLOPE_XX) * offset_of_SLOPE_XX for each steep slope steep_slopes = [(23, 16), (27, 17), (29, 15), (30, 18)] for slope, offset in steep_slopes: to_add = nmlop.MUL(nmlop.CMP_EQ(args[0], slope, pos), offset) expr = nmlop.ADD(expr, to_add) return expr
def reduce(self, id_dicts=[], unknown_id_fatal=True): expr = self.expr.reduce(id_dicts) if expr.type() != Type.INTEGER: raise generic.ScriptError("Not-operator (!) requires an integer argument.", expr.pos) if isinstance(expr, ConstantNumeric): return ConstantNumeric(expr.value == 0) if isinstance(expr, Not): return Boolean(expr.expr).reduce() if isinstance(expr, BinOp): if expr.op == nmlop.CMP_EQ: return nmlop.CMP_NEQ(expr.expr1, expr.expr2) if expr.op == nmlop.CMP_NEQ: return nmlop.CMP_EQ(expr.expr1, expr.expr2) if expr.op == nmlop.CMP_LE: return nmlop.CMP_GT(expr.expr1, expr.expr2) if expr.op == nmlop.CMP_GE: return nmlop.CMP_LT(expr.expr1, expr.expr2) if expr.op == nmlop.CMP_LT: return nmlop.CMP_GE(expr.expr1, expr.expr2) if expr.op == nmlop.CMP_GT: return nmlop.CMP_LE(expr.expr1, expr.expr2) if expr.op == nmlop.HASBIT: return nmlop.NOTHASBIT(expr.expr1, expr.expr2) if expr.op == nmlop.NOTHASBIT: return nmlop.HASBIT(expr.expr1, expr.expr2) return Not(expr)
def value_equals(const): return lambda var, info: nmlop.CMP_EQ(var, const)