From 6ba078a08e74b8a20229f212b043535bade61dfb Mon Sep 17 00:00:00 2001 From: Jens Ayton Date: Sun, 3 Jan 2010 12:46:16 +0000 Subject: [PATCH] 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 --- src/Core/Entities/PlayerEntitySound.m | 2 +- src/Core/Entities/ShipEntity.m | 160 +++++++++++++------------- src/Core/Universe.m | 23 +++- 3 files changed, 105 insertions(+), 80 deletions(-) diff --git a/src/Core/Entities/PlayerEntitySound.m b/src/Core/Entities/PlayerEntitySound.m index cf50379d..e5701f59 100644 --- a/src/Core/Entities/PlayerEntitySound.m +++ b/src/Core/Entities/PlayerEntitySound.m @@ -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 { diff --git a/src/Core/Entities/ShipEntity.m b/src/Core/Entities/ShipEntity.m index aa290563..ac34de16 100644 --- a/src/Core/Entities/ShipEntity.m +++ b/src/Core/Entities/ShipEntity.m @@ -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 } diff --git a/src/Core/Universe.m b/src/Core/Universe.m index a0d83958..a79074b9 100644 --- a/src/Core/Universe.m +++ b/src/Core/Universe.m @@ -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++)