/Volumes/Plantain/MyDocuments/Projects/MacTrek/MacTrek/Data/Universe.m

00001 //
00002 //  Universe.m
00003 //  MacTrek
00004 //
00005 //  Created by Aqua on 22/04/2006.
00006 //  Copyright 2006 __MyCompanyName__. All rights reserved.
00007 //
00008 
00009 #import "Universe.h"
00010 #import "LLTrigonometry.h"
00011 
00012 
00013 @implementation Universe
00014 
00015 LLTrigonometry *trigonometry;
00016 Universe *defaultInstance;
00017 NSLock *synchronizeAccess;
00018 
00019 // performance improvement, keep me
00020 static Player *me;
00021 
00022 - (id) init {
00023     self = [super init];
00024     if (self != nil) {
00025         // create helper
00026         trigonometry = [LLTrigonometry defaultInstance];
00027         
00028         status    = [[Status alloc] init];
00029         players   = [[NSMutableArray alloc] init];
00030         planets   = [[NSMutableArray alloc] init];
00031         teams     = [[NSMutableArray alloc] init];
00032         shipTypes = [[NSMutableArray alloc] init];
00033         phasers   = [[NSMutableArray alloc] init];
00034         torps     = [[NSMutableArray alloc] init];
00035         plasmas   = [[NSMutableArray alloc] init];
00036         me        = nil;
00037         synchronizeAccess = [[NSLock alloc] init];
00038 
00039         int torpId = 0;
00040         for (int i = 0; i < UNIVERSE_MAX_PLAYERS; i++) {
00041              // create players with one phaser and one plasma
00042             Player* player = [[Player alloc] initWithPlayerId:i]; 
00043             [players addObject:player];
00044             // $$ should add these to the player as well for easy reference
00045             Phaser *phaser = [[Phaser alloc] init];
00046             [phaser setOwner:player];
00047             [phasers addObject:phaser];
00048             Plasma *plasma = [[Plasma alloc] init];
00049             [plasma setOwner:player];
00050             [plasmas addObject:plasma];
00051             // create torps for player
00052             NSMutableArray *playerTorps = [[NSMutableArray alloc] init];
00053             for (int j = 0; j < UNIVERSE_MAX_TORPS; j++) {
00054                 Torp *torp = [[Torp alloc] initWithId:torpId];
00055                 torpId++;
00056                 [torp setOwner:player];                
00057                 // add to general stack
00058                 [torps addObject:torp];
00059                 // and to player
00060                 [playerTorps addObject:torp];
00061             }
00062             // add torps to player
00063             [player setTorps:playerTorps];            
00064         } 
00065        
00066         // and planets
00067         for (int i = 0; i < UNIVERSE_MAX_PLANETS; i++) {
00068             [planets addObject:[[Planet alloc] initWithPlanetId:i]];
00069         }
00070         // and teams
00071         for (int i = 0; i < TEAM_MAX; i++) {
00072             [teams addObject:[[Team alloc] initWithTeamId:i]];
00073         }
00074         // and ships
00075         for (int i = 0; i < SHIP_MAX; i++) {
00076             [shipTypes addObject:[[Ship alloc] initWithType:i]];
00077         } 
00078 
00079     }
00080     return self;
00081 }
00082 
00083 + (Universe*) defaultInstance {
00084     
00085     if (defaultInstance == nil) {
00086         defaultInstance = [[Universe alloc] init];
00087     }
00088     return defaultInstance;
00089 }
00090 
00091 - (int) distanceToEntity:(Entity*)obj1 from:(Entity*)obj2 {
00092     return [trigonometry hypotOfBase:([obj2 position].x - [obj1 position].x) heigth: ([obj2 position].y - [obj1 position].y)];
00093 }
00094 
00095 - (float)angleDegBetweenEntity:(Entity*)obj1 from:(Entity*)obj2  {
00096     
00097     return [trigonometry angleDegBetween:[obj1 position] andPoint:[obj2 position]];
00098 }
00099 
00100 - (float)angleDegBetween:(NSPoint)p1 andPoint:(NSPoint)p2 {
00101     
00102     return [trigonometry angleDegBetween:p1 andPoint:p2];
00103 }
00104 
00105 
00106 - (bool) entity:(Entity*)obj1 closerToPos:(NSPoint)pos than:(Entity*)obj2 {
00107     
00108     int distanceTo1 = [trigonometry hypotOfBase:(pos.x - [obj1 position].x) heigth: (pos.y - [obj1 position].y)];
00109     int distanceTo2 = [trigonometry hypotOfBase:(pos.x - [obj2 position].x) heigth: (pos.y - [obj2 position].y)];
00110     
00111     if (distanceTo1 < distanceTo2) {
00112         return YES;
00113     } else {
00114         return NO;
00115     }
00116 }
00117 
00118 // universal lock, logic must be added by users that have a conflict
00119 // themselfs, eg. a view (painter) and the communications thread
00120 // just lock and unlock on desire.
00121 -(NSLock *)synchronizeAccess {
00122     return synchronizeAccess;
00123 }
00124 
00125 -(int)remappedTeamIdWithId:(int)teamId {
00126     
00127     // remapped team id in new protocol?
00128     switch (teamId) {
00129     case 1:
00130         return TEAM_FED;
00131         break;
00132     case 2:
00133         return TEAM_ROM;
00134         break;
00135     case 4:
00136         return TEAM_KLI;
00137         break;
00138     case 8:
00139         return TEAM_ORI;
00140         break;
00141     default:
00142         return TEAM_IND;
00143         break;
00144     }
00145 }
00146 
00147 -(Rank *) rankWithId:(int)rankId {
00148     // take any player
00149     Player *player = [players objectAtIndex:0];
00150     // get his stats
00151     PlayerStats *stats = [player stats];
00152     // get the rank
00153     return [stats rankWithId:rankId];
00154 }
00155 
00156 - (bool) entity:(Entity*)obj1 closerToPlayer:(Player*)player than:(Entity*)obj2 {
00157     return [self entity:obj1 closerToPos: [player position] than:obj2];
00158 }
00159 
00160 - (bool) entity:(Entity*)obj1 closerToMeThan:(Entity*)obj2 {
00161     return [self entity:obj1 closerToPlayer: [self playerThatIsMe] than:obj2];
00162 }
00163 
00164 - (Planet *) planetNearPosition:(NSPoint) pos {
00165           
00166     // start with the first one
00167     Planet *closest = [planets objectAtIndex:0];
00168     Planet *planet = nil;
00169     
00170     // check if the others are closer
00171     for(int p = 1; p < [planets count]; p++) {
00172         planet = [planets objectAtIndex:p];
00173         
00174         if ([self entity:planet closerToPos:pos than:closest]) {
00175             closest = planet;
00176         }
00177     }
00178 
00179     return closest;
00180 }
00181     
00182 - (Player *) playerNearPosition:(NSPoint) pos ofType:(int) target_type {
00183     
00184     if((target_type & (UNIVERSE_TARG_PLAYER | UNIVERSE_TARG_FRIEND | UNIVERSE_TARG_ENEMY | UNIVERSE_TARG_BASE)) != 0) {
00185         bool friendly;
00186         Player *player;
00187         Player *closest = nil;
00188         for(int p = 0; p < [players count]; p++) {
00189             player = [players objectAtIndex:p];
00190             if([player status] != PLAYER_ALIVE) {
00191                 continue;
00192             }
00193             if(([player flags] & PLAYER_CLOAK) != 0 && (target_type & UNIVERSE_TARG_CLOAK) == 0) {
00194                 continue;
00195             }
00196             if([player isMe] && (target_type & UNIVERSE_TARG_SELF) == 0) {
00197                 continue;
00198             }
00199             if((target_type & UNIVERSE_TARG_BASE) != 0 && [[player ship] type] != SHIP_SB) {
00200                 continue;
00201             }
00202             // friendly to me?
00203             friendly = [player friendlyToPlayer:[self playerThatIsMe]];
00204             if (friendly && (target_type & UNIVERSE_TARG_ENEMY) != 0) {
00205                 continue;
00206             }
00207             if (!friendly && (target_type & UNIVERSE_TARG_FRIEND) != 0) {
00208                 continue;
00209             }
00210             
00211             if (closest == nil) {
00212                 // first one
00213                 closest = player;
00214             } else {
00215                 if ([self entity:player closerToPos:pos than:closest]) {
00216                     closest = player;
00217                 }  
00218             }
00219 
00220         }
00221         return closest;
00222     }
00223     return nil;
00224     
00225 }
00226 
00227 - (Player *) playerNearPlayer:(Player *) player ofType:(int) type {
00228     return [self playerNearPosition:[player position] ofType: type];
00229 }
00230 
00231 - (Player *) playerNearMeOfType:(int) type {
00232     return [self playerNearPlayer:[self playerThatIsMe] ofType:type];
00233 }
00234 
00235 - (Planet *) planetNearPlayer:(Player *) player {
00236     return [self planetNearPosition:[player position]];
00237 }
00238 
00239 - (Planet *) planetNearMe {
00240     return [self planetNearPlayer:[self playerThatIsMe]];
00241 }
00242 
00243 - (Planet *) planetWithId:(int)planetId {
00244     //  could need planet remap here...
00245     //NSLog([NSString stringWithFormat: @"Universe.planetWithId: %d", planetId]);
00246     return [planets objectAtIndex:planetId];
00247 }
00248 
00249 - (Player *) playerWithId:(int)playerId {
00250     //NSLog([NSString stringWithFormat: @"Universe.playerWithId: %d", playerId]);
00251     return [players objectAtIndex:playerId];
00252 }
00253 
00254 - (Player *) playerThatIsMe {
00255     
00256     // check if i still exist
00257     if ((me != nil) && ([me isMe])) {
00258         return me;
00259     }
00260     
00261     for (int i = 0; i < [players count]; i++) {
00262         if ([[players objectAtIndex:i] isMe]) {
00263             me = [players objectAtIndex:i];
00264             return me;
00265         }
00266     }
00267     return nil;
00268 }
00269 
00270 - (int)      playerCount {
00271     return [players count];
00272 }
00273 
00274 - (Ship *)   shipOfType:(int)shipType {
00275     return [shipTypes objectAtIndex:shipType];
00276 }
00277 
00278 - (Ship *)   shipWithPhaserId:(int)phaserId {
00279     // we store phasers with the same index as players
00280     // as each player has only one ship and each ship
00281     // has only one phaser
00282     return [[players objectAtIndex:phaserId] ship];
00283 }
00284 
00285 - (Team *)   teamWithId:(int)teamId {
00286     return [teams objectAtIndex:teamId];
00287 }
00288 
00289 - (Status *) status {
00290     return status;
00291 }
00292 
00293 - (Torp *)   torpWithId:(int)torpId {
00294     return [torps objectAtIndex:torpId];
00295 }
00296 
00297 - (Phaser *) phaserWithId:(int)phaserId {
00298     return [phasers objectAtIndex:phaserId];
00299 }
00300 
00301 - (Plasma *) plasmaWithId:(int)plasmaId {
00302     return [plasmas objectAtIndex:plasmaId];
00303 }
00304 
00305 - (void)     movePlayer:(Player *)player toTeam: (Team *)targetTeam {
00306     for (int i = 0; i < [teams count]; i++) {
00307         Team *team = [teams objectAtIndex:i];
00308         if (team == targetTeam) {
00309             [team addPlayer:player];
00310         } else {
00311             [team removePlayer:player];
00312         }
00313     }
00314 }
00315 
00316 - (void)     movePlanet:(Planet *)planet toTeam: (Team *)targetTeam{
00317     //NSLog([NSString stringWithFormat: @"Universe.movePlanet %@ to team %@", [planet name], [targetTeam abbreviation]]);
00318     for (int i = 0; i < [teams count]; i++) {
00319         Team *team = [teams objectAtIndex:i];
00320         if (team == targetTeam) {
00321             [team addPlanet:planet];
00322         } else {
00323             [team removePlanet:planet];
00324         }
00325     } 
00326     [planet setOwner:targetTeam];
00327 }
00328 
00329 // private function
00330 - (void)     setAllWeapons:(NSArray*) weapons toStatus:(int) newStatus {
00331     for (int i = 0; i < [weapons count]; i++) {
00332         [[weapons objectAtIndex:i] setStatus:newStatus];
00333     } 
00334 }
00335 
00336 - (void)     setAllTorpsStatus:(int) newStatus {
00337         [self setAllWeapons:torps toStatus:newStatus];
00338     for(int p = 0; p < [players count]; ++p) {
00339         [[players objectAtIndex:p] setTorps:0];
00340         }
00341 }
00342 
00343 - (void)     setAllPlasmasStatus:(int) newStatus {
00344            [self setAllWeapons:plasmas toStatus:newStatus];
00345     for(int p = 0; p < [players count]; ++p) {
00346         [[players objectAtIndex:p] setPlasmaCount:0];
00347         }
00348 }
00349 
00350 - (void)     setAllPhasersStatus:(int) newStatus {
00351            [self setAllWeapons:phasers toStatus:newStatus];
00352 }
00353 
00354 - (void)     resetWeaponInfo {
00355     [self setAllTorpsStatus:TORP_FREE];
00356     [self setAllPlasmasStatus:PLASMA_FREE];
00357     [self setAllPhasersStatus:PHASER_FREE];
00358 }
00359 
00360 @end

Generated on Fri Jul 28 19:15:17 2006 for MacTrek by  doxygen 1.4.7