Esempio n. 1
0
 def cast(self, context):
     from level import expandingCircle
     cx, cy = cxcy = context.player.tile.x, context.player.tile.y
     movers = []
     from math import atan2, sqrt
     radius = 8
     perimeter = []
     for region in expandingCircle( cxcy, size = radius ):
         fx = {}
         for x, y in region:
             fx[x,y] = dict( ch = ' ', fg = 'white', bg = 'blue' )
             dx, dy = x-cx, y-cy
             try:
                 tile = context.player.tile.level.tiles[x,y]
                 if tile.mobile and tile.mobile.flying and tile.mobile not in movers:
                     movers.append( tile.mobile )
                 perimeter.append( (atan2(dy, dx), sqrt(dx*dx+dy*dy), tile ) )
             except KeyError:
                 pass
         context.game.showEffects( fx )
     movers.reverse()
     for mover in movers:
         mover.logVisual( "You are caught in the blast!", "%s is caught in the blast!" )
         mx, my = mover.tile.x, mover.tile.y
         from level import sign
         dx, dy = sign(mx-cx), sign(my-cy)
         dirs = [ (dx,dy) ]
         if dx and dy:
             dirs.append( (dx,0) )
             dirs.append( (0,dy) )
         elif dx:
             dirs.append( (dx,1) )
             dirs.append( (dx,-1) )
         elif dy:
             dirs.append( (1,dy) )
             dirs.append( (-1,dy) )
         ma = atan2( my - cy, mx - cx )
         actuallyMoved = 0
         for i in range( radius ):
             bestAdist = 2**30
             step = None
             for dx, dy in dirs:
                 tile = mover.tile.getRelative(dx,dy)
                 if not tile:
                     continue
                 if tile.cannotEnterBecause( mover ):
                     continue
                 ta = atan2( tile.y - cy, tile.x - cx )
                 adist = abs( ma - ta )
                 if adist < bestAdist:
                     bestAdist = adist
                     step = tile
             if not step:
                 break
             mover.moveto( step, neverfail = True )
             actuallyMoved += 1
         if actuallyMoved:
             duration = random.randint( actuallyMoved * 20, actuallyMoved * 40 )
             mover.addBuff( self, duration )
Esempio n. 2
0
 def trigger(self, mob):
     # the rook is entirely stationary unless it spots a clear
     # straight line to the player. If it does, moves 8 (radius)
     # tiles
     pl = mob.context.player
     if not playerAccessibleForMelee( mob ):
         return
     if pl.invisible:
         return
     dx, dy = sign(pl.tile.x - mob.tile.x), sign(pl.tile.y - mob.tile.y)
     if dx != 0 and dy != 0:
         return # not a straight line, stationary
     lastTile = None
     tile = mob.tile.getRelative( dx, dy )
     dist = 0
     while not tile.mobile == pl:
         if not tile:
             return
         if tile.cannotEnterBecause( mob ):
             return
         dist += 1
         lastTile = tile
         tile = tile.getRelative( dx, dy )
     tile = lastTile
     # target acquired!
     if dist >= self.radius:
         tile = mob.tile.getRelative( dx * self.radius, dy * self.radius )
         doAttack = False
     else:
         tile = pl.tile.getRelative( -dx, -dy )
         doAttack = True
     if not pl.canBeMeleeAttackedBy( mob ):
         doAttack = False
     aniTarget = pl.tile if doAttack else tile
     # show an animation, a ray from mob.tile to aniTarget
     raylen = max( abs(aniTarget.x - mob.tile.x), abs(aniTarget.y - mob.tile.y) )
     mob.context.game.showStraightRay( (mob.tile.x, mob.tile.y), (dx,dy), raylen, 'white', 'black' )
     if not tile.cannotEnterBecause( mob ): # notably, can't move to its own square
         mob.moveto( tile )
     if doAttack:
         mob.meleeAttack( pl )
Esempio n. 3
0
 def trigger(self, mob):
     p = mob.context.player
     dx,dy = sign( p.tile.x - mob.tile.x ), sign( p.tile.y - mob.tile.y )
     tile = mob.tile.getRelative( dx, dy )
     if not tile:
         return # omgwtf
     if tile.mobile:
         if tile.mobile != p:
             self.frustration += 1
             if self.frustration > 5:
                 mob.logVisualMon( "%s touches " + tile.mobile.name.definiteSingular() + "." )
                 if not tile.mobile.essential:
                     tile.mobile.logVisualMon( "%s fades out of existence." )
                     tile.mobile.kill( noTriggerHooks = True )
                 else:
                     mob.logVisualMon( "%s stares at " + tile.mobile.name.definiteSingular() + " in surprise." )
                     mob.logVisualMon( "%s fades out of existence." )
                     mob.kill()
         elif playerAccessibleForMelee( mob ):
             mob.meleeAttack( p ) # for spectres, an instakill
     else:
         mob.logVisualMon( "%s floats slowly but steadily towards you." )
         mob.moveto( tile )
         self.frustration = 0