App/ClientController.m

00001 //
00002 //  ClientController.m
00003 //  MacTrek
00004 //
00005 //  Created by Aqua on 5/19/06.
00006 //  Copyright 2006 Luky Soft. All rights reserved.
00007 //
00008 
00009 #import "ClientController.h"
00010 
00011 
00012 @implementation ClientController
00013 
00014 // privates
00015 bool ghostStart = NO;
00016 
00017 - (id) initWithUniverse:(Universe*)newUniverse {
00018         self = [super init];
00019         if (self != nil) {
00020                 universe = newUniverse;
00021         communication = [[Communication alloc] initWithUniverse:universe baseUdpPort:0];
00022         
00023         // need the main run loop other wise the performSelector afterDelay will fail
00024         [notificationCenter addObserver:self selector:@selector(checkForDeath:) name:@"SP_PSTATUS" 
00025                                  object:nil useLocks:NO useMainRunLoop:YES];
00026     }
00027         return self;
00028 }
00029 
00030 - (void) checkForDeath:(Player *)player {
00031     // did i die?
00032     if ([player isMe]) {
00033         NSLog(@"ClientController.checkForDeath status = %@", [player statusString]);
00034         if (([player status] == PLAYER_EXPLODE) ) {
00035             NSLog(@"ClientController.checkForDeath: firing delayed death warrent");
00036             // || ([player status] == PLAYER_OUTFIT)){
00037             // wait for the drawing to end 
00038             // $$ then generate an event on the drawing of the explosion!
00039             // [self performSelector: @selector(iDied:) withObject:player afterDelay: 2.0];
00040             // $$ doesn't happen..
00041             [self iDied:player];
00042         }
00043     }
00044 }
00045 
00046 - (void) slowDeath:(Player *)me {
00047     // needed because this is called while still drawing the gameview 
00048     // changing the drawing now would invoke a different graphic context
00049     NSLog(@"ClientController.slowDeath: i think i am dead");
00050    [self performSelector: @selector(iDied:) withObject:me afterDelay: 0.1]; 
00051 }
00052 
00053 
00054 - (void) iDied:(Player *)me {
00055     // go to outfitting
00056     NSLog(@"ClientController.iDied: today was a good day to die");
00057     [me setStatus:PLAYER_OUTFIT];
00058     [notificationCenter postNotificationName:@"CC_GO_OUTFIT" 
00059                                       object:self 
00060                                     userInfo:nil];    
00061 }
00062 
00063 - (bool) slotObtained {
00064     
00065     // if i got a slot, i have become a player
00066         Player *me = [universe playerThatIsMe];
00067         if (me == nil) {
00068         NSLog(@"ClientController.slotObtained checking... nope");
00069         return NO;
00070     } else {
00071         NSLog(@"ClientController.slotObtained checking... YES");
00072         return YES;
00073     }    
00074 }
00075 
00076 - (void) setupSlot {
00077     
00078     // should only be called if i got a slot
00079     if (![self slotObtained]) {
00080         // i'm not a player yet
00081                  NSLog(@"ClientController.setupSlot called, but not a player");
00082                 return; 
00083     }
00084     
00085     Player *me = [universe playerThatIsMe];
00086     
00087         // report our success
00088     NSLog(@"ClientController.setupSlot started");
00089         [notificationCenter postNotificationName:@"CC_SLOT_FOUND" 
00090                                                                           object:self 
00091                                                                         userInfo:nil];
00092         
00093         if (ghostStart) {
00094                 // find my team $$ should be done already by Player class
00095                 // see if i exploded
00096                 if ([me damage] > [[me ship] maxDamage]) {
00097                         [me setStatus:PLAYER_OUTFIT];
00098                         // go to outfitting
00099                         [notificationCenter postNotificationName:@"CC_GO_OUTFIT" 
00100                                                                                           object:self 
00101                                                                                         userInfo:nil];
00102                 } else {
00103                         [me setStatus:PLAYER_ALIVE];
00104             // continue game
00105                 }               
00106         } 
00107         
00108         return;
00109 }
00110 
00111 
00112 // use this when multithreading
00113 - (void) findSlot {
00115     
00116     // loop until i find a slot $$ very BAD, wait for the proper event (something with
00117     // a player update i suppose :
00118     // SP_S_YOU_SS or SP_S_YOU or SP_YOU (probably the last entry) then unsubscribe
00119     // to avoid updates, for now it works ok
00120     if (![self slotObtained]) {
00121         // i'm not a player yet, keep trying
00122                 [self performSelector: @selector(findSlot) withObject: self afterDelay: 0.1];
00123                 return; 
00124     }
00125     [self setupSlot];
00126 }
00127 
00128 - (bool)sendSlotSettingsToServer {
00129         
00130         //try UDP
00131         //[communication sendUdpReq:[NSNumber numberWithInt:COMM_UDP]];
00132     [notificationCenter postNotificationName:@"COMM_SEND_SHORT_REQ" object:self userInfo:[NSNumber numberWithInt:COMM_UDP]];        
00133         //try short packets
00134         //[communication sendShortReq:[NSNumber numberWithInt:SPK_VON]];
00135     [notificationCenter postNotificationName:@"COMM_SEND_SHORT_REQ" object:self userInfo:[NSNumber numberWithInt:SPK_VON]];
00136         //send options we have set
00137         //[communication sendOptionsPacket];
00138     [notificationCenter postNotificationName:@"COMM_SEND_OPTIONS_PACKET" object:self userInfo:nil];
00139         // $$ don't ping yet
00140     //[communication sendPingReq:[NSNumber numberWithBool:NO]];
00141     [notificationCenter postNotificationName:@"COMM_SEND_PING_REQ" object:self userInfo:[NSNumber numberWithBool:NO]];
00142         //send desired updates per second
00143         //[communication sendUpdatePacket:[NSNumber numberWithInt:COMM_UPDATES_PER_SECOND]];
00144     [notificationCenter postNotificationName:@"COMM_SEND_UPDATE_PACKET" object:self userInfo:[NSNumber numberWithInt:COMM_UPDATES_PER_SECOND]]; 
00145     return YES;
00146 }
00147 
00148 - (void)singleReadFromServer {
00149     [communication readFromServer];
00150 }
00151 
00152 - (bool)startClientAt:(NSString *)server port:(int)port seperate:(bool)multiThread {
00153         
00154         NSLog(@"ClientController.startClientAt: %@ port %d", server, port);
00155     
00156     // call the server
00157         if ([communication callServer:server port:port]) {      
00158         [notificationCenter postNotificationName:@"CC_SERVER_CALL_SUCCESS"];
00159         
00160         // start listening to it
00161         [communication setMultiThreaded:multiThread]; 
00162         if (multiThread) {
00163             // invoke a seperate thread to read from the server
00164             // and use findslot to check if it was successfull
00165             if ([communication startCommunicationThread]) {            
00166                 // try to find a slot
00167                 [self findSlot];
00168                 return YES;
00169             } else {
00170                 NSLog(@"ClientController.startClientAt: ERROR starting thread");
00171                 return NO;
00172             } 
00173         } else {
00174             // poll loop until we get a slot
00175             while (![self slotObtained]) {
00176                 [communication readFromServer];  // $$ let's hope it doesn't block
00177             }
00178             // yeah we are in
00179             [self setupSlot];
00180             return YES;
00181         }
00182 
00183     } else {
00184         NSLog(@"ClientController.startClientAt: %@ port %d NO CONNECTION", server, port);
00185         [notificationCenter postNotificationName:@"CC_SERVER_CALL_FAILED"];
00186         return NO;
00187     }
00188 }
00189 
00190 - (void)stop {
00191     NSLog(@"ClientController.stop stoping thread and cleaning self");
00192     [communication stopCommunicationThread];
00193         [communication cleanUp:self];   
00194     // remove me from the universe (or i become a ghost)
00195     [[universe playerThatIsMe] setIsMe:NO];
00196 }
00197 
00198 @end

Generated on Sat Aug 26 21:14:07 2006 for MacTrek by  doxygen 1.4.7