import importlib from math import floor, ceil, sqrt, hypot import blocks importlib.reload(blocks) import data TICK = 0.05 def padd(p1, p2): return (p1[0] + p2[0], p1[1] + p2[1], p1[2] + p2[2]) def psub(p1, p2): return (p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]) def pmul(p, s): return (s*p[0], s*p[1], s*p[2]) def phyp(p1, p2): return hypot(p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]) def phyp_bias(p1, p2, origin): origin_distance = phyp(origin, p2) height_diff = p2[1] - p1[1] height_diff = height_diff*8 if height_diff < 0 else height_diff*0.5 return hypot(p1[0] - p2[0], height_diff, p1[2] - p2[2]) + origin_distance*0.5 def pint(p): return (floor(p[0]), floor(p[1]), floor(p[2])) def cap(x, amount): sign = 1 if x >= 0 else -1 return sign * min(abs(x), amount) def spiral(n): # return x, 0, z coords along a spiral at step n # I forget where I found this n += 1 k = ceil((sqrt(n)-1)/2) t = 2 * k + 1 m = t**2 t = t - 1 if n >= m-t: return k-(m-n), 0, -k else: m = m-t if n >= m-t: return -k, 0, -k+(m-n) else: m = m-t if n >= m-t: return -k+(m-n), 0, k else: return k, 0, k-(m-n-t) def alternate(n, amount): # return 0, y, 0 where y alternates +/- by amount # example: 0, 2, -2, 4, -4, 6, -6 for amount = 2 sign = 1 if n % 2 else -1 return (0, ceil(n/2) * sign * amount, 0) def diffrange(n): # same as range(n+1) but can go negative sign = 1 if n >= 0 else -1 return range(0, n+sign, sign) def break_time(block_id, held_item=0, in_water=False, on_ground=True, enchantments=[], effects={}): # from PrismarineJS/prismarine-block block_data = blocks.get(block_id) can_harvest = 'harvestTools' not in block_data or str(held_item) in block_data['harvestTools'] material = block_data.get('material', 'n/a') tool_multipliers = data.mcd.materials.get(material, []) is_best_tool = held_item in tool_multipliers time = block_data['hardness'] if can_harvest: time *= 1.5 else: time *= 5.0 if is_best_tool: speed_multiplier = tool_multipliers[held_item] # TODO: calc efficiency, haste, mining fatigue else: speed_multiplier = 1.0 time /= speed_multiplier if in_water: time *= 5.0 if not on_ground: time *= 5.0 return time