Ares
Public Member Functions | Public Attributes

BuildingExt::ExtData Class Reference

#include <src/Ext/Building/Body.h>

Inheritance diagram for BuildingExt::ExtData:
Extension< TT >

List of all members.

Public Member Functions

bool InfiltratedBy (HouseClass *Enterer)
 ExtData (const DWORD Canary, TT *const OwnerObject)
virtual ~ExtData ()
virtual size_t Size () const
virtual void InvalidatePointer (void *ptr)
bool RubbleYell (bool beingRepaired=false)
 This function switches the building into its Advanced Rubble state or back to normal.
void KickOutOfRubble ()
 Bumps all Technos that reside on a building's foundation out of the way.
bool canTraverseTo (BuildingClass *targetBuilding)
 This function checks if occupants of the current building can, on principle, move on to the target building.
void doTraverseTo (BuildingClass *targetBuilding)
 This function moves as many occupants as possible from the current to the target building.
bool sameTrench (BuildingClass *targetBuilding)
 This function checks if the current and the target building are both of the same trench kind.
bool isLinkable ()
 Returns true if this is a structure that can be linked to other structures, like a wall, fence, or trench. This is used to quick-check if the game has to look for linkable buildings in the first place.
bool canLinkTo (BuildingClass *targetBuilding)
 Checks if the current building can link to the given target building.
void evalRaidStatus ()
 Checks if the building is empty but still marked as raided, and returns the building to its previous owner, if so.
void UpdateFirewall ()
void ImmolateVictims ()
void ImmolateVictim (ObjectClass *Victim)
bool ReverseEngineer (TechnoClass *Victim)
 Returns true if Victim wasn't buildable and now should be.

Public Attributes

HouseClass * OwnerBeforeRaid
 Contains the house which owned this building prior to it being raided and turned over to the raiding party.
bool isCurrentlyRaided
 Whether this building is currently occupied by someone not the actual owner of the structure.
bool ignoreNextEVA
 This is used when returning raided buildings, to decide whether to play EVA announcements about building capture.
bool FreeUnits_Done
 Prevent free units and aircraft to be created multiple times. Set when the free units have been granted.
bool AboutToChronoshift
 This building is going to be shifted. It should not be attacked with temporal weapons now. Otherwise it would disappear.
cPrismForwarding PrismForwarding
std::set< TechnoClass * > RegisteredJammers
 Set of Radar Jammers which have registered themselves to be in range of this building. (Related to issue #305)

Constructor & Destructor Documentation

BuildingExt::ExtData::ExtData ( const DWORD  Canary,
TT *const  OwnerObject 
) [inline]
virtual BuildingExt::ExtData::~ExtData ( ) [inline, virtual]

Member Function Documentation

bool BuildingExt::ExtData::canLinkTo ( BuildingClass *  targetBuilding)

Checks if the current building can link to the given target building.

Parameters:
targetBuildingthe building to check for compatibility.
Returns:
true if the two buildings can be linked.
See also:
isLinkable()
                                                                {
        BuildingClass* currentBuilding = this->AttachedToObject;

        // Different owners // and owners not allied
        if((currentBuilding->Owner != targetBuilding->Owner) && !currentBuilding->Owner->IsAlliedWith(targetBuilding->Owner)) { //<-- see thread 1424
                return false;
        }

        BuildingTypeExt::ExtData* currentTypeExtData = BuildingTypeExt::ExtMap.Find(currentBuilding->Type);
        BuildingTypeExt::ExtData* targetTypeExtData = BuildingTypeExt::ExtMap.Find(targetBuilding->Type);

        // Firewalls
        if(currentTypeExtData->Firewall_Is && targetTypeExtData->Firewall_Is) {
                return true;
        }

        // Trenches
        if(this->sameTrench(targetBuilding)) {
                return true;
        }

        return false;
}
bool BuildingExt::ExtData::canTraverseTo ( BuildingClass *  targetBuilding)

This function checks if occupants of the current building can, on principle, move on to the target building.

Conditions checked are whether there are occupants in the current building, whether the target building is full, whether the current building even is a trench, and whether both buildings are of the same trench kind.

The current system assumes 1x1 sized trench parts; it will probably work in all cases where the 0,0 (top) cells of buildings touch (e.g. a 3x3 building next to a 1x3 building), but not when the 0,0 cells are further apart. This may be changed at a later point in time, if there is demand for it.

Parameters:
targetBuildinga pointer to the target building.
Returns:
true if traversal between both buildings is legal, otherwise false.
See also:
doTraverseTo()
Author:
Renegade
Date:
16.12.09+
                                                                    {
        BuildingClass* currentBuilding = this->AttachedToObject;
        //BuildingTypeClass* currentBuildingType = game_cast<BuildingTypeClass *>(currentBuilding->GetTechnoType());
        BuildingTypeClass* targetBuildingType = targetBuilding->Type;

        if((targetBuilding == currentBuilding)
                || (targetBuilding->Occupants.Count >= targetBuildingType->MaxNumberOccupants)
                || !currentBuilding->Occupants.Count
                || !targetBuildingType->CanBeOccupied) { // I'm a little if-clause short and stdout... // beat you to the punchline -- D
                // Can't traverse if there's no one to move, or the target is full, we can't actually occupy the target,
                // or if it's actually the same building
                return false;
        }

        BuildingTypeExt::ExtData* currentBuildingTypeExt = BuildingTypeExt::ExtMap.Find(currentBuilding->Type);
        BuildingTypeExt::ExtData* targetBuildingTypeExt = BuildingTypeExt::ExtMap.Find(targetBuilding->Type);

        if(this->sameTrench(targetBuilding)) {
                // if we've come here, there's room, there are people to move, and the buildings are trenches and of the same kind
                // the only questioning remaining is whether they are next to each other.
                // if the target building is more than 256 leptons away, it's not on a straight neighboring cell.
                return targetBuilding->Location.DistanceFrom(currentBuilding->Location) <= 256.0;

        } else {
                return false; // not the same trench kind or not a trench
        }

}
void BuildingExt::ExtData::doTraverseTo ( BuildingClass *  targetBuilding)

This function moves as many occupants as possible from the current to the target building.

This function will move occupants from the current building to the target building until either a) the target building is full, or b) the current building is empty.

Warning:
The function assumes the legality of the traversal was checked beforehand with canTraverseTo(), and will therefore not do any safety checks.
Parameters:
targetBuildinga pointer to the target building.
See also:
canTraverseTo()
Author:
Renegade
Date:
16.12.09+
                                                                   {
        BuildingClass* currentBuilding = this->AttachedToObject;
        BuildingTypeClass* targetBuildingType = targetBuilding->Type;

        // depending on Westwood's handling, this could explode when Size > 1 units are involved...but don't tell the users that
        while(currentBuilding->Occupants.Count && (targetBuilding->Occupants.Count < targetBuildingType->MaxNumberOccupants)) {
                targetBuilding->Occupants.AddItem(currentBuilding->Occupants.GetItem(0));
                currentBuilding->Occupants.RemoveItem(0); // maybe switch Add/Remove if the game gets pissy about multiple of them walking around
        }

        this->evalRaidStatus(); // if the traversal emptied the current building, it'll have to be returned to its owner
}
void BuildingExt::ExtData::evalRaidStatus ( )

Checks if the building is empty but still marked as raided, and returns the building to its previous owner, if so.

                                        {
        // if the building is still marked as raided, but unoccupied, return it to its previous owner
        if(this->isCurrentlyRaided && !this->AttachedToObject->Occupants.Count) {
                // Fix for #838: Only return the building to the previous owner if he hasn't been defeated
                if(!this->OwnerBeforeRaid->Defeated) {
                        this->ignoreNextEVA = true; // #698 - used in BuildingClass_ChangeOwnership_TrenchEVA to override EVA announcement
                        this->AttachedToObject->SetOwningHouse(this->OwnerBeforeRaid);
                }
                this->OwnerBeforeRaid = NULL;
                this->isCurrentlyRaided = false;
        }
}
void BuildingExt::ExtData::ImmolateVictim ( ObjectClass *  Victim)
                                                            {
        BuildingClass *pThis = this->AttachedToObject;
        if(generic_cast<TechnoClass *>(Victim) && Victim != pThis && !Victim->InLimbo && Victim->IsAlive && Victim->Health) {
                CoordStruct XYZ;
                Victim->GetCoords(&XYZ);
                int Damage = Victim->Health;
                Victim->ReceiveDamage(&Damage, 0, RulesClass::Instance->C4Warhead/* todo */, 0, 1, 0, pThis->Owner);

                if(AnimTypeClass *FSAnim = AnimTypeClass::Find(Victim->IsInAir() ? "FSAIR" : "FSGRND")) {
                        AnimClass * placeholder;
                        GAME_ALLOC(AnimClass, placeholder, FSAnim, &XYZ);
                }

        }
}
void BuildingExt::ExtData::ImmolateVictims ( )
                                         {
        CellClass *C = this->AttachedToObject->GetCell();
        for(ObjectClass *O = C->GetContent(); O; O = O->NextObject) {
                this->ImmolateVictim(O);
        }
}
bool BuildingExt::ExtData::InfiltratedBy ( HouseClass *  Enterer)
                                                          {
        BuildingClass *EnteredBuilding = this->AttachedToObject;
        BuildingTypeClass *EnteredType = EnteredBuilding->Type;
        HouseClass *Owner = EnteredBuilding->Owner;
        BuildingTypeExt::ExtData* pTypeExt = BuildingTypeExt::ExtMap.Find(EnteredBuilding->Type);
        HouseExt::ExtData* pEntererExt = HouseExt::ExtMap.Find(Enterer);

        if(!pTypeExt->InfiltrateCustom) {
                return false;
        }

        if(Owner == Enterer) {
                return true;
        }

        bool raiseEva = false;

        if(Enterer->ControlledByPlayer() || Owner->ControlledByPlayer()) {
                CellStruct xy;
                EnteredBuilding->GetMapCoords(&xy);
                if(RadarEventClass::Create(RADAREVENT_STRUCTUREINFILTRATED, xy)) {
                        raiseEva = true;
                }
        }

        bool evaForOwner = Owner->ControlledByPlayer() && raiseEva;
        bool evaForEnterer = Enterer->ControlledByPlayer() && raiseEva;
        bool effectApplied = false;

        if(pTypeExt->ResetRadar.Get()) {
                Owner->ReshroudMap();
                if(!Owner->SpySatActive && evaForOwner) {
                        VoxClass::Play("EVA_RadarSabotaged");
                }
                if(!Owner->SpySatActive && evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfRadarSabotaged");
                }
                effectApplied = true;
        }


        if(pTypeExt->PowerOutageDuration > 0) {
                Owner->CreatePowerOutage(pTypeExt->PowerOutageDuration);
                if(evaForOwner) {
                        VoxClass::Play("EVA_PowerSabotaged");
                }
                if(evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfiltrated");
                        VoxClass::Play("EVA_EnemyBasePoweredDown");
                }
                effectApplied = true;
        }


        if(pTypeExt->StolenTechIndex > -1) {
                pEntererExt->StolenTech.set(pTypeExt->StolenTechIndex);

                Enterer->ShouldRecheckTechTree = true;
                if(evaForOwner) {
                        VoxClass::Play("EVA_TechnologyStolen");
                }
                if(evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfiltrated");
                        VoxClass::Play("EVA_NewTechnologyAcquired");
                }
                effectApplied = true;
        }


        if(pTypeExt->UnReverseEngineer.Get()) {
                int idx = HouseClass::Array->FindItemIndex(&Owner);

                Debug::Log("Undoing all Reverse Engineering achieved by house %ls (#%d)\n", Owner->UIName, idx);

                if(idx != -1) {
                        for(int i = 0; i < TechnoTypeClass::Array->Count; ++i) {
                                TechnoTypeClass * Type = TechnoTypeClass::Array->GetItem(i);
                                TechnoTypeExt::ExtData * TypeData = TechnoTypeExt::ExtMap.Find(Type);
                                if(TypeData->ReversedByHouses.ValidIndex(idx)) {
                                        Debug::Log("Zeroing out RevEng of %s\n", Type->ID);
                                        TypeData->ReversedByHouses[idx] = false;
                                }
                        }
                        Owner->ShouldRecheckTechTree = true;
                }

                if(evaForOwner) {
                        VoxClass::Play("EVA_BuildingInfiltrated");
                }
                if(evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfiltrated");
                }
                effectApplied = true;
        }


        if(pTypeExt->ResetSW.Get()) {
                bool somethingReset = false;
                int swIdx = EnteredType->SuperWeapon;
                if(swIdx != -1) {
                        Owner->Supers.Items[swIdx]->Reset();
                        somethingReset = true;
                }
                swIdx = EnteredType->SuperWeapon2;
                if(swIdx != -1) {
                        Owner->Supers.Items[swIdx]->Reset();
                        somethingReset = true;
                }
                for(int i = 0; i < EnteredType->Upgrades; ++i) {
                        if(BuildingTypeClass *Upgrade = EnteredBuilding->Upgrades[i]) {
                                swIdx = Upgrade->SuperWeapon;
                                if(swIdx != -1) {
                                        Owner->Supers.Items[swIdx]->Reset();
                                        somethingReset = true;
                                }
                                swIdx = Upgrade->SuperWeapon2;
                                if(swIdx != -1) {
                                        Owner->Supers.Items[swIdx]->Reset();
                                        somethingReset = true;
                                }
                        }
                }

                if(somethingReset) {
                        if(evaForOwner || evaForEnterer) {
                                VoxClass::Play("EVA_BuildingInfiltrated");
                        }
                        effectApplied = true;
                }
        }


        int bounty = 0;
        int available = Owner->Available_Money();
        if(pTypeExt->StolenMoneyAmount > 0) {
                bounty = pTypeExt->StolenMoneyAmount;
        } else if(pTypeExt->StolenMoneyPercentage > 0) {
                bounty = int(available * pTypeExt->StolenMoneyPercentage);
        }
        if(bounty > 0) {
                bounty = std::min(bounty, available);
                Owner->TakeMoney(bounty);
                Enterer->GiveMoney(bounty);
                if(evaForOwner) {
                        VoxClass::Play("EVA_CashStolen");
                }
                if(evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfCashStolen");
                }
                effectApplied = true;
        }


        if(pTypeExt->GainVeterancy.Get()) {
                bool promotionStolen = true;

                switch(EnteredType->Factory) {
                        case UnitTypeClass::AbsID:
                                Enterer->WarFactoryInfiltrated = true;
                                break;
                        case InfantryTypeClass::AbsID:
                                Enterer->BarracksInfiltrated = true;
                                break;
                                // TODO: aircraft/building
                        default:
                                promotionStolen = false;
                }

                if(promotionStolen) {
                        Enterer->ShouldRecheckTechTree = true;
                        if(Enterer->ControlledByPlayer()) {
                                MouseClass::Instance->SidebarNeedsRepaint();
                        }
                        if(evaForOwner) {
                                VoxClass::Play("EVA_TechnologyStolen");
                        }
                        if(evaForEnterer) {
                                VoxClass::Play("EVA_BuildingInfiltrated");
                                VoxClass::Play("EVA_NewTechnologyAcquired");
                        }
                        effectApplied = true;
                }
        }


        /*      RA1-Style Spying, as requested in issue #633
                This sets the respective bit to inform the game that a particular house has spied this building.
                Knowing that, the game will reveal the current production in this building to the players who have spied it.
                In practice, this means: If a player who has spied a factory clicks on that factory,
                he will see the cameo of whatever is being built in the factory.

                Addition 04.03.10: People complained about it not being optional. Now it is.
        */
        if(pTypeExt->RevealProduction.Get()) {
                EnteredBuilding->DisplayProductionTo.Add(Enterer);
                if(evaForOwner || evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfiltrated");
                }
                effectApplied = true;
        }

        if(pTypeExt->RevealRadar.Get()) {
                EnteredBuilding->DisplayProductionTo.Add(Enterer);
                BuildingExt::UpdateDisplayTo(EnteredBuilding);
                if(evaForOwner || evaForEnterer) {
                        VoxClass::Play("EVA_BuildingInfiltrated");
                }
                MapClass::Instance->sub_657CE0();
                MapClass::Instance->RedrawSidebar(2);
                effectApplied = true;
        }

        if(effectApplied) {
                EnteredBuilding->SetLayer(Layer::Ground);
        }
        return true;
}
virtual void BuildingExt::ExtData::InvalidatePointer ( void *  ptr) [inline, virtual]

Implements Extension< TT >.

                                                          {
                        AnnounceInvalidPointer(OwnerBeforeRaid, ptr);
                }
bool BuildingExt::ExtData::isLinkable ( )

Returns true if this is a structure that can be linked to other structures, like a wall, fence, or trench. This is used to quick-check if the game has to look for linkable buildings in the first place.

See also:
canLinkTo()
                                    {
        BuildingTypeExt::ExtData* typeExtData = BuildingTypeExt::ExtMap.Find(this->AttachedToObject->Type);
        return typeExtData->IsLinkable();
}
void BuildingExt::ExtData::KickOutOfRubble ( )

Bumps all Technos that reside on a building's foundation out of the way.

All units on the building's foundation are kicked out.

Author:
AlexB
Date:
2010-06-27
                                         {
        BuildingClass* pBld = this->AttachedToObject;

        if(BuildingTypeExt::ExtData *pData = BuildingTypeExt::ExtMap.Find(pBld->Type)) {
                // get the number of cells and a pointer to the cell data
                int length = 0, height = 0, width = 0;
                CellStruct *data = NULL;
                if(pData->IsCustom) {
                        width = pData->CustomWidth;
                        height = pData->CustomHeight;
                        data = pData->CustomData;
                } else {
                        // these are length constants derived from the fnd_* constants
                        int fnd_widths[] = {1, 2, 1, 2, 2, 3, 3, 3, 4, 3, 1, 3, 4, 1, 1, 2, 2, 5, 4, 3, 6, 0};
                        int fnd_heights[] = {1, 1, 2, 2, 3, 2, 3, 5, 2, 3, 3, 1, 3, 4, 5, 6, 5, 3, 4, 4, 4, 0};
                        width = fnd_widths[pBld->Type->Foundation];
                        height = fnd_heights[pBld->Type->Foundation];
                        data = pBld->Type->FoundationData;
                }
                length = height * width;

                // iterate over all cells and remove all infantry
                DynamicVectorClass<TechnoClass*> *list = new DynamicVectorClass<TechnoClass*>();
                DynamicVectorClass<bool> *sel = new DynamicVectorClass<bool>();
                CellStruct location = MapClass::Instance->GetCellAt(&pBld->Location)->MapCoords;
                for(int i=0; i<length; ++i) {
                        CellStruct pos = data[i];
                        if((pos.X != 0x7FFF) && (pos.Y != 0x7FFF)) {
                                pos += location;

                                // remove every techno that resides on this cell
                                CellClass* cell = MapClass::Instance->GetCellAt(&pos);
                                for(ObjectClass* pObj = cell->GetContent(); pObj; pObj = pObj->NextObject) {
                                        if(TechnoClass* pTech = generic_cast<FootClass*>(pObj)) {
                                                bool bSel = pTech->IsSelected;
                                                if(pTech->Remove()) {
                                                        list->AddItem(pTech);
                                                        sel->AddItem(bSel);
                                                }
                                        }
                                }
                        } else {
                                // invalid cell.
                                break;
                        }
                }

                // this part kicks out all units we found in the rubble
                for(int i=0; i<list->Count; ++i) {
                        TechnoClass* pTech = list->GetItem(i);
                        pBld->KickOutUnit(pTech, &location);
                        if(sel->GetItem(i)) {
                                pTech->Select();
                        }
                }

                delete list;
                delete sel;
        }
}
bool BuildingExt::ExtData::ReverseEngineer ( TechnoClass *  Victim)

Returns true if Victim wasn't buildable and now should be.

                                                            {
        BuildingTypeExt::ExtData *pReverseData = BuildingTypeExt::ExtMap.Find(this->AttachedToObject->Type);
        if(!pReverseData->ReverseEngineersVictims) {
                return false;
        }

        TechnoTypeClass * VictimType = Victim->GetTechnoType();
        TechnoTypeExt::ExtData *pVictimData = TechnoTypeExt::ExtMap.Find(VictimType);

        if(!pVictimData->CanBeReversed) {
                return false;
        }

        HouseClass *Owner = this->AttachedToObject->Owner;

        int idx = HouseClass::Array->FindItemIndex(&Owner);

        if(pVictimData->ReversedByHouses.ValidIndex(idx)) {
                if(!pVictimData->ReversedByHouses[idx]) {

                        bool WasBuildable = HouseExt::PrereqValidate(Owner, VictimType, false, true) == 1;
                        pVictimData->ReversedByHouses[idx] = true;
                        if(!WasBuildable) {
                                bool IsBuildable = HouseExt::RequirementsMet(Owner, VictimType) != HouseExt::Forbidden;
                                if(IsBuildable) {
                                        Owner->ShouldRecheckTechTree = true;
                                        return true;
                                }
                        }
                }
        }
        return false;
}
bool BuildingExt::ExtData::RubbleYell ( bool  beingRepaired = false)

This function switches the building into its Advanced Rubble state or back to normal.

If no respective target-state object exists in the ExtData so far, the function will create it. It'll check beforehand whether the necessary Rubble.Intact or Rubble.Destroyed are actually set on the type. If the necessary one is not set, it'll log a debug message and abort.

Rubble is set to full health on placing, since, no matter what we do in the backend, to the player, each pile of rubble is a new one. The reconstructed building, on the other hand, is set to 1% of it's health, since it was just no reconstructed, and not freshly built or repaired yet.

Lastly, the function will set the current building as the alternate state on the other state, to ensure that, if the other state gets triggered back, it is connected to this state. (e.g. when a building is turned into rubble, the normal state will set itself as the normal state of the rubble, so when the rubble is reconstructed, it switches back to the correct normal state.)

Parameters:
beingRepairedif set to true, the function will turn the building back into its normal state. If false or unset, the building will be turned into rubble.
Returns:
true if the new state could be deployed, false otherwise.
Author:
Renegade
Date:
16.12.09+
                                                      {
        BuildingClass* currentBuilding = this->AttachedToObject;
        BuildingTypeExt::ExtData* pTypeData = BuildingTypeExt::ExtMap.Find(currentBuilding->Type);
        BuildingClass* newState = NULL;

        currentBuilding->Remove(); // only takes it off the map
        currentBuilding->DestroyNthAnim(BuildingAnimSlot::All);

        if(beingRepaired) {
                if(!pTypeData->RubbleIntact) {
                        Debug::Log("Warning! Advanced Rubble was supposed to be reconstructed but Ares could not obtain its normal state. \
                        Check if [%s]Rubble.Intact is set (correctly).\n", currentBuilding->Type->ID);
                        return true;
                }

                newState = specific_cast<BuildingClass *>(pTypeData->RubbleIntact->CreateObject(currentBuilding->Owner));
                newState->Health = static_cast<int>(std::max((newState->Type->Strength / 100), 1)); // see description above
                newState->IsAlive = true; // assuming this is in the sense of "is not destroyed"
                // Location should not be changed by removal
                if(!newState->Put(&currentBuilding->Location, currentBuilding->Facing)) {
                        Debug::Log("Advanced Rubble: Failed to place normal state on map!\n");
                        GAME_DEALLOC(newState);
                        return false;
                }
                // currentBuilding->UnInit(); DON'T DO THIS

        } else { // if we're not here to repair that thing, obviously, we're gonna crush it
                if(!pTypeData->RubbleDestroyed) {
                        Debug::Log("Warning! Building was supposed to be turned into Advanced Rubble but Ares could not obtain its rubble state. \
                        Check if [%s]Rubble.Destroyed is set (correctly).\n", currentBuilding->Type->ID);
                        return true;
                }

                newState = specific_cast<BuildingClass *>(pTypeData->RubbleDestroyed->CreateObject(currentBuilding->Owner));
                // Location should not be changed by removal
                if(!newState->Put(&currentBuilding->Location, currentBuilding->Facing)) {
                        Debug::Log("Advanced Rubble: Failed to place rubble state on map!\n");
                        GAME_DEALLOC(newState);
                }
        }

        return true;
}
bool BuildingExt::ExtData::sameTrench ( BuildingClass *  targetBuilding)

This function checks if the current and the target building are both of the same trench kind.

Parameters:
targetBuildinga pointer to the target building.
Returns:
true if both buildings are trenches and are of the same trench kind, otherwise false.
Author:
Renegade
Date:
25.12.09+
                                                                 {
        BuildingTypeExt::ExtData* currentTypeExtData = BuildingTypeExt::ExtMap.Find(this->AttachedToObject->Type);
        BuildingTypeExt::ExtData* targetTypeExtData = BuildingTypeExt::ExtMap.Find(targetBuilding->Type);

        return ((currentTypeExtData->IsTrench > -1) && (currentTypeExtData->IsTrench == targetTypeExtData->IsTrench));
}
virtual size_t BuildingExt::ExtData::Size ( ) const [inline, virtual]

Implements Extension< TT >.

{ return sizeof(*this); };
void BuildingExt::ExtData::UpdateFirewall ( )
                                        {
        BuildingClass *B = this->AttachedToObject;
        BuildingTypeClass *BT = B->Type;
        HouseClass *H = B->Owner;
        BuildingTypeExt::ExtData* pTypeData = BuildingTypeExt::ExtMap.Find(BT);

        if(!pTypeData->Firewall_Is) {
                return;
        }

        HouseExt::ExtData *pHouseData = HouseExt::ExtMap.Find(H);
        bool FS = pHouseData->FirewallActive;

        DWORD FWFrame = BuildingExt::GetFirewallFlags(B);
        if(FS) {
                FWFrame += 32;
        }

        if(B->FirestormWallFrame != FWFrame) {
                if(!pHouseData->FirewallRecalc) {
                        pHouseData->FirewallRecalc = 1;
                }
                B->FirestormWallFrame = FWFrame;
                B->GetCell()->Setup(0xFFFFFFFF);
                B->SetLayer(Layer::Ground); // HACK - repaints properly
        }

        if(!FS) {
                return;
        }

        if(!(Unsorted::CurrentFrame % 7) && ScenarioClass::Instance->Random.RandomRanged(0, 15) == 1) {
                int corners = (FWFrame & 0xF); // 1111b
                if(AnimClass *IdleAnim = B->FirestormAnim) {
                        GAME_DEALLOC(IdleAnim);
                        B->FirestormAnim = 0;
                }
                if(corners != 5 && corners != 10) {  // (0101b || 1010b) == part of a straight line
                        CoordStruct XYZ;
                        B->GetCoords(&XYZ);
                        XYZ.X -= 768;
                        XYZ.Y -= 768;
                        if(AnimTypeClass *FSA = AnimTypeClass::Find("FSIDLE")) {
                                GAME_ALLOC(AnimClass, B->FirestormAnim, FSA, &XYZ);
                        }
                }
        }

        this->ImmolateVictims();
}

Member Data Documentation

This building is going to be shifted. It should not be attacked with temporal weapons now. Otherwise it would disappear.

Prevent free units and aircraft to be created multiple times. Set when the free units have been granted.

This is used when returning raided buildings, to decide whether to play EVA announcements about building capture.

Whether this building is currently occupied by someone not the actual owner of the structure.

Contains the house which owned this building prior to it being raided and turned over to the raiding party.

std::set<TechnoClass *> BuildingExt::ExtData::RegisteredJammers

Set of Radar Jammers which have registered themselves to be in range of this building. (Related to issue #305)


The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines