# 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
|