| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* The administration page for the Game Clock module.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Define the help pages for hook_help().
|
| 11 |
*/
|
| 12 |
function _game_clock_help($section) {
|
| 13 |
switch ($section) {
|
| 14 |
case 'admin/settings/game_clock':
|
| 15 |
return t("
|
| 16 |
<p>Game clocks may be used for various purposes, such as keeping an in-game calendar, tracking game effects and events, and limiting characters to acting at a slower pace suitable for a web-based game.</p>
|
| 17 |
<p>You may view all active game clocks from this page, as well as create new clocks below. Additionally, you can create new game clocks programmatically with the API provided with the Game Clock module. See the !help page for more information.</p>
|
| 18 |
", array('!help' => l(t('Game Clock help'), 'admin/help/game_clock')));
|
| 19 |
case 'admin/help#game_clock':
|
| 20 |
return t("
|
| 21 |
<p>Game clocks may be used for various purposes, such as keeping an in-game calendar, tracking game effects and events, and limiting characters to acting at a slower pace suitable for a web-based game.</p>
|
| 22 |
<p>You may view all active game clocks from the !game_clock page, as well as create new clocks there. Additionally, you can create new game clocks programmatically with the API provided with the Game Clock module.</p>
|
| 23 |
<p>To do so, you would create a game clock array as follows:</p>
|
| 24 |
<pre> \$game = array(
|
| 25 |
'name' => \$name, // A unique machine-name.
|
| 26 |
'title' => \$title, // A human-readable title.
|
| 27 |
'status' => \$status, // If TRUE, then the clock will begin started. If FALSE it begins paused. Defaults to FALSE.
|
| 28 |
'turn' => \$turn, // The current turn to begin the clock. Defaults to 0.
|
| 29 |
'increment' => \$increment, // How many seconds before incrementing to the next turn. Defaults to 0 (never; must be manually incremented).
|
| 30 |
'block' => \$block, // If TRUE, then a block displaying this clock's current turn and status will become available. Defaults to FALSE.
|
| 31 |
'init' => \$init, // If TRUE, then the clock will be checked for incrementation on every page load, assuming the proper time has passed.
|
| 32 |
);
|
| 33 |
game_clock_create(\$game);
|
| 34 |
</pre>
|
| 35 |
<p>Other available functions in the Game Clock API that may be useful:</p>
|
| 36 |
<pre>
|
| 37 |
game_clock_pause(\$clock = 'default', \$status = FALSE);
|
| 38 |
game_clock_start(\$clock = 'default');
|
| 39 |
game_clock_increment(\$clock = 'default', \$force = FALSE);
|
| 40 |
game_clock_reset(\$clock = 'default', \$turn = NULL);
|
| 41 |
game_clock_state(\$clock = NULL);
|
| 42 |
</pre>
|
| 43 |
<p>Additionally, you may create a hook_game_clock function in your module to act on game clock events, as follows:</p>
|
| 44 |
<pre>
|
| 45 |
function hook_game_clock(\$op, \$clock = 'default', \$state = NULL) {
|
| 46 |
switch (\$op) {
|
| 47 |
case 'create':
|
| 48 |
// A clock named \$clock has been created with \$state.
|
| 49 |
break;
|
| 50 |
case 'pause':
|
| 51 |
// The clock named \$clock has just been paused.
|
| 52 |
break;
|
| 53 |
case 'start':
|
| 54 |
// The clock named \$clock has just been started.
|
| 55 |
break;
|
| 56 |
case 'increment':
|
| 57 |
// The clock named \$clock has just been incremented a tick.
|
| 58 |
break;
|
| 59 |
case 'reset':
|
| 60 |
// The clock named \$clock has just been reset (usually to 0).
|
| 61 |
break;
|
| 62 |
}
|
| 63 |
}
|
| 64 |
</pre>
|
| 65 |
<p>Please read the documentation in the game_clock.module file for more information.</p>
|
| 66 |
", array('!game_clock' => l(t('Game Clock administration'), 'admin/settings/game_clock')));
|
| 67 |
}
|
| 68 |
}
|
| 69 |
|
| 70 |
function game_clock_settings_page() {
|
| 71 |
$output .= drupal_get_form('game_clock_settings_form');
|
| 72 |
$output .= drupal_get_form('game_clock_settings_add_form');
|
| 73 |
return $output;
|
| 74 |
}
|
| 75 |
|
| 76 |
/**
|
| 77 |
* Callback for admin/settings/game_clock.
|
| 78 |
*/
|
| 79 |
function game_clock_settings_form() {
|
| 80 |
$form = array();
|
| 81 |
$options = array(
|
| 82 |
'pause' => t('Pause game clocks'),
|
| 83 |
'run' => t('Run game clocks'),
|
| 84 |
'reset' => t('Reset game clocks'),
|
| 85 |
'delete' => t('Delete game clocks'),
|
| 86 |
);
|
| 87 |
$form['selector'] = array(
|
| 88 |
'#type' => 'select',
|
| 89 |
'#title' => t('With selected game clocks:'),
|
| 90 |
'#options' => $options,
|
| 91 |
);
|
| 92 |
$form['submit'] = array(
|
| 93 |
'#type' => 'submit',
|
| 94 |
'#value' => t('Submit'),
|
| 95 |
);
|
| 96 |
$form['#theme'] = 'game_clock_settings_form';
|
| 97 |
$game_clocks = game_clock_state();
|
| 98 |
$form['game_clocks'] = array(
|
| 99 |
'#type' => 'value',
|
| 100 |
'#value' => $game_clocks,
|
| 101 |
);
|
| 102 |
foreach ($game_clocks as $clock => $state) {
|
| 103 |
$form['clocks'][$clock] = array();
|
| 104 |
$form['clocks'][$clock]['selection'] = array(
|
| 105 |
'#type' => 'checkbox',
|
| 106 |
);
|
| 107 |
$form['clocks'][$clock]['title'] = array(
|
| 108 |
'#type' => 'item',
|
| 109 |
'#value' => t('@title (@clock)', array('@title' => $state->title, '@clock' => $clock)),
|
| 110 |
);
|
| 111 |
$form['clocks'][$clock]['state'] = array(
|
| 112 |
'#type' => 'item',
|
| 113 |
'#value' => t('@state', array('@state' => ($state->status ? t('started') : t('paused')))),
|
| 114 |
);
|
| 115 |
$form['clocks'][$clock]['turn'] = array(
|
| 116 |
'#type' => 'item',
|
| 117 |
'#value' => t('@turn', array('@turn' => $state->turn)),
|
| 118 |
);
|
| 119 |
$form['clocks'][$clock]['increment'] = array(
|
| 120 |
'#type' => 'item',
|
| 121 |
'#value' => t('@increment', array('@increment' => _game_clock_selections($state->increment))),
|
| 122 |
);
|
| 123 |
$form['clocks'][$clock]['init'] = array(
|
| 124 |
'#type' => 'item',
|
| 125 |
'#value' => t('@init', array('@init' => ($state->init ? t('Yes') : t('No')))),
|
| 126 |
);
|
| 127 |
$ops = array(
|
| 128 |
l(t('edit'), 'admin/settings/game_clock/'. $clock),
|
| 129 |
l(t('pause'), 'admin/settings/game_clock/'. $clock .'/pause'),
|
| 130 |
l(t('run'), 'admin/settings/game_clock/'. $clock .'/run'),
|
| 131 |
l(t('reset'), 'admin/settings/game_clock/'. $clock .'/reset'),
|
| 132 |
l(t('delete'), 'admin/settings/game_clock/'. $clock .'/delete'),
|
| 133 |
);
|
| 134 |
$form['clocks'][$clock]['ops'] = array(
|
| 135 |
'#type' => 'item',
|
| 136 |
'#value' => implode(', ', $ops),
|
| 137 |
);
|
| 138 |
}
|
| 139 |
return $form;
|
| 140 |
}
|
| 141 |
|
| 142 |
function game_clock_settings_add_form() {
|
| 143 |
$form = array();
|
| 144 |
$form['clock'] = array(
|
| 145 |
'#type' => 'fieldset',
|
| 146 |
'#title' => t('Create new game clock'),
|
| 147 |
'#collapsible' => TRUE,
|
| 148 |
'#collapsed' => TRUE,
|
| 149 |
'#description' => t('You may add a new clock with this form. This can be useful for tracking game turns, special effects, and the like. You can also create clocks programmatically. See the !help page for more information.', array('!help' => l('game clock help', 'admin/help/game_clock'))),
|
| 150 |
);
|
| 151 |
$form['clock']['name'] = array(
|
| 152 |
'#type' => 'textfield',
|
| 153 |
'#title' => t('Name'),
|
| 154 |
'#required' => TRUE,
|
| 155 |
'#description' => t('A unique machine name for this game clock. It must contain only lower-case, alphanumeric characters and underscores, and begin with a letter.'),
|
| 156 |
);
|
| 157 |
$form['clock']['title'] = array(
|
| 158 |
'#type' => 'textfield',
|
| 159 |
'#title' => t('Title'),
|
| 160 |
'#description' => t('A human readable title for this game clock.'),
|
| 161 |
);
|
| 162 |
$form['clock']['status'] = array(
|
| 163 |
'#type' => 'checkbox',
|
| 164 |
'#title' => t('Start clock'),
|
| 165 |
'#default_value' => TRUE,
|
| 166 |
'#description' => t('If checked, then this game clock will begin started. Otherwise, it will be paused.'),
|
| 167 |
);
|
| 168 |
$form['clock']['turn'] = array(
|
| 169 |
'#type' => 'textfield',
|
| 170 |
'#title' => t('Starting turn'),
|
| 171 |
'#default_value' => '0',
|
| 172 |
'#description' => t('What turn should the clock begin at?'),
|
| 173 |
);
|
| 174 |
$form['clock']['increment'] = array(
|
| 175 |
'#type' => 'select',
|
| 176 |
'#options' => _game_clock_selections(),
|
| 177 |
'#default_value' => GAME_CLOCK_INCREMENT_DEFAULT,
|
| 178 |
'#required' => TRUE,
|
| 179 |
'#description' => t('The clock will wait at least this much time before incrementing to the next tick.'),
|
| 180 |
);
|
| 181 |
$form['clock']['block'] = array(
|
| 182 |
'#type' => 'checkbox',
|
| 183 |
'#title' => t('Create display block'),
|
| 184 |
'#default_value' => TRUE,
|
| 185 |
'#description' => t('If checked, then make a block available that will display the current turn and status of this clocked.'),
|
| 186 |
);
|
| 187 |
$form['clock']['init'] = array(
|
| 188 |
'#type' => 'checkbox',
|
| 189 |
'#title' => t('Increment clock on page load'),
|
| 190 |
'#default_value' => TRUE,
|
| 191 |
'#description' => 'If checked, then this clock will be checked for incrementation on normal page loads. Otherwise, it will only be checked during a cron run. If a clock has an increment value higher than the cron settings, it may be useful to check this box.',
|
| 192 |
);
|
| 193 |
$form['clock']['submit'] = array(
|
| 194 |
'#type' => 'submit',
|
| 195 |
'#value' => t('Create clock'),
|
| 196 |
);
|
| 197 |
return $form;
|
| 198 |
}
|
| 199 |
|
| 200 |
function game_clock_settings_add_form_validate($form, &$form_state) {
|
| 201 |
$state = $form_state['values'];
|
| 202 |
// Ensure a safe machine name.
|
| 203 |
if (!preg_match('/^[a-z_][a-z0-9_]*$/', $state['name'])) {
|
| 204 |
form_set_error('name', t('The game clock name may only contain lowercase letters, underscores, and numbers; and begin with a letter.'));
|
| 205 |
}
|
| 206 |
else {
|
| 207 |
// Ensure the machine name is unique.
|
| 208 |
$test_state = game_clock_state($this['name']);
|
| 209 |
if ($test_state->cid) {
|
| 210 |
form_set_error('name', t('Game clock names must be unique. This game clock name is already in use.'));
|
| 211 |
}
|
| 212 |
}
|
| 213 |
}
|
| 214 |
|
| 215 |
function game_clock_settings_add_form_submit($form, &$form_state) {
|
| 216 |
$state = game_clock_create($form_state['values'], TRUE);
|
| 217 |
if ($state->cid) {
|
| 218 |
drupal_set_message(t("The %clock game clock was successfully created.", array('%clock' => $state->title)));
|
| 219 |
}
|
| 220 |
}
|
| 221 |
|
| 222 |
function _game_clock_selections($increment = NULL) {
|
| 223 |
static $selections;
|
| 224 |
if (is_null($selections)) {
|
| 225 |
$selections = array(
|
| 226 |
0 => t('Never'),
|
| 227 |
1 => t('1 seconds'),
|
| 228 |
2 => t('2 seconds'),
|
| 229 |
3 => t('3 seconds'),
|
| 230 |
5 => t('5 seconds'),
|
| 231 |
15 => t('15 seconds'),
|
| 232 |
30 => t('30 seconds'),
|
| 233 |
60 => t('1 minute'),
|
| 234 |
120 => t('2 minutes'),
|
| 235 |
300 => t('5 minutes'),
|
| 236 |
600 => t('10 minutes'),
|
| 237 |
900 => t('15 minutes'),
|
| 238 |
1800 => t('30 minutes'),
|
| 239 |
3600 => t('1 hour'),
|
| 240 |
(3600 * 2) => t('2 hours'),
|
| 241 |
(3600 * 4) => t('4 hours'),
|
| 242 |
(3600 * 8) => t('8 hours'),
|
| 243 |
(3600 * 12) => t('12 hours'),
|
| 244 |
(3600 * 24) => t('1 day'),
|
| 245 |
(3600 * 24 * 2) => t('2 days'),
|
| 246 |
(3600 * 24 * 3) => t('3 days'),
|
| 247 |
(3600 * 24 * 4) => t('4 days'),
|
| 248 |
(3600 * 24 * 5) => t('5 days'),
|
| 249 |
(3600 * 24 * 6) => t('6 days'),
|
| 250 |
(3600 * 24 * 7) => t('7 days'),
|
| 251 |
);
|
| 252 |
}
|
| 253 |
if (is_null($increment)) {
|
| 254 |
return $selections;
|
| 255 |
}
|
| 256 |
if (isset($selections[$increment])) {
|
| 257 |
return $selections[$increment];
|
| 258 |
}
|
| 259 |
return t('@count seconds', array('@count' => $increment));
|
| 260 |
}
|
| 261 |
|
| 262 |
/**
|
| 263 |
* Create a new game clock.
|
| 264 |
* @param $state
|
| 265 |
* An object or array with at least the following neccessary parameters:
|
| 266 |
* ['name'] => A unique machine name.
|
| 267 |
* ['title'] => A human readable name for the clock.
|
| 268 |
* ['increment'] => The number of seconds before incrementing each tick.
|
| 269 |
* @param $report_errors
|
| 270 |
* If TRUE, then display messages of any errors. In any case, errors will be logged to the watchdog.
|
| 271 |
* @return
|
| 272 |
* Either the newly created clock object, or FALSE if there was an error.
|
| 273 |
*/
|
| 274 |
function _game_clock_create($state, $report_errors = FALSE) {
|
| 275 |
$state = (object) $state;
|
| 276 |
if (is_null($state->name)) {
|
| 277 |
$error = 'Tried to create unnamed game clock.';
|
| 278 |
if ($report_errors) {
|
| 279 |
drupal_set_message(t($error), 'error');
|
| 280 |
}
|
| 281 |
watchdog('game_clock', $error, array(), WATCHDOG_ERROR);
|
| 282 |
return FALSE;
|
| 283 |
}
|
| 284 |
$test_state = game_clock_state($state->name);
|
| 285 |
if (!is_null($test_state)) {
|
| 286 |
$error = 'Tried to create duplicate game clock: %clock.';
|
| 287 |
$options = array('%clock' => $state->name);
|
| 288 |
if ($report_errors) {
|
| 289 |
drupal_set_message(t($error, $options), 'error');
|
| 290 |
}
|
| 291 |
watchdog('game_clock', $error, $options, WATCHDOG_ERROR);
|
| 292 |
return FALSE;
|
| 293 |
}
|
| 294 |
$status = db_query("INSERT INTO {game_clocks} (name, title, status, turn, increment, block, init) VALUES ('%s', '%s', %d, %d, %d, %d, %d)", $state->name, $state->title, $state->status, $state->turn, $state->increment, $state->block, $state->init);
|
| 295 |
if (!$status) {
|
| 296 |
$error = 'Creation of the %clock game clock failed for an unknown reason.';
|
| 297 |
if ($report_errors) {
|
| 298 |
drupal_set_message($error, 'error');
|
| 299 |
}
|
| 300 |
watchdog('game_clock', $error, array(), WATCHDOG_ERROR);
|
| 301 |
return FALSE;
|
| 302 |
}
|
| 303 |
$state = game_clock_state($state->name);
|
| 304 |
module_invoke_all('game_clock', 'create', $state->name, $state);
|
| 305 |
return $state;
|
| 306 |
}
|
| 307 |
|
| 308 |
/**
|
| 309 |
* Render the form as a table of clock settings and ops.
|
| 310 |
*/
|
| 311 |
function theme_game_clock_settings_form($form) {
|
| 312 |
$output .= drupal_render($form['selector']);
|
| 313 |
$output .= drupal_render($form['submit']);
|
| 314 |
$select_header = theme('table_select_header_cell');
|
| 315 |
$header = array($select_header, t('Title'), t('State'), t('Turn'), t('Increment'), t('On page load?'), t('Ops'));
|
| 316 |
$rows = array();
|
| 317 |
foreach ($form['game_clocks']['#value'] as $clock => $state) {
|
| 318 |
$cells = array();
|
| 319 |
$cells[] = drupal_render($form['clocks'][$clock]['selection']);
|
| 320 |
$cells[] = drupal_render($form['clocks'][$clock]['title']);
|
| 321 |
$cells[] = drupal_render($form['clocks'][$clock]['state']);
|
| 322 |
$cells[] = drupal_render($form['clocks'][$clock]['turn']);
|
| 323 |
$cells[] = drupal_render($form['clocks'][$clock]['increment']);
|
| 324 |
$cells[] = drupal_render($form['clocks'][$clock]['init']);
|
| 325 |
$cells[] = drupal_render($form['clocks'][$clock]['ops']);
|
| 326 |
$rows[] = $cells;
|
| 327 |
}
|
| 328 |
$output .= theme('table', $header, $rows);
|
| 329 |
return $output;
|
| 330 |
}
|