Index: game.module
===================================================================
RCS file: /www/REPOSITORIES/contrib/contributions/modules/game/Attic/game.module,v
retrieving revision 1.52.2.3
diff -u -r1.52.2.3 game.module
--- game.module	16 May 2008 14:32:36 -0000	1.52.2.3
+++ game.module	25 Oct 2008 23:05:08 -0000
@@ -30,26 +30,54 @@
  *   An array containing player uids and their parties.
  */
 function game_play_combat_round($parties) {
+  global $game_log;
   $parties = game_roll_initiative($parties);
 
   foreach ($parties as $uid => $party) {
     if (!isset($parties[$uid])) { continue; } // skip players who were just defeated.
-    watchdog('game combat', 'Beginning turn for %uid.', array('%uid' => $uid), WATCHDOG_DEBUG);
+//    watchdog('game combat', 'Beginning turn for %uid.', array('%uid' => $uid), WATCHDOG_DEBUG);
+    $game_log->set(array(
+      'dispatcher'    => 'game_play_combat_round',
+      'message type'  => 'game combat',
+      'message'       => 'Beginning turn for %uid.',
+      'variables'     => array('%uid' => $uid),
+    ));
     $opposing_player = array_rand(array_diff_key($parties, array($uid => $party)));
 
     foreach ($parties[$uid] as $creature) {
       $opposing_creature = array_rand($parties[$opposing_player]);
-      watchdog('game combat', 'Activating %creature against %opposing_creature.', array('%creature' => $creature['name'], '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+//      watchdog('game combat', 'Activating %creature against %opposing_creature.', array('%creature' => $creature['name'], '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+
+      $game_log->set(array(
+        'dispatcher'    => 'game_play_combat_round',
+        'message type'  => 'game combat',
+        'message'       => 'Activating %creature against %opposing_creature.',
+        'variables'     => array('%creature' => $creature['name'], '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']),
+      ));
+
       $attack_roll = game_roll_d20(t('Attack roll for %attack', array('%attack' => $creature['actions'][0]['name'])), $creature['actions'][0]['modifier']);
       $opposing_defense = $creature['actions'][0]['modifier against'];
 
-      watchdog('game combat', 'Attack roll (@attack_roll) vs. %opposing_defense (@opposing_defense_value).',
-        array('@attack_roll' => $attack_roll, '%opposing_defense' => $opposing_defense, '@opposing_defense_value'
-        => $parties[$opposing_player][$opposing_creature][$opposing_defense]), WATCHDOG_DEBUG);
+//      watchdog('game combat', 'Attack roll (@attack_roll) vs. %opposing_defense (@opposing_defense_value).',
+//        array('@attack_roll' => $attack_roll, '%opposing_defense' => $opposing_defense, '@opposing_defense_value'
+//        => $parties[$opposing_player][$opposing_creature][$opposing_defense]), WATCHDOG_DEBUG);
+      $game_log->set(array(
+        'dispatcher'    => 'game_play_combat_round',
+        'message type'  => 'game combat',
+        'message'       => 'Attack roll (@attack_roll) vs. %opposing_defense (@opposing_defense_value).',
+        'variables'     => array('@attack_roll' => $attack_roll, '%opposing_defense' => $opposing_defense, '@opposing_defense_value' => $parties[$opposing_player][$opposing_creature][$opposing_defense]),
+      ));
 
-      $critial_hit = FALSE;
+      $critical_hit = FALSE;
       if ($attack_roll - $creature['actions'][0]['modifier'] == 20) {
-        watchdog('game combat', 'Attack roll was a natural 20: critical hit!', array('@damage' => $damage, '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+        $damage = $creature['actions'][0]['damage'];
+//        watchdog('game combat', 'Attack roll was a natural 20: critical hit!', array('@damage' => $damage, '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+        $game_log->set(array(
+          'dispatcher'    => 'game_play_combat_round',
+          'message type'  => 'game combat',
+          'message'       => 'Attack roll was a natural 20: critical hit!',
+          'variables'     => array('@damage' => $damage, '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']),
+        ));
         $critical_hit = TRUE;
       }
 
@@ -57,21 +85,50 @@
         $damage = $creature['actions'][0]['damage'];
         $damage = $critical_hit ? $damage * 2 : $damage;
         $parties[$opposing_player][$opposing_creature]['hp'] -= $damage;
-        watchdog('game combat', 'Attack deals @damage damage to %opposing_creature.', array('@damage' => $damage, '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
-        watchdog('game combat', '%opposing_creature now has @hp HP.', array('%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name'], '@hp' => $parties[$opposing_player][$opposing_creature]['hp']), WATCHDOG_DEBUG);
+//        watchdog('game combat', 'Attack deals @damage damage to %opposing_creature.', array('@damage' => $damage, '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+//        watchdog('game combat', '%opposing_creature now has @hp HP.', array('%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name'], '@hp' => $parties[$opposing_player][$opposing_creature]['hp']), WATCHDOG_DEBUG);
+        $game_log->set(array(
+          'dispatcher'    => 'game_play_combat_round',
+          'message type'  => 'game combat',
+          'message'       => 'Attack deals @damage damage to %opposing_creature.',
+          'variables'     => array('@damage' => $damage, '%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']),
+        ))->set(array(//OMG CHAINING!!!!!!!!!!!!!!!!!!!!!!
+          'dispatcher'    => 'game_play_combat_round',
+          'message type'  => 'game combat',
+          'message'       => '%opposing_creature now has @hp HP.',
+          'variables'     => array('%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name'], '@hp' => $parties[$opposing_player][$opposing_creature]['hp']),
+        ));
 
         if ($parties[$opposing_player][$opposing_creature]['hp'] <= 0) {
-          watchdog('game combat', '%opposing_creature has been destroyed.', array('%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+//          watchdog('game combat', '%opposing_creature has been destroyed.', array('%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']), WATCHDOG_DEBUG);
+          $game_log->set(array(
+            'dispatcher'    => 'game_play_combat_round',
+            'message type'  => 'game combat',
+            'message'       => '%opposing_creature has been destroyed.',
+            'variables'     => array('%opposing_creature' => $parties[$opposing_player][$opposing_creature]['name']),
+          ));
           unset($parties[$opposing_player][$opposing_creature]);
         }
 
         if (count($parties[$opposing_player]) == 0) {
-          watchdog('game combat', '%opposing_player has been defeated.', array('%opposing_player' => $opposing_player), WATCHDOG_DEBUG);
+//          watchdog('game combat', '%opposing_player has been defeated.', array('%opposing_player' => $opposing_player), WATCHDOG_DEBUG);
+          $game_log->set(array(
+            'dispatcher'    => 'game_play_combat_round',
+            'message type'  => 'game combat',
+            'message'       => '%opposing_player has been defeated.',
+            'variables'     => array('%opposing_player' => $opposing_player),
+          ));
           unset($parties[$opposing_player]);
         }
       }
       else {
-        watchdog('game combat', 'Attack failed for %creature.', array('%creature' => $creature['name']), WATCHDOG_DEBUG);
+//        watchdog('game combat', 'Attack failed for %creature.', array('%creature' => $creature['name']), WATCHDOG_DEBUG);
+        $game_log->set(array(
+          'dispatcher'    => 'game_play_combat_round',
+          'message type'  => 'game combat',
+          'message'       => 'Attack failed for %creature.',
+          'variables'     => array('%creature' => $creature['name']),
+        ));
       }
     }
   }
@@ -88,6 +145,7 @@
  *   The same array, only resorted in winning initiative order.
  */
 function game_roll_initiative($parties) {
+  global $game_log;
   foreach ($parties as $uid => $party) {
     $uids[$uid] = game_roll_d20(t('Initiative roll for %uid', array('%uid' => $uid)));
   }
@@ -96,7 +154,12 @@
   // uids, it means that two players rolled the same initiative.
   // @bug this forces ALL players to reroll, not just contenders.
   if (count(array_unique($uids)) != count($uids)) {
-    watchdog('game combat', 'Initiatives matched. Re-rolling.', array(), WATCHDOG_DEBUG);
+//    watchdog('game combat', 'Initiatives matched. Re-rolling.', array(), WATCHDOG_DEBUG);
+    $game_log->set(array(
+      'dispatcher'    => 'game_roll_initiative',
+      'message type'  => 'game combat',
+      'message'       => 'Initiatives matched. Re-rolling.',
+    ));
     $uids = game_roll_initiative($parties);
   }
 
@@ -119,16 +182,33 @@
  *   An integer indicating the result rolled and modified.
  */
 function game_roll_d20($description, $modifier = 0) {
+  global $game_log;
   $unmodified = rand(1, 20);
   $result = $unmodified + $modifier;
-  watchdog('game dice', '!description: @unmodified (+@modifier): @result.', array(
-    '!description' => $description ? $description : 'Unspecified roll', '@unmodified' => $unmodified,
-    '@modifier' => $modifier, '@result' => $result), WATCHDOG_DEBUG);
+
+  $game_log->set(array(
+    'dispatcher'    => 'game_roll_d20',
+    'message type'  => 'game dice',
+    'severity'      => 'notice',
+    'message'       => '!description: @unmodified (+@modifier): @result.',
+    'variables'     => array(
+      '!description'  => $description ? $description : 'Unspecified roll',
+      '@unmodified'   => $unmodified,
+      '@modifier'     => $modifier,
+      '@result'       => $result,
+    ),
+  ));
+
+//  watchdog('game dice', '!description: @unmodified (+@modifier): @result.', array(
+//    '!description' => $description ? $description : 'Unspecified roll', '@unmodified' => $unmodified,
+//    '@modifier' => $modifier, '@result' => $result), WATCHDOG_DEBUG);
   return $result;
 }
 
 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
 function game_sandbox() {
+  global $game_log;
+  $game_log = new game_log();
   include_once(drupal_get_path('module', 'game') . '/creatures/human_sellsword.inc');
   include_once(drupal_get_path('module', 'game') . '/creatures/naga_swiftscale.inc');
   $parties = array(
@@ -148,3 +228,97 @@
   return $output;
 }
 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
+
+
+
+/**
+ * - dispatcher - which module sent this log
+ * - message type - type of the log
+ * - severity - string for severity level. will decide whether to log it, or to display it.
+ * - message string
+ * - variables replacement
+ * - timestamp
+ * - uid
+ */
+class game_log {
+
+  public function set(array $options = array()) {
+    $options += $this->default_options(); // initialize default values
+    drupal_alter('game_log', $options);   // allow other modules to modify our log object. This is potential performance killer
+    $this->log_route($options);           // initiate message routing
+    return $this;                         // i never chained anything before, but people seem to like it.
+  }
+
+  /**
+   * Log router. responsible for sending the log to the correct handler. possible options: $_SESSION, {game_log}, watchdog(), what ever...
+   */
+  private function log_route($options) {
+    switch ($this->find_log_handler($options)) {
+      case 'drupal_set_message':
+        drupal_set_message(t($options['message'], $options['variables']), $options['severity']);
+        break;
+      case 'game_log':
+        $this->save_log($options);
+        break;
+      default:
+        /**
+         *
+         */
+        break;
+    }
+  }
+
+  private function save_log($options) {
+    //$options and game_log tables do not share the same schema so we must do some translation here
+    $log = array();
+    $log['uid']       = $options['uid'];
+    $log['type']      = $options['message type'];
+    $log['message']   = $options['message'];
+    $log['variables'] = serialize($options['variables']);
+    $log['timestamp'] = $options['timestamp'];
+
+    drupal_write_record('game_log', $log);
+  }
+  /**
+   * Returns the correct handler for this particular message type
+   */
+  private function find_log_handler($options) {
+    /**
+     * @todo: fetch log handlers settings from db.
+     * @todo: create admin UI to manage all of this
+     *
+     * @todo: figure out the desired level of granularity
+     * $handlers format: $handlers[$message_type][$severity] = 'log handler'
+     * $handlers format: $handlers[$dispatcher][$message_type][$severity] = 'log handler'
+     */
+    $handlers = array(
+      'game combat' => array(
+        'notice'      => 'drupal_set_message',
+        'error'      => 'game_log', // ? 'error recoverable'
+        'fatal'      => 'game_log', // ? 'error fatal'
+//        'notice'      => 'none',
+      ),
+      'game dice' => array(
+        'notice'      => 'drupal_set_message',
+//        'notice'      => 'game_log',
+//        'notice'      => 'none',
+      ),
+    );
+    /**
+     * @todo: Figure out if we want a global default handler or more granular per message type + severity default handler and if that is not set then fallback to global
+     */
+    return isset($handlers[$options['message type']][$options['severity']]) ? $handlers[$options['message type']][$options['severity']]: 'drupal_set_message';
+  }
+  private function default_options() {
+    global $user;
+    return array(
+      'dispatcher'    => 'Game Log',
+      'message type'  => 'log',
+      'message'       => '',
+      'severity'      => 'notice',
+      'variables'     => array(),
+      'timestamp'     => time(),
+      'uid'           => $user->uid,
+    );
+  }
+}
\ No newline at end of file
