Index: pycodeshooter/trunk/shooter/system.js
===================================================================
--- pycodeshooter/trunk/shooter/system.js	(revision 106)
+++ pycodeshooter/trunk/shooter/system.js	(revision 108)
@@ -22,9 +22,8 @@
     },
     "message":          null,
-    "boss":             null,
-    "player":           null,
+    "enemies":          new Array(),
+    "players":          new Array(),
     "backgroundObject": new Array(),
     "deathPieces":      new Array(),
-    "gameOver":         false,
     "mainIntervalId":   0
 };
@@ -32,5 +31,5 @@
 
 /*
- *  Tiun Tiun
+ *  Tiun Tiun Utilities
  */
 var DeathPiece = function(sizes, colors, x, y, dir, speed) {
@@ -55,8 +54,55 @@
 };
 
+function addDeathPieces(x, y, sizes, colors, speed, way) {
+    if (way % 2)
+        way++;
+
+    var pieces = new Array();
+    var angle  = 0;
+    var delta  = 2 / way;
+
+    for(var i = 0; i < way; i++) {
+        pieces.push(new DeathPiece(sizes, colors, x, y, angle * Math.PI, speed));
+        angle += delta;
+    }
+
+    System.deathPieces.push(pieces);
+}
+
+function updateDeathPieces(ctx, width, height) {
+    var newObjs = new Array();
+
+    for (var i = 0; i < System.deathPieces.length; i++) {
+        var pieces    = System.deathPieces[i];
+        var newPieces = new Array();
+
+        for (var k = 0; k < pieces.length; k++) {
+            pieces[k].next();
+            pieces[k].draw(ctx);
+            if (!pieces[k].vanished(width, height))
+                newPieces.push(pieces[k]);
+        }
+
+        if (newPieces.length)
+            newObjs.push(newPieces);
+    }
+
+    System.deathPieces = newObjs;
+}
+
 
 /*
  *  Utility Functions
  */
+function setMessage(elem, msg) {
+    if (elem)
+        elem.innerHTML = msg;
+}
+
+function addMessage(elem, msg) {
+    if (elem)
+        elem.innerHTML += msg;
+}
+
 function updateBackground(ctx, width, height, size, color, max) {
     if (System.backgroundObject.length < max) {
@@ -68,4 +114,5 @@
 
     var newObjs = new Array();
+
     for (var i = 0; i < System.backgroundObject.length; i++) {
         System.backgroundObject[i].next();
@@ -74,32 +121,6 @@
             newObjs.push(System.backgroundObject[i]);
     }
+
     System.backgroundObject = newObjs;
-}
-
-function updateDeathPieces(ctx, width, height, x, y, sizes, colors, speed, way) {
-    if (System.deathPieces.length <= 0) {
-        if (way % 2)
-            way++;
-
-        var angle = 0;
-        var delta = 2 / way;
-
-        for(i = 0; i < way; i++) {
-            System.deathPieces.push(
-                new DeathPiece(sizes, colors, x, y, angle * Math.PI, speed));
-            angle += delta;
-        }
-    }
-
-    var newObjs = new Array();
-    for (var i = 0; i < System.deathPieces.length; i++) {
-        System.deathPieces[i].next();
-        System.deathPieces[i].draw(ctx);
-        if (!System.deathPieces[i].vanished(width, height))
-            newObjs.push(System.deathPieces[i]);
-    }
-    System.deathPieces = newObjs;
-
-    return !System.deathPieces.length;
 }
 
@@ -151,47 +172,90 @@
 }
 
-function updateTrooper(trooper, enemy) {
-    if (System.gameOver) {
-        trooper.clearBullet();
-        enemy.clearBullet();
-
-        drawString(
-            System.screen.ctx, "source-over",
-            "GAME OVER",
-            System.screen.width / 2,
-            System.screen.height / 2,
-            "#ACF", "24pt monospace", "center"
-        );
-    }
-    else if (trooper.isDead()) {
-        trooper.clearBullet();
-        enemy.clearBullet();
-
-        System.gameOver = updateDeathPieces(
-            System.screen.ctx,
-            System.screen.width,
-            System.screen.height,
-            trooper.x,
-            trooper.y,
-            [6, 8, 10], ["#55F", "#AAF"], 3, 8
-        );
-    }
-    else if (enemy.isDead()) {
-        trooper.draw(System.screen.ctx);
-    }
-    else {
-        trooper.update(enemy);
-        trooper.draw(System.screen.ctx);
-    }
-}
-
-function setMessage(elem, msg) {
-    if (elem)
-        elem.innerHTML = msg;
-}
-
-function addMessage(elem, msg) {
-    if (elem)
-        elem.innerHTML += msg;
+function updateTrooper(trooper, enemyKey) {
+    trooper.update(System[enemyKey]);
+
+    var aliveEnemies = new Array();
+    for (var i = 0; i < System[enemyKey].length; i++) {
+        var enemy = System[enemyKey][i];
+
+        if (enemy.isDead()) {
+            addDeathPieces(
+                enemy.x, enemy.y,
+                [6, 8, 10], ["#55F", "#AAF"], 3, 8
+            );
+        }
+        else {
+            aliveEnemies.push(enemy);
+        }
+    }
+    System[enemyKey] = aliveEnemies;
+
+    trooper.draw(System.screen.ctx);
+}
+
+function addEnemy(enemyData) {
+    var actList = EnemyActionLists[enemyData.mtime % EnemyActionLists.length];
+    var shot    = EnemyShots[enemyData.hitpoint % EnemyShots.length];
+    var numAct  = enemyData.agility       % (EnemyActions.length  - 1) + 1;
+    var numBlt  = enemyData.skills.length % (EnemyBullets.length  - 1) + 1;
+    var numBrrg = enemyData.skills.length % (EnemyBarrages.length - 1) + 1;
+    var acts    = new Array();
+    var brrgs   = new Array();
+
+    var bulletWay         = Math.ceil(enemyData.concentration / 10);
+    var bulletInterval    = Math.round(50 * 1 / Math.log(enemyData.skillpoint + 0.1));
+    var bulletSize        = Math.round(Math.log(enemyData.luck + 1));
+    var bulletFrameWidth  = (bulletSize + 5) * 2;
+    var bulletFrameHeight = (bulletSize + 5) * 4;
+    var bulletSpeed       = enemyData.strength / 15;
+
+    bulletSpeed = Math.log(bulletSpeed < 1.5 ? 1.5 : bulletSpeed);
+
+    for (var i = 0; i < numAct; i++) {
+        var idx = (enemyData.agility + i) % EnemyActions.length;
+        acts.push(new EnemyActions[idx](new shot()));
+    }
+
+    for (var i = 0; i < numBrrg; i++) {
+        var idx     = (enemyData.skillpoint + i * (enemyData.skills.length + 1)) % EnemyBarrages.length;
+        var brrgCls = EnemyBarrages[idx];
+
+        for (var k = 0; k < numBlt; k++) {
+            var iidx = (enemyData.skills.length + i + k) % EnemyBullets.length;
+            brrgs.push(
+                new brrgCls(
+                    EnemyBullets[iidx],
+                    bulletSize,
+                    "#FF3",
+                    {"style": "rect", "color": "rgba(128,32,32,0.5)",
+                     "width": bulletFrameWidth, "height": bulletFrameHeight},
+                    bulletInterval,
+                    bulletSpeed,
+                    bulletWay
+                )
+            );
+        }
+    }
+
+    var size  = Math.ceil((System.screen.width / 2) * (1 / enemyData.defense));
+    var enemy = new Trooper(
+        enemyData.name,
+        new actList(acts),
+        size,
+        size,
+        "#F33",
+        "#F33",
+        System.screen.width / 2,
+        System.screen.height / 7,
+        System.screen.width,
+        System.screen.height,
+        enemyData.hitpoint,
+        Math.log(enemyData.agility + 0.1) * 3,
+        0,
+        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
+        brrgs
+    );
+
+    System.enemies.push(enemy);
 }
 
@@ -219,39 +283,62 @@
 
     // update/draw troopers
-    updateTrooper(System.player, System.boss);
-    updateTrooper(System.boss, System.player);
-
-    // draw player name/life
-    drawString(
-        System.screen.ctx,
-        "source-over",
-        System.player.name,
-        10, System.screen.height - 25,
-        "#ACF", "9pt monospace", "left"
-    );
-    drawLifeGauge(
-        System.screen.ctx,
-        "lighter",
-        System.player,
-        10,
-        System.screen.height - 20,
-        System.screen.width
-    );
-
-    // draw boss name/life
-    drawString(
-        System.screen.ctx,
-        "source-over",
-        System.boss.name, 10, 35,
-        "#FCA", "9pt monospace", "left"
-    );
-    drawLifeGauge(
-        System.screen.ctx,
-        "lighter",
-        System.boss,
-        10,
-        10,
-        System.screen.width
-    );
+    for (var i = 0; i < System.players.length; i++) {
+        var player = System.players[i];
+
+        updateTrooper(player, "enemies");
+
+        drawLifeGauge(
+            System.screen.ctx,
+            "lighter",
+            player,
+            10,
+            (System.screen.height - 20) - (i * 33),
+            System.screen.width
+        );
+
+        drawString(
+            System.screen.ctx,
+            "source-over",
+            player.name,
+            10,
+            (System.screen.height - 23) - (i * 33),
+            "#ACF", "9pt monospace", "left"
+        );
+    }
+
+    // update/draw enemies
+    for (var i = 0; i < System.enemies.length; i++) {
+        var enemy = System.enemies[i];
+
+        updateTrooper(enemy, "players");
+
+        drawLifeGauge(
+            System.screen.ctx,
+            "lighter",
+            enemy, 10, i * 33 + 10,
+            System.screen.width
+        );
+
+        drawString(
+            System.screen.ctx,
+            "source-over",
+            enemy.name, 10, i * 33 + 33,
+            "#FCA", "9pt monospace", "left"
+        );
+    }
+
+    updateDeathPieces(System.screen.ctx,
+                      System.screen.width,
+                      System.screen.height);
+
+    if (!System.players.length) {
+        drawString(
+            System.screen.ctx, "source-over",
+            "GAME OVER",
+            System.screen.width / 2,
+            System.screen.height / 2,
+            "#ACF", "24pt monospace", "center"
+        );
+    }
 }
 
@@ -260,5 +347,5 @@
  *  Initializer
  */
-function initGame(canvas, msg, bossId, bossData, playerData) {
+function initGame(canvas, msg, playerData) {
     System.screen.canvas = canvas;
     System.message       = msg;
@@ -283,5 +370,5 @@
     );
 
-    System.player = new Trooper(
+    System.players.push(new Trooper(
         playerData.name,
         new ActionList([new ManualAction(new ManualShot())]),
@@ -322,87 +409,5 @@
                           playerData.shotlevel + 2,
                           -0.5)]
-    );
-
-    var actList = EnemyActionLists[bossData.mtime % EnemyActionLists.length];
-    var shot    = EnemyShots[bossData.hitpoint % EnemyShots.length];
-    var numAct  = bossData.agility       % (EnemyActions.length  - 1) + 1;
-    var numBlt  = bossData.skills.length % (EnemyBullets.length  - 1) + 1;
-    var numBrrg = bossData.skills.length % (EnemyBarrages.length - 1) + 1;
-    var acts    = new Array();
-    var brrgs   = new Array();
-
-    var bulletWay         = Math.ceil(bossData.concentration / 10);
-    var bulletInterval    = Math.round(50 * 1 / Math.log(bossData.skillpoint + 0.1));
-    var bulletSize        = Math.round(Math.log(bossData.luck + 1));
-    var bulletFrameWidth  = (bulletSize + 5) * 2;
-    var bulletFrameHeight = (bulletSize + 5) * 4;
-    var bulletSpeed       = bossData.strength / 15;
-    bulletSpeed = Math.log(bulletSpeed < 1.5 ? 1.5 : bulletSpeed);
-
-    setMessage(System.message, "");
-    addMessage(System.message, " bulletWay:" + String(bulletWay) + "<br>");
-    addMessage(System.message, " bulletInterval:" + String(bulletInterval) + "<br>");
-    addMessage(System.message, " bulletSize:" + String(bulletSize) + "<br>");
-    addMessage(System.message, " bulletSpeed:" + String(bulletSpeed) + "<br>");
-
-    addMessage(System.message, "ActionsIdx:");
-
-    for (var i = 0; i < numAct; i++) {
-        var idx = (bossData.agility + i) % EnemyActions.length;
-        acts.push(new EnemyActions[idx](new shot()));
-
-        addMessage(System.message, String(idx) + "(" +
-                   String(bossData.hitpoint % EnemyShots.length) + "),");
-    }
-
-    addMessage(System.message, "<br>");
-
-    for (var i = 0; i < numBrrg; i++) {
-        var idx     = (bossData.skillpoint + i * (bossData.skills.length + 1)) % EnemyBarrages.length;
-        var brrgCls = EnemyBarrages[idx];
-
-        addMessage(System.message,
-                   "BarragesIdx:" + String(idx) + " / BulletsIdx:");
-
-        for (var k = 0; k < numBlt; k++) {
-            var iidx = (bossData.skills.length + i + k) % EnemyBullets.length;
-            brrgs.push(
-                new brrgCls(
-                    EnemyBullets[iidx],
-                    bulletSize,
-                    "#FF3",
-                    {"style": "rect", "color": "rgba(128,32,32,0.5)",
-                     "width": bulletFrameWidth, "height": bulletFrameHeight},
-                    bulletInterval,
-                    bulletSpeed,
-                    bulletWay
-                )
-            );
-
-            addMessage(System.message, String(iidx) + ",");
-        }
-
-        addMessage(System.message, "<br>");
-    }
-
-    var size = Math.ceil((System.screen.width / 2) * (1 / bossData.defense));
-    size = size < playerData.size ? playerData.size : size;
-    System.boss = new Trooper(
-        bossData.name,
-        new actList(acts),
-        size,
-        size,
-        "#F33",
-        "#F33",
-        System.screen.width / 2,
-        System.screen.height / 7,
-        System.screen.width,
-        System.screen.height,
-        bossData.hitpoint,
-        Math.log(bossData.agility + 0.1) * 3,
-        0,
-        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
-        brrgs
-    );
+    ));
 
     System.backgroundObject = new Array();
