Mercurial > touhou
changeset 471:06f0eeb519bb
Make Laser and Orb extension types, and use that where possible.
| author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
|---|---|
| date | Mon, 16 Sep 2013 18:42:04 +0200 |
| parents | 98995d8ac744 |
| children | 8038f1957b71 |
| files | pytouhou/game/enemy.pyx pytouhou/game/game.pxd pytouhou/game/game.pyx pytouhou/game/laser.pxd pytouhou/game/laser.py pytouhou/game/laser.pyx pytouhou/game/orb.pxd pytouhou/game/orb.py pytouhou/game/player.pyx pytouhou/games/eosd.py pytouhou/vm/eclrunner.py |
| diffstat | 11 files changed, 339 insertions(+), 289 deletions(-) [+] |
line wrap: on
line diff
--- a/pytouhou/game/enemy.pyx Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/game/enemy.pyx Mon Sep 16 18:42:04 2013 +0200 @@ -17,7 +17,7 @@ from pytouhou.vm.anmrunner import ANMRunner from pytouhou.game.sprite import Sprite from pytouhou.game.bullet cimport Bullet, LAUNCHED -from pytouhou.game.laser import Laser +from pytouhou.game.laser cimport Laser, PlayerLaser from pytouhou.game.effect cimport Effect @@ -301,8 +301,9 @@ cdef void check_collisions(self): cdef Bullet bullet cdef Player player + cdef PlayerLaser laser cdef long damages - cdef double half_size[2], lx, ly, phalf_size + cdef double half_size[2], phalf_size # Check for collisions ex, ey = self.x, self.y
--- a/pytouhou/game/game.pxd Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/game/game.pxd Mon Sep 16 18:42:04 2013 +0200 @@ -21,6 +21,7 @@ cpdef drop_bonus(self, double x, double y, long _type, end_pos=*) cdef void autocollect(self, Player player) except * cdef void cancel_bullets(self) except * + cdef void cancel_player_lasers(self) except * cpdef change_bullets_into_star_items(self) cpdef change_bullets_into_bonus(self) cpdef kill_enemies(self)
--- a/pytouhou/game/game.pyx Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/game/game.pyx Mon Sep 16 18:42:04 2013 +0200 @@ -19,6 +19,7 @@ from pytouhou.game.enemy cimport Enemy from pytouhou.game.item cimport Item from pytouhou.game.effect cimport Particle +from pytouhou.game.laser cimport Laser, PlayerLaser from pytouhou.game.text import Text, NativeText from pytouhou.game.face import Face @@ -145,17 +146,24 @@ cdef void cancel_bullets(self): cdef Bullet bullet - #TODO: cdef Laser laser + cdef Laser laser for bullet in self.bullets: bullet.cancel() for laser in self.lasers: laser.cancel() + cdef void cancel_player_lasers(self): + cdef PlayerLaser laser + for laser in self.players_lasers: + if laser is not None: + laser.cancel() + cpdef change_bullets_into_star_items(self): cdef Player player cdef Bullet bullet + cdef Laser laser player = self.players[0] #TODO item_type = self.item_types[6] @@ -253,6 +261,7 @@ cpdef run_iter(self, long keystate): + cdef Laser laser # 1. VMs. for runner in self.ecl_runners: runner.run_iter() @@ -371,6 +380,9 @@ cdef Player player cdef Bullet bullet cdef Item item + cdef PlayerLaser player_laser + cdef Laser laser + cdef double player_pos[2] if self.time_stop: return @@ -381,9 +393,9 @@ for bullet in self.bullets: bullet.update() - for laser in self.players_lasers: - if laser is not None: - laser.update() + for player_laser in self.players_lasers: + if player_laser is not None: + player_laser.update() for item in self.items: item.update() @@ -395,6 +407,7 @@ continue px, py = player_state.x, player_state.y + player_pos[:] = [px, py] phalf_size = <double>player.sht.hitbox px1, px2 = px - phalf_size, px + phalf_size py1, py2 = py - phalf_size, py + phalf_size @@ -404,10 +417,10 @@ gy1, gy2 = py - ghalf_size, py + ghalf_size for laser in self.lasers: - if laser.check_collision((px, py)): + if laser.check_collision(player_pos): if player_state.invulnerable_time == 0: player.collide() - elif laser.check_grazing((px, py)): + elif laser.check_grazing(player_pos): player_state.graze += 1 #TODO player_state.score += 500 #TODO player.play_sound('graze') @@ -460,6 +473,7 @@ cdef Enemy enemy cdef Bullet bullet cdef Item item + cdef PlayerLaser laser cdef long i # Filter out non-visible enemies
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytouhou/game/laser.pxd Mon Sep 16 18:42:04 2013 +0200 @@ -0,0 +1,44 @@ +from pytouhou.game.element cimport Element +from pytouhou.game.sprite cimport Sprite +from pytouhou.game.game cimport Game + +cdef enum State: + STARTING, STARTED, STOPPING + + +cdef class LaserLaunchAnim(Element): + cdef Laser _laser + + cpdef update(self) + + +cdef class Laser(Element): + cdef public unsigned long frame + cdef public double angle + + cdef unsigned long start_duration, duration, stop_duration, grazing_delay, + cdef unsigned long grazing_extra_duration, sprite_idx_offset + cdef double base_pos[2], speed, start_offset, end_offset, max_length, width + cdef State state + cdef Game _game + cdef object _laser_type + + cdef void set_anim(self, long sprite_idx_offset=*) except * + cpdef set_base_pos(self, double x, double y) + cdef bint _check_collision(self, double point[2], double border_size) + cdef bint check_collision(self, double point[2]) + cdef bint check_grazing(self, double point[2]) + #def get_bullets_pos(self) + cpdef cancel(self) + cpdef update(self) + + +cdef class PlayerLaser(Element): + cdef double hitbox[2], angle, offset + cdef unsigned long frame, duration, sprite_idx_offset, damage + cdef Element origin + cdef object _laser_type + + cdef void set_anim(self, long sprite_idx_offset=*) except * + cdef void cancel(self) except * + cdef void update(self) except *
--- a/pytouhou/game/laser.py Mon Sep 16 18:41:51 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,256 +0,0 @@ -# -*- encoding: utf-8 -*- -## -## Copyright (C) 2012 Thibaut Girka <thib@sitedethib.com> -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published -## by the Free Software Foundation; version 3 only. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## - -from math import cos, sin, pi - -from pytouhou.game.element import Element -from pytouhou.vm.anmrunner import ANMRunner -from pytouhou.game.sprite import Sprite - - -STARTING, STARTED, STOPPING = range(3) - - -class LaserLaunchAnim(Element): - def __init__(self, laser, anm, index): - Element.__init__(self, (0, 0)) - - self._laser = laser - self.sprite = Sprite() - self.sprite.anm = anm - self.sprite.texcoords = anm.sprites[index] - self.sprite.blendfunc = 1 - - - def update(self): - laser = self._laser - length = min(laser.end_offset - laser.start_offset, laser.max_length) - offset = laser.end_offset - length - dx, dy = cos(laser.angle), sin(laser.angle) - - self.x = laser.base_pos[0] + offset * dx - self.y = laser.base_pos[1] + offset * dy - - scale = laser.width / 10. - (offset - laser.start_offset) #TODO: check - self.sprite.rescale = (scale, scale) - self.sprite.changed = True - - if laser.removed or scale <= 0.: - self.removed = True - - - -class Laser(Element): - def __init__(self, base_pos, laser_type, sprite_idx_offset, - angle, speed, start_offset, end_offset, max_length, width, - start_duration, duration, stop_duration, - grazing_delay, grazing_extra_duration, - game): - Element.__init__(self, (0, 0)) - - self._game = game - launch_anim = LaserLaunchAnim(self, laser_type.anm, - laser_type.launch_anim_offsets[sprite_idx_offset] - + laser_type.launch_sprite_idx) - self._game.effects.append(launch_anim) - self._laser_type = laser_type - self.state = STARTING - - #TODO: hitbox - - self.frame = 0 - self.start_duration = start_duration - self.duration = duration - self.stop_duration = stop_duration - self.grazing_delay = grazing_delay - self.grazing_extra_duration = grazing_extra_duration - - self.sprite_idx_offset = sprite_idx_offset - self.base_pos = base_pos - self.angle = angle - self.speed = speed - self.start_offset = start_offset - self.end_offset = end_offset - self.max_length = max_length - self.width = width - - self.set_anim() - - - def set_anim(self, sprite_idx_offset=None): - if sprite_idx_offset is not None: - self.sprite_idx_offset = sprite_idx_offset - - lt = self._laser_type - self.sprite = Sprite() - self.sprite.angle = self.angle - self.anmrunner = ANMRunner(lt.anm, lt.anim_index, - self.sprite, self.sprite_idx_offset) - - - def _check_collision(self, point, border_size): - x, y = point[0] - self.base_pos[0], point[1] - self.base_pos[1] - dx, dy = cos(self.angle), sin(self.angle) - dx2, dy2 = -dy, dx - - length = min(self.end_offset - self.start_offset, self.max_length) - offset = self.end_offset - length - border_size / 2. - end_offset = self.end_offset + border_size / 2. - half_width = self.width / 4. + border_size / 2. - - c1 = dx * offset - dx2 * half_width, dy * offset - dy2 * half_width - c2 = dx * offset + dx2 * half_width, dy * offset + dy2 * half_width - c3 = dx * end_offset + dx2 * half_width, dy * end_offset + dy2 * half_width - vx, vy = x - c2[0], y - c2[1] - v1x, v1y = c1[0] - c2[0], c1[1] - c2[1] - v2x, v2y = c3[0] - c2[0], c3[1] - c2[1] - - return (0 <= vx * v1x + vy * v1y <= v1x * v1x + v1y * v1y - and 0 <= vx * v2x + vy * v2y <= v2x * v2x + v2y * v2y) - - - def check_collision(self, point): - if self.state != STARTED: - return False - - return self._check_collision(point, 2.5) - - - def check_grazing(self, point): - #TODO: quadruple check! - if self.state == STOPPING and self.frame >= self.grazing_extra_duration: - return False - if self.state == STARTING and self.frame <= self.grazing_delay: - return False - if self.frame % 12 != 0: - return False - - return self._check_collision(point, 96 + 2.5) - - - def get_bullets_pos(self): - #TODO: check - length = min(self.end_offset - self.start_offset, self.max_length) - offset = self.end_offset - length - dx, dy = cos(self.angle), sin(self.angle) - while self.start_offset <= offset < self.end_offset: - yield (self.base_pos[0] + offset * dx, self.base_pos[1] + offset * dy) - offset += 48. - - - def cancel(self): - self.grazing_extra_duration = 0 - if self.state != STOPPING: - self.frame = 0 - self.state = STOPPING - - - def update(self): - if self.anmrunner is not None and not self.anmrunner.run_frame(): - self.anmrunner = None - - self.end_offset += self.speed - - length = min(self.end_offset - self.start_offset, self.max_length) # TODO - if self.state == STARTING: - if self.frame == self.start_duration: - self.frame = 0 - self.state = STARTED - else: - width = self.width * float(self.frame) / self.start_duration #TODO - if self.state == STARTED: - width = self.width #TODO - if self.frame == self.duration: - self.frame = 0 - self.state = STOPPING - if self.state == STOPPING: - if self.frame == self.stop_duration: - width = 0. - self.removed = True - else: - width = self.width * (1. - float(self.frame) / self.stop_duration) #TODO - - offset = self.end_offset - length / 2. - self.x, self.y = self.base_pos[0] + offset * cos(self.angle), self.base_pos[1] + offset * sin(self.angle) - self.sprite.visible = (width > 0 and length > 0) - self.sprite.width_override = width - self.sprite.height_override = length - - self.sprite.update_orientation(pi/2. - self.angle, True) - self.sprite.changed = True #TODO - - self.frame += 1 - - -class PlayerLaser(Element): - def __init__(self, laser_type, sprite_idx_offset, hitbox, damage, - angle, offset, duration, origin): - Element.__init__(self) - - self._laser_type = laser_type - self.origin = origin - - self.hitbox = hitbox[0], hitbox[1] - - self.frame = 0 - self.duration = duration - - self.sprite_idx_offset = sprite_idx_offset - self.angle = angle - self.offset = offset - self.damage = damage - - self.set_anim() - - - @property - def x(self): - return self.origin.x + self.offset * cos(self.angle) - - - @property - def y(self): - return self.origin.y / 2. + self.offset * sin(self.angle) - - - def set_anim(self, sprite_idx_offset=None): - if sprite_idx_offset is not None: - self.sprite_idx_offset = sprite_idx_offset - - lt = self._laser_type - self.sprite = Sprite() - self.anmrunner = ANMRunner(lt.anm, lt.anim_index, - self.sprite, self.sprite_idx_offset) - #self.sprite.blendfunc = 1 #XXX - - - def cancel(self): - self.anmrunner.interrupt(1) - - - def update(self): - if self.anmrunner is not None and not self.anmrunner.run_frame(): - self.anmrunner = None - self.removed = True - - length = self.origin.y - if self.frame == self.duration: - self.cancel() - - self.sprite.visible = (length > 0) - self.sprite.height_override = length - self.sprite.changed = True #TODO - - self.frame += 1 -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytouhou/game/laser.pyx Mon Sep 16 18:42:04 2013 +0200 @@ -0,0 +1,253 @@ +# -*- encoding: utf-8 -*- +## +## Copyright (C) 2012 Thibaut Girka <thib@sitedethib.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +from libc.math cimport cos, sin, M_PI as pi + +from pytouhou.vm.anmrunner import ANMRunner + + +cdef class LaserLaunchAnim(Element): + def __init__(self, Laser laser, anm, unsigned long index): + Element.__init__(self, (0, 0)) + + self._laser = laser + self.sprite = Sprite() + self.sprite.anm = anm + self.sprite.texcoords = anm.sprites[index] + self.sprite.blendfunc = 1 + + + cpdef update(self): + laser = self._laser + length = <double>min(laser.end_offset - laser.start_offset, laser.max_length) + offset = laser.end_offset - length + dx, dy = cos(laser.angle), sin(laser.angle) + + self.x = laser.base_pos[0] + offset * dx + self.y = laser.base_pos[1] + offset * dy + + scale = laser.width / 10. - (offset - laser.start_offset) #TODO: check + self.sprite.rescale = (scale, scale) + self.sprite.changed = True + + if laser.removed or scale <= 0.: + self.removed = True + + + +cdef class Laser(Element): + def __init__(self, tuple base_pos, laser_type, + unsigned long sprite_idx_offset, double angle, double speed, + double start_offset, double end_offset, double max_length, + double width, unsigned long start_duration, + unsigned long duration, unsigned long stop_duration, + unsigned long grazing_delay, + unsigned long grazing_extra_duration, Game game): + Element.__init__(self, (0, 0)) + + self._game = game + launch_anim = LaserLaunchAnim(self, laser_type.anm, + laser_type.launch_anim_offsets[sprite_idx_offset] + + laser_type.launch_sprite_idx) + self._game.effects.append(launch_anim) + self._laser_type = laser_type + self.state = STARTING + + #TODO: hitbox + + self.frame = 0 + self.start_duration = start_duration + self.duration = duration + self.stop_duration = stop_duration + self.grazing_delay = grazing_delay + self.grazing_extra_duration = grazing_extra_duration + + self.sprite_idx_offset = sprite_idx_offset + self.set_base_pos(base_pos[0], base_pos[1]) + self.angle = angle + self.speed = speed + self.start_offset = start_offset + self.end_offset = end_offset + self.max_length = max_length + self.width = width + + self.set_anim() + + + cdef void set_anim(self, long sprite_idx_offset=-1): + if sprite_idx_offset >= 0: + self.sprite_idx_offset = sprite_idx_offset + + lt = self._laser_type + self.sprite = Sprite() + self.sprite.angle = self.angle + self.anmrunner = ANMRunner(lt.anm, lt.anim_index, + self.sprite, self.sprite_idx_offset) + + + cpdef set_base_pos(self, double x, double y): + self.base_pos[:] = [x, y] + + + cdef bint _check_collision(self, double point[2], double border_size): + cdef double c1[2], c2[2], c3[2] + + x, y = point[0] - self.base_pos[0], point[1] - self.base_pos[1] + dx, dy = cos(self.angle), sin(self.angle) + dx2, dy2 = -dy, dx + + length = <double>min(self.end_offset - self.start_offset, self.max_length) + offset = self.end_offset - length - border_size / 2. + end_offset = self.end_offset + border_size / 2. + half_width = self.width / 4. + border_size / 2. + + c1[:] = [dx * offset - dx2 * half_width, dy * offset - dy2 * half_width] + c2[:] = [dx * offset + dx2 * half_width, dy * offset + dy2 * half_width] + c3[:] = [dx * end_offset + dx2 * half_width, dy * end_offset + dy2 * half_width] + vx, vy = x - c2[0], y - c2[1] + v1x, v1y = c1[0] - c2[0], c1[1] - c2[1] + v2x, v2y = c3[0] - c2[0], c3[1] - c2[1] + + return (0 <= vx * v1x + vy * v1y <= v1x * v1x + v1y * v1y + and 0 <= vx * v2x + vy * v2y <= v2x * v2x + v2y * v2y) + + + cdef bint check_collision(self, double point[2]): + if self.state != STARTED: + return False + + return self._check_collision(point, 2.5) + + + cdef bint check_grazing(self, double point[2]): + #TODO: quadruple check! + if self.state == STOPPING and self.frame >= self.grazing_extra_duration: + return False + if self.state == STARTING and self.frame <= self.grazing_delay: + return False + if self.frame % 12 != 0: + return False + + return self._check_collision(point, 96 + 2.5) + + + def get_bullets_pos(self): + #TODO: check + length = <double>min(self.end_offset - self.start_offset, self.max_length) + offset = self.end_offset - length + dx, dy = cos(self.angle), sin(self.angle) + while self.start_offset <= offset < self.end_offset: + yield (self.base_pos[0] + offset * dx, self.base_pos[1] + offset * dy) + offset += 48. + + + cpdef cancel(self): + self.grazing_extra_duration = 0 + if self.state != STOPPING: + self.frame = 0 + self.state = STOPPING + + + cpdef update(self): + if self.anmrunner is not None and not self.anmrunner.run_frame(): + self.anmrunner = None + + self.end_offset += self.speed + + length = <double>min(self.end_offset - self.start_offset, self.max_length) # TODO + if self.state == STARTING: + if self.frame == self.start_duration: + self.frame = 0 + self.state = STARTED + else: + width = self.width * float(self.frame) / self.start_duration #TODO + if self.state == STARTED: + width = self.width #TODO + if self.frame == self.duration: + self.frame = 0 + self.state = STOPPING + if self.state == STOPPING: + if self.frame == self.stop_duration: + width = 0. + self.removed = True + else: + width = self.width * (1. - float(self.frame) / self.stop_duration) #TODO + + offset = self.end_offset - length / 2. + self.x = self.base_pos[0] + offset * cos(self.angle) + self.y = self.base_pos[1] + offset * sin(self.angle) + self.sprite.visible = (width > 0 and length > 0) + self.sprite.width_override = width + self.sprite.height_override = length + + self.sprite.update_orientation(pi/2. - self.angle, True) + self.sprite.changed = True #TODO + + self.frame += 1 + + +cdef class PlayerLaser(Element): + def __init__(self, laser_type, unsigned long sprite_idx_offset, + tuple hitbox, unsigned long damage, double angle, + double offset, unsigned long duration, Element origin): + Element.__init__(self) + + self._laser_type = laser_type + self.origin = origin + + self.hitbox[:] = [hitbox[0], hitbox[1]] + + self.frame = 0 + self.duration = duration + + self.sprite_idx_offset = sprite_idx_offset + self.angle = angle + self.offset = offset + self.damage = damage + + self.set_anim() + + + cdef void set_anim(self, long sprite_idx_offset=-1): + if sprite_idx_offset >= 0: + self.sprite_idx_offset = sprite_idx_offset + + lt = self._laser_type + self.sprite = Sprite() + self.anmrunner = ANMRunner(lt.anm, lt.anim_index, + self.sprite, self.sprite_idx_offset) + #self.sprite.blendfunc = 1 #XXX + + + cdef void cancel(self): + self.anmrunner.interrupt(1) + + + cdef void update(self): + if self.anmrunner is not None and not self.anmrunner.run_frame(): + self.anmrunner = None + self.removed = True + + length = self.origin.y + if self.frame == self.duration: + self.cancel() + + self.sprite.visible = (length > 0) + self.sprite.height_override = length + self.sprite.changed = True #TODO + + self.x = self.origin.x + self.offset * cos(self.angle) + self.y = self.origin.y / 2. + self.offset * sin(self.angle) + + self.frame += 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytouhou/game/orb.pxd Mon Sep 16 18:42:04 2013 +0200 @@ -0,0 +1,10 @@ +from pytouhou.game.element cimport Element +from pytouhou.game.sprite cimport Sprite +from pytouhou.game.player cimport PlayerState + +cdef class Orb(Element): + cdef public double offset_x, offset_y + cdef PlayerState player_state + cdef object fire + + cpdef update(self)
--- a/pytouhou/game/orb.py Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/game/orb.py Mon Sep 16 18:42:04 2013 +0200 @@ -12,16 +12,11 @@ ## GNU General Public License for more details. ## - -from pytouhou.game.element import Element -from pytouhou.game.sprite import Sprite from pytouhou.vm.anmrunner import ANMRunner class Orb(Element): - __slots__ = ('offset_x', 'offset_y', 'player_state', 'fire') - - def __init__(self, anm, index, player_state, fire_func): + def __init__(self, anm, index, player_state): Element.__init__(self) self.sprite = Sprite() @@ -31,19 +26,9 @@ self.offset_y = 0 self.player_state = player_state - self.fire = fire_func - - - @property - def x(self): - return self.player_state.x + self.offset_x - - - @property - def y(self): - return self.player_state.y + self.offset_y def update(self): self.anmrunner.run_frame() - + self.x = self.player_state.x + self.offset_x + self.y = self.player_state.y + self.offset_y
--- a/pytouhou/game/player.pyx Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/game/player.pyx Mon Sep 16 18:42:04 2013 +0200 @@ -19,7 +19,7 @@ from pytouhou.game.bullettype import BulletType from pytouhou.game.bullet cimport Bullet from pytouhou.game.lasertype import LaserType -from pytouhou.game.laser import PlayerLaser +from pytouhou.game.laser cimport PlayerLaser class GameOver(Exception): @@ -247,9 +247,7 @@ self.state.power -= 16 else: self.state.power = 0 - for laser in self._game.players_lasers: - if laser is not None: - laser.cancel() + self._game.cancel_player_lasers() self.state.miss += 1 self.state.lives -= 1
--- a/pytouhou/games/eosd.py Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/games/eosd.py Mon Sep 16 18:42:04 2013 +0200 @@ -275,8 +275,8 @@ Player.__init__(self, state, game, self.anm) - self.orbs = [Orb(self.anm, 128, self.state, None), - Orb(self.anm, 129, self.state, None)] + self.orbs = [Orb(self.anm, 128, self.state), + Orb(self.anm, 129, self.state)] self.orbs[0].offset_x = -24 self.orbs[1].offset_x = 24
--- a/pytouhou/vm/eclrunner.py Mon Sep 16 18:41:51 2013 +0200 +++ b/pytouhou/vm/eclrunner.py Mon Sep 16 18:42:04 2013 +0200 @@ -728,7 +728,7 @@ except KeyError: pass #TODO else: - laser.base_pos = self._enemy.x + ox, self._enemy.y + oy + laser.set_base_pos(self._enemy.x + ox, self._enemy.y + oy) @instruction(92)
