# Copyright (c) 1997 Cabochon Technologies, Inc. All rights reserved. """ Teleports caster randomly a few squares away. Author: rhialto """ from wyvern.lib import Point, Range from wyvern.lib.classes.magic import Spell class blink(Spell): def start(self): """Tries a number of times to teleport the caster.""" if self.fails_preconditions(): return level = self.compute_level() failed, x, y = self.computeDestination(level) if failed: self.tellCaster('The spell fails!') return path = self.agent.map.virtualPath cmd = "teleport %s %d %d" % (path, x, y) self.agent.commandNow(cmd) def computeDestination(self, level): """Finds a destination point for the teleport. Pass: - level: the spell level (affects num retries) Returns three values: - failed: true if we couldn't find a free point inside the map bounds, else false - x: the x location to blink to (if not failed) - y: the y location to blink to (if not failed) """ agent = self.agent map = self.agent.map bounds = map.bounds failed = 1 success = 0 ref = agent.referenceLoc refx, refy = ref.x(), ref.y() count = level while count > 0: count = count - 1 # choose random location 0 to 3 squares away # (maybe 3 should go up with another element skill?) x, y = self.random_offsets() nx = refx + x ny = refy + y p = Point(nx, ny) if (bounds.contains(nx, ny) and agent.canMoveTo(map, p)): return success, nx, ny return failed, 0, 0 def random_offsets(self): """Chooses a random pair of (x, y) offsets. Will not return (0, 0). """ x = 0 y = 0 while x == 0 and y == 0: x = Range.randomValue(-3, 3) y = Range.randomValue(-3, 3) return x, y def fails_preconditions(self): """Returns true if there's no caster, or the map doesn't support teleporting. Issues appropriate message to caster. """ if self.agent is None or self.agent.map is None: return 1 agent = self.agent if agent.map.hasProperty('no-teleport'): if self.agent.isWizard(): return 0 agent.message('You cannot teleport here.') return 1 # passed all preconditions return 0 def compute_level(self): """Computes spell level based on SPIRIT skill. Never returns less than 1. """ level = self.getLevel(self.SPIRIT) * 2 + 4 if level < 1: level = 1 return level |