LCOV - code coverage report
Current view: top level - Core/Entities - Entity.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 18 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : Entity.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "Entity.h"
      26             : #import "EntityOOJavaScriptExtensions.h"
      27             : #import "PlayerEntity.h"
      28             : #import "OOPlanetEntity.h"
      29             : 
      30             : #import "OOMaths.h"
      31             : #import "Universe.h"
      32             : #import "GameController.h"
      33             : #import "ResourceManager.h"
      34             : #import "OOConstToString.h"
      35             : 
      36             : #import "CollisionRegion.h"
      37             : 
      38             : #import "NSScannerOOExtensions.h"
      39             : #import "OODebugFlags.h"
      40             : #import "NSObjectOOExtensions.h"
      41             : 
      42             : #ifndef NDEBUG
      43           0 : uint32_t gLiveEntityCount = 0;
      44           0 : size_t gTotalEntityMemory = 0;
      45             : #endif
      46             : 
      47             : 
      48             : #ifndef NDEBUG
      49           0 : static NSString * const kOOLogEntityAddToList                           = @"entity.linkedList.add";
      50           0 : static NSString * const kOOLogEntityAddToListError                      = @"entity.linkedList.add.error";
      51           0 : static NSString * const kOOLogEntityRemoveFromList                      = @"entity.linkedList.remove";
      52           0 : static NSString * const kOOLogEntityRemoveFromListError         = @"entity.linkedList.remove.error";
      53           0 : static NSString * const kOOLogEntityUpdateError                         = @"entity.linkedList.update.error";
      54             : #endif
      55           0 : static NSString * const kOOLogEntityVerificationError           = @"entity.linkedList.verify.error";
      56             : 
      57             : 
      58             : 
      59             : @interface Entity (OOPrivate)
      60             : 
      61           0 : - (BOOL) checkLinkedLists;
      62             : 
      63             : @end
      64             : 
      65             : 
      66             : @implementation Entity
      67             : 
      68           0 : - (id) init
      69             : {
      70             :         self = [super init];
      71             :         if (EXPECT_NOT(self == nil))  return nil;
      72             :         
      73             :         _sessionID = [UNIVERSE sessionID];
      74             :         
      75             :         orientation = kIdentityQuaternion;
      76             :         rotMatrix = kIdentityMatrix;
      77             :         position = kZeroHPVector;
      78             :         
      79             :         no_draw_distance = 100000.0;  //  10 km
      80             :         
      81             :         collidingEntities = [[NSMutableArray alloc] init];
      82             :         
      83             :         scanClass = CLASS_NOT_SET;
      84             :         [self setStatus:STATUS_COCKPIT_DISPLAY];
      85             :         
      86             :         spawnTime = [UNIVERSE getTime];
      87             :         
      88             :         isSunlit = YES;
      89             : 
      90             :         atmosphereFogging = [[OOColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.0] retain];
      91             :         
      92             : #ifndef NDEBUG
      93             :         gLiveEntityCount++;
      94             :         gTotalEntityMemory += [self oo_objectSize];
      95             : #endif
      96             :         
      97             :         return self;
      98             : }
      99             : 
     100             : 
     101           0 : - (void) dealloc
     102             : {
     103             :         [UNIVERSE ensureEntityReallyRemoved:self];
     104             :         DESTROY(collidingEntities);
     105             :         DESTROY(collisionRegion);
     106             :         [self deleteJSSelf];
     107             :         [self setOwner:nil];
     108             :         [atmosphereFogging release];
     109             :         
     110             : #ifndef NDEBUG
     111             :         gLiveEntityCount--;
     112             :         gTotalEntityMemory -= [self oo_objectSize];
     113             : #endif
     114             :         
     115             :         [super dealloc];
     116             : }
     117             : 
     118             : 
     119           0 : - (NSString *)descriptionComponents
     120             : {
     121             :         return [NSString stringWithFormat:@"position: %@ scanClass: %@ status: %@", HPVectorDescription([self position]), OOStringFromScanClass([self scanClass]), OOStringFromEntityStatus([self status])];
     122             : }
     123             : 
     124             : 
     125             : - (NSUInteger) sessionID
     126             : {
     127             :         return _sessionID;
     128             : }
     129             : 
     130             : 
     131             : - (BOOL)isShip
     132             : {
     133             :         return isShip;
     134             : }
     135             : 
     136             : 
     137             : - (BOOL)isDock
     138             : {
     139             :         return NO;
     140             : }
     141             : 
     142             : 
     143             : - (BOOL)isStation
     144             : {
     145             :         return isStation;
     146             : }
     147             : 
     148             : 
     149             : - (BOOL)isSubEntity
     150             : {
     151             :         return isSubEntity;
     152             : }
     153             : 
     154             : 
     155             : - (BOOL)isPlayer
     156             : {
     157             :         return isPlayer;
     158             : }
     159             : 
     160             : 
     161             : - (BOOL)isPlanet
     162             : {
     163             :         return NO;
     164             : }
     165             : 
     166             : 
     167             : - (BOOL)isSun
     168             : {
     169             :         return NO;
     170             : }
     171             : 
     172             : 
     173             : - (BOOL) isSunlit
     174             : {
     175             :         return isSunlit;
     176             : }
     177             : 
     178             : 
     179             : - (BOOL) isStellarObject
     180             : {
     181             :         return [self isPlanet] || [self isSun];
     182             : }
     183             : 
     184             : 
     185             : - (BOOL)isSky
     186             : {
     187             :         return NO;
     188             : }
     189             : 
     190             : - (BOOL)isWormhole
     191             : {
     192             :         return isWormhole;
     193             : }
     194             : 
     195             : 
     196             : - (BOOL) isEffect
     197             : {
     198             :         return NO;
     199             : }
     200             : 
     201             : 
     202             : - (BOOL) isVisualEffect
     203             : {
     204             :         return NO;
     205             : }
     206             : 
     207             : 
     208             : - (BOOL) isWaypoint
     209             : {
     210             :         return NO;
     211             : }
     212             : 
     213             : 
     214             : - (BOOL) validForAddToUniverse
     215             : {
     216             :         NSUInteger mySessionID = [self sessionID];
     217             :         NSUInteger currentSessionID = [UNIVERSE sessionID];
     218             :         if (EXPECT_NOT(mySessionID != currentSessionID))
     219             :         {
     220             :                 OOLogERR(@"entity.invalidSession", @"Entity %@ from session %lu cannot be added to universe in session %lu. This is an internal error, please report it.", [self shortDescription], mySessionID, currentSessionID);
     221             :                 return NO;
     222             :         }
     223             :         
     224             :         return YES;
     225             : }
     226             : 
     227             : 
     228             : - (void) addToLinkedLists
     229             : {
     230             : #ifndef NDEBUG
     231             :         if (gDebugFlags & DEBUG_LINKED_LISTS)
     232             :                 OOLog(kOOLogEntityAddToList, @"DEBUG adding entity %@ to linked lists", self);
     233             : #endif
     234             :         //
     235             :         // insert at the start
     236             :         if (UNIVERSE)
     237             :         {
     238             :                 x_previous = nil; x_next = UNIVERSE->x_list_start;
     239             :                 // move UP the list
     240             :                 while ((x_next)&&(x_next->position.x - x_next->collision_radius < position.x - collision_radius))
     241             :                 {
     242             :                         x_previous = x_next;
     243             :                         x_next = x_next->x_next;
     244             :                 }       
     245             :                 if (x_next)             x_next->x_previous = self;
     246             :                 if (x_previous) x_previous->x_next = self;
     247             :                 else                    UNIVERSE->x_list_start = self;
     248             :                 
     249             :                 y_previous = nil; y_next = UNIVERSE->y_list_start;
     250             :                 // move UP the list
     251             :                 while ((y_next)&&(y_next->position.y - y_next->collision_radius < position.y - collision_radius))
     252             :                 {
     253             :                         y_previous = y_next;
     254             :                         y_next = y_next->y_next;
     255             :                 }       
     256             :                 if (y_next)             y_next->y_previous = self;
     257             :                 if (y_previous) y_previous->y_next = self;
     258             :                 else                    UNIVERSE->y_list_start = self;
     259             : 
     260             :                 z_previous = nil; z_next = UNIVERSE->z_list_start;
     261             :                 // move UP the list
     262             :                 while ((z_next)&&(z_next->position.z - z_next->collision_radius < position.z - collision_radius))
     263             :                 {
     264             :                         z_previous = z_next;
     265             :                         z_next = z_next->z_next;
     266             :                 }       
     267             :                 if (z_next)             z_next->z_previous = self;
     268             :                 if (z_previous) z_previous->z_next = self;
     269             :                 else                    UNIVERSE->z_list_start = self;
     270             :                                 
     271             :         }
     272             :         
     273             : #ifndef NDEBUG
     274             :         if (gDebugFlags & DEBUG_LINKED_LISTS)
     275             :         {
     276             :                 if (![self checkLinkedLists])
     277             :                 {
     278             :                         OOLog(kOOLogEntityAddToListError, @"DEBUG LINKED LISTS - problem encountered while adding %@ to linked lists", self);
     279             :                         [UNIVERSE debugDumpEntities];
     280             :                 }
     281             :         }
     282             : #endif
     283             : }
     284             : 
     285             : 
     286             : - (void) removeFromLinkedLists
     287             : {
     288             : #ifndef NDEBUG
     289             :         if (gDebugFlags & DEBUG_LINKED_LISTS)
     290             :                 OOLog(kOOLogEntityRemoveFromList, @"DEBUG removing entity %@ from linked lists", self);
     291             : #endif
     292             :         
     293             :         if ((x_next == nil)&&(x_previous == nil))       // removed already!
     294             :                 return;
     295             : 
     296             :         // make sure the starting point is still correct
     297             :         if (UNIVERSE)
     298             :         {
     299             :                 if ((UNIVERSE->x_list_start == self)&&(x_next))
     300             :                                 UNIVERSE->x_list_start = x_next;
     301             :                 if ((UNIVERSE->y_list_start == self)&&(y_next))
     302             :                                 UNIVERSE->y_list_start = y_next;
     303             :                 if ((UNIVERSE->z_list_start == self)&&(z_next))
     304             :                                 UNIVERSE->z_list_start = z_next;
     305             :         }
     306             :         //
     307             :         if (x_previous)         x_previous->x_next = x_next;
     308             :         if (x_next)                     x_next->x_previous = x_previous;
     309             :         //
     310             :         if (y_previous)         y_previous->y_next = y_next;
     311             :         if (y_next)                     y_next->y_previous = y_previous;
     312             :         //
     313             :         if (z_previous)         z_previous->z_next = z_next;
     314             :         if (z_next)                     z_next->z_previous = z_previous;
     315             :         //
     316             :         x_previous = nil;       x_next = nil;
     317             :         y_previous = nil;       y_next = nil;
     318             :         z_previous = nil;       z_next = nil;
     319             : 
     320             : #ifndef NDEBUG
     321             :         if (gDebugFlags & DEBUG_LINKED_LISTS)
     322             :         {
     323             :                 if (![self checkLinkedLists])
     324             :                 {
     325             :                         OOLog(kOOLogEntityRemoveFromListError, @"DEBUG LINKED LISTS - problem encountered while removing %@ from linked lists", self);
     326             :                         [UNIVERSE debugDumpEntities];
     327             :                 }
     328             :         }
     329             : #endif
     330             : }
     331             : 
     332             : 
     333           0 : - (BOOL) checkLinkedLists
     334             : {
     335             :         // DEBUG check for loops
     336             :         if (UNIVERSE->n_entities > 0)
     337             :         {
     338             :                 int n;
     339             :                 Entity  *check, *last;
     340             :                 //
     341             :                 last = nil;
     342             :                 //
     343             :                 n = UNIVERSE->n_entities;
     344             :                 check = UNIVERSE->x_list_start;
     345             :                 while ((n--)&&(check))
     346             :                 {
     347             :                         last = check;
     348             :                         check = check->x_next;
     349             :                 }
     350             :                 if ((check)||(n > 0))
     351             :                 {
     352             :                         OOLog(kOOLogEntityVerificationError, @"Broken x_next %@ list (%d) ***", UNIVERSE->x_list_start, n);
     353             :                         return NO;
     354             :                 }
     355             :                 //
     356             :                 n = UNIVERSE->n_entities;
     357             :                 check = last;
     358             :                 while ((n--)&&(check))  check = check->x_previous;
     359             :                 if ((check)||(n > 0))
     360             :                 {
     361             :                         OOLog(kOOLogEntityVerificationError, @"Broken x_previous %@ list (%d) ***", UNIVERSE->x_list_start, n);
     362             :                         return NO;
     363             :                 }
     364             :                 //
     365             :                 n = UNIVERSE->n_entities;
     366             :                 check = UNIVERSE->y_list_start;
     367             :                 while ((n--)&&(check))
     368             :                 {
     369             :                         last = check;
     370             :                         check = check->y_next;
     371             :                 }
     372             :                 if ((check)||(n > 0))
     373             :                 {
     374             :                         OOLog(kOOLogEntityVerificationError, @"Broken y_next %@ list (%d) ***", UNIVERSE->y_list_start, n);
     375             :                         return NO;
     376             :                 }
     377             :                 //
     378             :                 n = UNIVERSE->n_entities;
     379             :                 check = last;
     380             :                 while ((n--)&&(check))  check = check->y_previous;
     381             :                 if ((check)||(n > 0))
     382             :                 {
     383             :                         OOLog(kOOLogEntityVerificationError, @"Broken y_previous %@ list (%d) ***", UNIVERSE->y_list_start, n);
     384             :                         return NO;
     385             :                 }
     386             :                 //
     387             :                 n = UNIVERSE->n_entities;
     388             :                 check = UNIVERSE->z_list_start;
     389             :                 while ((n--)&&(check))
     390             :                 {
     391             :                         last = check;
     392             :                         check = check->z_next;
     393             :                 }
     394             :                 if ((check)||(n > 0))
     395             :                 {
     396             :                         OOLog(kOOLogEntityVerificationError, @"Broken z_next %@ list (%d) ***", UNIVERSE->z_list_start, n);
     397             :                         return NO;
     398             :                 }
     399             :                 //
     400             :                 n = UNIVERSE->n_entities;
     401             :                 check = last;
     402             :                 while ((n--)&&(check))  check = check->z_previous;
     403             :                 if ((check)||(n > 0))
     404             :                 {
     405             :                         OOLog(kOOLogEntityVerificationError, @"Broken z_previous %@ list (%d) ***", UNIVERSE->z_list_start, n);
     406             :                         return NO;
     407             :                 }
     408             :         }
     409             :         return YES;
     410             : }
     411             : 
     412             : 
     413             : - (void) updateLinkedLists
     414             : {
     415             :         if (!UNIVERSE)
     416             :                 return; // not in the UNIVERSE - don't do this!
     417             :         if ((x_next == nil)&&(x_previous == nil))
     418             :                 return; // not in the lists - don't do this!
     419             :         
     420             : #ifndef NDEBUG
     421             :         if (gDebugFlags & DEBUG_LINKED_LISTS)
     422             :         {
     423             :                 if (![self checkLinkedLists])
     424             :                 {
     425             :                         OOLog(kOOLogEntityVerificationError, @"DEBUG LINKED LISTS problem encountered before updating linked lists for %@", self);
     426             :                         [UNIVERSE debugDumpEntities];
     427             :                 }
     428             :         }
     429             : #endif
     430             :         
     431             :         // update position in linked list for position.x
     432             :         // take self out of list..
     433             :         if (x_previous)         x_previous->x_next = x_next;
     434             :         if (x_next)                     x_next->x_previous = x_previous;
     435             :         // sink DOWN the list
     436             :         while ((x_previous)&&(x_previous->position.x - x_previous->collision_radius > position.x - collision_radius))
     437             :         {
     438             :                 x_next = x_previous;
     439             :                 x_previous = x_previous->x_previous;
     440             :         }
     441             :         // bubble UP the list
     442             :         while ((x_next)&&(x_next->position.x - x_next->collision_radius < position.x - collision_radius))
     443             :         {
     444             :                 x_previous = x_next;
     445             :                 x_next = x_next->x_next;
     446             :         }
     447             :         if (x_next)             // insert self into the list before x_next..
     448             :                 x_next->x_previous = self;
     449             :         if (x_previous) // insert self into the list after x_previous..
     450             :                 x_previous->x_next = self;
     451             :         if ((x_previous == nil)&&(UNIVERSE))    // if we're the first then tell the UNIVERSE!
     452             :                         UNIVERSE->x_list_start = self;
     453             :         
     454             :         // update position in linked list for position.y
     455             :         // take self out of list..
     456             :         if (y_previous)         y_previous->y_next = y_next;
     457             :         if (y_next)                     y_next->y_previous = y_previous;
     458             :         // sink DOWN the list
     459             :         while ((y_previous)&&(y_previous->position.y - y_previous->collision_radius > position.y - collision_radius))
     460             :         {
     461             :                 y_next = y_previous;
     462             :                 y_previous = y_previous->y_previous;
     463             :         }
     464             :         // bubble UP the list
     465             :         while ((y_next)&&(y_next->position.y - y_next->collision_radius < position.y - collision_radius))
     466             :         {
     467             :                 y_previous = y_next;
     468             :                 y_next = y_next->y_next;
     469             :         }
     470             :         if (y_next)             // insert self into the list before y_next..
     471             :                 y_next->y_previous = self;
     472             :         if (y_previous) // insert self into the list after y_previous..
     473             :                 y_previous->y_next = self;
     474             :         if ((y_previous == nil)&&(UNIVERSE))    // if we're the first then tell the UNIVERSE!
     475             :                         UNIVERSE->y_list_start = self;
     476             :         
     477             :         // update position in linked list for position.z
     478             :         // take self out of list..
     479             :         if (z_previous)         z_previous->z_next = z_next;
     480             :         if (z_next)                     z_next->z_previous = z_previous;
     481             :         // sink DOWN the list
     482             :         while ((z_previous)&&(z_previous->position.z - z_previous->collision_radius > position.z - collision_radius))
     483             :         {
     484             :                 z_next = z_previous;
     485             :                 z_previous = z_previous->z_previous;
     486             :         }
     487             :         // bubble UP the list
     488             :         while ((z_next)&&(z_next->position.z - z_next->collision_radius < position.z - collision_radius))
     489             :         {
     490             :                 z_previous = z_next;
     491             :                 z_next = z_next->z_next;
     492             :         }
     493             :         if (z_next)             // insert self into the list before z_next..
     494             :                 z_next->z_previous = self;
     495             :         if (z_previous) // insert self into the list after z_previous..
     496             :                 z_previous->z_next = self;
     497             :         if ((z_previous == nil)&&(UNIVERSE))    // if we're the first then tell the UNIVERSE!
     498             :                         UNIVERSE->z_list_start = self;
     499             :         
     500             :         // done
     501             : #ifndef NDEBUG
     502             :         if (gDebugFlags & DEBUG_LINKED_LISTS)
     503             :         {
     504             :                 if (![self checkLinkedLists])
     505             :                 {
     506             :                         OOLog(kOOLogEntityUpdateError, @"DEBUG LINKED LISTS problem encountered after updating linked lists for %@", self);
     507             :                         [UNIVERSE debugDumpEntities];
     508             :                 }
     509             :         }
     510             : #endif
     511             : }
     512             : 
     513             : 
     514             : - (void) wasAddedToUniverse
     515             : {
     516             :         // Do nothing
     517             : }
     518             : 
     519             : 
     520             : - (void) wasRemovedFromUniverse
     521             : {
     522             :         // Do nothing
     523             : }
     524             : 
     525             : 
     526             : - (void) warnAboutHostiles
     527             : {
     528             :         // do nothing for now, this can be expanded in sub classes
     529             :         OOLog(@"general.error.subclassResponsibility.Entity-warnAboutHostiles", @"%@", @"***** Entity does nothing in warnAboutHostiles");
     530             : }
     531             : 
     532             : 
     533             : - (CollisionRegion*) collisionRegion
     534             : {
     535             :         return collisionRegion;
     536             : }
     537             : 
     538             : 
     539             : - (void) setCollisionRegion: (CollisionRegion*) region
     540             : {
     541             :         if (collisionRegion) [collisionRegion release];
     542             :         collisionRegion = [region retain];
     543             : }
     544             : 
     545             : 
     546             : - (void) setUniversalID:(OOUniversalID)uid
     547             : {
     548             :         universalID = uid;
     549             : }
     550             : 
     551             : 
     552             : - (OOUniversalID) universalID
     553             : {
     554             :         return universalID;
     555             : }
     556             : 
     557             : 
     558             : - (BOOL) throwingSparks
     559             : {
     560             :         return throw_sparks;
     561             : }
     562             : 
     563             : 
     564             : - (void) setThrowSparks:(BOOL) value
     565             : {
     566             :         throw_sparks = value;
     567             : }
     568             : 
     569             : 
     570             : - (void) throwSparks
     571             : {
     572             :         // do nothing for now
     573             : }
     574             : 
     575             : 
     576             : - (void) setOwner:(Entity *)ent
     577             : {
     578             :         [_owner release];
     579             :         _owner = [ent weakRetain];
     580             : }
     581             : 
     582             : 
     583             : - (id) owner
     584             : {
     585             :         return [_owner weakRefUnderlyingObject];
     586             : }
     587             : 
     588             : 
     589             : - (ShipEntity *)parentEntity
     590             : {
     591             :         id owner = [self owner];
     592             :         if ([owner isShipWithSubEntityShip:self])  return owner;
     593             :         return nil;
     594             : }
     595             : 
     596             : 
     597           0 : - (id<OOWeakReferenceSupport>) superShaderBindingTarget
     598             : {
     599             :         return [self parentEntity];
     600             : }
     601             : 
     602             : 
     603             : - (ShipEntity *) rootShipEntity
     604             : {
     605             :         ShipEntity *parent = [self parentEntity];
     606             :         if (parent != nil)  return [parent rootShipEntity];
     607             :         if ([self isShip])  return (ShipEntity *)self;
     608             :         return nil;
     609             : }
     610             : 
     611             : 
     612             : - (HPVector) position
     613             : {
     614             :         return position;
     615             : }
     616             : 
     617             : - (Vector) cameraRelativePosition
     618             : {
     619             :         return cameraRelativePosition;
     620             : }
     621             : 
     622             : - (GLfloat) cameraRangeFront
     623             : {
     624             :         return magnitude(cameraRelativePosition) - [self frustumRadius];
     625             : }
     626             : 
     627             : - (GLfloat) cameraRangeBack
     628             : {
     629             :         return magnitude(cameraRelativePosition) + [self frustumRadius];
     630             : }
     631             : 
     632             : 
     633             : 
     634             : // Exposed to uniform bindings.
     635             : // so needs to remain at OpenGL precision levels
     636           0 : - (Vector) relativePosition
     637             : {
     638             :         return HPVectorToVector(HPvector_subtract([self position], [PLAYER position]));
     639             : }
     640             : 
     641             : - (Vector) vectorTo:(Entity *)entity
     642             : {
     643             :         return HPVectorToVector(HPvector_subtract([entity position], [self position]));
     644             : }
     645             : 
     646             : 
     647             : - (void) setPosition:(HPVector) posn
     648             : {
     649             :         position = posn;
     650             :         [self updateCameraRelativePosition];
     651             : }
     652             : 
     653             : 
     654             : - (void) setPositionX:(OOHPScalar)x y:(OOHPScalar)y z:(OOHPScalar)z
     655             : {
     656             :         position.x = x;
     657             :         position.y = y;
     658             :         position.z = z;
     659             :         [self updateCameraRelativePosition];
     660             : }
     661             : 
     662             : 
     663             : - (void) updateCameraRelativePosition
     664             : {
     665             :         cameraRelativePosition = HPVectorToVector(HPvector_subtract([self absolutePositionForSubentity],[PLAYER viewpointPosition]));
     666             : }
     667             : 
     668             : 
     669             : - (HPVector) absolutePositionForSubentity
     670             : {
     671             :         return [self absolutePositionForSubentityOffset:kZeroHPVector];
     672             : }
     673             : 
     674             : 
     675             : - (HPVector) absolutePositionForSubentityOffset:(HPVector) offset
     676             : {
     677             :         HPVector                abspos = HPvector_add(position, OOHPVectorMultiplyMatrix(offset, rotMatrix));
     678             :         Entity          *last = nil;
     679             :         Entity          *father = [self parentEntity];
     680             :         
     681             :         while (father != nil && father != last)
     682             :         {
     683             :                 abspos = HPvector_add(OOHPVectorMultiplyMatrix(abspos, [father drawRotationMatrix]), [father position]);
     684             :                 last = father;
     685             :                 if (![last isSubEntity]) break;
     686             :                 father = [father owner];
     687             :         }
     688             :         return abspos;
     689             : }
     690             : 
     691             : 
     692             : - (double) zeroDistance
     693             : {
     694             :         return zero_distance;
     695             : }
     696             : 
     697             : 
     698             : - (double) camZeroDistance
     699             : {
     700             :         return cam_zero_distance;
     701             : }
     702             : 
     703             : 
     704             : - (NSComparisonResult) compareZeroDistance:(Entity *)otherEntity
     705             : {
     706             :         if ((otherEntity)&&(zero_distance > otherEntity->zero_distance))
     707             :                 return NSOrderedAscending;
     708             :         else
     709             :                 return NSOrderedDescending;
     710             : }
     711             : 
     712             : 
     713             : - (BoundingBox) boundingBox
     714             : {
     715             :         return boundingBox;
     716             : }
     717             : 
     718             : 
     719             : - (GLfloat) mass
     720             : {
     721             :         return mass;
     722             : }
     723             : 
     724             : 
     725             : - (void) setOrientation:(Quaternion) quat
     726             : {
     727             :         orientation = quat;
     728             :         [self orientationChanged];
     729             : }
     730             : 
     731             : 
     732             : - (Quaternion) orientation
     733             : {
     734             :         return orientation;
     735             : }
     736             : 
     737             : 
     738             : - (Quaternion) normalOrientation
     739             : {
     740             :         return [self orientation];
     741             : }
     742             : 
     743             : 
     744             : - (void) setNormalOrientation:(Quaternion) quat
     745             : {
     746             :         [self setOrientation:quat];
     747             : }
     748             : 
     749             : 
     750             : - (void) orientationChanged
     751             : {
     752             :         quaternion_normalize(&orientation);
     753             :         rotMatrix = OOMatrixForQuaternionRotation(orientation);
     754             : }
     755             : 
     756             : 
     757             : - (void) setVelocity:(Vector) vel
     758             : {
     759             :         velocity = vel;
     760             : }
     761             : 
     762             : 
     763             : - (Vector) velocity
     764             : {
     765             :         return velocity;
     766             : }
     767             : 
     768             : 
     769             : - (double) speed
     770             : {
     771             :         return magnitude([self velocity]);
     772             : }
     773             : 
     774             : 
     775             : - (GLfloat) distanceTravelled
     776             : {
     777             :         return distanceTravelled;
     778             : }
     779             : 
     780             : 
     781             : - (void) setDistanceTravelled: (GLfloat) value
     782             : {
     783             :         distanceTravelled = value;
     784             : }
     785             : 
     786             : 
     787             : - (void) setStatus:(OOEntityStatus) stat
     788             : {
     789             :         _status = stat;
     790             : }
     791             : 
     792             : 
     793             : - (OOEntityStatus) status
     794             : {
     795             :         return _status;
     796             : }
     797             : 
     798             : 
     799             : - (void) setScanClass:(OOScanClass)sClass
     800             : {
     801             :         scanClass = sClass;
     802             : }
     803             : 
     804             : 
     805             : - (OOScanClass) scanClass
     806             : {
     807             :         return scanClass;
     808             : }
     809             : 
     810             : 
     811             : - (void) setEnergy:(GLfloat) amount
     812             : {
     813             :         energy = amount;
     814             : }
     815             : 
     816             : 
     817             : - (GLfloat) energy
     818             : {
     819             :         return energy;
     820             : }
     821             : 
     822             : 
     823             : - (void) setMaxEnergy:(GLfloat)amount
     824             : {
     825             :         maxEnergy = amount;
     826             : }
     827             : 
     828             : 
     829             : - (GLfloat) maxEnergy
     830             : {
     831             :         return maxEnergy;
     832             : }
     833             : 
     834             : 
     835             : - (void) applyRoll:(GLfloat) roll andClimb:(GLfloat) climb
     836             : {
     837             :         if ((roll == 0.0)&&(climb == 0.0)&&(!hasRotated))
     838             :                 return;
     839             : 
     840             :         if (roll)
     841             :                 quaternion_rotate_about_z(&orientation, -roll);
     842             :         if (climb)
     843             :                 quaternion_rotate_about_x(&orientation, -climb);
     844             :         
     845             :         [self orientationChanged];
     846             : }
     847             : 
     848             : 
     849             : - (void) applyRoll:(GLfloat) roll climb:(GLfloat) climb andYaw:(GLfloat) yaw
     850             : {
     851             :         if ((roll == 0.0)&&(climb == 0.0)&&(yaw == 0.0)&&(!hasRotated))
     852             :                 return;
     853             : 
     854             :         if (roll)
     855             :                 quaternion_rotate_about_z(&orientation, -roll);
     856             :         if (climb)
     857             :                 quaternion_rotate_about_x(&orientation, -climb);
     858             :         if (yaw)
     859             :                 quaternion_rotate_about_y(&orientation, -yaw);
     860             : 
     861             :         [self orientationChanged];
     862             : }
     863             : 
     864             : 
     865             : - (void) moveForward:(double)amount
     866             : {
     867             :         HPVector forward = HPvector_multiply_scalar(HPvector_forward_from_quaternion(orientation), amount);
     868             :         position = HPvector_add(position, forward);
     869             :         distanceTravelled += amount;
     870             : }
     871             : 
     872             : 
     873             : - (OOMatrix) rotationMatrix
     874             : {
     875             :         return rotMatrix;
     876             : }
     877             : 
     878             : 
     879             : - (OOMatrix) drawRotationMatrix
     880             : {
     881             :         return rotMatrix;
     882             : }
     883             : 
     884             : 
     885             : - (OOMatrix) transformationMatrix
     886             : {
     887             :         OOMatrix result = rotMatrix;
     888             :         return OOMatrixHPTranslate(result, position);
     889             : }
     890             : 
     891             : 
     892             : - (OOMatrix) drawTransformationMatrix
     893             : {
     894             :         OOMatrix result = rotMatrix;
     895             :         return OOMatrixHPTranslate(result, position);
     896             : }
     897             : 
     898             : 
     899             : - (BOOL) canCollide
     900             : {
     901             :         return YES;
     902             : }
     903             : 
     904             : 
     905             : - (GLfloat) collisionRadius
     906             : {
     907             :         return collision_radius;
     908             : }
     909             : 
     910             : 
     911             : - (GLfloat) frustumRadius
     912             : {
     913             :         return collision_radius;
     914             : }
     915             : 
     916             : 
     917             : - (void) setCollisionRadius:(GLfloat) amount
     918             : {
     919             :         collision_radius = amount;
     920             : }
     921             : 
     922             : 
     923             : - (NSMutableArray *) collisionArray
     924             : {
     925             :         return collidingEntities;
     926             : }
     927             : 
     928             : 
     929             : - (void) update:(OOTimeDelta)delta_t
     930             : {
     931             :         if (_status != STATUS_COCKPIT_DISPLAY)
     932             :         {
     933             :                 if ([self isSubEntity])
     934             :                 {
     935             :                         zero_distance = [[self owner] zeroDistance];
     936             :                         cam_zero_distance = [[self owner] camZeroDistance];
     937             :                         [self updateCameraRelativePosition];
     938             :                 }
     939             :                 else
     940             :                 {
     941             :                         zero_distance = HPdistance2(PLAYER->position, position);
     942             :                         cam_zero_distance = HPdistance2([PLAYER viewpointPosition], position);
     943             :                         [self updateCameraRelativePosition];
     944             :                 }
     945             :         }
     946             :         else
     947             :         {
     948             :                 zero_distance = HPmagnitude2(position);
     949             :                 cam_zero_distance = zero_distance;
     950             :                 cameraRelativePosition = HPVectorToVector(position);
     951             :         }
     952             :         
     953             :         if ([self status] != STATUS_COCKPIT_DISPLAY)
     954             :         {
     955             :                 [self applyVelocity:delta_t];
     956             :         }
     957             : 
     958             :         hasMoved = !HPvector_equal(position, lastPosition);
     959             :         hasRotated = !quaternion_equal(orientation, lastOrientation);
     960             :         lastPosition = position;
     961             :         lastOrientation = orientation;
     962             : }
     963             : 
     964             : 
     965             : - (void) applyVelocity:(OOTimeDelta)delta_t
     966             : {
     967             :         position = HPvector_add(position, HPvector_multiply_scalar(vectorToHPVector(velocity), delta_t));
     968             : }
     969             : 
     970             : 
     971             : - (BOOL) checkCloseCollisionWith:(Entity *)other
     972             : {
     973             :         return other != nil;
     974             : }
     975             : 
     976             : 
     977             : - (double)findCollisionRadius
     978             : {
     979             :         OOLogGenericSubclassResponsibility();
     980             :         return 0;
     981             : }
     982             : 
     983             : 
     984             : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent
     985             : {
     986             :         OOLogGenericSubclassResponsibility();
     987             : }
     988             : 
     989             : 
     990             : - (void) takeEnergyDamage:(double) amount from:(Entity *) ent becauseOf:(Entity *) other weaponIdentifier:(NSString *)weaponIdentifier
     991             : {
     992             :         
     993             : }
     994             : 
     995             : 
     996             : - (void)dumpState
     997             : {
     998             :         if (OOLogWillDisplayMessagesInClass(@"dumpState"))
     999             :         {
    1000             :                 OOLog(@"dumpState", @"State for %@:", self);
    1001             :                 OOLogPushIndent();
    1002             :                 OOLogIndent();
    1003             :                 @try
    1004             :                 {
    1005             :                         [self dumpSelfState];
    1006             :                 }
    1007             :                 @catch (id exception) {}
    1008             :                 OOLogPopIndent();
    1009             :         }
    1010             : }
    1011             : 
    1012             : 
    1013             : - (void)dumpSelfState
    1014             : {
    1015             :         NSMutableArray          *flags = nil;
    1016             :         NSString                        *flagsString = nil;
    1017             :         id                                      owner = [self owner];
    1018             :         
    1019             :         if (owner == self)  owner = @"self";
    1020             :         else if (owner == nil)  owner = @"none";
    1021             :         
    1022             :         OOLog(@"dumpState.entity", @"Universal ID: %u", universalID);
    1023             :         OOLog(@"dumpState.entity", @"Scan class: %@", OOStringFromScanClass(scanClass));
    1024             :         OOLog(@"dumpState.entity", @"Status: %@", OOStringFromEntityStatus([self status]));
    1025             :         OOLog(@"dumpState.entity", @"Position: %@", HPVectorDescription(position));
    1026             :         OOLog(@"dumpState.entity", @"Orientation: %@", QuaternionDescription(orientation));
    1027             :         OOLog(@"dumpState.entity", @"Distance travelled: %g", distanceTravelled);
    1028             :         OOLog(@"dumpState.entity", @"Energy: %g of %g", energy, maxEnergy);
    1029             :         OOLog(@"dumpState.entity", @"Mass: %g", mass);
    1030             :         OOLog(@"dumpState.entity", @"Owner: %@", owner);
    1031             :         
    1032             :         flags = [NSMutableArray array];
    1033           0 :         #define ADD_FLAG_IF_SET(x)              if (x) { [flags addObject:@#x]; }
    1034             :         ADD_FLAG_IF_SET(isShip);
    1035             :         ADD_FLAG_IF_SET(isStation);
    1036             :         ADD_FLAG_IF_SET(isPlayer);
    1037             :         ADD_FLAG_IF_SET(isWormhole);
    1038             :         ADD_FLAG_IF_SET(isSubEntity);
    1039             :         ADD_FLAG_IF_SET(hasMoved);
    1040             :         ADD_FLAG_IF_SET(hasRotated);
    1041             :         ADD_FLAG_IF_SET(isSunlit);
    1042             :         ADD_FLAG_IF_SET(throw_sparks);
    1043             :         flagsString = [flags count] ? [flags componentsJoinedByString:@", "] : (NSString *)@"none";
    1044             :         OOLog(@"dumpState.entity", @"Flags: %@", flagsString);
    1045             :         OOLog(@"dumpState.entity", @"Collision Test Filter: %u", collisionTestFilter);
    1046             : 
    1047             : }
    1048             : 
    1049             : 
    1050           0 : - (void)subEntityReallyDied:(ShipEntity *)sub
    1051             : {
    1052             :         OOLog(@"entity.bug", @"%s called for non-ship entity %p by %p", __PRETTY_FUNCTION__, self, sub);
    1053             : }
    1054             : 
    1055             : 
    1056             : // For shader bindings.
    1057             : - (GLfloat)universalTime
    1058             : {
    1059             :         return [UNIVERSE getTime];
    1060             : }
    1061             : 
    1062             : 
    1063             : - (GLfloat)spawnTime
    1064             : {
    1065             :         return spawnTime;
    1066             : }
    1067             : 
    1068             : 
    1069             : - (GLfloat)timeElapsedSinceSpawn
    1070             : {
    1071             :         return [UNIVERSE getTime] - spawnTime;
    1072             : }
    1073             : 
    1074             : 
    1075             : - (void) setAtmosphereFogging: (OOColor *)fogging
    1076             : {
    1077             :         [atmosphereFogging release];
    1078             :         atmosphereFogging = [fogging retain];
    1079             : }
    1080             : 
    1081             : - (OOColor *) fogUniform
    1082             : {
    1083             :         return [[atmosphereFogging retain] autorelease];
    1084             : }
    1085             : 
    1086             : #ifndef NDEBUG
    1087             : - (NSString *) descriptionForObjDumpBasic
    1088             : {
    1089             :         NSString *result = [self descriptionComponents];
    1090             :         if (result != nil)  result = [NSString stringWithFormat:@"%@ %@", NSStringFromClass([self class]), result];
    1091             :         else  result = [self description];
    1092             :         
    1093             :         return result;
    1094             : }
    1095             : 
    1096             : 
    1097             : - (NSString *) descriptionForObjDump
    1098             : {
    1099             :         NSString *result = [self descriptionForObjDumpBasic];
    1100             :         
    1101             :         result = [result stringByAppendingFormat:@" range: %g (visible: %@)", HPdistance([self position], [PLAYER position]), [self isVisible] ? @"yes" : @"no"];
    1102             :         
    1103             :         return result;
    1104             : }
    1105             : 
    1106             : 
    1107             : - (NSSet *) allTextures
    1108             : {
    1109             :         return nil;
    1110             : }
    1111             : #endif
    1112             : 
    1113             : 
    1114             : - (BOOL) isVisible
    1115             : {
    1116             :         return cam_zero_distance <= ABSOLUTE_NO_DRAW_DISTANCE2;
    1117             : }
    1118             : 
    1119             : 
    1120             : - (BOOL) isInSpace
    1121             : {
    1122             :         switch ([self status])
    1123             :         {
    1124             :         case STATUS_IN_FLIGHT:
    1125             :         case STATUS_DOCKING:
    1126             :         case STATUS_LAUNCHING:
    1127             :         case STATUS_AUTOPILOT_ENGAGED:
    1128             :         case STATUS_WITCHSPACE_COUNTDOWN:
    1129             :         case STATUS_BEING_SCOOPED:
    1130             :         case STATUS_EFFECT:
    1131             :         case STATUS_ACTIVE:
    1132             :                 return YES;
    1133             :         default:
    1134             :                 return NO;
    1135             :         }
    1136             : }
    1137             : 
    1138             : 
    1139             : - (BOOL) isImmuneToBreakPatternHide
    1140             : {
    1141             :         return isImmuneToBreakPatternHide;
    1142             : }
    1143             : 
    1144             : @end

Generated by: LCOV version 1.14