Fire, relative: I'm certain the reference implementation is wrong.
[python-bulletml.git] / bulletml / impl.py
index 65d234a..9df26c6 100644 (file)
@@ -12,6 +12,8 @@ from bulletml import parser
 # TODO(jfw): This is very non-Pythonic, it's pretty much just the
 # BulletML reference ActionImpl translated to Python.
 
+PI_2 = math.pi * 2
+
 class Action(object):
     """Running action implementation."""
 
@@ -145,8 +147,11 @@ class Action(object):
                     if type == "sequence":
                         speed += self.previous_fire_speed
                     elif type == "relative":
-                        # FIXME(jfw): Reference impl uses prvFireSpeed
-                        # here?  That doesn't seem right at all.
+                        # The reference Noiz implementation uses
+                        # prvFireSpeed here, but the standard is
+                        # pretty clear -- "0 means that the direction
+                        # of this fire and the direction of the bullet
+                        # are the same".
                         speed += self.owner.speed
                 else:
                     speed = 1
@@ -177,7 +182,7 @@ class Action(object):
                     if type == "absolute":
                         self.aiming = False
                         self.direction = (
-                            direction - self.owner.direction) % 360
+                            direction - self.owner.direction) % PI_2
                     elif type == "relative":
                         self.aiming = False
                         self.direction = direction
@@ -186,12 +191,12 @@ class Action(object):
                         self.direction = (
                             direction
                             + self.owner.aim
-                            - self.owner.direction) % 360
+                            - self.owner.direction) % PI_2
 
-                    while self.direction > 180:
-                        self.direction -= 360
-                    while self.direction < -180:
-                        self.direction += 360
+                    while self.direction > math.pi:
+                        self.direction -= PI_2
+                    while self.direction < -math.pi:
+                        self.direction += PI_2
                     self.direction /= self.direction_frames
 
             elif isinstance(action, parser.Accel):
@@ -257,16 +262,17 @@ class Bullet(object):
         if self.target is None:
             return self.direction
         else:
-            return math.degrees(
-                math.atan2(self.target.x - self.x, self.y - self.target.y))
+            return math.atan2(self.target.x - self.x, self.y - self.target.y)
 
     @property
     def finished(self):
         """Check if this bullet is finished running."""
+        if not self.vanished:
+            return False
         for action in self.actions:
             if not action.finished:
                 return False
-        return self.vanished
+        return True
 
     def vanish(self):
         """Vanish this bullet and stop all actions."""
@@ -291,11 +297,10 @@ class Bullet(object):
         for action in self.actions:
             created.extend(action.step())
 
-        direction = math.radians(self.direction)
         self.px = self.x
         self.py = self.y
-        self.x += self.mx + math.sin(direction) * self.speed
-        self.y += self.my - math.cos(direction) * self.speed
+        self.x += self.mx + math.sin(self.direction) * self.speed
+        self.y += self.my - math.cos(self.direction) * self.speed
 
         return created