Cleanup.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@5054 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
579e236b34
commit
1dce047d0f
@ -100,15 +100,16 @@ extern void GenerateGraphVizForAIStateMachine(NSDictionary *stateMachine, NSStri
|
|||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
self = [super init];
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
aiStack = [[NSMutableArray alloc] init];
|
aiStack = [[NSMutableArray alloc] init];
|
||||||
pendingMessages = [[NSMutableSet alloc] init];
|
pendingMessages = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
nextThinkTime = INFINITY; // don't think for a while
|
nextThinkTime = INFINITY; // don't think for a while
|
||||||
thinkTimeInterval = AI_THINK_INTERVAL;
|
thinkTimeInterval = AI_THINK_INTERVAL;
|
||||||
|
|
||||||
stateMachineName = [[NSString stringWithString:@"<no AI>"] retain]; // no initial brain
|
stateMachineName = @"<no AI>"; // no initial brain
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -116,10 +117,11 @@ extern void GenerateGraphVizForAIStateMachine(NSDictionary *stateMachine, NSStri
|
|||||||
|
|
||||||
- (id) initWithStateMachine:(NSString *) smName andState:(NSString *) stateName
|
- (id) initWithStateMachine:(NSString *) smName andState:(NSString *) stateName
|
||||||
{
|
{
|
||||||
self = [self init];
|
if ((self = [self init]))
|
||||||
|
{
|
||||||
if (smName != nil) [self setStateMachine:smName];
|
if (smName != nil) [self setStateMachine:smName];
|
||||||
if (stateName != nil) currentState = [stateName retain];
|
if (stateName != nil) currentState = [stateName retain];
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -28,16 +28,17 @@ MA 02110-1301, USA.
|
|||||||
#import "OOCocoa.h"
|
#import "OOCocoa.h"
|
||||||
#import "OOMaths.h"
|
#import "OOMaths.h"
|
||||||
|
|
||||||
|
|
||||||
#define COLLISION_REGION_BORDER_RADIUS 32000.0f
|
#define COLLISION_REGION_BORDER_RADIUS 32000.0f
|
||||||
#define COLLISION_MAX_ENTITIES 128
|
#define COLLISION_MAX_ENTITIES 128
|
||||||
#define MINIMUM_SHADOWING_ENTITY_RADIUS 75.0
|
#define MINIMUM_SHADOWING_ENTITY_RADIUS 75.0
|
||||||
|
|
||||||
@class Entity;
|
@class Entity;
|
||||||
|
|
||||||
@interface CollisionRegion : NSObject
|
|
||||||
{
|
|
||||||
@public
|
|
||||||
|
|
||||||
|
@interface CollisionRegion: NSObject
|
||||||
|
{
|
||||||
|
@private
|
||||||
BOOL isUniverse; // if YES location is origin and radius is 0.0f
|
BOOL isUniverse; // if YES location is origin and radius is 0.0f
|
||||||
|
|
||||||
int crid; // identifier
|
int crid; // identifier
|
||||||
@ -45,22 +46,18 @@ MA 02110-1301, USA.
|
|||||||
GLfloat radius; // inner radius of the region
|
GLfloat radius; // inner radius of the region
|
||||||
GLfloat border_radius; // additiønal, border radius of the region (typically 32km or some value > the scanner range)
|
GLfloat border_radius; // additiønal, border radius of the region (typically 32km or some value > the scanner range)
|
||||||
|
|
||||||
int checks_this_tick;
|
unsigned checks_this_tick;
|
||||||
int checks_within_range;
|
unsigned checks_within_range;
|
||||||
|
|
||||||
NSMutableArray *subregions;
|
NSMutableArray *subregions;
|
||||||
|
|
||||||
@protected
|
|
||||||
|
|
||||||
BOOL isPlayerInRegion;
|
BOOL isPlayerInRegion;
|
||||||
|
|
||||||
Entity **entity_array; // entities within the region
|
Entity **entity_array; // entities within the region
|
||||||
int n_entities; // number of entities
|
unsigned n_entities; // number of entities
|
||||||
int max_entities; // so storage can be expanded
|
unsigned max_entities; // so storage can be expanded
|
||||||
|
|
||||||
|
|
||||||
CollisionRegion *parentRegion;
|
CollisionRegion *parentRegion;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initAsUniverse;
|
- (id) initAsUniverse;
|
||||||
@ -69,24 +66,17 @@ MA 02110-1301, USA.
|
|||||||
- (void) clearSubregions;
|
- (void) clearSubregions;
|
||||||
- (void) addSubregionAtPosition:(Vector) pos withRadius:(GLfloat) rad;
|
- (void) addSubregionAtPosition:(Vector) pos withRadius:(GLfloat) rad;
|
||||||
|
|
||||||
// update routines to check if a position is within the radius or within it's borders
|
|
||||||
//
|
|
||||||
BOOL positionIsWithinRegion( Vector position, CollisionRegion* region);
|
|
||||||
BOOL sphereIsWithinRegion( Vector position, GLfloat rad, CollisionRegion* region);
|
|
||||||
BOOL positionIsWithinBorders( Vector position, CollisionRegion* region);
|
|
||||||
BOOL positionIsOnBorders( Vector position, CollisionRegion* region);
|
|
||||||
NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region);
|
|
||||||
|
|
||||||
// collision checking
|
// collision checking
|
||||||
//
|
|
||||||
- (void) clearEntityList;
|
- (void) clearEntityList;
|
||||||
- (void) addEntity:(Entity*) ent;
|
- (void) addEntity:(Entity *)ent;
|
||||||
//
|
- (BOOL) checkEntity:(Entity *)ent;
|
||||||
- (BOOL) checkEntity:(Entity*) ent;
|
|
||||||
//
|
|
||||||
- (void) findCollisions;
|
- (void) findCollisions;
|
||||||
- (void) findShadowedEntities;
|
- (void) findShadowedEntities;
|
||||||
|
|
||||||
- (NSString*) debugOut;
|
// Description for FPS HUD
|
||||||
|
- (NSString *) collisionDescription;
|
||||||
|
|
||||||
|
- (NSString *) debugOut;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -36,87 +36,75 @@ MA 02110-1301, USA.
|
|||||||
|
|
||||||
@implementation CollisionRegion
|
@implementation CollisionRegion
|
||||||
|
|
||||||
- (NSString *) description
|
|
||||||
{
|
|
||||||
int n_subs = [subregions count];
|
|
||||||
return [NSString stringWithFormat:@"ID: %d, %d subregions, %d ents", crid, n_subs, n_entities];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// basic alloc/ dealloc routines
|
// basic alloc/ dealloc routines
|
||||||
//
|
//
|
||||||
static int crid_counter = 1;
|
static int crid_counter = 1;
|
||||||
//
|
|
||||||
- (id) initAsUniverse
|
|
||||||
|
- (id) init // Designated initializer.
|
||||||
{
|
{
|
||||||
self = [super init];
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
location = kZeroVector;
|
|
||||||
radius = 0.0f;
|
|
||||||
border_radius = 0.0f;
|
|
||||||
isUniverse = YES;
|
|
||||||
isPlayerInRegion = NO;
|
|
||||||
|
|
||||||
max_entities = COLLISION_MAX_ENTITIES;
|
max_entities = COLLISION_MAX_ENTITIES;
|
||||||
n_entities = 0;
|
entity_array = (Entity **)malloc(max_entities * sizeof(Entity *));
|
||||||
entity_array = (Entity**) malloc( max_entities * sizeof(Entity*));
|
if (entity_array == NULL)
|
||||||
|
{
|
||||||
subregions = [[NSMutableArray alloc] initWithCapacity: 32]; // retained
|
[self release];
|
||||||
|
return nil;
|
||||||
parentRegion = nil;
|
}
|
||||||
|
|
||||||
crid = crid_counter++;
|
crid = crid_counter++;
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (id) initAtLocation:(Vector) locn withRadius:(GLfloat) rad withinRegion:(CollisionRegion*) otherRegion
|
- (id) initAsUniverse
|
||||||
{
|
{
|
||||||
self = [super init];
|
if ((self = [self init]))
|
||||||
|
{
|
||||||
|
isUniverse = YES;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (id) initAtLocation:(Vector)locn withRadius:(GLfloat)rad withinRegion:(CollisionRegion *)otherRegion
|
||||||
|
{
|
||||||
|
if ((self = [self init]))
|
||||||
|
{
|
||||||
location = locn;
|
location = locn;
|
||||||
radius = rad;
|
radius = rad;
|
||||||
border_radius = COLLISION_REGION_BORDER_RADIUS;
|
border_radius = COLLISION_REGION_BORDER_RADIUS;
|
||||||
isUniverse = NO;
|
|
||||||
isPlayerInRegion = NO;
|
|
||||||
|
|
||||||
max_entities = COLLISION_MAX_ENTITIES;
|
|
||||||
n_entities = 0;
|
|
||||||
entity_array = (Entity**) malloc( max_entities * sizeof(Entity*));
|
|
||||||
|
|
||||||
subregions = [[NSMutableArray alloc] initWithCapacity: 32]; // retained
|
|
||||||
|
|
||||||
if (otherRegion)
|
|
||||||
parentRegion = otherRegion;
|
parentRegion = otherRegion;
|
||||||
|
}
|
||||||
crid = crid_counter++;
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (entity_array)
|
free(entity_array);
|
||||||
free((void *)entity_array); // free up the allocated space
|
DESTROY(subregions);
|
||||||
if (subregions)
|
|
||||||
[subregions release];
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (NSString *) description
|
||||||
|
{
|
||||||
|
return [NSString stringWithFormat:@"<%@ %p>{ID: %d, %u subregions, %u ents}", [self class], self, crid, [subregions count], n_entities];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) clearSubregions
|
- (void) clearSubregions
|
||||||
{
|
{
|
||||||
int i;
|
[subregions makeObjectsPerformSelector:@selector(clearSubregions)];
|
||||||
int n_subs = [subregions count];
|
|
||||||
for (i = 0; i < n_subs; i++)
|
|
||||||
[(CollisionRegion*)[subregions objectAtIndex: i] clearSubregions];
|
|
||||||
[subregions removeAllObjects];
|
[subregions removeAllObjects];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) addSubregionAtPosition:(Vector) pos withRadius:(GLfloat) rad
|
- (void) addSubregionAtPosition:(Vector)pos withRadius:(GLfloat)rad
|
||||||
{
|
{
|
||||||
// check if this can be fitted within any of the subregions
|
// check if this can be fitted within any of the subregions
|
||||||
//
|
//
|
||||||
@ -124,14 +112,14 @@ static int crid_counter = 1;
|
|||||||
int n_subs = [subregions count];
|
int n_subs = [subregions count];
|
||||||
for (i = 0; i < n_subs; i++)
|
for (i = 0; i < n_subs; i++)
|
||||||
{
|
{
|
||||||
CollisionRegion* sub = (CollisionRegion*)[subregions objectAtIndex: i];
|
CollisionRegion *sub = (CollisionRegion *)[subregions objectAtIndex:i];
|
||||||
if (sphereIsWithinRegion( pos, rad, sub))
|
if (sphereIsWithinRegion(pos, rad, sub))
|
||||||
{
|
{
|
||||||
// if it fits, put it in!
|
// if it fits, put it in!
|
||||||
[sub addSubregionAtPosition: pos withRadius: rad];
|
[sub addSubregionAtPosition:pos withRadius:rad];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (positionIsWithinRegion( pos, sub))
|
if (positionIsWithinRegion(pos, sub))
|
||||||
{
|
{
|
||||||
// crosses the border of this region already - leave it out
|
// crosses the border of this region already - leave it out
|
||||||
return;
|
return;
|
||||||
@ -139,21 +127,19 @@ static int crid_counter = 1;
|
|||||||
}
|
}
|
||||||
// no subregion fit - move on...
|
// no subregion fit - move on...
|
||||||
//
|
//
|
||||||
CollisionRegion* sub = [[CollisionRegion alloc] initAtLocation: pos withRadius: rad withinRegion: self];
|
CollisionRegion *sub = [[CollisionRegion alloc] initAtLocation:pos withRadius:rad withinRegion:self];
|
||||||
|
if (subregions == nil) subregions = [[NSMutableArray alloc] initWithCapacity:32];
|
||||||
[subregions addObject:sub];
|
[subregions addObject:sub];
|
||||||
[sub release];
|
[sub release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// update routines to check if a position is within the radius or within it's borders
|
// update routines to check if a position is within the radius or within its borders
|
||||||
//
|
//
|
||||||
BOOL positionIsWithinRegion( Vector position, CollisionRegion* region)
|
static BOOL positionIsWithinRegion(Vector position, CollisionRegion *region)
|
||||||
{
|
{
|
||||||
if (!region)
|
if (region == nil) return NO;
|
||||||
return NO;
|
if (region->isUniverse) return YES;
|
||||||
|
|
||||||
if (region->isUniverse)
|
|
||||||
return YES;
|
|
||||||
|
|
||||||
Vector loc = region->location;
|
Vector loc = region->location;
|
||||||
GLfloat r1 = region->radius;
|
GLfloat r1 = region->radius;
|
||||||
@ -161,19 +147,18 @@ BOOL positionIsWithinRegion( Vector position, CollisionRegion* region)
|
|||||||
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
|
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
|
||||||
(position.y < loc.y - r1)||(position.y > loc.y + r1)||
|
(position.y < loc.y - r1)||(position.y > loc.y + r1)||
|
||||||
(position.z < loc.z - r1)||(position.z > loc.z + r1))
|
(position.z < loc.z - r1)||(position.z > loc.z + r1))
|
||||||
|
{
|
||||||
return NO;
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL sphereIsWithinRegion( Vector position, GLfloat rad, CollisionRegion* region)
|
static BOOL sphereIsWithinRegion(Vector position, GLfloat rad, CollisionRegion *region)
|
||||||
{
|
{
|
||||||
if (!region)
|
if (region == nil) return NO;
|
||||||
return NO;
|
if (region->isUniverse) return YES;
|
||||||
|
|
||||||
if (region->isUniverse)
|
|
||||||
return YES;
|
|
||||||
|
|
||||||
Vector loc = region->location;
|
Vector loc = region->location;
|
||||||
GLfloat r1 = region->radius;
|
GLfloat r1 = region->radius;
|
||||||
@ -181,19 +166,18 @@ BOOL sphereIsWithinRegion( Vector position, GLfloat rad, CollisionRegion* region
|
|||||||
if ((position.x - rad < loc.x - r1)||(position.x + rad > loc.x + r1)||
|
if ((position.x - rad < loc.x - r1)||(position.x + rad > loc.x + r1)||
|
||||||
(position.y - rad < loc.y - r1)||(position.y + rad > loc.y + r1)||
|
(position.y - rad < loc.y - r1)||(position.y + rad > loc.y + r1)||
|
||||||
(position.z - rad < loc.z - r1)||(position.z + rad > loc.z + r1))
|
(position.z - rad < loc.z - r1)||(position.z + rad > loc.z + r1))
|
||||||
|
{
|
||||||
return NO;
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL positionIsWithinBorders( Vector position, CollisionRegion* region)
|
static BOOL positionIsWithinBorders(Vector position, CollisionRegion *region)
|
||||||
{
|
{
|
||||||
if (!region)
|
if (region == nil) return NO;
|
||||||
return NO;
|
if (region->isUniverse) return YES;
|
||||||
|
|
||||||
if (region->isUniverse)
|
|
||||||
return YES;
|
|
||||||
|
|
||||||
Vector loc = region->location;
|
Vector loc = region->location;
|
||||||
GLfloat r1 = region->radius + region->border_radius;
|
GLfloat r1 = region->radius + region->border_radius;
|
||||||
@ -201,19 +185,21 @@ BOOL positionIsWithinBorders( Vector position, CollisionRegion* region)
|
|||||||
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
|
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
|
||||||
(position.y < loc.y - r1)||(position.y > loc.y + r1)||
|
(position.y < loc.y - r1)||(position.y > loc.y + r1)||
|
||||||
(position.z < loc.z - r1)||(position.z > loc.z + r1))
|
(position.z < loc.z - r1)||(position.z > loc.z + r1))
|
||||||
|
{
|
||||||
return NO;
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL positionIsOnBorders( Vector position, CollisionRegion* region)
|
#if 0
|
||||||
{
|
// These were lying about unused when I found them, honest guv. -- Ahruman 2012-07-08
|
||||||
if (!region)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
if (region->isUniverse)
|
static BOOL positionIsOnBorders(Vector position, CollisionRegion *region)
|
||||||
return NO;
|
{
|
||||||
|
if (region == nil) return NO;
|
||||||
|
if (region->isUniverse) return NO;
|
||||||
|
|
||||||
Vector loc = region->location;
|
Vector loc = region->location;
|
||||||
GLfloat r2 = region->radius + region->border_radius;
|
GLfloat r2 = region->radius + region->border_radius;
|
||||||
@ -221,121 +207,125 @@ BOOL positionIsOnBorders( Vector position, CollisionRegion* region)
|
|||||||
if ((position.x < loc.x - r2)||(position.x > loc.x + r2)||
|
if ((position.x < loc.x - r2)||(position.x > loc.x + r2)||
|
||||||
(position.y < loc.y - r2)||(position.y > loc.y + r2)||
|
(position.y < loc.y - r2)||(position.y > loc.y + r2)||
|
||||||
(position.z < loc.z - r2)||(position.z > loc.z + r2))
|
(position.z < loc.z - r2)||(position.z > loc.z + r2))
|
||||||
|
{
|
||||||
return NO;
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
return (!positionIsWithinRegion( position, region));
|
return !positionIsWithinRegion(position, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
static NSArray *subregionsContainingPosition(Vector position, CollisionRegion *region)
|
||||||
{
|
{
|
||||||
NSArray* subs = region->subregions;
|
NSArray *subs = region->subregions;
|
||||||
NSMutableArray* result = [NSMutableArray array]; // autoreleased
|
NSMutableArray *result = [NSMutableArray array]; // autoreleased
|
||||||
|
|
||||||
if (!subs)
|
int i, n_subs = [subs count];
|
||||||
return result; // empty array
|
|
||||||
|
|
||||||
int i;
|
|
||||||
int n_subs = [subs count];
|
|
||||||
for (i = 0; i < n_subs; i++)
|
for (i = 0; i < n_subs; i++)
|
||||||
if (positionIsWithinBorders( position, (CollisionRegion*)[subs objectAtIndex: i]))
|
{
|
||||||
[result addObject: [subs objectAtIndex: i]];
|
if (positionIsWithinBorders(position, (CollisionRegion *)[subs objectAtIndex:i]))
|
||||||
|
{
|
||||||
|
[result addObject:[subs objectAtIndex:i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// collision checking
|
// collision checking
|
||||||
//
|
//
|
||||||
- (void) clearEntityList
|
- (void) clearEntityList
|
||||||
{
|
{
|
||||||
|
[subregions makeObjectsPerformSelector:@selector(clearEntityList)];
|
||||||
n_entities = 0;
|
n_entities = 0;
|
||||||
int i;
|
|
||||||
int n_subs = [subregions count];
|
|
||||||
for (i = 0; i < n_subs; i++)
|
|
||||||
[(CollisionRegion*)[subregions objectAtIndex: i] clearEntityList];
|
|
||||||
isPlayerInRegion = NO;
|
isPlayerInRegion = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) addEntity:(Entity*) ent
|
- (void) addEntity:(Entity *)ent
|
||||||
{
|
{
|
||||||
// expand if necessary
|
// expand if necessary
|
||||||
//
|
//
|
||||||
if (n_entities == max_entities)
|
if (n_entities == max_entities)
|
||||||
{
|
{
|
||||||
max_entities = 1 + max_entities * 2;
|
max_entities = 1 + max_entities * 2;
|
||||||
Entity** new_store = (Entity**) malloc( max_entities * sizeof(Entity*));
|
Entity **new_store = (Entity **)realloc(entity_array, max_entities * sizeof(Entity *));
|
||||||
int i;
|
if (new_store == NULL)
|
||||||
for (i = 0; i < n_entities; i++)
|
{
|
||||||
new_store[i] = entity_array[i];
|
[NSException raise:NSMallocException format:@"Not enough memory to grow collision region member list."];
|
||||||
free( (void*)entity_array);
|
}
|
||||||
|
|
||||||
entity_array = new_store;
|
entity_array = new_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
isPlayerInRegion |= (ent->isPlayer);
|
if ([ent isPlayer]) isPlayerInRegion = YES;
|
||||||
entity_array[n_entities++] = ent;
|
entity_array[n_entities++] = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (BOOL) checkEntity:(Entity*) ent
|
- (BOOL) checkEntity:(Entity *)ent
|
||||||
{
|
{
|
||||||
Vector position = ent->position;
|
Vector position = ent->position;
|
||||||
|
|
||||||
// check subregions
|
// check subregions
|
||||||
BOOL foundRegion = NO;
|
int i, n_subs = [subregions count];
|
||||||
int n_subs = [subregions count];
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < n_subs; i++)
|
for (i = 0; i < n_subs; i++)
|
||||||
{
|
{
|
||||||
CollisionRegion* sub = (CollisionRegion*)[subregions objectAtIndex:i];
|
CollisionRegion *sub = [subregions objectAtIndex:i];
|
||||||
if (positionIsWithinBorders( position, sub))
|
if (positionIsWithinBorders(position, sub) && [sub checkEntity:ent])
|
||||||
foundRegion |= [sub checkEntity:ent];
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (foundRegion)
|
|
||||||
return YES; // it's in a subregion so no further action is neccesary
|
|
||||||
|
|
||||||
if (!positionIsWithinBorders( position, self))
|
if (!positionIsWithinBorders(position, self))
|
||||||
|
{
|
||||||
return NO;
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
[self addEntity: ent];
|
[self addEntity:ent];
|
||||||
[ent setCollisionRegion: self];
|
[ent setCollisionRegion:self];
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) findCollisions
|
- (void) findCollisions
|
||||||
{
|
{
|
||||||
|
// test for collisions in each subregion
|
||||||
|
[subregions makeObjectsPerformSelector:@selector(findCollisions)];
|
||||||
|
|
||||||
|
// reject trivial cases
|
||||||
|
if (n_entities < 2) return;
|
||||||
|
|
||||||
//
|
//
|
||||||
// According to Shark, when this was in Universe this was where Oolite spent most time!
|
// According to Shark, when this was in Universe this was where Oolite spent most time!
|
||||||
//
|
//
|
||||||
Entity *e1,*e2;
|
Entity *e1, *e2;
|
||||||
Vector p1, p2;
|
Vector p1, p2;
|
||||||
double dist2, r1, r2, r0, min_dist2;
|
double dist2, r1, r2, r0, min_dist2;
|
||||||
int i;
|
unsigned i;
|
||||||
Entity* entities_to_test[n_entities];
|
Entity *entities_to_test[n_entities];
|
||||||
//
|
|
||||||
|
|
||||||
// reject trivial cases
|
|
||||||
//
|
|
||||||
if (n_entities < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// only check unfiltered entities
|
// only check unfiltered entities
|
||||||
int n_entities_to_test = 0;
|
unsigned n_entities_to_test = 0;
|
||||||
for (i = 0; i < n_entities; i++)
|
for (i = 0; i < n_entities; i++)
|
||||||
{
|
{
|
||||||
e1 = entity_array[i];
|
e1 = entity_array[i];
|
||||||
if (!(e1->collisionTestFilter))
|
if (!(e1->collisionTestFilter))
|
||||||
|
{
|
||||||
entities_to_test[n_entities_to_test++] = e1;
|
entities_to_test[n_entities_to_test++] = e1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (gDebugFlags & DEBUG_COLLISIONS)
|
if (gDebugFlags & DEBUG_COLLISIONS)
|
||||||
|
{
|
||||||
OOLog(@"collisionRegion.debug", @"DEBUG in collision region %@ testing %d out of %d entities", self, n_entities_to_test, n_entities);
|
OOLog(@"collisionRegion.debug", @"DEBUG in collision region %@ testing %d out of %d entities", self, n_entities_to_test, n_entities);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (n_entities_to_test < 2)
|
if (n_entities_to_test < 2) return;
|
||||||
return;
|
|
||||||
|
|
||||||
// clear collision variables
|
// clear collision variables
|
||||||
//
|
//
|
||||||
@ -343,24 +333,17 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
|||||||
{
|
{
|
||||||
e1 = entities_to_test[i];
|
e1 = entities_to_test[i];
|
||||||
if (e1->hasCollided)
|
if (e1->hasCollided)
|
||||||
|
{
|
||||||
[[e1 collisionArray] removeAllObjects];
|
[[e1 collisionArray] removeAllObjects];
|
||||||
e1->hasCollided = NO;
|
e1->hasCollided = NO;
|
||||||
|
}
|
||||||
if (e1->isShip)
|
if (e1->isShip)
|
||||||
|
{
|
||||||
[(ShipEntity*)e1 setProximity_alert:nil];
|
[(ShipEntity*)e1 setProximity_alert:nil];
|
||||||
|
}
|
||||||
e1->collider = nil;
|
e1->collider = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for collisions in each subregion
|
|
||||||
//
|
|
||||||
/* There are never subregions created in the current code, so skip this check for now.
|
|
||||||
|
|
||||||
int n_subs = [subregions count];
|
|
||||||
for (i = 0; i < n_subs; i++)
|
|
||||||
[(CollisionRegion*)[subregions objectAtIndex: i] findCollisions];
|
|
||||||
|
|
||||||
*/
|
|
||||||
//
|
|
||||||
|
|
||||||
checks_this_tick = 0;
|
checks_this_tick = 0;
|
||||||
checks_within_range = 0;
|
checks_within_range = 0;
|
||||||
|
|
||||||
@ -378,10 +361,9 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
|||||||
{
|
{
|
||||||
checks_this_tick++;
|
checks_this_tick++;
|
||||||
|
|
||||||
p2 = e2->position;
|
p2 = vector_subtract(e2->position, p1);
|
||||||
r2 = e2->collision_radius;
|
r2 = e2->collision_radius;
|
||||||
r0 = r1 + r2;
|
r0 = r1 + r2;
|
||||||
p2 = vector_subtract(p2, p1);
|
|
||||||
dist2 = magnitude2(p2);
|
dist2 = magnitude2(p2);
|
||||||
min_dist2 = r0 * r0;
|
min_dist2 = r0 * r0;
|
||||||
if (dist2 < PROXIMITY_WARN_DISTANCE2 * min_dist2)
|
if (dist2 < PROXIMITY_WARN_DISTANCE2 * min_dist2)
|
||||||
@ -395,7 +377,7 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
|||||||
#endif
|
#endif
|
||||||
checks_within_range++;
|
checks_within_range++;
|
||||||
|
|
||||||
if ((e1->isShip) && (e2->isShip))
|
if (e1->isShip && e2->isShip)
|
||||||
{
|
{
|
||||||
if ((dist2 < PROXIMITY_WARN_DISTANCE2 * r2 * r2) || (dist2 < PROXIMITY_WARN_DISTANCE2 * r1 * r1))
|
if ((dist2 < PROXIMITY_WARN_DISTANCE2 * r2 * r2) || (dist2 < PROXIMITY_WARN_DISTANCE2 * r1 * r1))
|
||||||
{
|
{
|
||||||
@ -409,36 +391,54 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
|||||||
|
|
||||||
if (e1->isStation)
|
if (e1->isStation)
|
||||||
{
|
{
|
||||||
StationEntity* se1 = (StationEntity*) e1;
|
StationEntity* se1 = (StationEntity *)e1;
|
||||||
if ([se1 shipIsInDockingCorridor: (ShipEntity*)e2])
|
if ([se1 shipIsInDockingCorridor:(ShipEntity *)e2])
|
||||||
|
{
|
||||||
collision = NO;
|
collision = NO;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
collision = [e1 checkCloseCollisionWith: e2];
|
{
|
||||||
|
collision = [e1 checkCloseCollisionWith:e2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (e2->isStation)
|
else if (e2->isStation)
|
||||||
{
|
{
|
||||||
StationEntity* se2 = (StationEntity*) e2;
|
StationEntity* se2 = (StationEntity *)e2;
|
||||||
if ([se2 shipIsInDockingCorridor: (ShipEntity*)e1])
|
if ([se2 shipIsInDockingCorridor:(ShipEntity *)e1])
|
||||||
|
{
|
||||||
collision = NO;
|
collision = NO;
|
||||||
else
|
|
||||||
collision = [e2 checkCloseCollisionWith: e1];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
collision = [e1 checkCloseCollisionWith: e2];
|
{
|
||||||
|
collision = [e2 checkCloseCollisionWith:e1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
collision = [e1 checkCloseCollisionWith:e2];
|
||||||
|
}
|
||||||
|
|
||||||
if (collision)
|
if (collision)
|
||||||
{
|
{
|
||||||
// now we have no need to check the e2-e1 collision
|
// now we have no need to check the e2-e1 collision
|
||||||
if (e1->collider)
|
if (e1->collider)
|
||||||
|
{
|
||||||
[[e1 collisionArray] addObject:e1->collider];
|
[[e1 collisionArray] addObject:e1->collider];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
[[e1 collisionArray] addObject:e2];
|
[[e1 collisionArray] addObject:e2];
|
||||||
|
}
|
||||||
e1->hasCollided = YES;
|
e1->hasCollided = YES;
|
||||||
//
|
|
||||||
if (e2->collider)
|
if (e2->collider)
|
||||||
|
{
|
||||||
[[e2 collisionArray] addObject:e2->collider];
|
[[e2 collisionArray] addObject:e2->collider];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
[[e2 collisionArray] addObject:e1];
|
[[e2 collisionArray] addObject:e1];
|
||||||
|
}
|
||||||
e2->hasCollided = YES;
|
e2->hasCollided = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,58 +535,59 @@ static BOOL testEntityOccludedByEntity(Entity *e1, Entity *e2, OOSunEntity *the_
|
|||||||
|
|
||||||
- (void) findShadowedEntities
|
- (void) findShadowedEntities
|
||||||
{
|
{
|
||||||
|
// reject trivial cases
|
||||||
|
if (n_entities < 2) return;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copy/pasting the collision code to detect occlusion!
|
// Copy/pasting the collision code to detect occlusion!
|
||||||
//
|
//
|
||||||
Entity* e1;
|
unsigned i, j;
|
||||||
int i,j;
|
|
||||||
|
|
||||||
if ([UNIVERSE reducedDetail]) return; // don't do this in reduced detail mode
|
if ([UNIVERSE reducedDetail]) return; // don't do this in reduced detail mode
|
||||||
|
|
||||||
OOSunEntity* the_sun = [UNIVERSE sun];
|
OOSunEntity* the_sun = [UNIVERSE sun];
|
||||||
|
|
||||||
if (!the_sun)
|
if (the_sun == nil)
|
||||||
|
{
|
||||||
return; // sun is required
|
return; // sun is required
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ent_count = UNIVERSE->n_entities;
|
||||||
|
Entity **uni_entities = UNIVERSE->sortedEntities; // grab the public sorted list
|
||||||
|
Entity *planets[ent_count];
|
||||||
|
unsigned n_planets = 0;
|
||||||
|
Entity *ships[ent_count];
|
||||||
|
unsigned n_ships = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// get a list of planet entities because they can shade across regions
|
|
||||||
int ent_count = UNIVERSE->n_entities;
|
|
||||||
Entity** uni_entities = UNIVERSE->sortedEntities; // grab the public sorted list
|
|
||||||
Entity* planets[ent_count];
|
|
||||||
int n_planets = 0;
|
|
||||||
Entity* ships[ent_count];
|
|
||||||
int n_ships = 0;
|
|
||||||
for (i = 0; i < ent_count; i++)
|
for (i = 0; i < ent_count; i++)
|
||||||
{
|
{
|
||||||
if ([uni_entities[i] isPlanet] && uni_entities[i]->isSunlit)
|
if (uni_entities[i]->isSunlit)
|
||||||
planets[n_planets++] = uni_entities[i]; // don't bother retaining - nothing will happen to them!
|
{
|
||||||
|
// get a list of planet entities because they can shade across regions
|
||||||
|
if ([uni_entities[i] isPlanet])
|
||||||
|
{
|
||||||
|
// don't bother retaining - nothing will happen to them!
|
||||||
|
planets[n_planets++] = uni_entities[i];
|
||||||
|
}
|
||||||
|
|
||||||
// and a list of shipentities large enough that they might cast a noticeable shadow
|
// and a list of shipentities large enough that they might cast a noticeable shadow
|
||||||
// if we can't see it, it can't be shadowing anything important
|
// if we can't see it, it can't be shadowing anything important
|
||||||
else if ([uni_entities[i] isShip] && uni_entities[i]->isSunlit && [uni_entities[i] isVisible] && uni_entities[i]->collision_radius >= MINIMUM_SHADOWING_ENTITY_RADIUS)
|
else if ([uni_entities[i] isShip] &&
|
||||||
|
[uni_entities[i] isVisible] &&
|
||||||
|
uni_entities[i]->collision_radius >= MINIMUM_SHADOWING_ENTITY_RADIUS)
|
||||||
{
|
{
|
||||||
ships[n_ships++] = uni_entities[i]; // don't bother retaining - nothing will happen to them!
|
ships[n_ships++] = uni_entities[i]; // don't bother retaining - nothing will happen to them!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// reject trivial cases
|
|
||||||
//
|
|
||||||
if (n_entities < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// test for shadows in each subregion
|
// test for shadows in each subregion
|
||||||
//
|
[subregions makeObjectsPerformSelector:@selector(findShadowedEntities)];
|
||||||
int n_subs = [subregions count];
|
|
||||||
for (i = 0; i < n_subs; i++)
|
|
||||||
[[subregions objectAtIndex: i] findShadowedEntities];
|
|
||||||
//
|
|
||||||
|
|
||||||
// test each entity in this region against the others
|
// test each entity in this region against the others
|
||||||
//
|
|
||||||
for (i = 0; i < n_entities; i++)
|
for (i = 0; i < n_entities; i++)
|
||||||
{
|
{
|
||||||
e1 = entity_array[i];
|
Entity *e1 = entity_array[i];
|
||||||
if (![e1 isVisible])
|
if (![e1 isVisible])
|
||||||
{
|
{
|
||||||
continue; // don't check shading of objects we can't see
|
continue; // don't check shading of objects we can't see
|
||||||
@ -598,13 +599,15 @@ static BOOL testEntityOccludedByEntity(Entity *e1, Entity *e2, OOSunEntity *the_
|
|||||||
e1->shadingEntityID = NO_TARGET;
|
e1->shadingEntityID = NO_TARGET;
|
||||||
continue; // don't check shading in demo mode
|
continue; // don't check shading in demo mode
|
||||||
}
|
}
|
||||||
Entity* occluder = nil;
|
Entity *occluder = nil;
|
||||||
if (e1->isSunlit == NO)
|
if (e1->isSunlit == NO)
|
||||||
{
|
{
|
||||||
occluder = [UNIVERSE entityForUniversalID:e1->shadingEntityID];
|
occluder = [UNIVERSE entityForUniversalID:e1->shadingEntityID];
|
||||||
if (occluder)
|
if (occluder != nil)
|
||||||
|
{
|
||||||
occluder_moved = occluder->hasMoved;
|
occluder_moved = occluder->hasMoved;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (([e1 isShip] ||[e1 isPlanet]) && (e1->hasMoved || occluder_moved))
|
if (([e1 isShip] ||[e1 isPlanet]) && (e1->hasMoved || occluder_moved))
|
||||||
{
|
{
|
||||||
e1->isSunlit = YES; // sunlit by default
|
e1->isSunlit = YES; // sunlit by default
|
||||||
@ -612,39 +615,47 @@ static BOOL testEntityOccludedByEntity(Entity *e1, Entity *e2, OOSunEntity *the_
|
|||||||
//
|
//
|
||||||
// check demo mode here..
|
// check demo mode here..
|
||||||
if ([e1 isPlayer] && ([(PlayerEntity*)e1 showDemoShips]))
|
if ([e1 isPlayer] && ([(PlayerEntity*)e1 showDemoShips]))
|
||||||
|
{
|
||||||
continue; // don't check shading in demo mode
|
continue; // don't check shading in demo mode
|
||||||
//
|
}
|
||||||
|
|
||||||
// test last occluder (most likely case)
|
// test last occluder (most likely case)
|
||||||
//
|
|
||||||
double occlusionNumber;
|
|
||||||
if (occluder)
|
if (occluder)
|
||||||
{
|
{
|
||||||
if (entityByEntityOcclusionToValue(e1, occluder, the_sun, &occlusionNumber))
|
if (testEntityOccludedByEntity(e1, occluder, the_sun))
|
||||||
{
|
{
|
||||||
e1->isSunlit = NO;
|
e1->isSunlit = NO;
|
||||||
e1->shadingEntityID = [occluder universalID];
|
e1->shadingEntityID = [occluder universalID];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!e1->isSunlit) // no point in continuing tests
|
if (!e1->isSunlit)
|
||||||
|
{
|
||||||
|
// no point in continuing tests
|
||||||
continue;
|
continue;
|
||||||
//
|
}
|
||||||
|
|
||||||
// test planets
|
// test planets
|
||||||
//
|
|
||||||
for (j = 0; j < n_planets; j++)
|
for (j = 0; j < n_planets; j++)
|
||||||
{
|
{
|
||||||
|
double occlusionNumber;
|
||||||
if (entityByEntityOcclusionToValue(e1, planets[j], the_sun, &occlusionNumber))
|
if (entityByEntityOcclusionToValue(e1, planets[j], the_sun, &occlusionNumber))
|
||||||
{
|
{
|
||||||
e1->isSunlit = NO;
|
e1->isSunlit = NO;
|
||||||
e1->shadingEntityID = [planets[j] universalID];
|
e1->shadingEntityID = [planets[j] universalID];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (EXPECT_NOT([e1 isPlayer])) ((PlayerEntity *)e1)->occlusion_dial = occlusionNumber;
|
if ([e1 isPlayer])
|
||||||
|
{
|
||||||
|
((PlayerEntity *)e1)->occlusion_dial = occlusionNumber;
|
||||||
}
|
}
|
||||||
if (!e1->isSunlit) // no point in continuing tests
|
}
|
||||||
|
if (!e1->isSunlit)
|
||||||
|
{
|
||||||
|
// no point in continuing tests
|
||||||
continue;
|
continue;
|
||||||
//
|
}
|
||||||
|
|
||||||
// test local entities
|
// test local entities
|
||||||
//
|
|
||||||
for (j = 0; j < n_ships; j++)
|
for (j = 0; j < n_ships; j++)
|
||||||
{
|
{
|
||||||
if (testEntityOccludedByEntity(e1, ships[j], the_sun))
|
if (testEntityOccludedByEntity(e1, ships[j], the_sun))
|
||||||
@ -659,13 +670,21 @@ static BOOL testEntityOccludedByEntity(Entity *e1, Entity *e2, OOSunEntity *the_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString*) debugOut
|
- (NSString *) collisionDescription
|
||||||
|
{
|
||||||
|
return [NSString stringWithFormat:@"p%u - c%u", checks_this_tick, checks_within_range];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (NSString *) debugOut
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int n_subs = [subregions count];
|
int n_subs = [subregions count];
|
||||||
NSMutableString* result = [[NSMutableString alloc] initWithFormat:@"%d:", n_entities];
|
NSMutableString *result = [[NSMutableString alloc] initWithFormat:@"%d:", n_entities];
|
||||||
for (i = 0; i < n_subs; i++)
|
for (i = 0; i < n_subs; i++)
|
||||||
|
{
|
||||||
[result appendString:[(CollisionRegion*)[subregions objectAtIndex:i] debugOut]];
|
[result appendString:[(CollisionRegion*)[subregions objectAtIndex:i] debugOut]];
|
||||||
|
}
|
||||||
return [result autorelease];
|
return [result autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,16 +279,17 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n_ships; i++)
|
for (i = 0; i < n_ships; i++)
|
||||||
{
|
{
|
||||||
ShipEntity* ship = (ShipEntity*)[(NSDictionary*)[shipsInTransit objectAtIndex:i] objectForKey:@"ship"];
|
NSDictionary *shipInfo = [shipsInTransit objectAtIndex:i];
|
||||||
NSString *shipBeacon = [(NSDictionary *)[shipsInTransit objectAtIndex:i] objectForKey:@"shipBeacon"];
|
ShipEntity *ship = [shipInfo objectForKey:@"ship"];
|
||||||
double ship_arrival_time = arrival_time + [(NSNumber*)[(NSDictionary*)[shipsInTransit objectAtIndex:i] objectForKey:@"time"] doubleValue];
|
NSString *shipBeacon = [shipInfo objectForKey:@"shipBeacon"];
|
||||||
|
double ship_arrival_time = arrival_time + [shipInfo oo_doubleForKey:@"time"];
|
||||||
double time_passed = now - ship_arrival_time;
|
double time_passed = now - ship_arrival_time;
|
||||||
|
|
||||||
if ([ship status] == STATUS_DEAD) continue; // skip dead ships.
|
if ([ship status] == STATUS_DEAD) continue; // skip dead ships.
|
||||||
|
|
||||||
if (ship_arrival_time > now)
|
if (ship_arrival_time > now)
|
||||||
{
|
{
|
||||||
[shipsStillInTransit addObject:[shipsInTransit objectAtIndex:i]];
|
[shipsStillInTransit addObject:shipInfo];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -876,7 +876,7 @@ NSString *OOJSDescribeLocation(JSContext *context, JSStackFrame *stackFrame)
|
|||||||
const char *fileName;
|
const char *fileName;
|
||||||
OOUInteger lineNo;
|
OOUInteger lineNo;
|
||||||
GetLocationNameAndLine(context, stackFrame, &fileName, &lineNo);
|
GetLocationNameAndLine(context, stackFrame, &fileName, &lineNo);
|
||||||
if (fileName == NULL) return NO;
|
if (fileName == NULL) return nil;
|
||||||
|
|
||||||
// If this stops working, we probably need to switch to strcmp().
|
// If this stops working, we probably need to switch to strcmp().
|
||||||
if (fileName == sConsoleScriptName && lineNo >= sConsoleEvalLineNo) return @"<console input>";
|
if (fileName == sConsoleScriptName && lineNo >= sConsoleEvalLineNo) return @"<console input>";
|
||||||
|
@ -4913,22 +4913,21 @@ OOINLINE BOOL EntityInRange(Vector p1, Entity *e2, float range)
|
|||||||
[universeRegion clearEntityList];
|
[universeRegion clearEntityList];
|
||||||
|
|
||||||
for (i = 0; i < n_entities; i++)
|
for (i = 0; i < n_entities; i++)
|
||||||
[universeRegion checkEntity: sortedEntities[i]]; // sorts out which region it's in
|
{
|
||||||
|
[universeRegion checkEntity:sortedEntities[i]]; // sorts out which region it's in
|
||||||
|
}
|
||||||
|
|
||||||
[universeRegion findCollisions];
|
[universeRegion findCollisions];
|
||||||
|
|
||||||
// do check for entities that can't see the sun!
|
// do check for entities that can't see the sun!
|
||||||
[universeRegion findShadowedEntities];
|
[universeRegion findShadowedEntities];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString*) collisionDescription
|
- (NSString*) collisionDescription
|
||||||
{
|
{
|
||||||
if (universeRegion)
|
if (universeRegion != nil) return [universeRegion collisionDescription];
|
||||||
return [NSString stringWithFormat:@"p%d - c%d", universeRegion->checks_this_tick, universeRegion->checks_within_range];
|
else return @"-";
|
||||||
else
|
|
||||||
return @"-";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user