about summary refs log tree commit diff homepage
path: root/brutalmaze
diff options
context:
space:
mode:
authorNguyễn Gia Phong <vn.mcsinyx@gmail.com>2018-03-10 18:19:12 +0700
committerNguyễn Gia Phong <vn.mcsinyx@gmail.com>2018-03-10 18:19:12 +0700
commitace958677825cbde58a38911655f8011b0ee8131 (patch)
treee0c4725fafd28e376136bbd46c80d38157377b08 /brutalmaze
parentd7eb9071a0c06238d78fc69cb4e21855823e1ed9 (diff)
downloadbrutalmaze-ace958677825cbde58a38911655f8011b0ee8131.tar.gz
Fix several bugs 0.6.2
* Set connection timeout to avoid hanging along with the client
* Now visible Chameleons are exported in server mode
* Disable manual slashing's bullets blocking so that there won't be no delay after this type of attack that make aiming stiff
Diffstat (limited to 'brutalmaze')
-rw-r--r--brutalmaze/characters.py8
-rw-r--r--brutalmaze/game.py27
-rw-r--r--brutalmaze/maze.py10
-rw-r--r--brutalmaze/settings.ini2
4 files changed, 33 insertions, 14 deletions
diff --git a/brutalmaze/characters.py b/brutalmaze/characters.py
index daa97bc..e814d87 100644
--- a/brutalmaze/characters.py
+++ b/brutalmaze/characters.py
@@ -90,7 +90,7 @@ class Hero:
             self.next_strike = ATTACK_SPEED
             self.spin_queue = randsign() * self.spin_speed
             self.angle -= sign(self.spin_queue) * full_spin
-        if abs(self.spin_queue) > 0.5:
+        if round(self.spin_queue) != 0:
             self.angle += sign(self.spin_queue) * full_spin / self.spin_speed
             self.spin_queue -= sign(self.spin_queue)
         else:
@@ -104,12 +104,12 @@ class Hero:
 
     def update_angle(self, angle):
         """Turn to the given angle if the hero is not busy slashing."""
-        if abs(self.spin_queue) > 0.5: return
+        if round(self.spin_queue) != 0: return
         delta = (angle - self.angle + pi) % (pi * 2) - pi
         unit = pi * 2 / self.get_sides() / self.spin_speed
         if abs(delta) < unit:
             self.angle, self.spin_queue = angle, 0.0
-        elif self.next_strike <= 0:
+        else:
             self.spin_queue = delta / unit
 
     def get_color(self):
@@ -285,7 +285,7 @@ class Enemy:
                 self.spin_queue = randsign() * self.spin_speed
                 if not self.maze.hero.dead:
                     play(self.sfx_slash, self.get_slash(), self.get_angle())
-            if abs(self.spin_queue) > 0.5:
+            if round(self.spin_queue) != 0:
                 self.angle += sign(self.spin_queue) * pi / 2 / self.spin_speed
                 self.spin_queue -= sign(self.spin_queue)
             else:
diff --git a/brutalmaze/game.py b/brutalmaze/game.py
index affc4c0..afd2b29 100644
--- a/brutalmaze/game.py
+++ b/brutalmaze/game.py
@@ -17,7 +17,7 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with Brutal Maze.  If not, see <https://www.gnu.org/licenses/>.
 
-__version__ = '0.6.1'
+__version__ = '0.6.2'
 
 import re
 from argparse import ArgumentParser, FileType, RawTextHelpFormatter
@@ -73,6 +73,7 @@ class ConfigReader:
         self.server = self.config.getboolean('Server', 'Enable')
         self.host = self.config.get('Server', 'Host')
         self.port = self.config.getint('Server', 'Port')
+        self.timeout = self.config.getfloat('Server', 'Timeout')
         self.headless = self.config.getboolean('Server', 'Headless')
 
         if self.server: return
@@ -95,7 +96,7 @@ class ConfigReader:
     def read_args(self, arguments):
         """Read and parse a ArgumentParser.Namespace."""
         for option in ('size', 'max_fps', 'muted', 'musicvol',
-                       'server', 'host', 'port', 'headless'):
+                       'server', 'host', 'port', 'timeout', 'headless'):
             value = getattr(arguments, option)
             if value is not None: setattr(self, option, value)
 
@@ -122,6 +123,7 @@ class Game:
             self.server.listen(1)
             print('Socket server is listening on {}:{}'.format(config.host,
                                                                config.port))
+            self.timeout = config.timeout
             self.sockinp = 0, 0, -pi * 3 / 4, 0, 0  # freeze and point to NW
         else:
             self.server = self.sockinp = None
@@ -158,7 +160,8 @@ class Game:
             if not enemy.awake and walls:
                 walls[enemy.y-maze.rangey[0]][enemy.x-maze.rangex[0]] = WALL
                 continue
-            elif enemy.color == 'Chameleon' and maze.next_move <= 0:
+            # Check Chameleons
+            elif getattr(enemy, 'visible', 1) <= 0 and maze.next_move <= 0:
                 continue
             lines.append('{0} {2} {3} {1:.0f}'.format(
                 COLORS[enemy.get_color()], deg(enemy.angle),
@@ -253,9 +256,11 @@ class Game:
         clock = Clock()
         while True:
             connection, address = self.server.accept()
+            connection.settimeout(self.timeout)
             time = get_ticks()
             print('[{}] Connected to {}:{}'.format(time, *address))
             self.maze.reinit()
+            self.maze.score = 100000
             while True:
                 if self.hero.dead:
                     connection.send('0000000'.encode())
@@ -265,19 +270,22 @@ class Game:
                 connection.send(data)
                 try:
                     buf = connection.recv(7)
-                except:     # client is likely to be closed
+                except:     # client is closed or timed out
                     break
                 if not buf: break
-                move, angle, attack = (int(i) for i in buf.decode().split())
+                try:
+                    move, angle, attack = map(int, buf.decode().split())
+                except ValueError:  # invalid input
+                    break
                 y, x = (i - 1 for i in divmod(move, 3))
                 self.sockinp = x, y, radians(angle), attack & 1, attack >> 1
                 clock.tick(self.fps)
-            self.maze.lose()
             self.sockinp = 0, 0, -pi * 3 / 4, 0, 0
             new_time = get_ticks()
             print('[{0}] {3}:{4} scored {1} points in {2}ms'.format(
                 new_time, self.maze.get_score(), new_time - time, *address))
             connection.close()
+            if not self.hero.dead: self.maze.lose()
 
     def user_control(self):
         """Handle direct control from user's mouse and keyboard."""
@@ -350,11 +358,16 @@ def main():
     parser.add_argument('--no-server', action='store_false', dest='server',
                         help='disable server')
     parser.add_argument(
-        '--host', help='host to bind server to (fallback: {})'.format(config.host))
+        '--host', help='host to bind server to (fallback: {})'.format(
+            config.host))
     parser.add_argument(
         '--port', type=int,
         help='port for server to listen on (fallback: {})'.format(config.port))
     parser.add_argument(
+        '-t', '--timeout', type=float,
+        help='socket operations timeout in seconds (fallback: {})'.format(
+            config.timeout))
+    parser.add_argument(
         '--head', action='store_false', default=None, dest='headless',
         help='run server with graphics and sound (fallback: {})'.format(
             not config.headless))
diff --git a/brutalmaze/maze.py b/brutalmaze/maze.py
index 14e17d2..0516cb5 100644
--- a/brutalmaze/maze.py
+++ b/brutalmaze/maze.py
@@ -249,12 +249,16 @@ class Maze:
 
     def track_bullets(self):
         """Handle the bullets."""
-        fallen = []
         if (self.hero.firing and not self.hero.slashing
             and self.hero.next_strike <= 0):
             self.hero.next_strike = ATTACK_SPEED
             self.bullets.append(Bullet(self.surface, self.x, self.y,
                                        self.hero.angle, 'Aluminium'))
+
+        fallen = []
+        block = (self.hero.spin_queue and self.hero.next_heal <= 0
+                 and self.hero.next_strike > self.hero.spin_queue / self.fps)
+
         for i, bullet in enumerate(self.bullets):
             wound = bullet.fall_time / BULLET_LIFETIME
             bullet.update(self.fps, self.distance)
@@ -279,8 +283,8 @@ class Maze:
                         fallen.append(i)
                         break
             elif bullet.get_distance(self.x, self.y) < self.distance:
-                if self.hero.spin_queue and self.hero.next_heal <= 0:
-                    self.hero.next_strike = (abs(self.hero.spin_queue*self.fps)
+                if block:
+                    self.hero.next_strike = (abs(self.hero.spin_queue/self.fps)
                                              + ATTACK_SPEED)
                     play(bullet.sfx_missed, wound, bullet.angle + pi)
                 else:
diff --git a/brutalmaze/settings.ini b/brutalmaze/settings.ini
index a2bde8f..0641aad 100644
--- a/brutalmaze/settings.ini
+++ b/brutalmaze/settings.ini
@@ -30,5 +30,7 @@ Close-range attack: Mouse3
 Enable: no
 Host: localhost
 Port: 8089
+# Timeout on blocking socket operations, in seconds.
+Timeout: 1.0
 # Disable graphics and sound (only if socket server is enabled).
 Headless: no