Use OOWeakSet for ship defense targets.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@5151 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
c24d971705
commit
a9c0e85649
@ -241,7 +241,8 @@
|
||||
"setTargetToNearestFriendlyStation",
|
||||
"setTargetToSystemStation",
|
||||
"setUpEscorts",
|
||||
"fireMissile"
|
||||
"fireMissile",
|
||||
"removeAllDefenseTargets" // Don't use, use clearDefenseTargets instead
|
||||
);
|
||||
|
||||
ai_and_action_methods =
|
||||
@ -456,5 +457,6 @@
|
||||
"scanForRandomMerchantmen" = "scanForRandomMerchantman";
|
||||
"setUpEscorts" = "doNothing";
|
||||
"becomeExplosion" = "explodeSelf";
|
||||
"clearDefenseTargets" = "removeAllDefenseTargets";
|
||||
};
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
#import "OOJSPropID.h"
|
||||
|
||||
@class OOColor, StationEntity, WormholeEntity, AI, Octree, OOMesh, OOScript,
|
||||
OOJSScript, OORoleSet, OOShipGroup, OOEquipmentType;
|
||||
OOJSScript, OORoleSet, OOShipGroup, OOEquipmentType, OOWeakSet;
|
||||
|
||||
#ifdef OO_BRAIN_AI
|
||||
@class OOBrain;
|
||||
@ -323,7 +323,6 @@ typedef enum
|
||||
Vector jink; // x and y set factors for offsetting a pursuing ship's position
|
||||
Vector coordinates; // for flying to/from a set point
|
||||
Vector reference; // a direction vector of magnitude 1 (* turrets *)
|
||||
NSMutableArray *defenseTargets; // defense targets
|
||||
|
||||
OOUInteger _subIdx; // serialisation index - used only if this ship is a subentity
|
||||
OOUInteger _maxShipSubIdx; // serialisation index - the number of ship subentities inside the shipdata
|
||||
@ -443,6 +442,8 @@ typedef enum
|
||||
Vector _escortPositions[MAX_ESCORTS];
|
||||
BOOL _escortPositionsValid;
|
||||
|
||||
OOWeakSet *_defenseTargets; // defense targets
|
||||
|
||||
GLfloat _profileRadius;
|
||||
|
||||
OOWeakReference *_shipHitByLaser; // entity hit by the last laser shot
|
||||
@ -724,13 +725,13 @@ typedef enum
|
||||
- (BOOL) isHostileTo:(Entity *)entity;
|
||||
|
||||
// defense target handling
|
||||
- (unsigned) numDefenseTargets;
|
||||
- (Entity*) getDefenseTarget:(int)index;
|
||||
- (BOOL) addDefenseTarget:(Entity*)target;
|
||||
- (BOOL) isDefenseTarget:(Entity*)target;
|
||||
- (void) removeDefenseTarget:(unsigned)index;
|
||||
- (void) removeDefenseTargetByID:(Entity*)target;
|
||||
- (void) clearDefenseTargets;
|
||||
- (OOUInteger) defenseTargetCount;
|
||||
- (NSArray *) allDefenseTargets;
|
||||
- (NSEnumerator *) defenseTargetEnumerator;
|
||||
- (BOOL) addDefenseTarget:(Entity *)target;
|
||||
- (BOOL) isDefenseTarget:(Entity *)target;
|
||||
- (void) removeDefenseTarget:(Entity *)target;
|
||||
- (void) removeAllDefenseTargets;
|
||||
|
||||
|
||||
- (GLfloat) weaponRange;
|
||||
@ -741,13 +742,13 @@ typedef enum
|
||||
- (void) setWeaponEnergy:(float)value;
|
||||
|
||||
- (GLfloat) scannerRange;
|
||||
- (void) setScannerRange: (GLfloat) value;
|
||||
- (void) setScannerRange:(GLfloat)value;
|
||||
|
||||
- (Vector) reference;
|
||||
- (void) setReference:(Vector) v;
|
||||
- (void) setReference:(Vector)v;
|
||||
|
||||
- (BOOL) reportAIMessages;
|
||||
- (void) setReportAIMessages:(BOOL) yn;
|
||||
- (void) setReportAIMessages:(BOOL)yn;
|
||||
|
||||
- (void) transitionToAegisNone;
|
||||
- (OOPlanetEntity *) findNearestPlanet;
|
||||
@ -757,18 +758,18 @@ typedef enum
|
||||
- (BOOL) withinStationAegis;
|
||||
|
||||
- (NSArray*) crew;
|
||||
- (void) setCrew: (NSArray*) crewArray;
|
||||
- (void) setCrew:(NSArray *)crewArray;
|
||||
|
||||
// Fuel and capacity in tenths of light-years.
|
||||
- (OOFuelQuantity) fuel;
|
||||
- (void) setFuel:(OOFuelQuantity) amount;
|
||||
- (void) setFuel:(OOFuelQuantity)amount;
|
||||
- (OOFuelQuantity) fuelCapacity;
|
||||
|
||||
- (GLfloat) fuelChargeRate;
|
||||
|
||||
- (void) setRoll:(double) amount;
|
||||
- (void) setPitch:(double) amount;
|
||||
- (void) setThrust:(double) amount;
|
||||
- (void) setRoll:(double)amount;
|
||||
- (void) setPitch:(double)amount;
|
||||
- (void) setThrust:(double)amount;
|
||||
- (void) applySticks:(double)delta_t;
|
||||
|
||||
|
||||
@ -778,14 +779,14 @@ typedef enum
|
||||
Sets the bounty on this ship to amount.
|
||||
Does not check to see if the ship is allowed to have a bounty, for example if it is police.
|
||||
*/
|
||||
- (void) setBounty:(OOCreditsQuantity) amount;
|
||||
- (void) setBounty:(OOCreditsQuantity) amount withReason:(OOLegalStatusReason)reason;
|
||||
- (void) setBounty:(OOCreditsQuantity) amount withReasonAsString:(NSString *)reason;
|
||||
- (void) setBounty:(OOCreditsQuantity)amount;
|
||||
- (void) setBounty:(OOCreditsQuantity)amount withReason:(OOLegalStatusReason)reason;
|
||||
- (void) setBounty:(OOCreditsQuantity)amount withReasonAsString:(NSString *)reason;
|
||||
- (OOCreditsQuantity) bounty;
|
||||
|
||||
- (int) legalStatus;
|
||||
|
||||
- (void) setUpCargoType:(NSString *) cargoString;
|
||||
- (void) setUpCargoType:(NSString *)cargoString;
|
||||
- (void) setCommodity:(OOCommodityType)co_type andAmount:(OOCargoQuantity)co_amount;
|
||||
- (void) setCommodityForPod:(OOCommodityType)co_type andAmount:(OOCargoQuantity)co_amount;
|
||||
- (OOCommodityType) commodityType;
|
||||
@ -796,35 +797,35 @@ typedef enum
|
||||
- (OOCargoQuantity) cargoQuantityOnBoard;
|
||||
- (OOCargoType) cargoType;
|
||||
- (NSMutableArray *) cargo;
|
||||
- (void) setCargo:(NSArray *) some_cargo;
|
||||
- (void) setCargo:(NSArray *)some_cargo;
|
||||
- (BOOL) showScoopMessage;
|
||||
|
||||
- (NSArray *) passengerListForScripting;
|
||||
- (NSArray *) contractListForScripting;
|
||||
- (NSArray *) equipmentListForScripting;
|
||||
- (OOEquipmentType *) weaponTypeForFacing:(int) facing;
|
||||
- (OOEquipmentType *) weaponTypeForFacing:(int)facing;
|
||||
- (NSArray *) missilesList;
|
||||
|
||||
- (OOCargoFlag) cargoFlag;
|
||||
- (void) setCargoFlag:(OOCargoFlag) flag;
|
||||
- (void) setCargoFlag:(OOCargoFlag)flag;
|
||||
|
||||
- (void) setSpeed:(double) amount;
|
||||
- (void) setSpeed:(double)amount;
|
||||
- (double) desiredSpeed;
|
||||
- (void) setDesiredSpeed:(double) amount;
|
||||
- (void) setDesiredSpeed:(double)amount;
|
||||
|
||||
- (double) cruiseSpeed;
|
||||
|
||||
- (Vector) thrustVector;
|
||||
- (void) setTotalVelocity:(Vector)vel; // Set velocity to vel - thrustVector, effectively setting the instanteneous velocity to vel.
|
||||
|
||||
- (void) increase_flight_speed:(double) delta;
|
||||
- (void) decrease_flight_speed:(double) delta;
|
||||
- (void) increase_flight_roll:(double) delta;
|
||||
- (void) decrease_flight_roll:(double) delta;
|
||||
- (void) increase_flight_pitch:(double) delta;
|
||||
- (void) decrease_flight_pitch:(double) delta;
|
||||
- (void) increase_flight_yaw:(double) delta;
|
||||
- (void) decrease_flight_yaw:(double) delta;
|
||||
- (void) increase_flight_speed:(double)delta;
|
||||
- (void) decrease_flight_speed:(double)delta;
|
||||
- (void) increase_flight_roll:(double)delta;
|
||||
- (void) decrease_flight_roll:(double)delta;
|
||||
- (void) increase_flight_pitch:(double)delta;
|
||||
- (void) decrease_flight_pitch:(double)delta;
|
||||
- (void) increase_flight_yaw:(double)delta;
|
||||
- (void) decrease_flight_yaw:(double)delta;
|
||||
|
||||
- (GLfloat) flightRoll;
|
||||
- (GLfloat) flightPitch;
|
||||
|
@ -43,6 +43,7 @@ MA 02110-1301, USA.
|
||||
#import "OORoleSet.h"
|
||||
#import "OOShipGroup.h"
|
||||
#import "OOExcludeObjectEnumerator.h"
|
||||
#import "OOWeakSet.h"
|
||||
|
||||
#import "OOCharacter.h"
|
||||
#import "AI.h"
|
||||
@ -623,9 +624,6 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
|
||||
[self setShipScript:[shipDict oo_stringForKey:@"script"]];
|
||||
|
||||
// retained array of defense targets
|
||||
defenseTargets = [[NSMutableArray alloc] initWithCapacity:MAX_TARGETS];
|
||||
|
||||
return YES;
|
||||
|
||||
OOJS_PROFILE_EXIT
|
||||
@ -947,8 +945,7 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
DESTROY(crew);
|
||||
DESTROY(lastRadioMessage);
|
||||
DESTROY(octree);
|
||||
[defenseTargets removeAllObjects];
|
||||
DESTROY(defenseTargets);
|
||||
DESTROY(_defenseTargets);
|
||||
|
||||
[self setSubEntityTakingDamage:nil];
|
||||
[self removeAllEquipment];
|
||||
@ -5080,25 +5077,24 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
return;
|
||||
}
|
||||
|
||||
// can't fire on primary target; track secondary targets instead
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < [turret_owner numDefenseTargets]; i++)
|
||||
// can't fire on primary target; track secondary targets instead
|
||||
NSEnumerator *targetEnum = [turret_owner defenseTargetEnumerator];
|
||||
Entity *target = nil;
|
||||
while ((target = [targetEnum nextObject]))
|
||||
{
|
||||
Entity *my_target = [turret_owner getDefenseTarget:i];
|
||||
if (my_target == nil || [my_target scanClass] == CLASS_NO_DRAW || ![my_target isShip] || [(ShipEntity *)my_target isCloaked] || [my_target energy] <= 0.0)
|
||||
if ([target scanClass] == CLASS_NO_DRAW || [(ShipEntity *)target isCloaked] || [target energy] <= 0.0)
|
||||
{
|
||||
[turret_owner removeDefenseTarget:i--];
|
||||
[turret_owner removeDefenseTarget:target];
|
||||
}
|
||||
else
|
||||
{
|
||||
double range = [turret_owner rangeToSecondaryTarget:my_target];
|
||||
double range = [turret_owner rangeToSecondaryTarget:target];
|
||||
if (range < weaponRange)
|
||||
{
|
||||
aim = [self ballTrackLeadingTarget:delta_t atTarget:my_target];
|
||||
aim = [self ballTrackLeadingTarget:delta_t atTarget:target];
|
||||
if (aim > -1.0)
|
||||
{ // tracking...
|
||||
Vector p = vector_subtract([my_target position], [turret_owner position]);
|
||||
Vector p = vector_subtract([target position], [turret_owner position]);
|
||||
double cr = [turret_owner collisionRadius];
|
||||
|
||||
if (aim > .95)
|
||||
@ -5107,11 +5103,11 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
}
|
||||
return;
|
||||
}
|
||||
// else that target is out of range, try the next priority defense target
|
||||
// else that target is out of range, try the next priority defense target
|
||||
}
|
||||
else if (range > scannerRange)
|
||||
{
|
||||
[turret_owner removeDefenseTarget:i--];
|
||||
[turret_owner removeDefenseTarget:target];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8316,7 +8312,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
ShipEntity* ship = [self primaryTarget];
|
||||
if ([self isDefenseTarget:ship])
|
||||
{
|
||||
[self removeDefenseTargetByID:ship];
|
||||
[self removeDefenseTarget:ship];
|
||||
}
|
||||
target = (ship && ship->isShip) ? (id)ship : nil;
|
||||
if ([self primaryAggressor] == ship)
|
||||
@ -8350,7 +8346,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
}
|
||||
if ([self isDefenseTarget:target])
|
||||
{
|
||||
[self removeDefenseTargetByID:target];
|
||||
[self removeDefenseTarget:target];
|
||||
[shipAI message:@"DEFENSE_TARGET_DESTROYED"];
|
||||
}
|
||||
}
|
||||
@ -9215,21 +9211,27 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
}
|
||||
|
||||
|
||||
- (unsigned) numDefenseTargets
|
||||
- (OOUInteger) defenseTargetCount
|
||||
{
|
||||
return [defenseTargets count];
|
||||
return [_defenseTargets count];
|
||||
}
|
||||
|
||||
|
||||
- (Entity*) getDefenseTarget:(int)index
|
||||
- (NSArray *) allDefenseTargets
|
||||
{
|
||||
return [[defenseTargets objectAtIndex:index] weakRefUnderlyingObject];
|
||||
return [_defenseTargets allObjects];
|
||||
}
|
||||
|
||||
|
||||
- (NSEnumerator *) defenseTargetEnumerator
|
||||
{
|
||||
return [_defenseTargets objectEnumerator];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) addDefenseTarget:(Entity *)target
|
||||
{
|
||||
if ([defenseTargets count] >= MAX_TARGETS)
|
||||
if ([self defenseTargetCount] >= MAX_TARGETS)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
@ -9237,62 +9239,33 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
[defenseTargets addObject:[[target weakRetain] autorelease]];
|
||||
if (_defenseTargets == nil)
|
||||
{
|
||||
// Allocate lazily for the benefit of the ships that never get in fights.
|
||||
_defenseTargets = [[OOWeakSet alloc] init];
|
||||
}
|
||||
|
||||
[_defenseTargets addObject:target];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isDefenseTarget:(Entity *)target
|
||||
{
|
||||
if (target == nil)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
for (unsigned i=0; i<[defenseTargets count]; i++)
|
||||
{
|
||||
if ([[defenseTargets objectAtIndex:i] weakRefUnderlyingObject] == target)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
return [_defenseTargets containsObject:target];
|
||||
}
|
||||
|
||||
|
||||
// exposed to AI
|
||||
- (void) clearDefenseTargets
|
||||
// exposed to AI (as alias of clearDefenseTargets)
|
||||
- (void) removeAllDefenseTargets
|
||||
{
|
||||
[defenseTargets removeAllObjects];
|
||||
[_defenseTargets removeAllObjects];
|
||||
}
|
||||
|
||||
|
||||
- (void) removeDefenseTarget:(unsigned)index
|
||||
- (void) removeDefenseTarget:(Entity *)target
|
||||
{
|
||||
if (index < [defenseTargets count])
|
||||
{
|
||||
if ([defenseTargets count] == 1)
|
||||
{
|
||||
[shipAI reactToMessage:@"DEFENSE_TARGET_LOST" context:@"flight updates"]; // last defense target lost
|
||||
}
|
||||
else
|
||||
{
|
||||
[shipAI message:@"DEFENSE_TARGET_LOST"]; // no major urgency, we have more
|
||||
}
|
||||
[defenseTargets removeObjectAtIndex:index];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) removeDefenseTargetByID:(Entity *)target
|
||||
{
|
||||
for (unsigned i=0; i<[defenseTargets count]; i++)
|
||||
{
|
||||
if ([[defenseTargets objectAtIndex:i] weakRefUnderlyingObject] == target)
|
||||
{
|
||||
[self removeDefenseTarget:i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
[_defenseTargets removeObject:target];
|
||||
}
|
||||
|
||||
|
||||
@ -9729,24 +9702,24 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
|
||||
- (BOOL) fireDirectLaserDefensiveShot
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < [defenseTargets count]; i++)
|
||||
NSEnumerator *targetEnum = [self defenseTargetEnumerator];
|
||||
Entity *target = nil;
|
||||
while ((target = [targetEnum nextObject]))
|
||||
{
|
||||
Entity *my_target = [self getDefenseTarget:i];
|
||||
if (my_target == nil || [my_target scanClass] == CLASS_NO_DRAW || ![my_target isShip] || [(ShipEntity *)my_target isCloaked] || [my_target energy] <= 0.0)
|
||||
if ([target scanClass] == CLASS_NO_DRAW || [(ShipEntity *)target isCloaked] || [target energy] <= 0.0)
|
||||
{
|
||||
[self removeDefenseTarget:i--];
|
||||
[self removeDefenseTarget:target];
|
||||
}
|
||||
else
|
||||
{
|
||||
double range = [self rangeToSecondaryTarget:my_target];
|
||||
double range = [self rangeToSecondaryTarget:target];
|
||||
if (range < weaponRange)
|
||||
{
|
||||
return [self fireDirectLaserShotAt:my_target];
|
||||
return [self fireDirectLaserShotAt:target];
|
||||
}
|
||||
else if (range > scannerRange)
|
||||
{
|
||||
[self removeDefenseTarget:i--];
|
||||
[self removeDefenseTarget:target];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1507,7 +1507,7 @@
|
||||
}
|
||||
if ([other isDefenseTarget:self])
|
||||
{
|
||||
[other removeDefenseTargetByID:self];
|
||||
[other removeDefenseTarget:self];
|
||||
}
|
||||
}
|
||||
// now we're just a bunch of alien artefacts!
|
||||
|
@ -49,6 +49,8 @@ This code is hereby placed in the public domain.
|
||||
- (void) makeObjectsPerformSelector:(SEL)selector;
|
||||
- (void) makeObjectsPerformSelector:(SEL)selector withObject:(id)argument;
|
||||
|
||||
- (NSArray *) allObjects;
|
||||
|
||||
- (void) removeAllObjects;
|
||||
|
||||
@end
|
||||
|
@ -212,6 +212,24 @@ This code is hereby placed in the public domain.
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *) allObjects
|
||||
{
|
||||
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[_objects count]];
|
||||
OOWeakReference *weakRef = nil;
|
||||
foreach (weakRef, _objects)
|
||||
{
|
||||
id object = [weakRef weakRefUnderlyingObject];
|
||||
if (object != nil) [result addObject:object];
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
return result;
|
||||
#else
|
||||
return [NSArray arrayWithArray:result];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (void) removeAllObjects
|
||||
{
|
||||
[_objects removeAllObjects];
|
||||
|
@ -465,21 +465,9 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsid propID, j
|
||||
break;
|
||||
|
||||
case kShip_defenseTargets:
|
||||
{
|
||||
unsigned ndts = [entity numDefenseTargets];
|
||||
NSMutableArray* targets = [NSMutableArray arrayWithCapacity:ndts];
|
||||
for (unsigned i=0;i<ndts;i++)
|
||||
{
|
||||
Entity *dtarget = [entity getDefenseTarget:i];
|
||||
if (dtarget != nil)
|
||||
{
|
||||
[targets addObject:dtarget];
|
||||
}
|
||||
}
|
||||
result = [NSArray arrayWithArray:targets];
|
||||
if ([result count] == 0) result = nil;
|
||||
result = [entity allDefenseTargets];
|
||||
break;
|
||||
}
|
||||
|
||||
case kShip_escorts:
|
||||
result = [[entity escortGroup] memberArrayExcludingLeader];
|
||||
if ([result count] == 0) result = nil;
|
||||
@ -2363,7 +2351,7 @@ static JSBool ShipClearDefenseTargets(JSContext *context, uintN argc, jsval *vp)
|
||||
|
||||
ShipEntity *thisEnt = nil;
|
||||
GET_THIS_SHIP(thisEnt);
|
||||
[thisEnt clearDefenseTargets];
|
||||
[thisEnt removeAllDefenseTargets];
|
||||
|
||||
OOJS_RETURN_VOID;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user