clean koko_carnaval
[exterlulz-kokogems.git] / src / GameController.m
blobd2b52d23198ff2096c7c25de3aa9f3a41bd1db2c
1 /* ----====----====----====----====----====----====----====----====----====----
2 GameController.m (jeweltoy)
4 JewelToy is a simple game played against the clock.
5 Copyright (C) 2001  Giles Williams
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 ----====----====----====----====----====----====----====----====----====---- */
22 #import "GameController.h"
23 #import "TimerView.h"
24 #import "Game.h"
25 #import "GameView.h"
26 #import "Gem.h"
28 @implementation GameController
30 @synthesize _gameState;
32 - (id) init
34     self = [super init];
35     
36     hiScores = [[NSUserDefaults standardUserDefaults] arrayForKey:@"hiScores"];
38     //NSLog(@"hiScores : %@",hiScores);
40     if ((!hiScores)||([hiScores count] < 8))
41     {
42         //NSLog(@"Creating High Score Tables");
43         hiScores = [self makeBlankHiScoresWith:hiScores];
44         [[NSUserDefaults standardUserDefaults] setObject:hiScores forKey:@"hiScores"];
45     }
46     [hiScores retain];
47     
48     noMoreMovesString = [[NSBundle mainBundle]
49                             localizedStringForKey:@"NoMoreMovesHTML"
50                             value:nil table:nil];
51     jeweltoyStartString = [[NSBundle mainBundle]
52                             localizedStringForKey:@"JewelToyStartHTML"
53                             value:nil table:nil];
54     gameOverString = [[NSBundle mainBundle]
55                             localizedStringForKey:@"GameOverHTML"
56                             value:nil table:nil];
57     titleImage = [NSImage imageNamed:@"title"];
58     gameLevel = 0;
59     gameNames = [hiScores objectAtIndex:0];
60     gameScores = [hiScores objectAtIndex:1];
61         
62     game = [[Game alloc] init];
63     animationTimerLock = [[NSLock alloc] init];
64     
65     gemMoveSize = GEM_GRAPHIC_SIZE;
66     gemMoveSpeed = GEM_MOVE_SPEED;
67     gemMoveSteps = gemMoveSize / gemMoveSpeed;
68         
69     useAlternateGraphics = [[NSUserDefaults standardUserDefaults] boolForKey:@"useAlternateGraphics"];
70     useImportedGraphics = [[NSUserDefaults standardUserDefaults] boolForKey:@"useImportedGraphics"];
71     
72     useCustomBackgrounds = [[NSUserDefaults standardUserDefaults] boolForKey:@"useCustomBackgrounds"];
73     customBackgroundFolderPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"customBackgroundFolderPath"];
74     if (!customBackgroundFolderPath)
75         customBackgroundFolderPath = [[NSBundle mainBundle] localizedStringForKey:@"PicturesFolderPath"
76                                                                             value:nil table:nil];
77     return self;
80 - (void) dealloc
82     if (noMoreMovesString)      [noMoreMovesString release];
83     if (jeweltoyStartString)    [jeweltoyStartString release];
84     if (gameOverString) [gameOverString release];
85     if (game) [game release];
86     if (animationTimerLock) [animationTimerLock release];
87     if (timer)  [timer release];
88     if (hiScores)       [hiScores release];
89     [super dealloc];
92 - (void)awakeFromNib
94     [gameWindow setFrameAutosaveName:@"gameWindow"];
95     //useAlternateGraphics = [[NSUserDefaults standardUserDefaults] boolForKey:@"useAlternateGraphics"];
98 - (void)windowWillClose:(NSNotification *)aNotification
100     id obj = [aNotification object];
101     if (obj == aboutPanel)
102     {
103         //NSLog(@"Someone closed the 'About' window");
104         aboutPanel = nil;
105         return;
106     }
107     if (obj == prefsPanel)
108     {
109         //NSLog(@"Someone closed the 'Preferences' window");
110         useAlternateGraphics = [prefsAlternateGraphicsButton state];
111         [[NSUserDefaults standardUserDefaults]  setBool:useAlternateGraphics
112                                                 forKey:@"useAlternateGraphics"];
113         [[NSUserDefaults standardUserDefaults]  setBool:useImportedGraphics
114                                                 forKey:@"useImportedGraphics"];
116         useCustomBackgrounds = [prefsCustomBackgroundCheckbox state];
117         [[NSUserDefaults standardUserDefaults]  setBool:useCustomBackgrounds
118                                                 forKey:@"useCustomBackgrounds"];
119         [[NSUserDefaults standardUserDefaults]  removeObjectForKey:@"customBackgroundFolderPath"];
120         [[NSUserDefaults standardUserDefaults]  setObject:[prefsCustomBackgroundFolderTextField stringValue]
121                                                   forKey:@"customBackgroundFolderPath"];
122         if (gameView)
123         {
124             //[gameView loadImageArray];
125             [gameView graphicSetUp];
126             [gameView newBackground];
127             if (game)   [game setSpritesFrom:[gameView spriteArray]];
128             [gameView setNeedsDisplay:YES];
129         }
130         prefsPanel = nil;
131         return;
132     }
133     if (obj == gameWindow)
134     {
135         //NSLog(@"Someone closed the window - shutting down JewelToy");
136         [NSApp terminate:self];
137         return;
138     }
141 - (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void  *)contextInfo {
142     [prefsCustomBackgroundFolderTextField setStringValue:[[sheet filenames] objectAtIndex:0]];
145 // TODO: move algorithm to its own method
146 - (IBAction)prefsGraphicDropAction:(id)sender
148     //
149     //  slice and dice importedImage, saving images to defaults
150     //
151     NSImage *importedImage = [prefsAlternateGraphicsImageView image];
152     if (importedImage)
153     {
154         int i = 0;
155         NSRect  cropRect = NSMakeRect(0.0,0.0,[importedImage size].width/7.0,[importedImage size].height);
156         NSRect  gemRect = NSMakeRect(0.0,0.0,48.0,48.0);
157         NSSize imageSize = NSMakeSize(48.0,48.0);
158         for (i = 0; i < 7; i++)
159         {
160             NSImage     *gemImage = [[NSImage alloc] initWithSize:imageSize];
161             NSString *key = [NSString stringWithFormat:@"tiffGemImage%d", i];
162             cropRect.origin.x = i * [importedImage size].width/7.0;
163             [gemImage lockFocus];
164             [[NSColor clearColor] set];
165             NSRectFill(gemRect);
166             [importedImage drawInRect:gemRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
167             [gemImage unlockFocus];
168             [[NSUserDefaults standardUserDefaults]      setObject:[gemImage TIFFRepresentation] forKey:key];
169             if (i == 0) [iv1 setImage:gemImage];
170             if (i == 1) [iv2 setImage:gemImage];
171             if (i == 2) [iv3 setImage:gemImage];
172             if (i == 3) [iv4 setImage:gemImage];
173             if (i == 4) [iv5 setImage:gemImage];
174             if (i == 5) [iv6 setImage:gemImage];
175             if (i == 6) [iv7 setImage:gemImage];
176             [gemImage release];
177         }
178         useImportedGraphics = YES;
179     }
180         
183 - (IBAction)prefsCustomBackgroundCheckboxAction:(id)sender
185     //NSLog(@"prefsCustomBackgroundCheckboxAction");
187     if (sender!=prefsCustomBackgroundCheckbox)
188         return;
189     [prefsSelectFolderButton setEnabled:[prefsCustomBackgroundCheckbox state]];
190     [prefsCustomBackgroundFolderTextField setEnabled:[prefsCustomBackgroundCheckbox state]];
191     
194 - (IBAction)prefsSelectFolderButtonAction:(id)sender
196     NSOpenPanel *op=[NSOpenPanel openPanel];
198     //NSLog(@"prefsSelectFolderButtonAction");
199     [op setCanChooseDirectories:YES];
200     [op setCanChooseFiles:NO];
201     // get a sheet going to let the user pick a folder to scan for pictures
202     [op beginSheetForDirectory:[prefsCustomBackgroundFolderTextField stringValue] file:NULL types:NULL modalForWindow:prefsPanel modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
205 - (BOOL) validateMenuItem: (NSMenuItem*) aMenuItem
207     if (aMenuItem == easyGameMenuItem)
208         return [easyGameButton isEnabled];
209     if (aMenuItem == hardGameMenuItem)
210         return [hardGameButton isEnabled];
211     if (aMenuItem == toughGameMenuItem)
212         return [toughGameButton isEnabled];
213     if (aMenuItem == freePlayMenuItem)
214         return [easyGameButton isEnabled];
215     if (aMenuItem == abortGameMenuItem)
216         return [abortGameButton isEnabled];
217     if (aMenuItem == pauseGameMenuItem)
218         return [pauseGameButton isEnabled];
219     //
220     // only allow viewing and reset of scores between games
221     //
222     if (aMenuItem == showHighScoresMenuItem)
223         return [easyGameButton isEnabled];
224     if (aMenuItem == resetHighScoresMenuItem)
225         return [easyGameButton isEnabled];
226     return YES;
229 - (IBAction)startNewGame:(id)sender
231     //NSLog(@"gameController.startNewGame messaged gameView:%@",gameView);
232     
233     [easyGameButton setEnabled:NO];
234     [hardGameButton setEnabled:NO];
235     [toughGameButton setEnabled:NO];
236     [abortGameButton setEnabled:YES];
237     [pauseGameButton setEnabled:YES];
239     abortGame = NO;
240     gameSpeed = 1.0;
241     gameLevel = 0;
242     
243     if ((sender == easyGameButton) ||
244         (sender == easyGameMenuItem)) {
245         //NSLog(@"debug - hiScores = %@\n...hiScores.count = %d",hiScores,[hiScores count]);
246         gameLevel = 0;
247         gameTime = 600.0; // ten minutes
248         [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
249                                             localizedStringForKey:@"EasyHighScoresHTML"
250                                             value:nil table:nil]];
251     }
252   // TODO: add else if?
253     if ((sender == hardGameButton) ||
254         (sender == hardGameMenuItem)) {
255         gameLevel = 1;
256         gameTime = 180.0; // three minutes
257         [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
258                                             localizedStringForKey:@"HardHighScoresHTML"
259                                             value:nil table:nil]];
260     }
261   // TODO: add else if?
262     if ((sender == toughGameButton) ||
263         (sender == toughGameMenuItem)) {
264         gameLevel = 2;
265         gameTime = 90.0; // one and a half minutes
266         [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
267                                             localizedStringForKey:@"ToughHighScoresHTML"
268                                             value:nil table:nil]];
269     }
270   
271     if (sender==freePlayMenuItem)
272     {
273         gameLevel = 3;
274         gameTime = 3600.0; // one hour FWIW
275         freePlay = YES;//       FREEPLAY
276         [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
277                                             localizedStringForKey:@"FreePlayHighScoresHTML"
278                                             value:nil table:nil]];
279     }
280     else {
281         freePlay = NO;//        FREEPLAY
282     }
283   
284     gameNames = [hiScores objectAtIndex:gameLevel*2];
285     gameScores = [hiScores objectAtIndex:gameLevel*2+1];
286     [game wholeNewGameWithSpritesFrom:[gameView spriteArray]];
288     [scoreTextField setStringValue:[NSString stringWithFormat:@"%d", game._score]];
289     [scoreTextField setNeedsDisplay:YES];
290     [bonusTextField setStringValue:[NSString stringWithFormat:@"x%d", game._bonusMultiplier]];
291     [bonusTextField setNeedsDisplay:YES];
292     
293     [game setMuted:muted];
294     [gameView setGame:game];
295     [gameView setLegend:nil];
296     [gameView setPaused:NO];
297     [gameView setMuted:muted];
298     [gameView setShowHint:!freePlay];//         FREEPLAY
299     
300     [timerView setTimerRunningEvery:0.5/gameSpeed
301                 decrement:(0.5/gameTime)
302                 withTarget:self
303                 whenRunOut:@selector(runOutOfTime)
304                 whenRunOver:@selector(bonusAwarded)];
305     
306     if (freePlay)
307     {
308         [timerView setDecrement:0.0];// FREEPLAY MW
309         [timerView setTimer:0.0];
310     }
311     
312     [timerView setPaused:YES];
313         
314     [gameView setLastMoveDate];
315     [self startAnimation:@selector(waitForFirstClick)];
318 - (IBAction)abortGame:(id)sender
320     [abortGameButton setEnabled:NO];
321     if (paused) [self togglePauseMode:self];
322     [pauseGameButton setEnabled:NO];
323     abortGame = YES;
324     [self waitForFirstClick];
327 - (IBAction)receiveHiScoreName:(id)sender
329     int         i;
330     int         score = [hiScorePanelScoreTextField intValue];
331     NSString    *name = [hiScorePanelNameTextField stringValue];
333     [NSApp endSheet:hiScorePanel];
334     [hiScorePanel close];
335     
336     //NSLog(@"receiving HiScoreName:%@ %d",name,score);
337     
338     // reset arrays to gameLevel    
339     gameNames = [hiScores objectAtIndex:gameLevel*2];
340     gameScores = [hiScores objectAtIndex:gameLevel*2+1];
341     
342     for (i = 0; i < 10; i++)
343     {
344         if (score > [[gameScores objectAtIndex:i] intValue])
345         {
346             [gameScores insertObject:[NSNumber numberWithInt:score] atIndex:i];
347             [gameScores removeObjectAtIndex:10];
348             [gameNames  insertObject:name atIndex:i];
349             [gameNames  removeObjectAtIndex:10];
350             break;
351         }
352     }
354     [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"hiScores"];     // or it won't work!?!
355     [[NSUserDefaults standardUserDefaults] setObject:hiScores forKey:@"hiScores"];
357     //NSLog(@"written high-scores to preferences");
358     
359     _gameState = GAMESTATE_GAMEOVER;
360     [gameView showHighScores:gameScores andNames:gameNames];
361     [gameView setLastMoveDate]; //reset timer so scores show for 20s    
364 - (IBAction)togglePauseMode:(id)sender
366     //NSLog(@"Pause game toggled, sender state is %d",[sender state]);
367     if (sender == pauseGameButton)
368         paused = [sender state];
369     else
370         paused = !paused;
371     
372     [pauseGameButton setState:paused];
373     [timerView setPaused:paused];
374     if (paused)
375     {
376         [gameView setPaused:YES];
377         [gameView setHTMLLegend:[[NSBundle mainBundle]
378                             localizedStringForKey:@"PausedHTML"
379                             value:nil table:nil]];
380         [pauseGameMenuItem setTitle:[[NSBundle mainBundle]
381                             localizedStringForKey:@"ContinueGameMenuItemTitle"
382                             value:nil table:nil]];
383     }
384     else
385     {
386         [gameView setPaused:NO];
387         [gameView setLegend:nil];
388         [pauseGameMenuItem setTitle:[[NSBundle mainBundle]
389                             localizedStringForKey:@"PauseGameMenuItemTitle"
390                             value:nil table:nil]];
391     }
394 - (IBAction)toggleMute:(id)sender
396     if (sender == muteButton)
397         muted = [sender state];
398     else
399         muted = !muted;
400     
401     [muteButton setState:muted];
402     [gameView setMuted:muted];
403     [game setMuted:muted];
404     
405     if (muted)
406         [muteMenuItem setTitle:[[NSBundle mainBundle]
407                             localizedStringForKey:@"UnMuteGameMenuItemTitle"
408                             value:nil table:nil]];
409     else
410         [muteMenuItem setTitle:[[NSBundle mainBundle]
411                             localizedStringForKey:@"MuteGameMenuItemTitle"
412                             value:nil table:nil]];
413     
416 - (IBAction)orderFrontAboutPanel:(id)sender
418     //NSLog(@"GameController showAboutPanel called");
419     if (!aboutPanel)
420         [NSBundle loadNibNamed:@"About" owner:self];
421     [aboutPanel setFrameAutosaveName:@"aboutPanel"];
422     [aboutPanel makeKeyAndOrderFront:self];
425 - (IBAction)orderFrontPreferencesPanel:(id)sender
427     if (!prefsPanel)
428         [NSBundle loadNibNamed:@"Preferences" owner:self];
430     [prefsStandardGraphicsButton setState:!useAlternateGraphics];
431     [prefsAlternateGraphicsButton setState:useAlternateGraphics];
433     [prefsCustomBackgroundCheckbox setState:useCustomBackgrounds];
434     [prefsCustomBackgroundFolderTextField setStringValue:customBackgroundFolderPath];
435     [prefsSelectFolderButton setEnabled:[prefsCustomBackgroundCheckbox state]];
436     [prefsCustomBackgroundFolderTextField setEnabled:[prefsCustomBackgroundCheckbox state]];
437     
438     if ([[NSUserDefaults standardUserDefaults]  dataForKey:@"tiffGemImage0"])
439     {    // set up images!
440         int i = 0;
441         for (i = 0; i < 7; i++)
442         {
443             NSString    *key = [NSString stringWithFormat:@"tiffGemImage%d", i];
444             NSData      *tiffData = [[NSUserDefaults standardUserDefaults]      dataForKey:key];
445             NSImage     *gemImage = [[NSImage alloc] initWithData:tiffData];
446             if (i == 0) [iv1 setImage:gemImage];
447             if (i == 1) [iv2 setImage:gemImage];
448             if (i == 2) [iv3 setImage:gemImage];
449             if (i == 3) [iv4 setImage:gemImage];
450             if (i == 4) [iv5 setImage:gemImage];
451             if (i == 5) [iv6 setImage:gemImage];
452             if (i == 6) [iv7 setImage:gemImage];
453             [gemImage release];
454         }
455     }
456     
457     [prefsPanel setFrameAutosaveName:@"prefsPanel"];
458     [prefsPanel makeKeyAndOrderFront:self];
461 - (IBAction)showHighScores:(id)sender
463     // rotate which scores to show
464     //
465     gameNames = [hiScores objectAtIndex:gameLevel*2];
466     gameScores = [hiScores objectAtIndex:gameLevel*2+1];
467     if (gameLevel==0)
468     [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
469                                             localizedStringForKey:@"EasyHighScoresHTML"
470                                             value:nil table:nil]];
471     else if (gameLevel==1)
472     [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
473                                             localizedStringForKey:@"HardHighScoresHTML"
474                                             value:nil table:nil]];
475     else if (gameLevel==2)
476     [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
477                                             localizedStringForKey:@"ToughHighScoresHTML"
478                                             value:nil table:nil]];
479     else if (gameLevel==3)
480     [gameView setHTMLHiScoreLegend:[[NSBundle mainBundle]
481                                             localizedStringForKey:@"FreePlayHighScoresHTML"
482                                             value:nil table:nil]];
483     gameLevel = (gameLevel +1)%4;
484     
485     [gameView showHighScores:gameScores andNames:gameNames];
486     [gameView setLastMoveDate]; //reset timer so scores show for 20s    
489 - (IBAction)resetHighScores:(id)sender
491     // don't rotate which scores to show
492     //
493     // blank the hi scores
494     //
495     [hiScores release];
496     hiScores = [[self makeBlankHiScoresWith:nil] retain];
497     [[NSUserDefaults standardUserDefaults] setObject:hiScores forKey:@"hiScores"];
498     
499     [self showHighScores:sender];       //call the show scores routine    
502 - (NSArray *)makeBlankHiScoresWith:(NSArray *)oldScores
504     //int i,j;
505     int j;
506     NSMutableArray      *result = [NSMutableArray arrayWithCapacity:0];
507     
508     if (oldScores)      result = [NSMutableArray arrayWithArray:oldScores];
509     
510     //for (i = 0; i < 3; i++)
511     while ([result count] < 8)
512     {
513         NSMutableArray  *scores = [NSMutableArray arrayWithCapacity:0];
514         NSMutableArray  *names = [NSMutableArray arrayWithCapacity:0];
515         for (j = 0; j < 10; j++)
516         {
517             [scores addObject:[NSNumber numberWithInt:1000]];
518             [names addObject:[[NSBundle mainBundle]
519                                 localizedStringForKey:@"AnonymousName"
520                                 value:nil table:nil]];
521         }
522         [result addObject:names];
523         [result addObject:scores];
524     }
525     return [NSArray arrayWithArray:result];
528 - (void)runOutOfTime
530     _gameState = GAMESTATE_GAMEOVER;
531     [abortGameButton setEnabled:NO];
532     [pauseGameButton setEnabled:NO];
533     abortGame = YES;
534     [gameView setHTMLLegend:gameOverString];
535     [game shake];
536     [self startAnimation:@selector(waitForFirstClick)];
539 - (void)checkHiScores
541     int i;
542     // reset arrays with gameLevel
543     gameNames = [hiScores objectAtIndex:gameLevel*2];
544     gameScores = [hiScores objectAtIndex:gameLevel*2+1];
545     for (i = 0; i < 10; i++)
546     {
547         if (game._score > [[gameScores objectAtIndex:i] intValue])
548         {
549             [hiScorePanelScoreTextField
550                 setStringValue:[NSString stringWithFormat:@"%d", game._score]];
551             [NSApp      beginSheet:hiScorePanel
552                             modalForWindow:gameWindow
553                             modalDelegate:self
554                             didEndSelector:NULL
555                             contextInfo:NULL];
556             return;
557         }
558     }
559     [gameView showHighScores:gameScores andNames:gameNames];
562 - (void)bonusAwarded
565     [gameView newBackground];
567     if (!muted)         [[NSSound soundNamed:@"yes"] play];
569     if (!freePlay) {            // FREEPLAY MW
570         [game increaseBonusMultiplier];
571         [timerView decrementMeter:0.5];
572     } else {
573         [game increaseBonusMultiplier];
574         [timerView decrementMeter:1];
575     }
577     if (gameSpeed < SPEED_LIMIT)                // capping speed limit
578         gameSpeed = gameSpeed * 1.5;
579     //NSLog(@"...gamesSpeed %f",gameSpeed);
580     [timerView setTimerRunningEvery:0.5/gameSpeed
581                 decrement:(0.5/gameTime)
582                 withTarget:self
583                 whenRunOut:@selector(runOutOfTime)
584                 whenRunOver:@selector(bonusAwarded)];
585                 
586     if (freePlay)       [timerView setDecrement:0];//   FREEPLAY
589 - (void)startAnimation:(SEL)andThenSelector
591     [animationTimerLock lock];
592     //
593     if (!timer)
594         timer = [[NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL
595                                                   target:gameView
596                                                 selector:@selector(animate)
597                                                 userInfo:self
598                                                  repeats:YES] retain];
599     //
600     whatNext = andThenSelector;
601     //
602   gameView._animating = YES;
603     //
604     [animationTimerLock unlock];
607 - (void)animationEnded
609     //NSLog(@"gameController.animationEnded messaged");
610     
611     [animationTimerLock lock];
612     //
613   gameView._animating = NO;
614     //
615     [animationTimerLock unlock];
616     
617     if (whatNext)       [self performSelector:whatNext];
618         
619     [gameView setNeedsDisplay:YES];
622 - (void)waitForNewGame
624     [self checkHiScores];
625     
626     [game wholeNewGameWithSpritesFrom:[gameView spriteArray]];
627     [gameView setLegend:titleImage];
628     [easyGameButton setEnabled:YES];
629     [hardGameButton setEnabled:YES];
630     [toughGameButton setEnabled:YES];
631     [abortGameButton setEnabled:NO];
632     [pauseGameButton setEnabled:NO];
635 - (void)newBoard1
637     //NSLog(@"newBoard1");
638     [game erupt];
639     [self startAnimation:@selector(newBoard2)];
642 - (void)newBoard2
644     Gem *gem;
645     int i,j,r;
646     //NSLog(@"newBoard2");
647     for (i = 0; i < 8; i++)
648     {
649         for (j = 0; j < 8; j++)
650         {
651             gem = [game gemAt:i:j];
652             //NSLog(@"..gem..%@",gem);
653             r = rand() % 7;
654             [gem setGemType:r];
655             //[gem setImage:[[gameView imageArray] objectAtIndex:r]];
656             [gem setSprite:[[gameView spriteArray] objectAtIndex:r]];
657             [gem setPositionOnBoard:i:j];
658             [gem setPositionOnScreen:i*48:(i+j+8)*48];
659             [gem fall];
660         }
661     }
662     [gameView newBackground];
663     [gameView setLegend:nil];
664     [self startAnimation:@selector(testForThreesAgain)];
667 - (void)waitForFirstClick
669     //NSLog(@"waitForFirstClick");
670     /*- if (!freePlay)  MW CHANGE -*/   [timerView setPaused:NO];
671     if (abortGame)
672     {
673         [timerView setTimer:0.5];
674         _gameState = GAMESTATE_GAMEOVER;
675         [game explodeGameOver];
676         [self startAnimation:@selector(waitForNewGame)];
677         return;
678     }
679     if (![game boardHasMoves])
680     {
681         [timerView setPaused:YES];
682         [gameView setHTMLLegend:noMoreMovesString];
683         [game shake];
684         
685         if (freePlay)   [self startAnimation:@selector(runOutOfTime)];//        FREEPLAY
686         else            [self startAnimation:@selector(newBoard1)];//   FREEPLAY
687         
688         return;
689     }
690     _gameState = GAMESTATE_AWAITINGFIRSTCLICK;
693 - (void)receiveClickAt:(int)x:(int)y
695     if (paused) return;
696     if ((x < 0)||(x > 383)||(y < 0)||(y > 383)) return;
697     if (_gameState == GAMESTATE_AWAITINGFIRSTCLICK)
698     {
699         chx1 = floor(x / 48);
700         chy1 = floor(y / 48);
701         _gameState = GAMESTATE_AWAITINGSECONDCLICK;
702         [gameView setNeedsDisplay:YES];
703         return;
704     }
705     if (_gameState == GAMESTATE_AWAITINGSECONDCLICK)
706     {
707         chx2 = floor(x / 48);
708         chy2 = floor(y / 48);
709         if ((chx2 != chx1)^(chy2 != chy1))      // xor!
710         {
711             int d = (chx1-chx2)*(chx1-chx2)+(chy1-chy2)*(chy1-chy2);
712             //NSLog(@"square distance ==%d",d);
713             if (d==1)
714             {
715                 _gameState = GAMESTATE_FRACULATING;
716                 [gameView setNeedsDisplay:YES];
717                 [gameView setLastMoveDate];
718                 /*- MW CHANGE if (!freePlay) -*/ [timerView setPaused:YES];
719                 [self tryMoveSwapping:chx1:chy1 and:chx2:chy2];
720                 return;
721             }
722         }
723         // fall out of routine setting first click location
724         chx1 = floor(x / 48);
725         chy1 = floor(y / 48);
726         _gameState = GAMESTATE_AWAITINGSECONDCLICK;
727         [gameView setNeedsDisplay:YES];
728     }
731 - (void)tryMoveSwapping:(int)x1:(int)y1 and:(int)x2:(int)y2
733     // do stuff here!!!
734     int xx1, yy1, xx2, yy2;
735     //NSLog(@"tryMoveSwapping");
736     if (x1 != x2)
737     {
738         if (x1 < x2)    { xx1 = x1; xx2 = x2; }
739         else            { xx1 = x2; xx2 = x1; }
740         yy1 = y1;
741         yy2 = y2;
742     }
743     else
744     {
745         if (y1 < y2)    { yy1 = y1; yy2 = y2; }
746         else            { yy1 = y2; yy2 = y1; }
747         xx1 = x1;
748         xx2 = x2;
749     }
750     // store swap positions
751     chx1 = xx1; chy1 = yy1; chx2 = xx2; chy2 = yy2;
752     // swap positions
753     if (chx1 < chx2)    // swapping horizontally
754     {
755         [[game gemAt:chx1:chy1] setVelocity:gemMoveSpeed:0:gemMoveSteps];
756         [[game gemAt:chx2:chy2] setVelocity:-gemMoveSpeed:0:gemMoveSteps];
757     }
758     else                // swapping vertically
759     {
760         [[game gemAt:chx1:chy1] setVelocity:0:gemMoveSpeed:gemMoveSteps];
761         [[game gemAt:chx2:chy2] setVelocity:0:-gemMoveSpeed:gemMoveSteps];
762     }
763     [game swap:chx1:chy1 and:chx2:chy2];
764     _gameState = GAMESTATE_SWAPPING;
765     [self startAnimation:@selector(testForThrees)];
768     // test for threes
769 - (void)testForThrees
771     BOOL anyThrees;
772     int oldScore = game._score;
773     //NSLog(@"testForThrees");
774     anyThrees = ([game testForThreeAt:chx1:chy1])|([game testForThreeAt:chx2:chy2]);
775     [scoreTextField setStringValue:[NSString stringWithFormat:@"%d", game._score]];
776     [scoreTextField setNeedsDisplay:YES];
777     [bonusTextField setStringValue:[NSString stringWithFormat:@"x%d", game._bonusMultiplier]];
778     [bonusTextField setNeedsDisplay:YES];
779     if (game._score > oldScore) [timerView incrementMeter:[game collectGemsFaded]/GEMS_FOR_BONUS];
780     if (anyThrees)
781         [self startAnimation:@selector(removeThreesAndReplaceGems)];    // fade gems
782     else
783         [self unSwap];
784 }    
786     //// repeat:        remove threes
787 - (void)removeThreesAndReplaceGems
789     
790     //NSLog(@"removeThreesAndReplaceGems");
791     // deal with fading
792     [game removeFadedGemsAndReorganiseWithSpritesFrom:[gameView spriteArray]];
793     
794     [self startAnimation:@selector(testForThreesAgain)];        // gems fall down
795 }    
797 - (void)testForThreesAgain
799     BOOL anyThrees;
800     int oldScore = game._score;
801     //NSLog(@"testForThreesAgain");
802     anyThrees = [game checkBoardForThrees];
803     [scoreTextField setStringValue:[NSString stringWithFormat:@"%d", game._score]];
804     [scoreTextField setNeedsDisplay:YES];
805     [bonusTextField setStringValue:[NSString stringWithFormat:@"x%d", game._bonusMultiplier]];
806     [bonusTextField setNeedsDisplay:YES];
807     if (game._score > oldScore) [timerView incrementMeter:[game collectGemsFaded]/GEMS_FOR_BONUS];
808     if (anyThrees)
809         [self startAnimation:@selector(removeThreesAndReplaceGems)];    // fade gems
810     else
811         [self waitForFirstClick];
812 }   
813     ////                allow gems to fall
814     ////                test for threes
815     //// until there are no threes
817 - (void)unSwap
819     //NSLog(@"unSwap");
820     
821     if (!muted) [[NSSound soundNamed:@"no"] play];
822     
823     // swap positions
824     if (chx1 < chx2)    // swapping horizontally
825     {
826         [[game gemAt:chx1:chy1] setVelocity:4:0:12];
827         [[game gemAt:chx2:chy2] setVelocity:-4:0:12];
828     }
829     else                // swapping vertically
830     {
831         [[game gemAt:chx1:chy1] setVelocity:0:4:12];
832         [[game gemAt:chx2:chy2] setVelocity:0:-4:12];
833     }
834     [game swap:chx1:chy1 and:chx2:chy2];
835     _gameState = GAMESTATE_SWAPPING;
836     [self startAnimation:@selector(waitForFirstClick)];
837 }    
839 - (BOOL) gameIsPaused {
840     return paused;
843 - (BOOL) useCustomBackgrounds {
844     return useCustomBackgrounds;
847 - (NSPoint) crossHair1Position {
848     return NSMakePoint(chx1*48,chy1*48);
851 - (NSPoint) crossHair2Position
853     return NSMakePoint(chx2*48,chy2*48);
856 @end