/[drupal]/contributions/modules/fsgame/fsgame.pages.inc
ViewVC logotype

Contents of /contributions/modules/fsgame/fsgame.pages.inc

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


Revision 1.16 - (show annotations) (download) (as text)
Fri Sep 26 02:38:23 2008 UTC (13 months, 4 weeks ago) by aaron
Branch: MAIN
CVS Tags: HEAD
Changes since 1.15: +13 -1 lines
File MIME type: text/x-php
  * Allow users to claim their anonymous character after login (aaronwinborn).
  * Track anonymous characters with the $_SESSION (aaronwinborn).
1 <?php
2 // $Id: fsgame.pages.inc,v 1.15 2008/08/13 11:46:00 aaron Exp $
3
4 /**
5 * @file
6 * Page callbacks for the 5 Second Game engine.
7 */
8
9 /**
10 * Page callback for /fsgame/contest.
11 * Allow two characters to compete.
12 * @param $form_state
13 * The form state.
14 * @param $character_nid
15 * The character nid, or a string to match against fsgame_contest_match_character.
16 * @param $opponent_nid
17 * The opponent nid, or a string to match against fsgame_contest_match_opponent.
18 */
19 function fsgame_contest_form($form_state, $character_nid = 'latest', $opponent_nid = 'latest') {
20 global $user;
21 $form = array();
22 $form['character'] = array(
23 '#type' => 'fieldset',
24 '#title' => t('Your character'),
25 '#collapsible' => TRUE,
26 );
27 if ($user->uid) {
28 $cnid = fsgame_contest_match_character($character_nid, $opponent_nid);
29 }
30 else {
31 $cnid = fsgame_contest_anonymous_character();
32 }
33 if ($cnid && is_numeric($cnid)) {
34 $character = node_load($cnid);
35 $form['character']['#title'] = t('Your character: @name', array('@name' => $character->title));
36 $form['character']['#collapsed'] = TRUE;
37 $form['character']['character_node'] = array(
38 '#type' => 'value',
39 '#value' => $character,
40 );
41 $form['character']['teaser'] = array(
42 '#type' => 'item',
43 '#value' => node_view($character),
44 );
45 fsgame_user_set_latest_character($user->uid, $character->nid);
46 }
47 else {
48 $cnid = 'latest';
49 }
50 $form['character']['character_autocomplete'] = array(
51 '#type' => 'textfield',
52 '#title' => t('Name'),
53 '#autocomplete_path' => 'fsgame/autocomplete/'. $user->uid,
54 );
55 $form['character']['select'] = array(
56 '#type' => 'submit',
57 '#value' => t('Select character'),
58 );
59 $form['opponent'] = array(
60 '#type' => 'fieldset',
61 '#title' => t('Your opponent'),
62 '#collapsible' => TRUE,
63 );
64 $onid = fsgame_contest_match_opponent($opponent_nid, $cnid);
65 if ($onid && is_numeric($onid)) {
66 $opponent = node_load($onid);
67 $form['opponent']['#title'] = t('Your opponent: @name', array('@name' => $opponent->title));
68 $form['opponent']['#collapsed'] = TRUE;
69 $form['opponent']['opponent_node'] = array(
70 '#type' => 'value',
71 '#value' => $opponent,
72 );
73 $form['opponent']['teaser'] = array(
74 '#type' => 'item',
75 '#value' => node_view($opponent),
76 );
77 }
78 else {
79 $onid = 'latest';
80 }
81
82 // If we don't allow contests of characters of the same user, then exclude them from the autocomplete.
83 $opponent_autocomplete_exclude_path = variable_get('fsgame_contest_allow_same_user', FALSE) ? '' : '-exclude';
84 $form['opponent']['opponent_autocomplete'] = array(
85 '#type' => 'textfield',
86 '#title' => t('Name'),
87 '#autocomplete_path' => 'fsgame/autocomplete'. $opponent_autocomplete_exclude_path .'/'. $user->uid,
88 );
89
90 $form['opponent']['select'] = array(
91 '#type' => 'submit',
92 '#value' => t('Select opponent'),
93 );
94 $form['character']['selectors'] = array(
95 '#type' => 'item',
96 '#value' => theme('fsgame_contest_selectors_character', $cnid, $onid),
97 );
98 $form['opponent']['selectors'] = array(
99 '#type' => 'item',
100 '#value' => theme('fsgame_contest_selectors_opponent', $cnid, $onid),
101 );
102 $form['modes'] = array(
103 '#type' => 'fieldset',
104 '#title' => t('Contest modes'),
105 );
106
107 $attributes = fsgame_base_attributes();
108 foreach ($attributes as $key => $attribute) {
109 $attacks[$key] = $attribute['title'];
110 $defenses[$key] = $attribute['title'];
111 }
112 // Allow modules implementing hook_fsgame_available_modes_alter to add/remove their own skills to/from the selectors.
113 drupal_alter('fsgame_available_modes', $attack, 'character', 'attack', $character, $opponent);
114 drupal_alter('fsgame_available_modes', $defense, 'character', 'defense', $character, $opponent);
115
116 $form['modes']['attack'] = array(
117 '#type' => 'select',
118 '#title' => t('Attack'),
119 '#options' => $attacks,
120 );
121 $form['modes']['defense'] = array(
122 '#type' => 'select',
123 '#title' => t('Defense'),
124 '#options' => $defenses,
125 );
126 $form['submit'] = array(
127 '#type' => 'submit',
128 '#value' => t('Fight!'),
129 );
130 return $form;
131 }
132
133 function fsgame_contest_form_validate($form, &$form_state) {
134 global $user;
135 $contest = array();
136 $character = $form_state['values']['character_node'];
137 if ($form_state['values']['character_autocomplete'] || !($form_state['values']['character_node'])) {
138 $character = node_load(_fsgame_autocomplete_nid($form_state['values']['character_autocomplete']));
139 if (($form_state['values']['op'] == t('Fight!')) && ($character->type != 'fsgame_character') || ($character->uid != $user->uid)) {
140 form_set_error('character_autocomplete', t('Please select a valid character that you own.'));
141 }
142 }
143 $opponent = $form_state['values']['opponent_node'];
144 if ($form_state['values']['opponent_autocomplete'] || !($form_state['values']['opponent_node'])) {
145 $opponent = node_load(_fsgame_autocomplete_nid($form_state['values']['opponent_autocomplete']));
146 if (($form_state['values']['op'] == t('Fight!')) && $opponent->type != 'fsgame_character') {
147 form_set_error('opponent_autocomplete', t('Please select a valid opponent.'));
148 }
149 }
150 $contest['character'] = $character;
151 $contest['opponent'] = $opponent;
152 if (($form_state['values']['op'] == t('Fight!')) && !fsgame_contest_allow($contest)) {
153 // print the reason returned for not allowing a specific contest.
154 form_set_error('', $contest['results']['disallow']);
155 }
156 $form_state['values']['contest'] = $contest;
157 }
158
159 function fsgame_contest_form_submit($form, &$form_state) {
160 global $user;
161 if ($form_state['values']['character_autocomplete']) {
162 $form_state['values']['character_node'] = node_load(_fsgame_autocomplete_nid($form_state['values']['character_autocomplete']));
163 }
164 if ($form_state['values']['opponent_autocomplete']) {
165 $form_state['values']['opponent_node'] = node_load(_fsgame_autocomplete_nid($form_state['values']['opponent_autocomplete']));
166 }
167 fsgame_user_set_latest_character($user->uid, $form_state['values']['character_node']->nid);
168 if ($form_state['values']['op'] == t('Fight!')) {
169 $contest = $form_state['values']['contest'];
170 $contest['character attack'] = fsgame_contest_select_mode('attack', $form_state['values']['attack'], $form_state['values']['character_node'], $form_state['values']['opponent_node']);
171 $contest['character defense'] = fsgame_contest_select_mode('defense', $form_state['values']['defense'], $form_state['values']['character_node'], $form_state['values']['opponent_node']);
172 fsgame_contest($contest);
173 $winner = $contest['results']['win'];
174 if ($winner == 'draw') {
175 drupal_set_message(t('The result is a draw.'));
176 }
177 else if ($winner->nid) {
178 drupal_set_message(t('!title wins the contest.', array('!title' => l($winner->title, 'node/'. $winner->nid))));
179 }
180 else {
181 drupal_set_message(t('Unknown error in fsgame_contest_form_submit'), 'error');
182 }
183 }
184 drupal_goto('fsgame/contest/'. $form_state['values']['character_node']->nid .'/'. $form_state['values']['opponent_node']->nid);
185 }
186
187 /**
188 * Match a game character.
189 * @param $character_nid
190 * Either the nid of the character to compete with, or one of the following strings:
191 * 'latest' => The last selected character of the currently logged in user.
192 * 'newest' => The most recently created character of the currently logged in user.
193 * 'random' => A random character from among those owned by the currently logged in user.
194 * 'select' => A drop-down of characters owned by the currently logged in user.
195 * 'autocomplete' => An autocomplete textfield, otherwise the same as 'select'.
196 * 'anonymous' => The anonymous character stored in the user's session (reverts to 'select' if not anonymous).
197 * If the user is anonymous, then this parameter is ignored, and treated as though it were 'anonymous'.
198 * Otherwise, if this doesn't match, then the string from $character_nid is passed through hook_fsgame_contest_match_character,
199 * so that other modules may choose a character from the given argument.
200 * @TODO: finish implementing this
201 */
202 function fsgame_contest_match_character($character_nid, $opponent_nid = NULL) {
203 global $user;
204 if ($character_nid && is_numeric($character_nid)) {
205 $node = node_load($character_nid);
206 if ($node->type == 'fsgame_character' && ($node->uid == $user->uid)) {
207 return $character_nid;
208 }
209 return FALSE;
210 }
211 if ($character_nid == 'latest') {
212 return fsgame_user_get_latest_character($user->uid);
213 }
214 if ($character_nid == 'newest') {
215 $sql = "SELECT nid FROM {node} WHERE type='fsgame_character' AND uid=%d ORDER BY created DESC";
216 return db_result(db_query_range($sql, $user->uid, 0, 1));
217 }
218 if ($character_nid == 'random') {
219 $sql = "SELECT nid FROM {node} WHERE type='fsgame_character' AND uid=%d ORDER BY RAND()";
220 drupal_goto('fsgame/contest/'. db_result(db_query_range($sql, $user->uid, 0, 1)) .'/'. $opponent_nid);
221 }
222 }
223
224 /**
225 * Match a game opponent character.
226 * @param $opponent_nid
227 * Either the nid of the character to compete against, or one of the following strings:
228 * 'latest' => The last selected opponent of the selected character.
229 * 'random' => A random suitable opponent.
230 * 'select' => A drop-down of suitable opponents.
231 * 'autocomplete' => An autocomplete textfield, otherwise the same as 'select'.
232 * 'user:%uid' => A random suitable opponent belonging to the specified %uid.
233 * If this doesn't match, then the string from $opponent_nid is passed through hook_fsgame_contest_match_opponent,
234 * so that other modules may choose an opponent from the given argument.
235 * @param $character_nid
236 * If provided, this is the currently matched character's node's NID.
237 */
238 function fsgame_contest_match_opponent($opponent_nid, $character_nid = NULL) {
239 global $user;
240 if ($opponent_nid && is_numeric($opponent_nid)) {
241 $node = node_load($opponent_nid);
242 if ($node->type == 'fsgame_character' && ($node->uid != $user->uid)) {
243 return $opponent_nid;
244 }
245 return FALSE;
246 }
247 if ($opponent_nid == 'latest' && $character_nid && is_numeric($character_nid)) {
248 return fsgame_character_get_latest_opponent($character_nid);
249 }
250 if ($opponent_nid == 'random') {
251 $sql = "SELECT nid FROM {node} WHERE type='fsgame_character' AND uid<>%d ORDER BY RAND()";
252 $character_nid = isset($character_nid) ? $character_nid : '/latest';
253 return drupal_goto('fsgame/contest/'. $character_nid .'/'. db_result(db_query_range($sql, $user->uid, 0, 1)));
254 }
255 }
256
257 /**
258 * Return the character from this anonymous user's session.
259 * @TODO
260 */
261 function fsgame_contest_anonymous_character() {
262 return $_SESSION['fsgame_contest_anonymous_character'];
263 }
264
265 /**
266 * Retrieve a pipe delimited string of autocomplete suggestions
267 * @param $uid
268 * If a number that is not 0, then this will retrieve only characters of that user account.
269 * @param $string
270 * A partial string to match.
271 * @param $exclude_uid
272 * If non-NULL, then it will exclude characters of this user, including anonymous.
273 */
274 function fsgame_autocomplete($uid = NULL, $string = '') {
275 $matches = array();
276
277 $nodes = _fsgame_potential_nodes($uid, TRUE, $string);
278 foreach ($nodes as $node) {
279 $matches[check_plain($node->title) .' ('. $node->name .') ['. $node->nid .']'] = check_plain($node->title) .' ('. $node->name .') ['. $node->nid .']';
280 }
281 drupal_json($matches);
282 }
283
284 /**
285 * Retrieve a pipe delimited string of autocomplete suggestions.
286 * @param $uid
287 * If non-NULL, then it will exclude characters of this user, including anonymous if 0.
288 * @param $string
289 * A partial string to match.
290 */
291 function fsgame_autocomplete_exclude($uid = NULL, $string = '') {
292 $matches = array();
293
294 $nodes = _fsgame_potential_nodes(NULL, TRUE, $string, FALSE, $uid);
295 foreach ($nodes as $node) {
296 $matches[check_plain($node->title) .' ('. $node->name .') ['. $node->nid .']'] = check_plain($node->title) .' ('. $node->name .') ['. $node->nid .']';
297 }
298 drupal_json($matches);
299 }
300
301 /**
302 * Fetch an array of all candidate character nodes,
303 * for use in presenting the selection form to the user.
304 * @TODO: Allow views to further determine fetched characters, such as a from a specific guild. See nodereference.
305 */
306 function _fsgame_potential_nodes($uid = 0, $return_full_nodes = FALSE, $string = '', $exact_string = FALSE, $exclude_uid = NULL) {
307 // standard field : referenceable nodes defined by content types
308 // build the appropriate query
309 $conditions = array(" n.type = '%s'");
310 $args = array('fsgame_character');
311
312 if ($uid && is_numeric($uid)) {
313 $conditions[] = " n.uid = %d";
314 $args[] = $uid;
315 }
316
317 if (isset($string)) {
318 $conditions[] = $exact_string ? " n.title = '%s'" : " n.title LIKE '%%%s%'";
319 $args[] = $string;
320 }
321
322 if (isset($exclude_uid) && is_numeric($exclude_uid)) {
323 $conditions[] = " n.uid <> %d";
324 $args[] = $exclude_uid;
325 }
326
327 $conditions_clause = implode(' AND', $conditions);
328
329 $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, u.name FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE ". $conditions_clause ." ORDER BY n.title, n.type"), $args);
330
331 $rows = array();
332
333 while ($node = db_fetch_object($result)) {
334 if ($return_full_nodes) {
335 $rows[$node->nid] = $node;
336 }
337 else {
338 $rows[$node->nid] = $node->node_title;
339 }
340 }
341
342 return $rows;
343 }
344
345 function _fsgame_autocomplete_nid($character) {
346 if ($character && is_numeric($character)) {
347 $nid = $character;
348 }
349 else {
350 preg_match('@\[([0-9]+)\]@', $character, $matches);
351 $nid = $matches[1];
352 }
353 return $nid;
354 }
355
356 function fsgame_character_claim($node) {
357 if (!fsgame_claim_access($node)) {
358 drupal_access_denied();
359 }
360 global $user;
361 $node->uid = $user->uid;
362 node_save($node);
363 drupal_set_message(t("You have claimed the character %title as your own.", array('%title' => $node->title)));
364 unset($_SESSION['fsgame_contest_anonymous_character']);
365 drupal_goto('node/'. $node->nid);
366 }

  ViewVC Help
Powered by ViewVC 1.1.2