Implemented role set vs. primary role distinction in ShipEntity. Appears to work.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1166 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
693c27e2c2
commit
dfc8f99526
@ -158,6 +158,12 @@ typedef struct
|
||||
struct JSObject *jsSelf;
|
||||
}
|
||||
|
||||
- (BOOL)isShip;
|
||||
- (BOOL)isStation;
|
||||
- (BOOL)isSubEntity;
|
||||
- (BOOL)isPlayer;
|
||||
- (BOOL)isPlanet;
|
||||
|
||||
- (BOOL) validForAddToUniverse;
|
||||
- (void) addToLinkedLists;
|
||||
- (void) removeFromLinkedLists;
|
||||
@ -180,7 +186,7 @@ typedef struct
|
||||
- (void) throwSparks;
|
||||
|
||||
- (void) setOwner:(Entity *)ent;
|
||||
- (Entity *)owner;
|
||||
- (id)owner;
|
||||
|
||||
- (void) setPosition:(Vector)posn;
|
||||
- (void) setPositionX:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
|
||||
|
@ -99,6 +99,36 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isShip
|
||||
{
|
||||
return isShip;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isStation
|
||||
{
|
||||
return isStation;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isSubEntity
|
||||
{
|
||||
return isSubentity;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPlayer
|
||||
{
|
||||
return isPlayer;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPlanet
|
||||
{
|
||||
return isPlanet;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) validForAddToUniverse
|
||||
{
|
||||
return YES;
|
||||
@ -476,7 +506,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
|
||||
}
|
||||
|
||||
|
||||
- (Entity *) owner
|
||||
- (id) owner
|
||||
{
|
||||
return [UNIVERSE entityForUniversalID:owner];
|
||||
}
|
||||
|
@ -1042,7 +1042,7 @@ static GLfloat texture_uv_array[10400 * 2];
|
||||
if (other->isShip)
|
||||
{
|
||||
ShipEntity *ship = (ShipEntity *)other;
|
||||
if ([[ship roles] isEqual:@"shuttle"])
|
||||
if ([ship isShuttle])
|
||||
{
|
||||
[ship landOnPlanet];
|
||||
if ([ship reportAIMessages])
|
||||
|
@ -294,11 +294,13 @@ static PlayerEntity *sSharedPlayer = nil;
|
||||
{
|
||||
if (missile_entity[i])
|
||||
{
|
||||
[missile_roles addObject:[missile_entity[i] roles]];
|
||||
[missile_roles addObject:[missile_entity[i] primaryRole]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[missile_roles addObject:@"NONE"];
|
||||
}
|
||||
}
|
||||
[result setObject:missile_roles forKey:@"missile_roles"];
|
||||
// [self safeAllMissiles]; // affects missile_status!!
|
||||
|
||||
@ -1054,7 +1056,9 @@ static PlayerEntity *sSharedPlayer = nil;
|
||||
[name autorelease];
|
||||
name = [[shipDict stringForKey:@"name" defaultValue:name] copy];
|
||||
|
||||
[self setRoles:@"player"];
|
||||
[roleSet release];
|
||||
roleSet = nil;
|
||||
[self setPrimaryRole:@"player"];
|
||||
|
||||
OOColor *color = [OOColor brightColorWithDescription:[shipDict objectForKey:@"laser_color"]];
|
||||
if (color == nil) color = [OOColor redColor];
|
||||
@ -1653,7 +1657,7 @@ double scoopSoundPlayTime = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((missile_status == MISSILE_STATUS_ARMED)&&(ident_engaged||[[missile_entity[activeMissile] roles] hasSuffix:@"MISSILE"])&&((status == STATUS_IN_FLIGHT)||(status == STATUS_WITCHSPACE_COUNTDOWN)))
|
||||
if ((missile_status == MISSILE_STATUS_ARMED)&&(ident_engaged||[missile_entity[activeMissile] isMissile])&&((status == STATUS_IN_FLIGHT)||(status == STATUS_WITCHSPACE_COUNTDOWN)))
|
||||
{
|
||||
int first_target_id = [UNIVERSE getFirstEntityTargettedByPlayer:self];
|
||||
if (first_target_id != NO_TARGET)
|
||||
@ -2568,11 +2572,10 @@ double scoopSoundPlayTime = 0.0;
|
||||
if (missile_entity[next_missile])
|
||||
{
|
||||
// if this is a missile then select it
|
||||
// if ([[missile_entity[next_missile] roles] isEqual:@"EQ_MISSILE"])
|
||||
if (missile_entity[next_missile]) // if it exists
|
||||
{
|
||||
[self setActiveMissile:next_missile];
|
||||
if (([[missile_entity[next_missile] roles] hasSuffix:@"MISSILE"])&&([missile_entity[next_missile] primaryTarget] != nil))
|
||||
if (([missile_entity[next_missile] isMissile])&&([missile_entity[next_missile] primaryTarget] != nil))
|
||||
{
|
||||
// copy the missile's target
|
||||
[self addTarget:[missile_entity[next_missile] primaryTarget]];
|
||||
@ -2727,7 +2730,7 @@ double scoopSoundPlayTime = 0.0;
|
||||
|
||||
double mcr = missile->collision_radius;
|
||||
|
||||
if ([[missile roles] hasSuffix:@"MINE"]&&((missile_status == MISSILE_STATUS_ARMED)||(missile_status == MISSILE_STATUS_TARGET_LOCKED)))
|
||||
if ([missile isMine]&&((missile_status == MISSILE_STATUS_ARMED)||(missile_status == MISSILE_STATUS_TARGET_LOCKED)))
|
||||
{
|
||||
BOOL launchedOK = [self launchMine:missile];
|
||||
if (launchedOK)
|
||||
@ -3387,7 +3390,7 @@ double scoopSoundPlayTime = 0.0;
|
||||
int killClass = other->scanClass; // **tgape** change (+line)
|
||||
int kill_award = 1;
|
||||
|
||||
if ([[other roles] isEqual:@"police"]) // oops, we shot a copper!
|
||||
if ([other isPolice]) // oops, we shot a copper!
|
||||
legalStatus |= 64;
|
||||
|
||||
if (![UNIVERSE strict]) // only mess with the scores if we're not in 'strict' mode
|
||||
@ -3395,7 +3398,7 @@ double scoopSoundPlayTime = 0.0;
|
||||
BOOL killIsCargo = ((killClass == CLASS_CARGO) && ([other commodityAmount] > 0));
|
||||
if ((killIsCargo) || (killClass == CLASS_BUOY) || (killClass == CLASS_ROCK))
|
||||
{
|
||||
if (![[other roles] isEqual:@"tharglet"]) // okay, we'll count tharglets as proper kills
|
||||
if (![other hasRole:@"tharglet"]) // okay, we'll count tharglets as proper kills
|
||||
{
|
||||
score /= 10; // reduce bounty awarded
|
||||
kill_award = 0; // don't award a kill
|
||||
@ -5266,7 +5269,7 @@ static int last_outfitting_index;
|
||||
missile_entity[i] = nil;
|
||||
if (weapon)
|
||||
{
|
||||
NSString* weapon_key = [weapon roles];
|
||||
NSString* weapon_key = [weapon primaryRole];
|
||||
int weapon_value = [UNIVERSE getPriceForWeaponSystemWithKey:weapon_key];
|
||||
tradeIn += weapon_value;
|
||||
[weapon release];
|
||||
|
@ -423,7 +423,7 @@ static NSTimeInterval time_last_frame;
|
||||
// launch here
|
||||
if (!fire_missile_pressed)
|
||||
{
|
||||
BOOL missile_noise = [[missile_entity[activeMissile] roles] hasSuffix:@"MISSILE"];
|
||||
BOOL missile_noise = [missile_entity[activeMissile] isMissile];
|
||||
if ([self fireMissile])
|
||||
{
|
||||
if (missile_noise) [missileSound play];
|
||||
@ -515,7 +515,7 @@ static NSTimeInterval time_last_frame;
|
||||
missile_status = MISSILE_STATUS_ARMED;
|
||||
if ((ident_engaged) && ([self primaryTarget]))
|
||||
{
|
||||
if ([[missile_entity[activeMissile] roles] hasSuffix:@"MISSILE"])
|
||||
if ([missile_entity[activeMissile] isMissile])
|
||||
{
|
||||
missile_status = MISSILE_STATUS_TARGET_LOCKED;
|
||||
[missile_entity[activeMissile] addTarget:[self primaryTarget]];
|
||||
@ -527,7 +527,7 @@ static NSTimeInterval time_last_frame;
|
||||
else
|
||||
{
|
||||
primaryTarget = NO_TARGET;
|
||||
if ([[missile_entity[activeMissile] roles] hasSuffix:@"MISSILE"])
|
||||
if ([missile_entity[activeMissile] isMissile])
|
||||
{
|
||||
if (missile_entity[activeMissile])
|
||||
[missile_entity[activeMissile] removeTarget:nil];
|
||||
@ -536,7 +536,7 @@ static NSTimeInterval time_last_frame;
|
||||
[self beep];
|
||||
}
|
||||
}
|
||||
if ([[missile_entity[activeMissile] roles] hasSuffix:@"MINE"])
|
||||
if ([missile_entity[activeMissile] isMine])
|
||||
{
|
||||
[UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[mine-armed]") forCount:4.5];
|
||||
if (![UNIVERSE playCustomSound:@"[mine-armed]"])
|
||||
|
@ -1185,7 +1185,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
|
||||
[tokens removeObjectAtIndex:0];
|
||||
messageString = [tokens componentsJoinedByString:@" "];
|
||||
|
||||
[UNIVERSE sendShipsWithRole:roleString messageToAI:messageString];
|
||||
[UNIVERSE sendShipsWithPrimaryRole:roleString messageToAI:messageString];
|
||||
}
|
||||
|
||||
|
||||
@ -1224,7 +1224,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
|
||||
OOLog(kOOLogNoteAddShips, @"DEBUG ..... Going to add %d ships with role '%@'", number, roleString);
|
||||
|
||||
while (number--)
|
||||
[UNIVERSE witchspaceShipWithRole:roleString];
|
||||
[UNIVERSE witchspaceShipWithPrimaryRole:roleString];
|
||||
}
|
||||
|
||||
|
||||
@ -1873,7 +1873,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
|
||||
[se1AI setStateMachine:@"exitingTraderAI.plist"];
|
||||
[se1AI setState:@"EXIT_SYSTEM"];
|
||||
[se1AI reactToMessage:[NSString stringWithFormat:@"pauseAI: %d", 3 + (ranrot_rand() & 15)]];
|
||||
[se1 setRoles:@"none"]; // prevents new ship from appearing at witchpoint when this one leaves!
|
||||
[se1 setPrimaryRole:@"none"]; // prevents new ship from appearing at witchpoint when this one leaves!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ MA 02110-1301, USA.
|
||||
#import "OOEntityWithDrawable.h"
|
||||
|
||||
@class OOBrain, OOColor, StationEntity, ParticleEntity, PlanetEntity,
|
||||
WormholeEntity, AI, Octree, OOMesh, OOScript;
|
||||
WormholeEntity, AI, Octree, OOMesh, OOScript, OORoleSet;
|
||||
|
||||
|
||||
#define MAX_TARGETS 24
|
||||
@ -192,7 +192,8 @@ MA 02110-1301, USA.
|
||||
AI *shipAI; // ship's AI system
|
||||
|
||||
NSString *name; // descriptive name
|
||||
NSString *roles; // names fo roles a ship can take, eg. trader, hunter, police, pirate, scavenger &c.
|
||||
OORoleSet *roleSet; // Roles a ship can take, eg. trader, hunter, police, pirate, scavenger &c.
|
||||
NSString *primaryRole; // "Main" role of the ship.
|
||||
|
||||
// AI stuff
|
||||
Vector jink; // x and y set factors for offsetting a pursuing ship's position
|
||||
@ -385,8 +386,23 @@ MA 02110-1301, USA.
|
||||
|
||||
- (NSString *) name;
|
||||
- (NSString *) identFromShip:(ShipEntity*) otherShip; // name displayed to other ships
|
||||
- (NSString *) roles;
|
||||
- (void) setRoles:(NSString *) value;
|
||||
|
||||
- (BOOL) hasRole:(NSString *)role;
|
||||
- (OORoleSet *)roleSet;
|
||||
|
||||
- (NSString *)primaryRole;
|
||||
- (void)setPrimaryRole:(NSString *)role;
|
||||
- (BOOL)hasPrimaryRole:(NSString *)role;
|
||||
|
||||
- (BOOL)isPolice; // Scan class is CLASS_POLICE
|
||||
- (BOOL)isThargoid; // Scan class is CLASS_THARGOID
|
||||
- (BOOL)isTrader; // Primary role is "trader" || isPlayer
|
||||
- (BOOL)isPirate; // Primary role is "pirate"
|
||||
- (BOOL)isMissile; // Primary role has suffix "MISSILE"
|
||||
- (BOOL)isMine; // Primary role has suffix "MINE"
|
||||
- (BOOL)isWeapon; // isMissile || isWeapon
|
||||
- (BOOL)isEscort; // Primary role is "escort" or "wingman"
|
||||
- (BOOL)isShuttle; // Primary role is "shuttle"
|
||||
|
||||
- (BOOL) hasHostileTarget;
|
||||
|
||||
@ -515,7 +531,7 @@ BOOL class_masslocks(int some_class);
|
||||
- (void) setPrimaryAggressor:(Entity *) targetEntity;
|
||||
- (void) addTarget:(Entity *) targetEntity;
|
||||
- (void) removeTarget:(Entity *) targetEntity;
|
||||
- (Entity *) primaryTarget;
|
||||
- (id) primaryTarget;
|
||||
- (int) primaryTargetID;
|
||||
|
||||
- (OOBehaviour) behaviour;
|
||||
@ -586,7 +602,7 @@ BOOL class_masslocks(int some_class);
|
||||
|
||||
- (void) setDestination:(Vector) dest;
|
||||
|
||||
inline BOOL pairOK(NSString* my_role, NSString* their_role);
|
||||
- (BOOL) canAcceptEscort:(ShipEntity *)potentialEscort;
|
||||
- (BOOL) acceptAsEscort:(ShipEntity *) other_ship;
|
||||
- (Vector) coordinatesForEscortPosition:(int) f_pos;
|
||||
- (void) deployEscorts;
|
||||
|
@ -35,6 +35,7 @@ MA 02110-1301, USA.
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "OOConstToString.h"
|
||||
#import "NSScannerOOExtensions.h"
|
||||
#import "OORoleSet.h"
|
||||
|
||||
#import "OOCharacter.h"
|
||||
#import "OOBrain.h"
|
||||
@ -267,8 +268,10 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
|
||||
[name autorelease];
|
||||
name = [[shipDict stringForKey:@"name" defaultValue:name] copy];
|
||||
|
||||
[roles release];
|
||||
roles = [[shipDict stringForKey:@"roles"] copy];
|
||||
[roleSet release];
|
||||
roleSet = [[OORoleSet alloc] initWithRoleString:[shipDict stringForKey:@"roles"]];
|
||||
[primaryRole release];
|
||||
primaryRole = nil;
|
||||
|
||||
[self setOwner:self];
|
||||
|
||||
@ -454,14 +457,15 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
|
||||
|
||||
if (isSubentity)
|
||||
{
|
||||
[(ShipEntity *)[self owner] subEntityReallyDied:self];
|
||||
[[self owner] subEntityReallyDied:self];
|
||||
}
|
||||
|
||||
[shipinfoDictionary release];
|
||||
[shipAI release];
|
||||
[cargo release];
|
||||
[name release];
|
||||
[roles release];
|
||||
[roleSet release];
|
||||
[primaryRole release];
|
||||
[sub_entities release];
|
||||
[laser_color release];
|
||||
[script release];
|
||||
@ -744,12 +748,8 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
|
||||
NSString *escortRole = @"escort";
|
||||
NSString *escortShipKey = nil;
|
||||
|
||||
// FIXME: should look for substring, or in more sensible role manager
|
||||
if ([roles isEqual:@"trader"])
|
||||
escortRole = @"escort";
|
||||
|
||||
if ([roles isEqual:@"police"])
|
||||
escortRole = @"wingman";
|
||||
// if ([self isTrader]) escortRole = @"escort";
|
||||
if ([self isPolice]) escortRole = @"wingman";
|
||||
|
||||
if ([shipinfoDictionary objectForKey:@"escort-role"])
|
||||
{
|
||||
@ -796,7 +796,7 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
|
||||
|
||||
[escorter setStatus:STATUS_IN_FLIGHT];
|
||||
|
||||
[escorter setRoles:escortRole];
|
||||
[escorter setPrimaryRole:escortRole];
|
||||
|
||||
[escorter setScanClass:scanClass]; // you are the same as I
|
||||
|
||||
@ -2867,17 +2867,123 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) roles
|
||||
- (BOOL) hasRole:(NSString *)role
|
||||
{
|
||||
return roles;
|
||||
return [roleSet hasRole:role] || [role isEqual:primaryRole];
|
||||
}
|
||||
|
||||
|
||||
- (void) setRoles:(NSString *) value
|
||||
- (OORoleSet *)roleSet
|
||||
{
|
||||
if (roleSet == nil) roleSet = [[OORoleSet alloc] initWithRoleString:primaryRole];
|
||||
return [roleSet roleSetWithAddedRoleIfNotSet:primaryRole probability:1.0];
|
||||
}
|
||||
|
||||
/*
|
||||
- (void) setRoles:(OORoleSet *)inRoles
|
||||
{
|
||||
if (inRoles != nil && ![inRoles isEqual:roles])
|
||||
{
|
||||
if (roles)
|
||||
[roles release];
|
||||
roles = value ? [value copy] : @"";
|
||||
roles = [inRoles copy];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) setRoleString:(NSString *)string
|
||||
{
|
||||
[self setRoles:[OORoleSet roleSetWithString:string]];
|
||||
}*/
|
||||
|
||||
|
||||
- (NSString *)primaryRole
|
||||
{
|
||||
if (primaryRole == nil)
|
||||
{
|
||||
primaryRole = [roleSet anyRole];
|
||||
if (primaryRole == nil) primaryRole = @"trader";
|
||||
[primaryRole retain];
|
||||
OOLog(@"ship.noPrimaryRole", @"%@ had no primary role, randomly selected \"%@\".", primaryRole);
|
||||
}
|
||||
|
||||
return primaryRole;
|
||||
}
|
||||
|
||||
|
||||
- (void)setPrimaryRole:(NSString *)role
|
||||
{
|
||||
if (![role isEqual:primaryRole])
|
||||
{
|
||||
[primaryRole release];
|
||||
primaryRole = [role copy];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)hasPrimaryRole:(NSString *)role
|
||||
{
|
||||
return [[self primaryRole] isEqual:role];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPolice
|
||||
{
|
||||
#if 0
|
||||
return [self hasPrimaryRole:@"police"] || [self hasPrimaryRole:@"interceptor"] || [self hasPrimaryRole:@"wingman"];
|
||||
#else
|
||||
return [self scanClass] == CLASS_POLICE;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)isThargoid
|
||||
{
|
||||
#if 0
|
||||
return [self hasPrimaryRole:@"thargoid"];
|
||||
#else
|
||||
return [self scanClass] == CLASS_THARGOID;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isTrader
|
||||
{
|
||||
return isPlayer || [self hasPrimaryRole:@"trader"];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPirate
|
||||
{
|
||||
return [self hasPrimaryRole:@"pirate"];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isMissile
|
||||
{
|
||||
return [[self primaryRole] hasSuffix:@"MISSILE"];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isMine
|
||||
{
|
||||
return [[self primaryRole] hasSuffix:@"MINE"];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isWeapon
|
||||
{
|
||||
return [self isMissile] || [self isMine];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isEscort
|
||||
{
|
||||
return [self hasPrimaryRole:@"escort"] || [self hasPrimaryRole:@"wingman"];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isShuttle
|
||||
{
|
||||
return [self hasPrimaryRole:@"shuttle"];
|
||||
}
|
||||
|
||||
|
||||
@ -3501,8 +3607,7 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
|
||||
[self doScriptEvent:@"didDie"];
|
||||
}
|
||||
|
||||
if ([roles isEqual:@"thargoid"])
|
||||
[self broadcastThargoidDestroyed];
|
||||
if ([self isThargoid]) [self broadcastThargoidDestroyed];
|
||||
|
||||
if (!suppressExplosion)
|
||||
{
|
||||
@ -3627,7 +3732,7 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
|
||||
|
||||
// Throw out rocks and alloys to be scooped up
|
||||
//
|
||||
if ([roles isEqual:@"asteroid"])
|
||||
if ([self hasPrimaryRole:@"asteroid"])
|
||||
{
|
||||
if ((being_mined)||(randf() < 0.20))
|
||||
{
|
||||
@ -3663,7 +3768,7 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
|
||||
return; // don't do anything more
|
||||
}
|
||||
|
||||
if ([roles isEqual:@"boulder"])
|
||||
if ([self hasPrimaryRole:@"boulder"])
|
||||
{
|
||||
if ((being_mined)||(ranrot_rand() % 100 < 20))
|
||||
{
|
||||
@ -4069,8 +4174,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
|
||||
- (void) collectBountyFor:(ShipEntity *)other
|
||||
{
|
||||
if ([roles isEqual:@"pirate"])
|
||||
bounty += [other bounty];
|
||||
if ([self isPirate]) bounty += [other bounty];
|
||||
}
|
||||
|
||||
|
||||
@ -4258,7 +4362,7 @@ BOOL class_masslocks(int some_class)
|
||||
}
|
||||
|
||||
|
||||
- (Entity *) primaryTarget
|
||||
- (id) primaryTarget
|
||||
{
|
||||
return [UNIVERSE entityForUniversalID:primaryTarget];
|
||||
}
|
||||
@ -6229,25 +6333,29 @@ BOOL class_masslocks(int some_class)
|
||||
}
|
||||
}
|
||||
|
||||
BOOL iAmTheLaw = (scanClass == CLASS_POLICE);
|
||||
BOOL uAreTheLaw = ((other)&&(other->scanClass == CLASS_POLICE));
|
||||
|
||||
energy -= amount;
|
||||
being_mined = NO;
|
||||
//
|
||||
ShipEntity *hunter = nil;
|
||||
|
||||
if ((other)&&(other->isShip))
|
||||
{
|
||||
ShipEntity* hunter = (ShipEntity *)other;
|
||||
if ([hunter isCloaked]) other = nil; // lose it!
|
||||
hunter = (ShipEntity *)other;
|
||||
if ([hunter isCloaked])
|
||||
{
|
||||
// lose it!
|
||||
other = nil;
|
||||
hunter = nil;
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
// if the other entity is a ship note it as an aggressor
|
||||
if ((other)&&(other->isShip))
|
||||
if (hunter != nil)
|
||||
{
|
||||
ShipEntity* hunter = (ShipEntity *)other;
|
||||
//
|
||||
BOOL iAmTheLaw = [self isPolice];
|
||||
BOOL uAreTheLaw = [hunter isPolice];
|
||||
|
||||
last_escort_target = NO_TARGET; // we're being attacked, escorts can scramble!
|
||||
//
|
||||
|
||||
primaryAggressor = [hunter universalID];
|
||||
found_target = primaryAggressor;
|
||||
|
||||
@ -6264,7 +6372,7 @@ BOOL class_masslocks(int some_class)
|
||||
// tell our group we've been attacked
|
||||
if (groupID != NO_TARGET)
|
||||
{
|
||||
if ([roles isEqual:@"escort"]||[roles isEqual:@"trader"])
|
||||
if ([self isTrader]|| [self isEscort])
|
||||
{
|
||||
ShipEntity *group_leader = [UNIVERSE entityForUniversalID:groupID];
|
||||
if ((group_leader)&&(group_leader->isShip))
|
||||
@ -6276,7 +6384,7 @@ BOOL class_masslocks(int some_class)
|
||||
else
|
||||
groupID = NO_TARGET;
|
||||
}
|
||||
if ([roles isEqual:@"pirate"])
|
||||
if ([self isPirate])
|
||||
{
|
||||
NSArray *fellow_pirates = [self shipsInGroup:groupID];
|
||||
for (i = 0; i < [fellow_pirates count]; i++)
|
||||
@ -6323,13 +6431,12 @@ BOOL class_masslocks(int some_class)
|
||||
// die if I'm out of energy
|
||||
if (energy <= 0.0)
|
||||
{
|
||||
if ((other)&&(other->isShip))
|
||||
if (hunter != nil)
|
||||
{
|
||||
ShipEntity* hunter = (ShipEntity *)other;
|
||||
[hunter collectBountyFor:self];
|
||||
if ([hunter primaryTarget] == (Entity *)self)
|
||||
if ([hunter primaryTarget] == self)
|
||||
{
|
||||
[hunter removeTarget:(Entity *)self];
|
||||
[hunter removeTarget:self];
|
||||
[[hunter getAI] message:@"TARGET_DESTROYED"];
|
||||
}
|
||||
}
|
||||
@ -6465,7 +6572,7 @@ BOOL class_masslocks(int some_class)
|
||||
/* Add a new ship to maintain quantities of standard ships, unless
|
||||
there's a nova in the works (or the AI asked us not to).
|
||||
*/
|
||||
[UNIVERSE witchspaceShipWithRole:roles];
|
||||
[UNIVERSE witchspaceShipWithPrimaryRole:[self primaryRole]];
|
||||
}
|
||||
|
||||
[w_hole suckInShip: self]; // removes ship from universe
|
||||
@ -6486,7 +6593,7 @@ BOOL class_masslocks(int some_class)
|
||||
[shipAI message:@"ENTERED_WITCHSPACE"];
|
||||
|
||||
if (![[UNIVERSE sun] willGoNova]) // if the sun's not going nova
|
||||
[UNIVERSE witchspaceShipWithRole:roles]; // then add a new ship like this one leaving!
|
||||
[UNIVERSE witchspaceShipWithPrimaryRole:[self primaryRole]]; // then add a new ship like this one leaving!
|
||||
|
||||
[UNIVERSE removeEntity:self];
|
||||
}
|
||||
@ -6575,14 +6682,19 @@ int w_space_seed = 1234567;
|
||||
frustration = 0.0; // new destination => no frustration!
|
||||
}
|
||||
|
||||
inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
|
||||
- (BOOL) canAcceptEscort:(ShipEntity *)potentialEscort
|
||||
{
|
||||
BOOL pairing_okay = NO;
|
||||
if (![self isEscort])
|
||||
{
|
||||
return [potentialEscort hasRole:@"escort"];
|
||||
}
|
||||
if (([self hasRole:@"police"] || [self hasRole:@"interceptor"]))
|
||||
{
|
||||
return [potentialEscort hasRole:@"wingman"];
|
||||
}
|
||||
|
||||
pairing_okay |= (![my_role isEqual:@"escort"] && ![my_role isEqual:@"wingman"] && [their_role isEqual:@"escort"]);
|
||||
pairing_okay |= (([my_role isEqual:@"police"]||[my_role isEqual:@"interceptor"]) && [their_role isEqual:@"wingman"]);
|
||||
|
||||
return pairing_okay;
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@ -6595,7 +6707,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
if ([shipAI ai_stack_depth] > 1)
|
||||
return NO;
|
||||
|
||||
if (pairOK(roles, [other_ship roles]))
|
||||
if ([self canAcceptEscort:other_ship])
|
||||
{
|
||||
unsigned i;
|
||||
// check it's not already been accepted
|
||||
@ -6864,7 +6976,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
{
|
||||
ShipEntity* ship = (ShipEntity *)my_entities[i];
|
||||
d2 = distance2(position, ship->position);
|
||||
if ((d2 < found_d2)&&([[ship roles] isEqual:@"tharglet"]))
|
||||
if ((d2 < found_d2)&&([ship hasPrimaryRole:@"tharglet"]))
|
||||
[[ship getAI] message:@"THARGOID_DESTROYED"];
|
||||
}
|
||||
for (i = 0; i < ship_count; i++)
|
||||
@ -7045,7 +7157,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
|
||||
- (void) setNumberOfMinedRocks:(int) value
|
||||
{
|
||||
if (![roles isEqual:@"asteroid"])
|
||||
if (![self hasPrimaryRole:@"asteroid"])
|
||||
return;
|
||||
likely_cargo = value;
|
||||
}
|
||||
@ -7170,7 +7282,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
{
|
||||
// Create a bouy and beacon where the hulk is.
|
||||
// Get the main GalCop station to launch a pilot boat to deliver a pilot to the hulk.
|
||||
NSLog(@"claimAsSalvage called on %@ %@", [self name], [self roles]);
|
||||
NSLog(@"claimAsSalvage called on %@ %@", [self name], [self roleSet]);
|
||||
/*
|
||||
// Won't work in interstellar space because there is no GalCop station
|
||||
if ([[self planet_number] intValue] < 0)
|
||||
@ -7211,7 +7323,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
|
||||
n_scanned_ships = 0;
|
||||
scan = z_previous;
|
||||
NSLog(@"searching for pilot boat");
|
||||
OOLog(@"ship.pilotage", @"searching for pilot boat");
|
||||
while (scan &&(scan->isShip == NO))
|
||||
scan = scan->z_previous; // skip non-ships
|
||||
|
||||
@ -7221,14 +7333,14 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
if (scan->isShip)
|
||||
{
|
||||
scanShip = (ShipEntity *)scan;
|
||||
NSArray *scanRoles = ScanTokensFromString([scanShip roles]);
|
||||
|
||||
if ([scanRoles containsObject:@"pilot"] == YES)
|
||||
if ([self hasRole:@"pilot"] == YES)
|
||||
{
|
||||
if ([scanShip primaryTargetID] == NO_TARGET)
|
||||
{
|
||||
NSLog(@"found pilot boat with no target, will use this one");
|
||||
OOLog(@"ship.pilotage", @"found pilot boat with no target, will use this one");
|
||||
pilot = scanShip;
|
||||
[pilot setPrimaryRole:@"pilot"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -7240,7 +7352,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
|
||||
if (pilot != nil)
|
||||
{
|
||||
NSLog(@"becoming pilot target and setting AI");
|
||||
OOLog(@"ship.pilotage", @"becoming pilot target and setting AI");
|
||||
[pilot setReportAIMessages:YES];
|
||||
[pilot addTarget:self];
|
||||
[pilot setStateMachine:@"pilotAI.plist"];
|
||||
@ -7263,7 +7375,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
[super dumpSelfState];
|
||||
|
||||
OOLog(@"dumpState.shipEntity", @"Name: %@", name);
|
||||
OOLog(@"dumpState.shipEntity", @"Roles: %@", roles);
|
||||
OOLog(@"dumpState.shipEntity", @"Roles: %@", roleSet);
|
||||
OOLog(@"dumpState.shipEntity", @"Script: %@", script);
|
||||
if (sub_entities != nil) OOLog(@"dumpState.shipEntity", @"Subentity count: %u", [sub_entities count]);
|
||||
OOLog(@"dumpState.shipEntity", @"Behaviour: %@", BehaviourToString(behaviour));
|
||||
|
@ -172,10 +172,10 @@ MA 02110-1301, USA.
|
||||
for (i = 0; i < n_scanned_ships ; i++)
|
||||
{
|
||||
ShipEntity *ship = scanned_ships[i];
|
||||
if ((([[ship roles] isEqual:@"trader"])||(ship->isPlayer))&&(ship->status != STATUS_DEAD)&&(ship->status != STATUS_DOCKED))
|
||||
if ([ship isTrader] && (ship->status != STATUS_DEAD) && (ship->status != STATUS_DOCKED))
|
||||
{
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if (([roles isEqual:@"pirate"])&&(d2 < desired_range * desired_range)&&(ship->isPlayer)&&(PIRATES_PREFER_PLAYER))
|
||||
if (PIRATES_PREFER_PLAYER && ship->isPlayer && [self isPirate] && (d2 < desired_range * desired_range))
|
||||
d2 = 0.0;
|
||||
if (d2 < found_d2)
|
||||
{
|
||||
@ -203,7 +203,7 @@ MA 02110-1301, USA.
|
||||
for (i = 0; i < n_scanned_ships ; i++)
|
||||
{
|
||||
ShipEntity *ship = scanned_ships[i];
|
||||
if ((([[ship roles] isEqual:@"trader"])||(ship->isPlayer))&&(ship->status != STATUS_DEAD)&&(ship->status != STATUS_DOCKED))
|
||||
if ([ship isTrader] && (ship->status != STATUS_DEAD) && (ship->status != STATUS_DOCKED))
|
||||
ids_found[n_found++] = ship->universalID;
|
||||
}
|
||||
if (n_found == 0)
|
||||
@ -244,10 +244,8 @@ MA 02110-1301, USA.
|
||||
}
|
||||
}
|
||||
|
||||
BOOL isPolice = (scanClass == CLASS_POLICE);
|
||||
//
|
||||
[self checkScanner];
|
||||
//
|
||||
|
||||
double found_d2 = scannerRange * scannerRange;
|
||||
found_target = NO_TARGET;
|
||||
unsigned i;
|
||||
@ -256,7 +254,7 @@ MA 02110-1301, USA.
|
||||
ShipEntity *other = (ShipEntity *)scanned_ships[i];
|
||||
if ((other->scanClass == CLASS_CARGO)&&([other cargoType] != CARGO_NOT_CARGO))
|
||||
{
|
||||
if ((!isPolice) || ([other commodityType] == 3)) // police only rescue lifepods and slaves
|
||||
if ((![self isPolice]) || ([other commodityType] == 3)) // police only rescue lifepods and slaves
|
||||
{
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if (d2 < found_d2)
|
||||
@ -457,12 +455,12 @@ MA 02110-1301, USA.
|
||||
if (has_ecm)
|
||||
{
|
||||
// use the ECM and battle on
|
||||
ShipEntity* hunter = (ShipEntity*)[missile owner];
|
||||
ShipEntity *hunter = [missile owner];
|
||||
|
||||
[self setPrimaryAggressor:hunter]; // lets get them now for that!
|
||||
found_target = primaryAggressor;
|
||||
|
||||
if ([roles isEqual:@"police"]||[roles isEqual:@"interceptor"]||[roles isEqual:@"wingman"])
|
||||
if ([self isPolice])
|
||||
{
|
||||
NSArray *fellow_police = [self shipsInGroup:groupID];
|
||||
unsigned i;
|
||||
@ -475,17 +473,13 @@ MA 02110-1301, USA.
|
||||
}
|
||||
|
||||
// if I'm a copper and you're not, then mark the other as an offender!
|
||||
BOOL iAmTheLaw = ([roles isEqual:@"police"]||[roles isEqual:@"wingman"]||[roles isEqual:@"interceptor"]);
|
||||
BOOL uAreTheLaw = ([[hunter roles] isEqual:@"police"]||[[hunter roles] isEqual:@"wingman"]||[[hunter roles] isEqual:@"interceptor"]);
|
||||
if ((iAmTheLaw)&&(!uAreTheLaw))
|
||||
[hunter markAsOffender:64];
|
||||
if ([self isPolice] && ![hunter isPolice]) [hunter markAsOffender:64];
|
||||
|
||||
[self fireECM];
|
||||
return;
|
||||
}
|
||||
|
||||
// RUN AWAY !!
|
||||
//
|
||||
jink.x = 0.0;
|
||||
jink.y = 0.0;
|
||||
jink.z = 1000.0;
|
||||
@ -921,9 +915,9 @@ WormholeEntity* whole;
|
||||
}
|
||||
if (ship->isStation)
|
||||
[ship acceptDistressMessageFrom:self];
|
||||
if ([[ship roles] isEqual:@"police"])
|
||||
if ([ship hasPrimaryRole:@"police"]) // Not isPolice because we don't want wingmen shooting off... but what about interceptors?
|
||||
[ship acceptDistressMessageFrom:self];
|
||||
if ([[ship roles] isEqual:@"hunter"])
|
||||
if ([ship hasPrimaryRole:@"hunter"])
|
||||
[ship acceptDistressMessageFrom:self];
|
||||
}
|
||||
}
|
||||
@ -946,7 +940,7 @@ WormholeEntity* whole;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((scanClass == CLASS_POLICE)||[roles isEqual:@"police"]||[roles isEqual:@"interceptor"]||[roles isEqual:@"wingman"])
|
||||
if ([self isPolice])
|
||||
[[UNIVERSE entityForUniversalID:found_target] markAsOffender:8]; // you have been warned!!
|
||||
[shipAI reactToMessage:@"ACCEPT_DISTRESS_CALL"];
|
||||
break;
|
||||
@ -985,13 +979,13 @@ WormholeEntity* whole;
|
||||
/*-- Locates all the thargoid warships in range and chooses the nearest --*/
|
||||
[self checkScanner];
|
||||
unsigned i;
|
||||
//
|
||||
|
||||
GLfloat found_d2 = scannerRange * scannerRange;
|
||||
found_target = NO_TARGET;
|
||||
for (i = 0; i < n_scanned_ships; i++)
|
||||
{
|
||||
ShipEntity *ship = scanned_ships[i];
|
||||
if ([[ship roles] isEqual:@"thargoid"])
|
||||
if ([ship isThargoid])
|
||||
{
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if (d2< found_d2)
|
||||
@ -1001,10 +995,8 @@ WormholeEntity* whole;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_target != NO_TARGET)
|
||||
[shipAI message:@"TARGET_FOUND"];
|
||||
else
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
|
||||
else [shipAI message:@"NOTHING_FOUND"];
|
||||
}
|
||||
|
||||
|
||||
@ -1020,17 +1012,15 @@ WormholeEntity* whole;
|
||||
{
|
||||
ShipEntity *thing = scanned_ships[i];
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if ((thing->scanClass != CLASS_CARGO)&&(thing->status != STATUS_DOCKED)&&(![[thing roles] hasPrefix:@"tharg"])&&(d2 < found_d2))
|
||||
if ((thing->scanClass != CLASS_CARGO) && (thing->status != STATUS_DOCKED) && ![thing isThargoid] && (d2 < found_d2))
|
||||
{
|
||||
found_target = [thing universalID];
|
||||
if (thing->isPlayer) d2 = 0.0; // prefer the player
|
||||
found_d2 = d2;
|
||||
}
|
||||
}
|
||||
if (found_target != NO_TARGET)
|
||||
[shipAI message:@"TARGET_FOUND"];
|
||||
else
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
|
||||
else [shipAI message:@"NOTHING_FOUND"];
|
||||
}
|
||||
|
||||
|
||||
@ -1085,7 +1075,7 @@ WormholeEntity* whole;
|
||||
{
|
||||
ShipEntity *thing = scanned_ships[i];
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if (((thing->scanClass == CLASS_THARGOID)||(([thing primaryTarget] == self)&&([thing hasHostileTarget])))&&(d2 < found_d2))
|
||||
if ((d2 < found_d2) && ([thing isThargoid] || (([thing primaryTarget] == self) && [thing hasHostileTarget])))
|
||||
{
|
||||
found_target = [thing universalID];
|
||||
found_d2 = d2;
|
||||
@ -1262,22 +1252,23 @@ WormholeEntity* whole;
|
||||
if ((ship != self) && (!ship->isPlayer) && (ship->scanClass == scanClass)) // look for alike
|
||||
{
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if ((d2 < found_d2)&&(pairOK([ship roles], roles)))
|
||||
if ((d2 < found_d2) && [ship canAcceptEscort:self])
|
||||
{
|
||||
found_d2 = d2;
|
||||
found_target = ship->universalID;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_target != NO_TARGET)
|
||||
[shipAI message:@"TARGET_FOUND"];
|
||||
|
||||
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
|
||||
else
|
||||
{
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
if ([roles isEqual:@"wingman"])
|
||||
if ([self hasPrimaryRole:@"wingman"])
|
||||
{
|
||||
// become free-lance police :)
|
||||
[shipAI setStateMachine:@"route1patrolAI.plist"]; // use this to avoid referencing a released AI
|
||||
[self setPrimaryRole:@"police"];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1404,13 +1395,12 @@ WormholeEntity* whole;
|
||||
|
||||
- (void) checkForMotherStation
|
||||
{
|
||||
Entity* my_owner = [self owner];
|
||||
if ((!my_owner) || (!(my_owner->isStation)))
|
||||
StationEntity *motherStation = [self owner];
|
||||
if ((!motherStation) || (!(motherStation->isStation)))
|
||||
{
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
return;
|
||||
}
|
||||
StationEntity* motherStation = (StationEntity*)[self owner];
|
||||
Vector v0 = motherStation->position;
|
||||
Vector rpos = make_vector(position.x - v0.x, position.y - v0.y, position.z - v0.z);
|
||||
double found_d2 = scannerRange * scannerRange;
|
||||
@ -1425,28 +1415,27 @@ WormholeEntity* whole;
|
||||
|
||||
- (void) sendTargetCommsMessage:(NSString*) message
|
||||
{
|
||||
ShipEntity* ship = (ShipEntity*)[self primaryTarget];
|
||||
if ((!ship)||(ship->status == STATUS_DEAD)||(ship->status == STATUS_DOCKED))
|
||||
ShipEntity *ship = [self primaryTarget];
|
||||
if ((ship == nil) || (ship->status == STATUS_DEAD) || (ship->status == STATUS_DOCKED))
|
||||
{
|
||||
primaryTarget = NO_TARGET;
|
||||
[shipAI reactToMessage:@"TARGET_LOST"];
|
||||
return;
|
||||
}
|
||||
[self sendExpandedMessage:message toShip:(ShipEntity*)[self primaryTarget]];
|
||||
[self sendExpandedMessage:message toShip:[self primaryTarget]];
|
||||
}
|
||||
|
||||
|
||||
- (void) markTargetForFines
|
||||
{
|
||||
ShipEntity* ship = (ShipEntity*)[self primaryTarget];
|
||||
if ((!ship)||(ship->status == STATUS_DEAD)||(ship->status == STATUS_DOCKED))
|
||||
ShipEntity *ship = [self primaryTarget];
|
||||
if ((ship == nil) || (ship->status == STATUS_DEAD) || (ship->status == STATUS_DOCKED))
|
||||
{
|
||||
primaryTarget = NO_TARGET;
|
||||
[shipAI reactToMessage:@"TARGET_LOST"];
|
||||
return;
|
||||
}
|
||||
if ([(ShipEntity*)[self primaryTarget] markForFines])
|
||||
[shipAI message:@"TARGET_MARKED"];
|
||||
if ([ship markForFines]) [shipAI message:@"TARGET_MARKED"];
|
||||
}
|
||||
|
||||
|
||||
@ -1454,8 +1443,8 @@ WormholeEntity* whole;
|
||||
{
|
||||
if ((isStation)||(scanClass == CLASS_POLICE))
|
||||
{
|
||||
ShipEntity* ship = (ShipEntity*)[self primaryTarget];
|
||||
if ((!ship)||(ship->status == STATUS_DEAD)||(ship->status == STATUS_DOCKED))
|
||||
ShipEntity *ship = [self primaryTarget];
|
||||
if ((ship == nil) || (ship->status == STATUS_DEAD) || (ship->status == STATUS_DOCKED))
|
||||
{
|
||||
primaryTarget = NO_TARGET;
|
||||
[shipAI reactToMessage:@"TARGET_LOST"];
|
||||
@ -1480,7 +1469,7 @@ WormholeEntity* whole;
|
||||
for (i = 0; i < n_scanned_ships; i++)
|
||||
{
|
||||
ShipEntity *thing = scanned_ships[i];
|
||||
if ([[thing roles] rangeOfString:@"boulder"].location != NSNotFound)
|
||||
if ([thing hasRole:@"boulder"])
|
||||
{
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if (d2 < found_d2)
|
||||
@ -1495,7 +1484,7 @@ WormholeEntity* whole;
|
||||
for (i = 0; i < n_scanned_ships; i++)
|
||||
{
|
||||
ShipEntity *thing = scanned_ships[i];
|
||||
if ([[thing roles] rangeOfString:@"asteroid"].location != NSNotFound)
|
||||
if ([thing hasRole:@"boulder"])
|
||||
{
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if (d2 < found_d2)
|
||||
@ -1507,10 +1496,8 @@ WormholeEntity* whole;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_target != NO_TARGET)
|
||||
[shipAI message:@"TARGET_FOUND"];
|
||||
else
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
|
||||
else [shipAI message:@"NOTHING_FOUND"];
|
||||
}
|
||||
|
||||
|
||||
@ -1529,10 +1516,8 @@ WormholeEntity* whole;
|
||||
Vector d0 = (the_target) ? the_target->position : kZeroVector;
|
||||
v0.x += (randf() - 0.5)*collision_radius; v0.y += (randf() - 0.5)*collision_radius; v0.z += (randf() - 0.5)*collision_radius;
|
||||
v0.x -= d0.x; v0.y -= d0.y; v0.z -= d0.z;
|
||||
if (v0.x||v0.y||v0.z)
|
||||
v0 = unit_vector(&v0);
|
||||
else
|
||||
v0.z = -1.0;
|
||||
v0 = vector_normal_or_fallback(v0, make_vector(0, 0, -1));
|
||||
|
||||
v0.x *= bo_distance; v0.y *= bo_distance; v0.z *= bo_distance;
|
||||
v0.x += d0.x; v0.y += d0.y; v0.z += d0.z;
|
||||
coordinates = v0;
|
||||
@ -1542,9 +1527,7 @@ WormholeEntity* whole;
|
||||
|
||||
- (void) requestNewTarget
|
||||
{
|
||||
ShipEntity* mother = nil;
|
||||
if ([self owner])
|
||||
mother = (ShipEntity*)[self owner];
|
||||
ShipEntity *mother = [self owner];
|
||||
if ((mother == nil)&&([UNIVERSE entityForUniversalID:groupID]))
|
||||
mother = [UNIVERSE entityForUniversalID:groupID];
|
||||
if (!mother)
|
||||
@ -1565,7 +1548,7 @@ WormholeEntity* whole;
|
||||
ShipEntity *thing = scanned_ships[i];
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
GLfloat e1 = [thing energy];
|
||||
if (((thing->scanClass == CLASS_THARGOID)||(([thing primaryTarget] == mother)&&([thing hasHostileTarget])))&&(d2 < found_d2))
|
||||
if ((d2 < found_d2) && ([thing isThargoid] || (([thing primaryTarget] == mother) && [thing hasHostileTarget])))
|
||||
{
|
||||
if (e1 > max_e)
|
||||
{
|
||||
@ -1576,10 +1559,8 @@ WormholeEntity* whole;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_target != NO_TARGET)
|
||||
[shipAI message:@"TARGET_FOUND"];
|
||||
else
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
|
||||
else [shipAI message:@"NOTHING_FOUND"];
|
||||
}
|
||||
|
||||
|
||||
@ -1610,7 +1591,7 @@ WormholeEntity* whole;
|
||||
{
|
||||
ShipEntity *thing = scanned_ships[i];
|
||||
GLfloat d2 = distance2_scanned_ships[i];
|
||||
if ((thing->scanClass != CLASS_CARGO)&&(thing->status != STATUS_DOCKED)&&([[thing roles] isEqual:scanRole])&&(d2 < found_d2))
|
||||
if ((d2 < found_d2) && (thing->scanClass != CLASS_CARGO) && (thing->status != STATUS_DOCKED) && ([thing hasPrimaryRole:scanRole]))
|
||||
{
|
||||
found_target = thing->universalID;
|
||||
found_d2 = d2;
|
||||
@ -1873,7 +1854,7 @@ WormholeEntity* whole;
|
||||
{
|
||||
// two point - one at z - cr one at z + cr
|
||||
ShipEntity *ship = [UNIVERSE entityForUniversalID:primaryTarget];
|
||||
if (!ship)
|
||||
if (ship == nil)
|
||||
{
|
||||
[shipAI message:@"NOTHING_FOUND"];
|
||||
return;
|
||||
|
@ -145,7 +145,7 @@ typedef enum
|
||||
|
||||
- (void) addShipToLaunchQueue:(ShipEntity *) ship;
|
||||
|
||||
- (unsigned) countShipsInLaunchQueueWithRole:(NSString *) a_role;
|
||||
- (unsigned) countShipsInLaunchQueueWithPrimaryRole:(NSString *)role;
|
||||
|
||||
- (void) launchShip:(ShipEntity *) ship;
|
||||
|
||||
|
@ -525,8 +525,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
int corridor_count = 9;
|
||||
int corridor_final_approach = 3;
|
||||
|
||||
int ship_id = [ship universalID];
|
||||
NSString* shipID = [NSString stringWithFormat:@"%d", ship_id];
|
||||
NSNumber *shipID = [NSNumber numberWithUnsignedShort:[ship universalID]];
|
||||
|
||||
Vector launchVector = vector_forward_from_quaternion(quaternion_multiply(port_orientation, orientation));
|
||||
Vector temp = (fabsf(launchVector.x) < 0.8)? make_vector(1,0,0) : make_vector(0,1,0);
|
||||
@ -534,9 +533,8 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
Vector rightVector = cross_product(launchVector, temp);
|
||||
Vector upVector = cross_product(launchVector, rightVector);
|
||||
|
||||
// will select a direction for offset based on the shipID
|
||||
//
|
||||
int offset_id = ship_id & 0xf; // 16 point compass
|
||||
// will select a direction for offset based on the entity personality (was ship ID)
|
||||
int offset_id = [ship entityPersonalityInt] & 0xf; // 16 point compass
|
||||
double c = cos(offset_id * M_PI * ONE_EIGHTH);
|
||||
double s = sin(offset_id * M_PI * ONE_EIGHTH);
|
||||
|
||||
@ -1109,15 +1107,14 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
}
|
||||
|
||||
|
||||
- (unsigned) countShipsInLaunchQueueWithRole:(NSString *) a_role
|
||||
- (unsigned) countShipsInLaunchQueueWithPrimaryRole:(NSString *)role
|
||||
{
|
||||
if ([launchQueue count] == 0)
|
||||
return 0;
|
||||
unsigned i;
|
||||
unsigned result = 0;
|
||||
unsigned i, count, result = 0;
|
||||
count = [launchQueue count];
|
||||
|
||||
for (i = 0; i < [launchQueue count]; i++)
|
||||
{
|
||||
if ([[(ShipEntity *)[launchQueue objectAtIndex:i] roles] isEqual:a_role])
|
||||
if ([[launchQueue objectAtIndex:i] hasPrimaryRole:role])
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
@ -1167,26 +1164,25 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
|
||||
// set last launch time to avoid clashes with outgoing ships
|
||||
last_launch_time = [UNIVERSE getTime];
|
||||
if ([[ship roles] isEqual:@"shuttle"])
|
||||
docked_shuttles++;
|
||||
if ([[ship roles] isEqual:@"trader"])
|
||||
docked_traders++;
|
||||
if ([[ship roles] isEqual:@"police"])
|
||||
police_launched--;
|
||||
if ([[ship roles] isEqual:@"hermit-ship"])
|
||||
police_launched--;
|
||||
if ([[ship roles] isEqual:@"defense_ship"])
|
||||
police_launched--;
|
||||
if ([[ship roles] isEqual:@"scavenger"]||[[ship roles] isEqual:@"miner"]) // treat miners and scavengers alike!
|
||||
scavengers_launched--;
|
||||
if ([ship isShuttle]) docked_shuttles++;
|
||||
else if ([ship isTrader] && ![ship isPlayer]) docked_traders++;
|
||||
else if (([ship isPolice] && ![ship isEscort]) || [ship hasPrimaryRole:@"hermit-ship"] || [ship hasPrimaryRole:@"defense_ship"])
|
||||
{
|
||||
if (0 < police_launched) police_launched--;
|
||||
}
|
||||
else if ([ship hasPrimaryRole:@"scavenger"] || [ship hasPrimaryRole:@"miner"]) // treat miners and scavengers alike!
|
||||
{
|
||||
if (0 < scavengers_launched) scavengers_launched--;
|
||||
}
|
||||
|
||||
OOUniversalID ship_id = [ship universalID];
|
||||
NSNumber *shipID = [NSNumber numberWithUnsignedShort:ship_id];
|
||||
|
||||
int ship_id = [ship universalID];
|
||||
NSString* shipID = [NSString stringWithFormat:@"%d", ship_id];
|
||||
[shipsOnApproach removeObjectForKey:shipID];
|
||||
if ([shipsOnApproach count] == 0)
|
||||
[shipAI message:@"DOCKING_COMPLETE"];
|
||||
|
||||
int i; // clear any previously owned docking stages
|
||||
unsigned i; // clear any previously owned docking stages
|
||||
for (i = 0; i < MAX_DOCKING_STAGES; i++)
|
||||
if ((id_lock[i] == ship_id)||([UNIVERSE entityForUniversalID:id_lock[i]] == nil))
|
||||
id_lock[i] = NO_TARGET;
|
||||
@ -1346,7 +1342,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
[OOCharacter randomCharacterWithRole: @"police"
|
||||
andOriginalSystem: [UNIVERSE systemSeed]]]];
|
||||
|
||||
[police_ship setRoles:@"police"];
|
||||
[police_ship setPrimaryRole:@"police"];
|
||||
[police_ship addTarget:[UNIVERSE entityForUniversalID:police_target]];
|
||||
[police_ship setScanClass: CLASS_POLICE];
|
||||
[police_ship setBounty:0];
|
||||
@ -1399,7 +1395,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
if (!defense_ship)
|
||||
return;
|
||||
|
||||
[defense_ship setRoles:@"defense_ship"];
|
||||
[defense_ship setPrimaryRole:@"defense_ship"];
|
||||
|
||||
police_launched++;
|
||||
|
||||
@ -1429,7 +1425,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
{
|
||||
ShipEntity *scavenger_ship;
|
||||
|
||||
unsigned scavs = [UNIVERSE countShipsWithRole:@"scavenger" inRange:SCANNER_MAX_RANGE ofEntity:self] + [self countShipsInLaunchQueueWithRole:@"scavenger"];
|
||||
unsigned scavs = [UNIVERSE countShipsWithRole:@"scavenger" inRange:SCANNER_MAX_RANGE ofEntity:self] + [self countShipsInLaunchQueueWithPrimaryRole:@"scavenger"];
|
||||
|
||||
if (scavs >= max_scavengers) return;
|
||||
if (scavengers_launched >= max_scavengers) return;
|
||||
@ -1457,7 +1453,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
{
|
||||
ShipEntity *miner_ship;
|
||||
|
||||
int n_miners = [UNIVERSE countShipsWithRole:@"miner" inRange:SCANNER_MAX_RANGE ofEntity:self] + [self countShipsInLaunchQueueWithRole:@"miner"];
|
||||
int n_miners = [UNIVERSE countShipsWithRole:@"miner" inRange:SCANNER_MAX_RANGE ofEntity:self] + [self countShipsInLaunchQueueWithPrimaryRole:@"miner"];
|
||||
|
||||
if (n_miners >= 1) // just the one
|
||||
return;
|
||||
@ -1565,7 +1561,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
[OOCharacter randomCharacterWithRole: @"trader"
|
||||
andOriginalSystem: [UNIVERSE systemSeed]]]];
|
||||
|
||||
[trader_ship setRoles:@"trader"];
|
||||
[trader_ship setPrimaryRole:@"trader"];
|
||||
[trader_ship setScanClass: CLASS_NEUTRAL];
|
||||
[trader_ship setCargoFlag:CARGO_FLAG_FULL_PLENTIFUL];
|
||||
|
||||
@ -1641,7 +1637,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
|
||||
[patrol_ship switchLightsOff];
|
||||
[patrol_ship setScanClass: CLASS_POLICE];
|
||||
[patrol_ship setRoles:@"police"];
|
||||
[patrol_ship setPrimaryRole:@"police"];
|
||||
[patrol_ship setBounty:0];
|
||||
[patrol_ship setGroupID:universalID]; // who's your Daddy
|
||||
[[patrol_ship getAI] setStateMachine:@"planetPatrolAI.plist"];
|
||||
@ -1664,7 +1660,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
[ship setCrew:[NSArray arrayWithObject:
|
||||
[OOCharacter randomCharacterWithRole: role
|
||||
andOriginalSystem: [UNIVERSE systemSeed]]]];
|
||||
[ship setRoles: role];
|
||||
[ship setPrimaryRole:role];
|
||||
[ship setGroupID:universalID]; // who's your Daddy
|
||||
[self addShipToLaunchQueue:ship];
|
||||
[ship release];
|
||||
@ -1687,8 +1683,8 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
|
||||
if (scanClass == CLASS_ROCK) // ie we're a rock hermit or similar
|
||||
{
|
||||
// set the roles so that we break up into rocks!
|
||||
roles = @"asteroid";
|
||||
// set the role so that we break up into rocks!
|
||||
[self setPrimaryRole:@"asteroid"];
|
||||
being_mined = YES;
|
||||
}
|
||||
|
||||
@ -1780,7 +1776,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
|
||||
if (gDebugFlags & DEBUG_ENTITIES)
|
||||
{
|
||||
NSString* result = [[NSString alloc] initWithFormat:@"<StationEntity %@ %d (%@)%@%@ // %@>",
|
||||
name, universalID, roles, (UNIVERSE == nil)? @" (not in UNIVERSE)":@"", ([self isRotatingStation])? @" (rotating)":@"", collisionRegion];
|
||||
name, universalID, roleSet, (UNIVERSE == nil)? @" (not in UNIVERSE)":@"", ([self isRotatingStation])? @" (rotating)":@"", collisionRegion];
|
||||
return [result autorelease];
|
||||
}
|
||||
#endif
|
||||
|
@ -1294,7 +1294,8 @@ static BOOL hostiles;
|
||||
{
|
||||
if ([player missileForStation:i])
|
||||
{
|
||||
NSString *miss_roles = [[player missileForStation:i] roles];
|
||||
// TODO: copy icon data into missile object instead of looking it up each time. Possibly make weapon stores a ShipEntity subclass?
|
||||
NSString *miss_roles = [[player missileForStation:i] primaryRole];
|
||||
NSArray *miss_icon = [[UNIVERSE descriptions] arrayForKey:miss_roles];
|
||||
if (i == [player activeMissile])
|
||||
{
|
||||
|
@ -58,6 +58,7 @@ SOFTWARE.
|
||||
NSString *_roleString;
|
||||
NSDictionary *_rolesAndProbabilities;
|
||||
NSSet *_roles;
|
||||
float _totalProb;
|
||||
}
|
||||
|
||||
+ (id)roleSetWithString:(NSString *)roleString;
|
||||
@ -75,8 +76,12 @@ SOFTWARE.
|
||||
- (NSArray *)sortedRoles;
|
||||
- (NSDictionary *)rolesAndProbabilities;
|
||||
|
||||
// Returns a random role, taking probabilities into account.
|
||||
- (NSString *)anyRole;
|
||||
|
||||
// Creating modified copies of role sets:
|
||||
- (id)roleSetWithAddedRole:(NSString *)role probability:(float)probability;
|
||||
- (id)roleSetWithAddedRoleIfNotSet:(NSString *)role probability:(float)probability; // Unlike the above, does not change probability if role exists.
|
||||
- (id)roleSetWithRemovedRole:(NSString *)role;
|
||||
|
||||
@end
|
||||
|
@ -49,6 +49,8 @@ SOFTWARE.
|
||||
#import "OORoleSet.h"
|
||||
|
||||
#import "OOStringParsing.h"
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "OOLogging.h"
|
||||
|
||||
|
||||
@interface OORoleSet (OOPrivate)
|
||||
@ -109,6 +111,22 @@ SOFTWARE.
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isEqual:(id)other
|
||||
{
|
||||
if ([other isKindOfClass:[OORoleSet class]])
|
||||
{
|
||||
return [_rolesAndProbabilities isEqual:[other rolesAndProbabilities]];
|
||||
}
|
||||
else return NO;
|
||||
}
|
||||
|
||||
|
||||
- (unsigned)hash
|
||||
{
|
||||
return [_rolesAndProbabilities hash];
|
||||
}
|
||||
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
// Note: since object is immutable, a copy is no different from the original.
|
||||
@ -159,11 +177,7 @@ SOFTWARE.
|
||||
|
||||
- (float)probabilityForRole:(NSString *)role
|
||||
{
|
||||
NSNumber *value = nil;
|
||||
|
||||
if (role != nil) value = [_rolesAndProbabilities objectForKey:role];
|
||||
if (value != nil) return [value floatValue];
|
||||
else return 0.0f;
|
||||
return [_rolesAndProbabilities floatForKey:role defaultValue:0.0f];
|
||||
}
|
||||
|
||||
|
||||
@ -189,11 +203,52 @@ SOFTWARE.
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)anyRole
|
||||
{
|
||||
NSEnumerator *roleEnum = nil;
|
||||
NSString *role;
|
||||
float prob, selected;
|
||||
|
||||
selected = randf() * _totalProb;
|
||||
prob = 0.0f;
|
||||
|
||||
for (roleEnum = [_rolesAndProbabilities objectEnumerator]; (role = [roleEnum nextObject]); )
|
||||
{
|
||||
prob += [_rolesAndProbabilities floatForKey:role];
|
||||
if (selected <= prob) break;
|
||||
}
|
||||
if (role == nil)
|
||||
{
|
||||
role = [[self roles] anyObject];
|
||||
OOLog(@"roleSet.anyRole.failed", @"Could not get a weighted-random role from role set %@, returning unweighted selection %@. TotalProb: %g, selected: %g, prob at end: %@", self, role, _totalProb, selected, prob);
|
||||
}
|
||||
return role;
|
||||
}
|
||||
|
||||
|
||||
- (id)roleSetWithAddedRoleIfNotSet:(NSString *)role probability:(float)probability
|
||||
{
|
||||
NSMutableDictionary *dict = nil;
|
||||
|
||||
if (role == nil || probability < 0 || ([self hasRole:role] && [self probabilityForRole:role] == probability))
|
||||
{
|
||||
return [[self copy] autorelease];
|
||||
}
|
||||
|
||||
dict = [[_rolesAndProbabilities mutableCopy] autorelease];
|
||||
[dict setObject:[NSNumber numberWithFloat:probability] forKey:role];
|
||||
return [[[[self class] alloc] initWithRolesAndProbabilities:dict] autorelease];
|
||||
}
|
||||
|
||||
|
||||
- (id)roleSetWithAddedRole:(NSString *)role probability:(float)probability
|
||||
{
|
||||
NSMutableDictionary *dict = nil;
|
||||
|
||||
if (role == nil || probability < 0 || [self hasRole:role]) return [[self copy] autorelease];
|
||||
if (role == nil || probability < 0 || [self hasRole:role])
|
||||
{
|
||||
return [[self copy] autorelease];
|
||||
}
|
||||
|
||||
dict = [[_rolesAndProbabilities mutableCopy] autorelease];
|
||||
[dict setObject:[NSNumber numberWithFloat:probability] forKey:role];
|
||||
@ -219,6 +274,10 @@ SOFTWARE.
|
||||
|
||||
- (id)initWithRolesAndProbabilities:(NSDictionary *)dict
|
||||
{
|
||||
NSEnumerator *roleEnum = nil;
|
||||
NSString *role;
|
||||
float prob;
|
||||
|
||||
if (dict == nil)
|
||||
{
|
||||
[self release];
|
||||
@ -229,6 +288,20 @@ SOFTWARE.
|
||||
|
||||
// Note: _roles and _roleString are derived on the fly as needed.
|
||||
_rolesAndProbabilities = [dict copy];
|
||||
|
||||
for (roleEnum = [dict keyEnumerator]; (role = [roleEnum nextObject]); )
|
||||
{
|
||||
prob = [dict floatForKey:role defaultValue:-1];
|
||||
if (prob < 0)
|
||||
{
|
||||
OOLog(@"roleSet.badValue", @"Attempt to create a role set with negative or non-numerical probability for role %@.", role);
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
_totalProb += prob;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -35,12 +35,6 @@ MA 02110-1301, USA.
|
||||
|
||||
- (NSString *)jsClassName;
|
||||
|
||||
- (BOOL)isShip;
|
||||
- (BOOL)isStation;
|
||||
- (BOOL)isSubEntity;
|
||||
- (BOOL)isPlayer;
|
||||
- (BOOL)isPlanet;
|
||||
|
||||
// Internal:
|
||||
- (void)getJSClass:(JSClass **)outClass andPrototype:(JSObject **)outPrototype;
|
||||
- (void)deleteJSSelf;
|
||||
|
@ -48,36 +48,6 @@ MA 02110-1301, USA.
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isShip
|
||||
{
|
||||
return isShip;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isStation
|
||||
{
|
||||
return isStation;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isSubEntity
|
||||
{
|
||||
return isSubentity;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPlayer
|
||||
{
|
||||
return isPlayer;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPlanet
|
||||
{
|
||||
return isPlanet;
|
||||
}
|
||||
|
||||
|
||||
- (jsval)javaScriptValueInContext:(JSContext *)context
|
||||
{
|
||||
JSClass *class = NULL;
|
||||
|
@ -30,6 +30,7 @@ MA 02110-1301, USA.
|
||||
#import "AI.h"
|
||||
#import "OOStringParsing.h"
|
||||
#import "EntityOOJavaScriptExtensions.h"
|
||||
#import "OORoleSet.h"
|
||||
|
||||
|
||||
static JSObject *sShipPrototype;
|
||||
@ -45,8 +46,6 @@ static JSBool ShipReactToAIMessage(JSContext *context, JSObject *this, uintN arg
|
||||
static JSBool ShipDeployEscorts(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ShipDockEscorts(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
|
||||
static NSArray *ArrayOfRoles(NSString *rolesString);
|
||||
|
||||
|
||||
static JSExtendedClass sShipClass =
|
||||
{
|
||||
@ -76,6 +75,8 @@ enum
|
||||
// Property IDs
|
||||
kShip_shipDescription, // name, string, read-only
|
||||
kShip_roles, // roles, array, read-only
|
||||
kShip_roleProbabilities, // roles and probabilities, dictionary, read-only
|
||||
kShip_primaryRole, // Primary role, string, read-only
|
||||
kShip_AI, // AI state machine name, string, read/write
|
||||
kShip_AIState, // AI state machine state, string, read/write
|
||||
kShip_fuel, // fuel, float, read/write
|
||||
@ -102,7 +103,11 @@ enum
|
||||
kShip_maxCargo, // maximum cargo, integer, read-only
|
||||
kShip_speed, // current flight speed, double, read-only (should probably be read/write, but may interfere with AI behaviour)
|
||||
kShip_maxSpeed, // maximum flight speed, double, read-only
|
||||
kShip_script // script, Script, read-only
|
||||
kShip_script, // script, Script, read-only
|
||||
kShip_isPirate, // is pirate, boolean, read-only
|
||||
kShip_isPolice, // is police, boolean, read-only
|
||||
kShip_isThargoid, // is thargoid, boolean, read-only
|
||||
kShip_isTrader // is trader, boolean, read-only
|
||||
};
|
||||
|
||||
|
||||
@ -111,6 +116,8 @@ static JSPropertySpec sShipProperties[] =
|
||||
// JS name ID flags
|
||||
{ "shipDescription", kShip_shipDescription, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "roles", kShip_roles, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "roleProbabilities", kShip_roleProbabilities, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "primaryRole", kShip_primaryRole, JSPROP_PERMANENT | JSPROP_ENUMERATE },
|
||||
{ "AI", kShip_AI, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "AIState", kShip_AIState, JSPROP_PERMANENT | JSPROP_ENUMERATE },
|
||||
{ "fuel", kShip_fuel, JSPROP_PERMANENT | JSPROP_ENUMERATE },
|
||||
@ -138,6 +145,10 @@ static JSPropertySpec sShipProperties[] =
|
||||
{ "speed", kShip_speed, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "maxSpeed", kShip_maxSpeed, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "script", kShip_script, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "isPirate", kShip_isPirate, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "isPolice", kShip_isPolice, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "isThargoid", kShip_isThargoid, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "isTrader", kShip_isTrader, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -207,7 +218,15 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsval name, js
|
||||
break;
|
||||
|
||||
case kShip_roles:
|
||||
result = ArrayOfRoles([entity roles]);
|
||||
result = [[entity roleSet] sortedRoles];
|
||||
break;
|
||||
|
||||
case kShip_roleProbabilities:
|
||||
result = [[entity roleSet] rolesAndProbabilities];
|
||||
break;
|
||||
|
||||
case kShip_primaryRole:
|
||||
result = [entity primaryRole];
|
||||
break;
|
||||
|
||||
case kShip_AI:
|
||||
@ -324,6 +343,22 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsval name, js
|
||||
if (result == nil) result = [NSNull null];
|
||||
break;
|
||||
|
||||
case kShip_isPirate:
|
||||
*outValue = BOOLToJSVal([entity isPirate]);
|
||||
break;
|
||||
|
||||
case kShip_isPolice:
|
||||
*outValue = BOOLToJSVal([entity isPolice]);
|
||||
break;
|
||||
|
||||
case kShip_isThargoid:
|
||||
*outValue = BOOLToJSVal([entity isThargoid]);
|
||||
break;
|
||||
|
||||
case kShip_isTrader:
|
||||
*outValue = BOOLToJSVal([entity isTrader]);
|
||||
break;
|
||||
|
||||
default:
|
||||
OOReportJavaScriptBadPropertySelector(context, @"Ship", JSVAL_TO_INT(name));
|
||||
return NO;
|
||||
@ -349,10 +384,22 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js
|
||||
|
||||
switch (JSVAL_TO_INT(name))
|
||||
{
|
||||
case kShip_primaryRole:
|
||||
if (entity->isPlayer)
|
||||
{
|
||||
OOReportJavaScriptError(context, @"Ship.AIState [setter]: cannot set %@ for player.", "primary role");
|
||||
}
|
||||
else
|
||||
{
|
||||
strVal = [NSString stringWithJavaScriptValue:*value inContext:context];
|
||||
if (strVal != nil) [entity setPrimaryRole:strVal];
|
||||
}
|
||||
break;
|
||||
|
||||
case kShip_AIState:
|
||||
if (entity->isPlayer)
|
||||
{
|
||||
OOReportJavaScriptError(context, @"Ship.AIState [setter]: cannot set AI state for player.");
|
||||
OOReportJavaScriptError(context, @"Ship.AIState [setter]: cannot set %@ for player.", "AI state");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -550,36 +597,3 @@ static JSBool ShipDockEscorts(JSContext *context, JSObject *this, uintN argc, js
|
||||
[thisEnt dockEscorts];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
static NSArray *ArrayOfRoles(NSString *rolesString)
|
||||
{
|
||||
NSArray *rawRoles = nil;
|
||||
NSMutableArray *filteredRoles = nil;
|
||||
NSAutoreleasePool *pool = nil;
|
||||
unsigned i, count;
|
||||
NSString *role = nil;
|
||||
NSRange parenRange;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
rawRoles = ScanTokensFromString(rolesString);
|
||||
count = [rawRoles count];
|
||||
filteredRoles = [NSMutableArray arrayWithCapacity:count];
|
||||
|
||||
for (i = 0; i != count; ++i)
|
||||
{
|
||||
role = [rawRoles objectAtIndex:i];
|
||||
// Strip probability from string
|
||||
parenRange = [role rangeOfString:@"("];
|
||||
if (parenRange.location != NSNotFound)
|
||||
{
|
||||
role = [role substringToIndex:parenRange.location];
|
||||
}
|
||||
[filteredRoles addObject:role];
|
||||
}
|
||||
|
||||
[filteredRoles retain];
|
||||
[pool release];
|
||||
return filteredRoles;
|
||||
}
|
||||
|
@ -443,6 +443,7 @@ static JSBool SystemAddShips(JSContext *context, JSObject *this, uintN argc, jsv
|
||||
|
||||
}
|
||||
|
||||
// Note: need a way to specify the use of witchspace-in effects (as in legacy_addShips).
|
||||
OOReportJavaScriptError(context, @"System.addShips(): not implemented.");
|
||||
|
||||
return YES;
|
||||
@ -461,7 +462,7 @@ static JSBool SystemLegacyAddShips(JSContext *context, JSObject *this, uintN arg
|
||||
return YES;
|
||||
}
|
||||
|
||||
while (count--) [UNIVERSE witchspaceShipWithRole:role];
|
||||
while (count--) [UNIVERSE witchspaceShipWithPrimaryRole:role];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ MA 02110-1301, USA.
|
||||
#import "OOWeakReference.h"
|
||||
#import "OOTypes.h"
|
||||
|
||||
@class GameController, CollisionRegion, MyOpenGLView, GuiDisplayGen,
|
||||
Entity, ShipEntity, StationEntity, PlanetEntity, PlayerEntity,
|
||||
OORoleSet;
|
||||
|
||||
|
||||
#define CROSSHAIR_SIZE 32.0
|
||||
|
||||
enum
|
||||
@ -108,9 +113,6 @@ enum
|
||||
|
||||
#define BILLBOARD_DEPTH 50000.0
|
||||
|
||||
@class GameController, CollisionRegion, MyOpenGLView, GuiDisplayGen;
|
||||
@class Entity, ShipEntity, StationEntity, PlanetEntity, PlayerEntity;
|
||||
|
||||
|
||||
@interface Universe: NSObject <OOWeakReferenceSupport>
|
||||
{
|
||||
@ -277,7 +279,7 @@ enum
|
||||
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc nearPosition:(Vector) pos withCoordinateSystem:(NSString *) system withinRadius:(GLfloat) radius;
|
||||
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc intoBoundingBox:(BoundingBox) bbox;
|
||||
- (BOOL) spawnShip:(NSString *) shipdesc;
|
||||
- (void) witchspaceShipWithRole:(NSString *) desc;
|
||||
- (void) witchspaceShipWithPrimaryRole:(NSString *)role;
|
||||
- (void) spawnShipWithRole:(NSString *) desc near:(Entity *) entity;
|
||||
|
||||
- (void) set_up_break_pattern:(Vector) pos quaternion:(Quaternion) q;
|
||||
@ -353,10 +355,12 @@ enum
|
||||
- (int) getFirstEntityHitByLaserFromEntity:(Entity *) e1 inView:(int) viewdir offset:(Vector) offset rangeFound:(GLfloat*)range_ptr;
|
||||
- (int) getFirstEntityTargettedByPlayer:(PlayerEntity*) player;
|
||||
|
||||
- (NSArray *) getEntitiesWithinRange:(double) range1 ofEntity:(Entity *) e1;
|
||||
- (unsigned) countShipsWithRole:(NSString *) desc inRange:(double) range1 ofEntity:(Entity *)e1;
|
||||
- (unsigned) countShipsWithRole:(NSString *) desc;
|
||||
- (void) sendShipsWithRole:(NSString *) desc messageToAI:(NSString *) ms;
|
||||
- (NSArray *) getEntitiesWithinRange:(double)range ofEntity:(Entity *)entity;
|
||||
- (unsigned) countShipsWithRole:(NSString *)role inRange:(double)range ofEntity:(Entity *)entity;
|
||||
- (unsigned) countShipsWithRole:(NSString *)role;
|
||||
- (unsigned) countShipsWithPrimaryRole:(NSString *)role inRange:(double)range ofEntity:(Entity *)entity;
|
||||
- (unsigned) countShipsWithPrimaryRole:(NSString *)role;
|
||||
- (void) sendShipsWithPrimaryRole:(NSString *)role messageToAI:(NSString *)message;
|
||||
|
||||
- (OOTimeAbsolute) getTime;
|
||||
- (OOTimeDelta) getTimeDelta;
|
||||
|
@ -85,11 +85,21 @@ static NSComparisonResult compareName(NSDictionary *dict1, NSDictionary *dict2,
|
||||
static NSComparisonResult comparePrice(NSDictionary *dict1, NSDictionary *dict2, void * context);
|
||||
|
||||
|
||||
typedef BOOL (*ShipFilterPredicate)(ShipEntity *ship, id parameter);
|
||||
static BOOL HasRolePredicate(ShipEntity *ship, id parameter);
|
||||
static BOOL HasPrimaryRolePredicate(ShipEntity *ship, id parameter);
|
||||
|
||||
|
||||
@interface Universe (OOPrivate)
|
||||
|
||||
- (BOOL)doRemoveEntity:(Entity *)entity;
|
||||
- (NSDictionary *)getDictionaryForShip:(NSString *)desc recursionLimit:(uint32_t)recursionLimit;
|
||||
|
||||
- (unsigned) countShipsWithPredicate:(ShipFilterPredicate)predicate
|
||||
parameter:(id)parameter
|
||||
inRange:(double)range1
|
||||
ofEntity:(Entity *)e1;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -1398,7 +1408,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
[OOCharacter randomCharacterWithRole:@"police"
|
||||
andOriginalSystem: (randf() > 0.05)? systems[Ranrot() & 255]:system_seed]]];
|
||||
|
||||
[hunter_ship setRoles:@"police"];
|
||||
[hunter_ship setPrimaryRole:@"police"];
|
||||
if (hunter_ship->scanClass == CLASS_NOT_SET)
|
||||
[hunter_ship setScanClass: CLASS_POLICE];
|
||||
while (((Ranrot() & 7) + 2 < government)&&([hunter_ship escortCount] < 6))
|
||||
@ -1523,7 +1533,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
[OOCharacter randomCharacterWithRole:@"trader"
|
||||
andOriginalSystem: (randf() > 0.85)? systems[Ranrot() & 255]:system_seed]]];
|
||||
|
||||
[trader_ship setRoles:@"trader"]; // set this to allow escorts to pair with the ship
|
||||
[trader_ship setPrimaryRole:@"trader"]; // set this to allow escorts to pair with the ship
|
||||
if ((trader_ship)&&(trader_ship->scanClass == CLASS_NOT_SET))
|
||||
[trader_ship setScanClass: CLASS_NEUTRAL];
|
||||
[trader_ship setPosition:launchPos];
|
||||
@ -1635,7 +1645,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
[OOCharacter randomCharacterWithRole:@"police"
|
||||
andOriginalSystem: (randf() > 0.05)? systems[Ranrot() & 255]:system_seed]]];
|
||||
|
||||
[hunter_ship setRoles:@"police"];
|
||||
[hunter_ship setPrimaryRole:@"police"];
|
||||
if (hunter_ship->scanClass == CLASS_NOT_SET)
|
||||
[hunter_ship setScanClass: CLASS_POLICE];
|
||||
while (((Ranrot() & 7) + 2 < government)&&([hunter_ship escortCount] < 6))
|
||||
@ -2335,16 +2345,17 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
}
|
||||
|
||||
|
||||
- (void) witchspaceShipWithRole:(NSString *)desc
|
||||
- (void) witchspaceShipWithPrimaryRole:(NSString *)role
|
||||
{
|
||||
// adds a ship exiting witchspace (corollary of when ships leave the system)
|
||||
ShipEntity *ship;
|
||||
ship = [self newShipWithRole:desc]; // retain count = 1
|
||||
ShipEntity *ship = nil;
|
||||
|
||||
ship = [self newShipWithRole:role]; // retain count = 1
|
||||
if (ship)
|
||||
{
|
||||
if ((ship->scanClass == CLASS_NO_DRAW)||(ship->scanClass == CLASS_NOT_SET))
|
||||
[ship setScanClass: CLASS_NEUTRAL];
|
||||
if ([desc isEqual:@"trader"])
|
||||
if ([role isEqual:@"trader"])
|
||||
{
|
||||
[ship setCargoFlag: CARGO_FLAG_FULL_SCARCE];
|
||||
if (randf() > 0.10)
|
||||
@ -2352,14 +2363,14 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
else
|
||||
[[ship getAI] setStateMachine:@"route2sunskimAI.plist"]; // route3 really, but the AI's the same
|
||||
}
|
||||
if ([desc isEqual:@"pirate"])
|
||||
if ([role isEqual:@"pirate"])
|
||||
{
|
||||
[ship setCargoFlag: CARGO_FLAG_PIRATE];
|
||||
[ship setBounty: (Ranrot() & 7) + (Ranrot() & 7) + ((randf() < 0.05)? 63 : 23)]; // they already have a price on their heads
|
||||
}
|
||||
if (![ship crew])
|
||||
[ship setCrew:[NSArray arrayWithObject:
|
||||
[OOCharacter randomCharacterWithRole: desc
|
||||
[OOCharacter randomCharacterWithRole:role
|
||||
andOriginalSystem: systems[Ranrot() & 255]]]];
|
||||
|
||||
[ship leaveWitchspace]; // gets added to the universe here!
|
||||
@ -2784,45 +2795,6 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
foundf += chance;
|
||||
}
|
||||
}
|
||||
/*for (shipEnum = [shipdata keyEnumerator]; (shipKey = [shipEnum nextObject]); )
|
||||
{
|
||||
shipDict = [shipdata dictionaryForKey:shipKey];
|
||||
shipRoles = ScanTokensFromString([shipDict stringForKey:@"roles"]);
|
||||
|
||||
if ([shipDict arrayForKey:@"conditions"])
|
||||
{
|
||||
PlayerEntity* player = [PlayerEntity sharedPlayer];
|
||||
if ((player) && (player->isPlayer) && (![player checkCouplet:shipDict onEntity:player]))
|
||||
shipRoles = [NSArray array]; // empty array - ship does not meet conditions listed
|
||||
}
|
||||
|
||||
for (j = 0; j < [shipRoles count]; j++)
|
||||
{
|
||||
NSString *putative_roles = [shipRoles stringAtIndex:j];
|
||||
|
||||
GLfloat chance = 1.0;
|
||||
if (putative_roles)
|
||||
{
|
||||
if ([putative_roles hasPrefix:search] && ([putative_roles rangeOfString:@"("].location != NSNotFound))
|
||||
{
|
||||
NSScanner* scanner = [NSScanner scannerWithString:putative_roles]; // scanner
|
||||
[scanner scanUpToString:@"(" intoString:&putative_roles]; // look for '('
|
||||
[scanner scanString:@"(" intoString:NULL]; // skip over it
|
||||
if (![scanner scanFloat:&chance]) chance = 1.0; // try to scan a float
|
||||
// ignore from '(' onwards (lazy)
|
||||
|
||||
}
|
||||
|
||||
if ([putative_roles isEqual:search] && (chance > 0.0))
|
||||
{
|
||||
[foundShips addObject:shipKey];
|
||||
[foundChance addObject:[NSNumber numberWithFloat:chance]];
|
||||
found++;
|
||||
foundf += chance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
i = 0;
|
||||
|
||||
@ -2845,7 +2817,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
shipKey = [foundShips stringAtIndex:i];
|
||||
|
||||
ship = [self newShipWithName:shipKey]; // may return nil if not found!
|
||||
[ship setRoles:search]; // set its roles to this one particular chosen role
|
||||
[ship setPrimaryRole:search];
|
||||
|
||||
shipDict = [shipdata dictionaryForKey:shipKey];
|
||||
if ([shipDict fuzzyBooleanForKey:@"auto_ai" defaultValue:YES])
|
||||
@ -2876,7 +2848,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
[pool release]; // tidy everything up
|
||||
|
||||
// check a trader has fuel
|
||||
if ([ship fuel] == 0 &&([[ship roles] rangeOfString:@"trader"].location != NSNotFound))
|
||||
if ([ship fuel] == 0 && [[ship primaryRole] isEqual:@"trader"])
|
||||
{
|
||||
[ship setFuel: PLAYER_MAX_FUEL];
|
||||
}
|
||||
@ -2916,6 +2888,10 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
else [localException raise];
|
||||
NS_ENDHANDLER
|
||||
|
||||
// Set primary role to same as ship name, if ship name is also a role.
|
||||
// Otherwise, if caller doesn't set a role, one will be selected randomly.
|
||||
if ([ship hasRole:desc]) [ship setPrimaryRole:desc];
|
||||
|
||||
return ship; // retain count = 1
|
||||
}
|
||||
|
||||
@ -4602,65 +4578,37 @@ static BOOL MaintainLinkedLists(Universe* uni)
|
||||
}
|
||||
|
||||
|
||||
- (unsigned) countShipsWithRole:(NSString *) desc inRange:(double) range1 ofEntity:(Entity *)e1
|
||||
- (unsigned) countShipsWithRole:(NSString *)role inRange:(double)range ofEntity:(Entity *)entity
|
||||
{
|
||||
if (!e1) return 0;
|
||||
|
||||
unsigned i, found;
|
||||
unsigned ent_count = n_entities;
|
||||
unsigned ship_count = 0;
|
||||
Entity *my_entities[ent_count];
|
||||
|
||||
for (i = 0; i < ent_count; i++)
|
||||
if (sortedEntities[i]->isShip)
|
||||
my_entities[ship_count++] = [sortedEntities[i] retain]; // retained
|
||||
|
||||
found = 0;
|
||||
Vector p1 = e1->position;
|
||||
for (i = 0; i < ship_count; i++)
|
||||
{
|
||||
Entity *e2 = my_entities[i];
|
||||
if ((e2 != e1)&&([[(ShipEntity *)e2 roles] isEqual:desc]))
|
||||
{
|
||||
Vector p2 = e2->position;
|
||||
p2.x -= p1.x; p2.y -= p1.y; p2.z -= p1.z;
|
||||
double cr = range1 + e2->collision_radius;
|
||||
double d2 = p2.x*p2.x + p2.y*p2.y + p2.z*p2.z - cr*cr;
|
||||
if (d2 < 0)
|
||||
found++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ship_count; i++)
|
||||
[my_entities[i] release]; // released
|
||||
return found;
|
||||
return [self countShipsWithPredicate:HasRolePredicate
|
||||
parameter:role
|
||||
inRange:range
|
||||
ofEntity:entity];
|
||||
}
|
||||
|
||||
|
||||
- (unsigned) countShipsWithRole:(NSString *) desc
|
||||
- (unsigned) countShipsWithRole:(NSString *)role
|
||||
{
|
||||
unsigned i, found;
|
||||
unsigned ent_count = n_entities;
|
||||
unsigned ship_count = 0;
|
||||
Entity *my_entities[ent_count];
|
||||
|
||||
for (i = 0; i < ent_count; i++)
|
||||
if (sortedEntities[i]->isShip)
|
||||
my_entities[ship_count++] = [sortedEntities[i] retain]; // retained
|
||||
|
||||
found = 0;
|
||||
for (i = 0; i < ship_count; i++)
|
||||
{
|
||||
Entity *e2 = my_entities[i];
|
||||
if (([[(ShipEntity *)e2 roles] isEqual:desc]))
|
||||
found++;
|
||||
}
|
||||
for (i = 0; i < ship_count; i++)
|
||||
[my_entities[i] release]; // released
|
||||
return found;
|
||||
return [self countShipsWithRole:role inRange:-1 ofEntity:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) sendShipsWithRole:(NSString *) desc messageToAI:(NSString *) ms
|
||||
- (unsigned) countShipsWithPrimaryRole:(NSString *)role inRange:(double)range ofEntity:(Entity *)entity
|
||||
{
|
||||
return [self countShipsWithPredicate:HasPrimaryRolePredicate
|
||||
parameter:role
|
||||
inRange:range
|
||||
ofEntity:entity];
|
||||
}
|
||||
|
||||
|
||||
- (unsigned) countShipsWithPrimaryRole:(NSString *)role
|
||||
{
|
||||
return [self countShipsWithPrimaryRole:role inRange:-1 ofEntity:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) sendShipsWithPrimaryRole:(NSString *)role messageToAI:(NSString *)ms
|
||||
{
|
||||
int i, found;
|
||||
int ent_count = n_entities;
|
||||
@ -4674,7 +4622,7 @@ static BOOL MaintainLinkedLists(Universe* uni)
|
||||
for (i = 0; i < ship_count; i++)
|
||||
{
|
||||
Entity *e2 = my_entities[i];
|
||||
if ([[(ShipEntity *)e2 roles] isEqual:desc])
|
||||
if ([[(ShipEntity *)e2 primaryRole] isEqual:role])
|
||||
[[(ShipEntity *)e2 getAI] reactToMessage:ms];
|
||||
}
|
||||
for (i = 0; i < ship_count; i++)
|
||||
@ -6260,8 +6208,8 @@ static BOOL MaintainLinkedLists(Universe* uni)
|
||||
- (BOOL) generateEconomicDataWithEconomy:(OOEconomyID) economy andRandomFactor:(int) random_factor
|
||||
{
|
||||
StationEntity *some_station = [self station];
|
||||
NSString *station_roles = [some_station roles];
|
||||
if ([commoditylists arrayForKey:station_roles] == nil) station_roles = @"default";
|
||||
NSString *stationRole = [some_station primaryRole];
|
||||
if ([commoditylists arrayForKey:stationRole] == nil) stationRole = @"default";
|
||||
|
||||
[commoditydata release];
|
||||
commoditydata = [[self commodityDataForEconomy:economy andStation:some_station andRandomFactor:random_factor] retain];
|
||||
@ -6276,8 +6224,8 @@ static BOOL MaintainLinkedLists(Universe* uni)
|
||||
unsigned i;
|
||||
|
||||
station_roles = [[self currentSystemData] stringForKey:@"market"];
|
||||
if (station_roles == nil) station_roles = [some_station roles];
|
||||
if ([commoditylists arrayForKey:station_roles] == nil) station_roles = @"default";
|
||||
NSString *stationRole = [some_station primaryRole];
|
||||
if ([commoditylists arrayForKey:stationRole] == nil) stationRole = @"default";
|
||||
|
||||
ourEconomy = [NSMutableArray arrayWithArray:[commoditylists arrayForKey:station_roles]];
|
||||
|
||||
@ -7699,4 +7647,64 @@ static NSComparisonResult comparePrice(NSDictionary *dict1, NSDictionary *dict2,
|
||||
return shipdict;
|
||||
}
|
||||
|
||||
|
||||
- (unsigned) countShipsWithPredicate:(ShipFilterPredicate)predicate
|
||||
parameter:(id)parameter
|
||||
inRange:(double)range1
|
||||
ofEntity:(Entity *)e1
|
||||
{
|
||||
if (e1 == nil || predicate == NULL) return 0;
|
||||
|
||||
unsigned i, found;
|
||||
unsigned ent_count = n_entities;
|
||||
unsigned ship_count = 0;
|
||||
ShipEntity *my_entities[ent_count];
|
||||
Vector p1;
|
||||
|
||||
for (i = 0; i < ent_count; i++)
|
||||
if (sortedEntities[i]->isShip)
|
||||
my_entities[ship_count++] = [sortedEntities[i] retain]; // retained
|
||||
|
||||
found = 0;
|
||||
if (e1 != nil) p1 = e1->position;
|
||||
else p1 = kZeroVector;
|
||||
|
||||
for (i = 0; i < ship_count; i++)
|
||||
{
|
||||
ShipEntity *e2 = my_entities[i];
|
||||
if (e2 != e1 && predicate(e2, parameter))
|
||||
{
|
||||
double d2;
|
||||
if (range1 < 0) d2 = -1; // Negative range means infinity
|
||||
else
|
||||
{
|
||||
Vector p2 = e2->position;
|
||||
p2.x -= p1.x; p2.y -= p1.y; p2.z -= p1.z;
|
||||
double cr = range1 + e2->collision_radius;
|
||||
d2 = p2.x*p2.x + p2.y*p2.y + p2.z*p2.z - cr*cr;
|
||||
}
|
||||
if (d2 < 0)
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ship_count; i++)
|
||||
[my_entities[i] release]; // released
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static BOOL HasRolePredicate(ShipEntity *ship, id parameter)
|
||||
{
|
||||
return [ship hasRole:parameter];
|
||||
}
|
||||
|
||||
|
||||
static BOOL HasPrimaryRolePredicate(ShipEntity *ship, id parameter)
|
||||
{
|
||||
return [ship hasPrimaryRole:parameter];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user