From 20c1ee1fcecbcb341542f46bcb2719c1f8342b5d Mon Sep 17 00:00:00 2001 From: jarod42 <> Date: Fri, 22 Oct 2004 15:55:59 +0000 Subject: [PATCH] Fix bug #1048426 [BOS] segfault with a map. Fact of die should be correct now. --- src/unit/unit.cpp | 99 ++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 65 deletions(-) diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 4baa6c4b1..15b52001e 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -95,6 +95,8 @@ static int HelpMeLastY; ///< Last Y coordinate HelpMe sound pl -- Functions ----------------------------------------------------------------------------*/ +static void RemoveUnitFromContainer(Unit* unit); + /** ** Initial memory allocation for units. */ @@ -197,6 +199,11 @@ void ReleaseUnit(Unit* unit) // unit->Destroyed = 1; // mark as destroyed + if (unit->Container) { + MapUnmarkUnitSight(unit); + RemoveUnitFromContainer(unit); + } + if (--unit->Refs > 0) { return; } @@ -827,7 +834,7 @@ void RemoveUnit(Unit* unit, Unit* host) { if (unit->Removed) { // could happen! // If unit is removed (inside) and building is destroyed. - DebugPrint("unit '%s' already remove" _C_ unit->Type->Ident); + DebugPrint("unit '%s(%d)' already removed\n" _C_ unit->Type->Ident _C_ unit->Slot); return; } UnitCacheRemove(unit); @@ -2893,7 +2900,6 @@ void LetUnitDie(Unit* unit) 0, 0); } - // // Handle Teleporter Destination Removal if (type->Teleporter && unit->Goal) { RemoveUnit(unit->Goal, NULL); @@ -2903,66 +2909,18 @@ void LetUnitDie(Unit* unit) unit->Goal = NULL; } - // - // Building,... - // - if (type->Building) { - // - // Building with units inside? - // - // - // During resource build, the worker holds the resource amount, - // but if canceling building the platform, the worker is already - // outside. - if (type->GivesResource && - unit->Orders[0].Action == UnitActionBuilded && - unit->Data.Builded.Worker) { - // Restore value for oil-patch - unit->ResourcesHeld = unit->Data.Builded.Worker->ResourcesHeld; - } - - DestroyAllInside(unit); - RemoveUnit(unit, NULL); - UnitLost(unit); - UnitClearOrders(unit); - - // FIXME: buildings should get a die sequence - - if (type->CorpseType) { - unit->State = unit->Type->CorpseScript; - Assert(type->TileWidth == type->CorpseType->TileWidth && - type->TileHeight == type->CorpseType->TileHeight); - type = unit->Type = type->CorpseType; - -#ifdef DYNAMIC_LOAD - if (!type->Sprite) { - LoadUnitTypeSprite(type); - } -#endif - unit->IX = (type->Width - VideoGraphicWidth(type->Sprite)) / 2; - unit->IY = (type->Height - VideoGraphicHeight(type->Sprite)) / 2; - - unit->SubAction = 0; - unit->Removed = 0; - unit->Frame = 0; - unit->Orders[0].Action = UnitActionDie; - - Assert(unit->Type->Animations && - unit->Type->Animations->Die); - UnitShowAnimation(unit, unit->Type->Animations->Die); - DebugPrint("Frame %d\n" _C_ unit->Frame); - unit->CurrentSightRange = type->Stats[unit->Player->Player].SightRange; - MapMarkUnitSight(unit); - UnitCacheInsert(unit); - } else { - // no corpse available - unit->CurrentSightRange = 0; - } - return; + // During resource build, the worker holds the resource amount, + // but if canceling building the platform, the worker is already + // outside. + if (type->GivesResource && + unit->Orders[0].Action == UnitActionBuilded && + unit->Data.Builded.Worker) { + // Restore value for oil-patch + unit->ResourcesHeld = unit->Data.Builded.Worker->ResourcesHeld; } - // Transporters lose their units - if (unit->Type->CanTransport) { + // Transporters lose their units and building their workers + if (unit->UnitInside) { // FIXME: destroy or unload : do a flag. DestroyAllInside(unit); } @@ -2980,14 +2938,25 @@ void LetUnitDie(Unit* unit) unit->Reset = 0; unit->Wait = 1; unit->Orders[0].Action = UnitActionDie; - if (unit->Type->CorpseType) { - unit->CurrentSightRange = unit->Type->CorpseType->Stats[unit->Player->Player].SightRange; - MapMarkUnitSight(unit); + if (type->CorpseType) { +#ifdef DYNAMIC_LOAD + if (!type->Sprite) { + LoadUnitTypeSprite(type); + } +#endif + unit->IX = (type->CorpseType->Width - VideoGraphicWidth(type->CorpseType->Sprite)) / 2; + unit->IY = (type->CorpseType->Height - VideoGraphicHeight(type->CorpseType->Sprite)) / 2; + + unit->CurrentSightRange = type->CorpseType->Stats[unit->Player->Player].SightRange; } else { unit->CurrentSightRange = 0; } - unit->Removed = 0; - UnitCacheInsert(unit); + MapMarkUnitSight(unit); + + if (type->CorpseType || (type->Animations && type->Animations->Die)) { + unit->Removed = 0; + UnitCacheInsert(unit); + } } /**