Added code to avoid probable cause of STATUS_DEAD ghost ships, and moar code to catch them if they appear anyway. (Bug #16624)
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@2927 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
86d0553639
commit
6ba078a08e
@ -331,7 +331,7 @@ static OOSoundSource *sAfterburnerSources[2];
|
||||
|
||||
|
||||
// time delay method for playing afterburner sounds
|
||||
// this overlaps two sounds each 2 seconds long, but with a .5s
|
||||
// this overlaps two sounds each 2 seconds long, but with a 0.75s
|
||||
// crossfade
|
||||
- (void) updateAfterburnerSound
|
||||
{
|
||||
|
@ -5682,86 +5682,90 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
if ([self status] == STATUS_DEAD) return;
|
||||
[self setStatus:STATUS_DEAD];
|
||||
|
||||
//scripting
|
||||
if (script != nil)
|
||||
{
|
||||
[[PlayerEntity sharedPlayer] setScriptTarget:self];
|
||||
[self doScriptEvent:@"shipDied"]; // FIXME: params missing
|
||||
}
|
||||
|
||||
// two parts to the explosion:
|
||||
// 1. fast sparks
|
||||
float how_many = factor;
|
||||
while (how_many > 0.5f)
|
||||
{
|
||||
fragment = [[ParticleEntity alloc] initFragburstSize: collision_radius fromPosition:xposition];
|
||||
[UNIVERSE addEntity:fragment];
|
||||
[fragment release];
|
||||
how_many -= 1.0f;
|
||||
}
|
||||
// 2. slow clouds
|
||||
how_many = factor;
|
||||
while (how_many > 0.5f)
|
||||
{
|
||||
fragment = [[ParticleEntity alloc] initBurst2Size: collision_radius fromPosition:xposition];
|
||||
[UNIVERSE addEntity:fragment];
|
||||
[fragment release];
|
||||
how_many -= 1.0f;
|
||||
}
|
||||
|
||||
|
||||
// we need to throw out cargo at this point.
|
||||
unsigned cargo_chance = 10;
|
||||
if ([[name lowercaseString] rangeOfString:@"medical"].location != NSNotFound)
|
||||
{
|
||||
cargo_to_go = max_cargo * cargo_chance / 100;
|
||||
while (cargo_to_go > 15)
|
||||
cargo_to_go = ranrot_rand() % cargo_to_go;
|
||||
[self setCargo:[UNIVERSE getContainersOfDrugs:cargo_to_go]];
|
||||
cargo_chance = 100; // chance of any given piece of cargo surviving decompression
|
||||
cargo_flag = CARGO_FLAG_CANISTERS;
|
||||
}
|
||||
if (cargo_flag == CARGO_FLAG_FULL_PLENTIFUL || cargo_flag == CARGO_FLAG_FULL_SCARCE)
|
||||
{
|
||||
cargo_to_go = max_cargo / 10;
|
||||
while (cargo_to_go > 15)
|
||||
cargo_to_go = ranrot_rand() % cargo_to_go;
|
||||
[self setCargo:[UNIVERSE getContainersOfGoods:cargo_to_go scarce:(cargo_flag == CARGO_FLAG_FULL_SCARCE)]];
|
||||
cargo_chance = 100;
|
||||
}
|
||||
while ([cargo count] > 0)
|
||||
{
|
||||
if (Ranrot() % 100 < cargo_chance) // 10% chance of any given piece of cargo surviving decompression
|
||||
NS_DURING
|
||||
//scripting
|
||||
if (script != nil)
|
||||
{
|
||||
ShipEntity* container = [[cargo objectAtIndex:0] retain];
|
||||
Vector rpos = xposition;
|
||||
Vector rrand = randomPositionInBoundingBox(boundingBox);
|
||||
rpos.x += rrand.x; rpos.y += rrand.y; rpos.z += rrand.z;
|
||||
rpos.x += (ranrot_rand() % 7) - 3;
|
||||
rpos.y += (ranrot_rand() % 7) - 3;
|
||||
rpos.z += (ranrot_rand() % 7) - 3;
|
||||
[container setPosition:rpos];
|
||||
[container setScanClass: CLASS_CARGO];
|
||||
[UNIVERSE addEntity:container]; // STATUS_IN_FLIGHT, AI state GLOBAL
|
||||
[container release];
|
||||
if (n_cargo > 0)
|
||||
n_cargo--; // count down extra cargo
|
||||
[[PlayerEntity sharedPlayer] setScriptTarget:self];
|
||||
[self doScriptEvent:@"shipDied"]; // FIXME: params missing
|
||||
}
|
||||
[cargo removeObjectAtIndex:0];
|
||||
}
|
||||
|
||||
NSEnumerator *subEnum = nil;
|
||||
ShipEntity *se = nil;
|
||||
for (subEnum = [self shipSubEntityEnumerator]; (se = [subEnum nextObject]); )
|
||||
{
|
||||
[se setSuppressExplosion:suppressExplosion];
|
||||
[se setPosition:[se absolutePositionForSubentity]];
|
||||
[UNIVERSE addEntity:se];
|
||||
[se becomeExplosion];
|
||||
}
|
||||
[self clearSubEntities];
|
||||
|
||||
if (!isPlayer) [UNIVERSE removeEntity:self];
|
||||
|
||||
// two parts to the explosion:
|
||||
// 1. fast sparks
|
||||
float how_many = factor;
|
||||
while (how_many > 0.5f)
|
||||
{
|
||||
fragment = [[ParticleEntity alloc] initFragburstSize: collision_radius fromPosition:xposition];
|
||||
[UNIVERSE addEntity:fragment];
|
||||
[fragment release];
|
||||
how_many -= 1.0f;
|
||||
}
|
||||
// 2. slow clouds
|
||||
how_many = factor;
|
||||
while (how_many > 0.5f)
|
||||
{
|
||||
fragment = [[ParticleEntity alloc] initBurst2Size: collision_radius fromPosition:xposition];
|
||||
[UNIVERSE addEntity:fragment];
|
||||
[fragment release];
|
||||
how_many -= 1.0f;
|
||||
}
|
||||
|
||||
|
||||
// we need to throw out cargo at this point.
|
||||
unsigned cargo_chance = 10;
|
||||
if ([[name lowercaseString] rangeOfString:@"medical"].location != NSNotFound)
|
||||
{
|
||||
cargo_to_go = max_cargo * cargo_chance / 100;
|
||||
while (cargo_to_go > 15)
|
||||
cargo_to_go = ranrot_rand() % cargo_to_go;
|
||||
[self setCargo:[UNIVERSE getContainersOfDrugs:cargo_to_go]];
|
||||
cargo_chance = 100; // chance of any given piece of cargo surviving decompression
|
||||
cargo_flag = CARGO_FLAG_CANISTERS;
|
||||
}
|
||||
if (cargo_flag == CARGO_FLAG_FULL_PLENTIFUL || cargo_flag == CARGO_FLAG_FULL_SCARCE)
|
||||
{
|
||||
cargo_to_go = max_cargo / 10;
|
||||
while (cargo_to_go > 15)
|
||||
cargo_to_go = ranrot_rand() % cargo_to_go;
|
||||
[self setCargo:[UNIVERSE getContainersOfGoods:cargo_to_go scarce:(cargo_flag == CARGO_FLAG_FULL_SCARCE)]];
|
||||
cargo_chance = 100;
|
||||
}
|
||||
while ([cargo count] > 0)
|
||||
{
|
||||
if (Ranrot() % 100 < cargo_chance) // 10% chance of any given piece of cargo surviving decompression
|
||||
{
|
||||
ShipEntity* container = [[cargo objectAtIndex:0] retain];
|
||||
Vector rpos = xposition;
|
||||
Vector rrand = randomPositionInBoundingBox(boundingBox);
|
||||
rpos.x += rrand.x; rpos.y += rrand.y; rpos.z += rrand.z;
|
||||
rpos.x += (ranrot_rand() % 7) - 3;
|
||||
rpos.y += (ranrot_rand() % 7) - 3;
|
||||
rpos.z += (ranrot_rand() % 7) - 3;
|
||||
[container setPosition:rpos];
|
||||
[container setScanClass: CLASS_CARGO];
|
||||
[UNIVERSE addEntity:container]; // STATUS_IN_FLIGHT, AI state GLOBAL
|
||||
[container release];
|
||||
if (n_cargo > 0)
|
||||
n_cargo--; // count down extra cargo
|
||||
}
|
||||
[cargo removeObjectAtIndex:0];
|
||||
}
|
||||
|
||||
NSEnumerator *subEnum = nil;
|
||||
ShipEntity *se = nil;
|
||||
for (subEnum = [self shipSubEntityEnumerator]; (se = [subEnum nextObject]); )
|
||||
{
|
||||
[se setSuppressExplosion:suppressExplosion];
|
||||
[se setPosition:[se absolutePositionForSubentity]];
|
||||
[UNIVERSE addEntity:se];
|
||||
[se becomeExplosion];
|
||||
}
|
||||
[self clearSubEntities];
|
||||
|
||||
if (!isPlayer) [UNIVERSE removeEntity:self];
|
||||
NS_HANDLER
|
||||
if (!isPlayer) [UNIVERSE removeEntity:self];
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
|
||||
|
@ -5436,7 +5436,8 @@ OOINLINE BOOL EntityInRange(Vector p1, Entity *e2, float range)
|
||||
universal_time += delta_t;
|
||||
|
||||
update_stage = @"demo management";
|
||||
if (inGUIMode && [player guiScreen] == GUI_SCREEN_INTRO2){
|
||||
if (inGUIMode && [player guiScreen] == GUI_SCREEN_INTRO2)
|
||||
{
|
||||
if (universal_time >= demo_stage_time)
|
||||
{
|
||||
if (ent_count > 1)
|
||||
@ -5517,12 +5518,20 @@ OOINLINE BOOL EntityInRange(Vector p1, Entity *e2, float range)
|
||||
}
|
||||
|
||||
update_stage = @"update:entity";
|
||||
NSMutableSet *zombies = nil;
|
||||
|
||||
for (i = 0; i < ent_count; i++)
|
||||
{
|
||||
Entity *thing = my_entities[i];
|
||||
#ifndef NDEBUG
|
||||
update_stage = [NSString stringWithFormat:@"update:entity[%@]", [thing shortDescription]];
|
||||
#endif
|
||||
if (EXPECT_NOT([thing status] == STATUS_DEAD && ![entitiesDeadThisUpdate containsObject:thing]))
|
||||
{
|
||||
if (zombies == nil) zombies = [NSMutableSet set];
|
||||
[zombies addObject:thing];
|
||||
continue;
|
||||
}
|
||||
|
||||
[thing update:delta_t];
|
||||
|
||||
@ -5558,6 +5567,18 @@ OOINLINE BOOL EntityInRange(Vector p1, Entity *e2, float range)
|
||||
}
|
||||
}
|
||||
|
||||
if (zombies != nil)
|
||||
{
|
||||
update_stage = @"shootin' zombies";
|
||||
NSEnumerator *zombieEnum = nil;
|
||||
Entity *zombie = nil;
|
||||
for (zombieEnum = [zombies objectEnumerator]; (zombie = [zombieEnum nextObject]); )
|
||||
{
|
||||
OOLogERR(@"universe.zombie", @"Found dead entity %@ in active entity list, removing. This is an internal error, please report it.", zombie);
|
||||
[self removeEntity:zombie];
|
||||
}
|
||||
}
|
||||
|
||||
// Maintain x/y/z order lists
|
||||
update_stage = @"updating linked lists";
|
||||
for (i = 0; i < ent_count; i++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user