/[drupal]/contributions/modules/game/game.module
ViewVC logotype

Diff of /contributions/modules/game/game.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.52.2.18, Sat Nov 29 03:30:39 2008 UTC revision 1.52.2.19, Mon Dec 1 00:15:02 2008 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id: game.module,v 1.52.2.17 2008/11/25 16:00:45 morbus Exp $  // $Id: game.module,v 1.52.2.18 2008/11/29 03:30:39 morbus Exp $
3    
4  /**  /**
5   * @file   * @file
# Line 15  Line 15 
15   * @todo add missing/null/unowned bid checking to game_battle_process_form();   * @todo add missing/null/unowned bid checking to game_battle_process_form();
16   * @todo run an EXPLAIN on game_log_recent (8 seconds? wtf.)   * @todo run an EXPLAIN on game_log_recent (8 seconds? wtf.)
17   * @todo error if there are no mobs available (modules, etc.).   * @todo error if there are no mobs available (modules, etc.).
  * @todo add in "get random AI" code, or some alternative means?  
18   * @todo game_battle_play() needs to complain about missing params.   * @todo game_battle_play() needs to complain about missing params.
  * @todo modify game_menu() to check for valid $bids before hitting callback.  
19   * @todo go through and fine-tooth game_battle_play().   * @todo go through and fine-tooth game_battle_play().
20   * @todo move the dynamic 'hp' values into $state?   * @todo move the dynamic 'hp' values into $state?
21   * @todo add in uname to the variables (and other missing values).   * @todo add in uname to the variables (and other missing values).
# Line 25  Line 23 
23   *   using it inside array indexes. and, we use it so much that it makes it a   *   using it inside array indexes. and, we use it so much that it makes it a
24   *   bit prohibitive to add in a hook to it (but, do we NEED to is the question).   *   bit prohibitive to add in a hook to it (but, do we NEED to is the question).
25   * @todo print out the state and see if you're happy with all the variables.   * @todo print out the state and see if you're happy with all the variables.
  * @todo work on the "shared battle" database stuff; similar to shared logs.  
26   * @todo start breaking up game_battle_play() into smaller chunks.   * @todo start breaking up game_battle_play() into smaller chunks.
27   * @todo how should we maintain battle win/loss records and/or other stats?   * @todo how should we maintain battle win/loss records and/or other stats?
  * @todo if only one battle in the state at a time, do we need to pass bid?  
  * @todo should be add current_bid with the ID? would save on passing. state.  
  *   @todo worry about this with shared battles in; handle on state_load.  
28   * @todo we're forcing 's as a plural for mob names, without any good logic.   * @todo we're forcing 's as a plural for mob names, without any good logic.
29   * @todo storing $state['battles']['current'] is nicer than the $bid.   * @todo battle_load needs to check against the passed user as owner.
30   * @todo if we load only one battle at a time, why not just ['battle']?   * @todo if another module calls game_state_load() after ours, will they
31     *   be unable to get the latest information (if we haven't saved recently?).
32     * @todo we need a hook_user to handle user deletions and so forth.
33     * @todo store win/loss into game state; how to handle 2p game state? race?
34   */   */
35    
36  /**  /**
# Line 46  function game_menu() { Line 43  function game_menu() {
43      'page arguments'    => array('game_battle_init_form'),      'page arguments'    => array('game_battle_init_form'),
44      'title'             => 'Game battle',      'title'             => 'Game battle',
45    );    );
46    $items['game/battle/%'] = array(    $items['game/battle/%game_battle'] = array(
47      'access arguments'  => array('play game'),      'access arguments'  => array('play game'),
48      'page callback'     => 'drupal_get_form',      'page callback'     => 'drupal_get_form',
49      'page arguments'    => array('game_battle_process_form', 2),      'page arguments'    => array('game_battle_process_form', 2),
# Line 80  function game_battle_init_form(&$form_st Line 77  function game_battle_init_form(&$form_st
77    // @todo create a much nicer interface for selecting mobs and attack order.    // @todo create a much nicer interface for selecting mobs and attack order.
78    foreach (array($user->uid, 'AI-01') as $uid) {    foreach (array($user->uid, 'AI-01') as $uid) {
79      for ($mob_num = 1; $mob_num <= 2; $mob_num++) {      for ($mob_num = 1; $mob_num <= 2; $mob_num++) {
80        $form['game']['parties'][$uid][$mob_num] = array(        $form['game']['battle']['parties'][$uid][$mob_num] = array(
81          '#options'  => $options,          '#options'  => $options,
82          '#required' => $mob_num == 1 ? TRUE : FALSE,          '#required' => $mob_num == 1 ? TRUE : FALSE,
83          '#type'     => 'radios',          '#type'     => 'radios',
# Line 104  function game_battle_init_form_submit($f Line 101  function game_battle_init_form_submit($f
101    global $user;    global $user;
102    $mobs   = module_invoke_all('game_mobs');    $mobs   = module_invoke_all('game_mobs');
103    $state  = game_state_load();    $state  = game_state_load();
   $bid    = game_random_id();  
104    
105    // turn the mob selections into parties for a new battle.    // turn the mob selections into parties for a new battle.
106    foreach ($form_state['values']['game']['parties'] as $uid => $party) {    foreach ($form_state['values']['game']['battle']['parties'] as $uid => $party) {
107      foreach ($party as $mob_num => $mob_id) { // init battle.      foreach ($party as $mob_num => $mob_id) { // init battle.
108        if ($mob_id) { // 1 vs. 2 battles, 1 vs. 1, etc., etc.        if ($mob_id) { // 1 vs. 2 battles, 1 vs. 1, etc., etc.
109          $state['battles'][$bid]['parties'][$uid][$mob_num] = $mobs[$mob_id];          $state['battle']['parties'][$uid][$mob_num] = $mobs[$mob_id];
110        }        }
111      }      }
112    }    }
113    
114    // set the current user as an interactive.    // set the current user as an interactive.
115    $state['battles'][$bid]['state']['interactive'][$user->uid] = array();    $state['battle']['state']['interactive'][$user->uid] = array();
116    
117    // save the new battle.    // save the new battle.
118    game_state_save($state);    $state = game_state_save($state);
119    
120    // and send to our primary battle processor.    // and send to our primary battle processor.
121    $form_state['redirect'] = 'game/battle/'. $bid;    $form_state['redirect'] = 'game/battle/'. $state['battle']['bid'];
122  }  }
123    
124  /**  /**
125   * Menu callback; process a battle turn by turn.   * Menu callback; process a battle turn by turn.
126   *   *
127   * @param $bid   * @param $battle
128   *   The battle ID that is in-progress for the current user.   *   A loaded battle from game_battle_load() (menu wildcard loader).
129   */   */
130  function game_battle_process_form(&$form_state, $bid) {  function game_battle_process_form(&$form_state, $battle) {
131    global $user; // keep structure.    global $user; // keep structure.
132    $form['game']['#tree'] = TRUE;    $form['game']['#tree'] = TRUE;
133    $state = game_state_load();    $state = game_state_load($user->uid, $battle['bid']);
134    
135    // pass control to game_battle_play(). game_battle_play() will automate all    // pass control to game_battle_play(). game_battle_play() will automate all
136    // non-interactive opponents and when it requires information (turn choices)    // non-interactive opponents and when it requires information (turn choices)
137    // from an interactive user, it'll return the current state. we'll also    // from an interactive user, it'll return the current state. we'll also
138    // save all its finished automating in the database before continuing.    // save all its finished automating in the database before continuing.
139    $state = game_state_save(game_battle_play($state, $bid));    $state = game_state_save(game_battle_play($state));
140    
141    // if the next turn is the interactive user's, build the form.    // if the next turn is the interactive user's, build the form.
142    if ($state['battles'][$bid]['state']['attacker']['uid'] == $user->uid) {    if ($state['battle']['state']['attacker']['uid'] == $user->uid) {
143      $form['game']['bid'] = array(      $form['game']['bid'] = array(
144        '#type'       => 'value',        '#type'       => 'value',
145        '#value'      => $bid,        '#value'      => $state['battle']['bid'],
146      );      );
147      $form['submit'] = array(      $form['submit'] = array(
148        '#type'       => 'submit',        '#type'       => 'submit',
# Line 174  function game_battle_process_form(&$form Line 170  function game_battle_process_form(&$form
170   * Form #submit callback; starts a battle and passes to main handler.   * Form #submit callback; starts a battle and passes to main handler.
171   */   */
172  function game_battle_process_form_submit($form, &$form_state) {  function game_battle_process_form_submit($form, &$form_state) {
173    global $user;    global $user; // side effects may include uncontrollable muscle movement.
174    $state = game_state_load();    $state = game_state_load($user->uid, $form_state['values']['game']['bid']);
   $bid = $form_state['values']['game']['bid'];  
175    
176    // @todo naturally, this needs to actually implement user choices based on FAPI.    // @todo naturally, this needs to actually implement user choices based on FAPI.
177    $state['battles'][$bid]['state']['interactive'][$user->uid]['turn_received'] = TRUE;    $state['battle']['state']['interactive'][$user->uid]['turn_received'] = TRUE;
178    $state = game_state_save(game_battle_play($state, $bid));    $state = game_state_save(game_battle_play($state));
179  }  }
180    
181  /**  /**
# Line 191  function game_battle_process_form_submit Line 186  function game_battle_process_form_submit
186   * @param $state   * @param $state
187   *   The current game state, which should contain further information on who   *   The current game state, which should contain further information on who
188   *   is current attacker and target, which attacks have been selected, etc.   *   is current attacker and target, which attacks have been selected, etc.
  * @param $bid  
  *   The battle ID whose current turn should be processed.  
189   * @return $state   * @return $state
190   *   The modified game state when this battle turn has resolved.   *   The modified game state when this battle turn has resolved.
191   */   */
192  function game_battle_play($state, $bid) {  function game_battle_play($state) {
193    // keep going as long as there are parties left to attack. this    // keep going as long as there are parties left to attack.
194    // while loop will be short-circuited by interactives as necessary.    // loop will be short-circuited by interactives as necessary.
195    while (count($state['battles'][$bid]['parties']) > 1) {    while (count($state['battle']['parties']) > 1) {
196      // if there are no more turns in this round, or if turn order has yet      // if there are no more turns in this round, or if turn order has yet
197      // to be established (new round, etc.), roll initiative and store it.      // to be established (new round, etc.), roll initiative and store it.
198      if (count($state['battles'][$bid]['state']['turn_order']) == 0) {      if (count($state['battle']['state']['turn_order']) == 0) {
199        $state['battles'][$bid]['state']['turn_order'] = game_roll_initiative($state['battles'][$bid]['parties']);        $state['battle']['state']['turn_order'] = game_roll_initiative($state['battle']['parties']);
200      }      }
201    
202      // loop through the current turn order.      // loop through the current turn order.
203      foreach (array_keys($state['battles'][$bid]['state']['turn_order']) as $attacker_uid) {      foreach (array_keys($state['battle']['state']['turn_order']) as $attacker_uid) {
204        $state['battles'][$bid]['state']['attacker']['uid'] = $attacker_uid;        $state['battle']['state']['attacker']['uid'] = $attacker_uid;
   
       // @todo need to check if there's anyone left to kill.  
205    
206        // if the current turn is assigned to an interactive user who has not yet        // if the current turn is assigned to an interactive user who has not yet
207        // sent in their turn information, we'll return the $state to the caller and        // sent in their turn information, we'll return the $state to the caller and
208        // trust that the caller will ask for the inputs, then send it back to us.        // trust that the caller will ask for the inputs, then send it back to us.
209        if (is_array($state['battles'][$bid]['state']['interactive'][$attacker_uid])) {        if (is_array($state['battle']['state']['interactive'][$attacker_uid])) {
210          if (!$state['battles'][$bid]['state']['interactive'][$attacker_uid]['turn_received']) {          if (!$state['battle']['state']['interactive'][$attacker_uid]['turn_received']) {
211            return $state;            return $state;
212          }          }
213          else {          else {
214            // turn information has been received, so we'll continue processing below.            // turn information has been received, so we'll continue processing below.
215            // unset turn_received so that the user's next turn will be interactive too.            // unset turn_received so that the user's next turn will be interactive too.
216            unset($state['battles'][$bid]['state']['interactive'][$attacker_uid]['turn_received']);            unset($state['battle']['state']['interactive'][$attacker_uid]['turn_received']);
217          }          }
218        }        }
219    
220        // loop through all the attackers remaining creatures and attack.        // loop through all the attackers remaining creatures and attack.
221        foreach (array_keys($state['battles'][$bid]['parties'][$attacker_uid]) as $attacking_mob_num) {        foreach (array_keys($state['battle']['parties'][$attacker_uid]) as $attacking_mob_num) {
222          $state['battles'][$bid]['state']['attacker']['mob_num'] = $attacking_mob_num;          $state['battle']['state']['attacker']['mob_num'] = $attacking_mob_num;
223    
224          // if this mob has a target opponent and mob, use it. otherwise, random remaining.          // if this mob has a target opponent and mob, use it. otherwise, random remaining.
225          // this should really only be used when the AI is not automatically picking an          // this should really only be used when the AI is not automatically picking an
226          // opponent; users would always choose opponent + mob via the standard form UI.          // opponent; users would always choose opponent + mob via the standard form UI.
227          // @todo this defaulting should eventually go into an AI-sorta module.          // @todo this defaulting should eventually go into an AI-sorta module.
228          if (!$state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['target_uid']) {          if (!$state['battle']['state']['attacker']['party'][$attacking_mob_num]['target_uid']) {
229            $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['target_uid'] = array_rand(array_diff_key($state['battles'][$bid]['parties'], array($attacker_uid => 1)));            $state['battle']['state']['attacker']['party'][$attacking_mob_num]['target_uid'] = array_rand(array_diff_key($state['battle']['parties'], array($attacker_uid => 1)));
230            $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['target_mob_num'] = array_rand($state['battles'][$bid]['parties'][$state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['target_uid']]);            $state['battle']['state']['attacker']['party'][$attacking_mob_num]['target_mob_num'] = array_rand($state['battle']['parties'][$state['battle']['state']['attacker']['party'][$attacking_mob_num]['target_uid']]);
231            $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['attack'] = array_rand($state['battles'][$bid]['parties'][$attacker_uid][$attacking_mob_num]['actions']);            $state['battle']['state']['attacker']['party'][$attacking_mob_num]['attack'] = array_rand($state['battle']['parties'][$attacker_uid][$attacking_mob_num]['actions']);
232          }          }
233    
234          // roll attack; determine success or failure.          // roll attack for success or failure.
235          $state = game_battle_attack($state, $bid);          $state = game_battle_attack($state);
236    
237          // @todo move this and other damage related stuff into a new function.          // @todo move this and other damage related stuff into a new function.
238          $attack_status = $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'];          $attack_status = $state['battle']['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'];
239    
240          // if this attack was a success, process the damage.          // if this attack was a success, process the damage.
241          if ($attack_status == t('hit') || $attack_status == t('critical hit')) {          if ($attack_status == t('hit') || $attack_status == t('critical hit')) {
242            $state['battles'][$bid]['parties'][game_battle_variables($state, $bid, '@target_uid')][game_battle_variables($state, $bid, '@target_mob_num')]['hp'] -= game_battle_variables($state, $bid, '@total_damage');            $state['battle']['parties'][game_battle_variables($state, '@target_uid')][game_battle_variables($state, '@target_mob_num')]['hp'] -= game_battle_variables($state, '@total_damage');
243            game_log('combat', '%attacking_mob_attack_name deals @total_damage damage to %target_mob_name (HP is now @target_mob_hp).', game_battle_variables($state, $bid));            game_log('combat', '%attacking_mob_attack_name deals @total_damage damage to %target_mob_name (HP is now @target_mob_hp).', game_battle_variables($state));
244    
245            // remove this mob from the active party if destroyed.            // remove this mob from the active party if destroyed.
246            if (game_battle_variables($state, $bid, '@target_mob_hp') <= 0) {            if (game_battle_variables($state, '@target_mob_hp') <= 0) {
247              game_log('combat', '%target_mob_name has been destroyed.', game_battle_variables($state, $bid));              game_log('combat', '%target_mob_name has been destroyed.', game_battle_variables($state));
248              unset($state['battles'][$bid]['parties'][game_battle_variables($state, $bid, '@target_uid')][game_battle_variables($state, $bid, '@target_mob_num')]);              unset($state['battle']['parties'][game_battle_variables($state, '@target_uid')][game_battle_variables($state, '@target_mob_num')]);
249            }            }
250    
251            // remove this player from the active parties if destroyed.            // remove this player from the active parties if destroyed.
252            if (count($state['battles'][$bid]['parties'][game_battle_variables($state, $bid, '@target_uid')]) == 0) {            $target_uid = game_battle_variables($state, '@target_uid');
253              game_log('combat', '@target_uid has been defeated.', game_battle_variables($state, $bid));            if (count($state['battle']['parties'][$target_uid]) == 0) {
254              unset($state['battles'][$bid]['parties'][game_battle_variables($state, $bid, '@target_uid')]);              game_log('combat', '@target_uid has been defeated.', game_battle_variables($state));
255                unset($state['battle']['state']['turn_order'][$target_uid]);
256                unset($state['battle']['parties'][$target_uid]);
257            }            }
258          }          }
259        }        }
260    
261        // this turn is done, so remove the turn state and attacker.        // this turn is done, so remove the turn state and attacker.
262        unset($state['battles'][$bid]['state']['turn_order'][$attacker_uid]);        unset($state['battle']['state']['turn_order'][$attacker_uid]);
263        unset($state['battles'][$bid]['state']['attacker']);        unset($state['battle']['state']['attacker']);
264      }      }
265    }    }
266    
267    // if the battle is over, remove interim structure.    // if the battle is over, remove interim structure.
268    if (count($state['battles'][$bid]['parties']) == 1) {    if (count($state['battle']['parties']) == 1) {
269      unset($state['battles'][$bid]['parties']);      game_battle_delete($state['battle']['bid']);
270      unset($state['battles'][$bid]['state']);      unset($state['battle']); // trashed from state.
271    }    }
272    
273    return $state;    return $state;
# Line 285  function game_battle_play($state, $bid) Line 278  function game_battle_play($state, $bid)
278   *   *
279   * @param $state   * @param $state
280   *   The current game state to have variables generated from.   *   The current game state to have variables generated from.
  * @param $bid  
  *   The battle ID whose variables should be generated.  
281   */   */
282  function game_battle_attack($state, $bid) {  function game_battle_attack($state) {
283    $attacking_mob_num = $state['battles'][$bid]['state']['attacker']['mob_num'];    $attacking_mob_num = $state['battle']['state']['attacker']['mob_num'];
284    $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['attack_roll'] = game_roll_d20(t('Attack roll for %attacking_mob_name\'s %attacking_mob_attack_name', game_battle_variables($state, $bid)), game_battle_variables($state, $bid, '@attacking_mob_attack_modifier'));    $state['battle']['state']['attacker']['party'][$attacking_mob_num]['attack_roll'] = game_roll_d20(t('Attack roll for %attacking_mob_name\'s %attacking_mob_attack_name', game_battle_variables($state)), game_battle_variables($state, '@attacking_mob_attack_modifier'));
285    drupal_alter('game_battle_attack_roll', $state); // allow modules to modify the game state before we determine if this attack was a hit or miss.    drupal_alter('game_battle_attack_roll', $state); // allow modules to modify the game state before we determine if this attack was a hit or miss.
286    
287    // shorthand; we don't need up-to-date logging.    // shorthand; don't need up-to-date logging.
288    $bvars = game_battle_variables($state, $bid);    $bvars = game_battle_variables($state);
289    
290    // this attack is a success if it's higher than the target's defense...    // this attack is a success if it's higher than the target's defense...
291    $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'] =    $state['battle']['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'] =
292      $bvars['@attack_roll_result'] >= $bvars['@target_mob_defense_value'] ? t('hit') : t('miss');      $bvars['@attack_roll_result'] >= $bvars['@target_mob_defense_value'] ? t('hit') : t('miss');
293    
294    // was this a critical hit...    // was this a critical hit...
295    if ($bvars['@attack_roll_raw'] == 20) {    if ($bvars['@attack_roll_raw'] == 20) {
296      $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'] = t('critical hit');      $state['battle']['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'] = t('critical hit');
297    }    }
298    
299    // or perhaps a critical miss?    // or perhaps a critical miss?
300    if ($bvars['@attack_roll_raw'] == 1) {    if ($bvars['@attack_roll_raw'] == 1) {
301      $state['battles'][$bid]['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'] = t('critical miss');      $state['battle']['state']['attacker']['party'][$attacking_mob_num]['attack_roll']['status'] = t('critical miss');
302    }    }
303    
304    // allow modules to react to determined attack status.    // allow modules to react to determined attack status.
# Line 316  function game_battle_attack($state, $bid Line 307  function game_battle_attack($state, $bid
307    // log the final determination after all modules have gotten their grubby hands on it.    // log the final determination after all modules have gotten their grubby hands on it.
308    // we assume, nay, hope, that modules will include extra log messages explaining any major oddities.    // we assume, nay, hope, that modules will include extra log messages explaining any major oddities.
309    // we don't use $bvars here since we want the latest values from all hook modifications, etc.    // we don't use $bvars here since we want the latest values from all hook modifications, etc.
310    game_log('combat', '%attacking_mob_name\'s %attacking_mob_attack_name (@attack_roll_result) vs. %target_mob_name\'s @target_mob_defense (@target_mob_defense_value): @attack_roll_status.', game_battle_variables($state, $bid));    game_log('combat', '%attacking_mob_name\'s %attacking_mob_attack_name (@attack_roll_result) vs. %target_mob_name\'s @target_mob_defense (@target_mob_defense_value): @attack_roll_status.', game_battle_variables($state));
311    
312    return $state;    return $state;
313  }  }
# Line 326  function game_battle_attack($state, $bid Line 317  function game_battle_attack($state, $bid
317   *   *
318   * @param $state   * @param $state
319   *   The current game state to have variables generated from.   *   The current game state to have variables generated from.
  * @param $bid  
  *   The battle ID whose variables should be generated.  
320   * @param $variable   * @param $variable
321   *   A variable name that you'd like to retrieve the value for (only).   *   A variable name that you'd like to retrieve the value for (only).
322   * @return $variable(s)   * @return $variable(s)
323   *   Either an array of all $variables or the desired/passed $variable.   *   Either an array of all $variables or the desired/passed $variable.
324   */   */
325  function game_battle_variables($state, $bid, $variable = NULL) {  function game_battle_variables($state, $variable = NULL) {
326    $variables['@battle_id']                  = $bid;    $variables['@battle_id']                  = $state['battle']['bid'];
327    $variables['@attacking_uid']              = $state['battles'][$bid]['state']['attacker']['uid'];    $variables['@attacking_uid']              = $state['battle']['state']['attacker']['uid'];
328    $variables['%attacking_uname']            = '';    $variables['%attacking_uname']            = '';
329    $variables['@attacking_initiative']       = $state['battles'][$bid]['state']['turn_order'][$variables['@attacking_uid']];    $variables['@attacking_initiative']       = $state['battle']['state']['turn_order'][$variables['@attacking_uid']];
330    $variables['@attacking_mob_num']          = $state['battles'][$bid]['state']['attacker']['mob_num'];    $variables['@attacking_mob_num']          = $state['battle']['state']['attacker']['mob_num'];
331    $variables['%attacking_mob_name']         = $state['battles'][$bid]['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['name'];    $variables['%attacking_mob_name']         = $state['battle']['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['name'];
332    $variables['@attacking_mob_attack_id']    = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack'];    $variables['@attacking_mob_attack_id']    = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack'];
333    $variables['%attacking_mob_attack_name']  = $state['battles'][$bid]['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['name'];    $variables['%attacking_mob_attack_name']  = $state['battle']['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['name'];
334    $variables['@attacking_mob_attack_damage'] = $state['battles'][$bid]['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['damage'];    $variables['@attacking_mob_attack_damage'] = $state['battle']['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['damage'];
335    $variables['@attacking_mob_attack_modifier'] = $state['battles'][$bid]['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['modifier'];    $variables['@attacking_mob_attack_modifier'] = $state['battle']['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['modifier'];
336    $variables['@target_uid']                 = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['target_uid'];    $variables['@target_uid']                 = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['target_uid'];
337    $variables['%target_uname']               = '';    $variables['%target_uname']               = '';
338    $variables['@target_mob_num']             = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['target_mob_num'];    $variables['@target_mob_num']             = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['target_mob_num'];
339    $variables['%target_mob_name']            = $state['battles'][$bid]['parties'][$variables['@target_uid']][$variables['@target_mob_num']]['name'];    $variables['%target_mob_name']            = $state['battle']['parties'][$variables['@target_uid']][$variables['@target_mob_num']]['name'];
340    $variables['@target_mob_hp']              = $state['battles'][$bid]['parties'][$variables['@target_uid']][$variables['@target_mob_num']]['hp'];    $variables['@target_mob_hp']              = $state['battle']['parties'][$variables['@target_uid']][$variables['@target_mob_num']]['hp'];
341    $variables['@target_mob_defense']         = $state['battles'][$bid]['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['modifier against'];    $variables['@target_mob_defense']         = $state['battle']['parties'][$variables['@attacking_uid']][$variables['@attacking_mob_num']]['actions'][$variables['@attacking_mob_attack_id']]['modifier against'];
342    $variables['@target_mob_defense_value']   = $state['battles'][$bid]['parties'][$variables['@target_uid']][$variables['@target_mob_num']][$variables['@target_mob_defense']];    $variables['@target_mob_defense_value']   = $state['battle']['parties'][$variables['@target_uid']][$variables['@target_mob_num']][$variables['@target_mob_defense']];
343    $variables['@attack_roll_modifier']       = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['modifier'];    $variables['@attack_roll_modifier']       = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['modifier'];
344    $variables['@attack_roll_raw']            = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['raw'];    $variables['@attack_roll_raw']            = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['raw'];
345    $variables['@attack_roll_result']         = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['result'];    $variables['@attack_roll_result']         = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['result'];
346    $variables['@attack_roll_status']         = $state['battles'][$bid]['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['status'];    $variables['@attack_roll_status']         = $state['battle']['state']['attacker']['party'][$variables['@attacking_mob_num']]['attack_roll']['status'];
347    $variables['@total_damage']               = $variables['@attack_roll_status'] == t('critical hit') ? $variables['@attacking_mob_attack_damage'] * 2 : $variables['@attacking_mob_attack_damage'];    $variables['@total_damage']               = $variables['@attack_roll_status'] == t('critical hit') ? $variables['@attacking_mob_attack_damage'] * 2 : $variables['@attacking_mob_attack_damage'];
348    
349    return $variable ? $variables[$variable] : $variables;    return $variable ? $variables[$variable] : $variables;
# Line 428  function game_log($type, $message, $vari Line 417  function game_log($type, $message, $vari
417    $log->timestamp = time();    $log->timestamp = time();
418    drupal_write_record('game_log', $log);    drupal_write_record('game_log', $log);
419    
   // default to self.  
420    if (count($uids) == 0) {    if (count($uids) == 0) {
421      global $user; // sup.      global $user; // sup.
422      $uids[] = $user->uid;      $uids[] = $user->uid;
# Line 477  function game_log_recent($uid = NULL, $l Line 465  function game_log_recent($uid = NULL, $l
465  }  }
466    
467  /**  /**
468   * Generate a random ID for game events.   * Delete a battle state from the database.
469     */
470    function game_battle_delete($bid) {
471      if ($bid) { // WHO DARES SEND ME NO BID? I SHALL KEEELlLYYOOUU.
472        db_query('DELETE FROM game_battle_user WHERE bid = %d', $bid);
473        db_query('DELETE FROM game_battle WHERE bid = %d', $bid);
474      }
475    }
476    
477    /**
478     * Load a battle state from the database.
479     *
480     * Also used as a hook_menu() wildcard loader function.
481     *
482     * @param $bid
483     *   The battle ID to retrieve and de-serialize.
484     * @return $battle
485     *   The battle state, ready for adding to the master game $state.
486     *   If the battle state doesn't exist, we'll return FALSE instead.
487     */
488    function game_battle_load($bid) {
489      static $battles;
490    
491      if ($battles[$bid]) {
492        return $battles[$bid];
493      }
494    
495      if ($result = db_fetch_object(db_query("SELECT state FROM {game_battle} WHERE bid = %d", $bid))) {
496        $battles[$bid] = unserialize($result->state);
497        $battles[$bid]['bid'] = $bid; // embedded.
498        return $battles[$bid];
499      }
500    
501      return FALSE;
502    }
503    
504    /**
505     * Saves a battle state to the database.
506     *
507     * @param $battle
508     *   The current battle state to be saved.
509     * @return $battle
510     *   The battle state after saving (newly updated 'changed', etc.).
511   */   */
512  function game_random_id() {  function game_battle_save($battle) {
513    return drupal_substr(md5(uniqid()), 0, 8);    $record = new stdClass();
514      $update = array('bid');
515    
516      // has this battle just started?
517      if (!$battle['started']) { // nothing? new state.
518        $record->started = $battle['started'] = time();
519        $update = array();
520      }
521    
522      $record->changed  = $battle['changed'] = time();
523      $record->bid = $battle['bid'] ? $battle['bid'] : NULL;
524      $record->state    = serialize($battle);
525      drupal_write_record('game_battle', $record, $update);
526      $battle['bid'] = $record->bid; // so caller knows us.
527    
528      // associate this battle with all relevant users.
529      foreach (array_keys($battle['parties']) as $uid) {
530        // skip AI users, invites, emails, etc.
531        if (is_numeric($uid) && $uid != 0) {
532          $battle_user = new stdClass();
533          $battle_user->uid = $uid;
534          $battle_user->bid = $record->bid;
535          drupal_write_record('game_battle_user', $battle_user);
536        }
537      }
538    
539      return $battle;
540  }  }
541    
542  /**  /**
# Line 488  function game_random_id() { Line 544  function game_random_id() {
544   *   *
545   * @param $uid   * @param $uid
546   *   The user's game state to load. Defaults to global user.   *   The user's game state to load. Defaults to global user.
547     * @param $bid
548     *   Optional; a battle ID to load into this game state.
549   * @return $state   * @return $state
550   *   The user's game state. If a game state doesn't exist in the database,   *   The user's game state. If a game state doesn't exist
551   *   an array of just "new_state" will be returned (which game_state_save()   *   in the database, an empty array will be returned.
  *   will then recognize as a new record).  
552   */   */
553  function game_state_load($uid = NULL) {  function game_state_load($uid = NULL, $bid = NULL) {
554    if (!$uid) {    if (!$uid) {
555      global $user;      global $user;
556      $uid = $user->uid;      $uid = $user->uid;
557    }    }
558    
559    $result = db_fetch_object(db_query('SELECT state FROM {game_state} WHERE uid = %d', $uid));    $result = db_fetch_object(db_query('SELECT state FROM {game_state} WHERE uid = %d', $uid));
560    return $result->state? unserialize($result->state) : array('new_state' => TRUE);  
561      if (!$result->state) {
562        return array();
563      }
564    
565      if ($result->state) {
566        $state = unserialize($result->state);
567        $state['uid'] = $uid; // embedded.
568    
569        if ($bid) { // got a battle too? grand.
570          $state['battle'] = game_battle_load($bid);
571        }
572      }
573    
574      return $state;
575  }  }
576    
577  /**  /**
# Line 510  function game_state_load($uid = NULL) { Line 581  function game_state_load($uid = NULL) {
581   *   The current game state to be saved.   *   The current game state to be saved.
582   * @param $uid   * @param $uid
583   *   The owner of this game state. Defaults to global user.   *   The owner of this game state. Defaults to global user.
584     * @return $state
585     *   The state after saving (newly updated 'changed', etc.).
586   */   */
587  function game_state_save($state = array(), $uid = NULL) {  function game_state_save($state = array(), $uid = NULL) {
588    if (!$uid) {    if (!$uid) {
# Line 520  function game_state_save($state = array( Line 593  function game_state_save($state = array(
593    $record = new stdClass();    $record = new stdClass();
594    $update = array('uid');    $update = array('uid');
595    
596    // has this state just been started?    // has this state just started?
597    if ($state['new_state'] == TRUE) {    if (!$state['started']) { // nothing? new state.
598      unset($state['new_state']);      $record->started = $state['started'] = time();
     $record->started = time();  
599      $update = array();      $update = array();
600    }    }
601    
602    $record->uid      = $uid;    // battles are saved elsewhere.
603    $record->changed  = time();    if ($state['battle']) { // save and remove.
604        $battle = game_battle_save($state['battle']);
605        unset($state['battle']); // don't save in game state.
606      }
607    
608      $record->changed  = $state['changed'] = time();
609      $record->uid      = $state['uid']     = $uid;
610    $record->state    = serialize($state);    $record->state    = serialize($state);
611    drupal_write_record('game_state', $record, $update);    drupal_write_record('game_state', $record, $update);
612    
613      if ($battle) { // did we save off a battle in this load?
614        // then add it back to state for caller expectations.
615        $state['battle'] = $battle;
616      }
617    
618    return $state;    return $state;
619  }  }
620    

Legend:
Removed from v.1.52.2.18  
changed lines
  Added in v.1.52.2.19

  ViewVC Help
Powered by ViewVC 1.1.2