Ares
Public Member Functions | Public Attributes

TechnoTypeExt::ExtData Class Reference

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

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

List of all members.

Public Member Functions

 ExtData (const DWORD Canary, TT *const OwnerObject)
virtual ~ExtData ()
virtual size_t Size () const
virtual void LoadFromINIFile (TT *pThis, CCINIClass *pINI)
virtual void Initialize (TT *pThis)
virtual void InvalidatePointer (void *ptr)
bool CameoIsElite ()

Public Attributes

DynamicVectorClass
< InfantryTypeClass * > 
Survivors_Pilots
Promotable< int > Survivors_PilotChance
Promotable< int > Survivors_PassengerChance
int Survivors_PilotCount
 Defines the number of pilots inside this vehicle if Crewed=yes; maximum number of pilots who can survive. Defaults to 0 if Crewed=no; defaults to 1 if Crewed=yes. // NOTE: Flag in INI is called Survivor.Pilots.
DynamicVectorClass
< DynamicVectorClass< int > * > 
PrerequisiteLists
DynamicVectorClass< int > PrerequisiteNegatives
DWORD PrerequisiteTheaters
DWORD Secret_RequiredHouses
DWORD Secret_ForbiddenHouses
bool Is_Deso
bool Is_Deso_Radiation
bool Is_Cow
bool Is_Spotlighted
int Spot_Height
int Spot_Distance
SpotlightAttachment Spot_AttachedTo
bool Spot_DisableR
bool Spot_DisableG
bool Spot_DisableB
bool Spot_Reverse
bool Is_Bomb
DynamicVectorClass< WeaponStruct > Weapons
DynamicVectorClass< WeaponStruct > EliteWeapons
Promotable< SHPStruct * > Insignia
Valueable< AnimTypeClass * > Parachute_Anim
InfantryTypeClass * Operator
 Saves a pointer to an InfantryType required to be a passenger of this unit in order for it to work. Defaults to NULL.
bool IsAPromiscuousWhoreAndLetsAnyoneRideIt
 If this is true, Operator= is not checked, and the object will work with any passenger, provided there is one.
CustomPalette CameoPal
std::bitset< 32 > RequiredStolenTech
Customizable< bool > ImmuneToEMP
bool VeteranAbilityEMPIMMUNE
bool EliteAbilityEMPIMMUNE
int EMP_Threshold
float EMP_Modifier
float IC_Modifier
Valueable< bool > Chronoshift_Allow
Valueable< bool > Chronoshift_IsVehicle
bool ProtectedDriver
 Whether the driver of this vehicle cannot be killed, i.e. whether this vehicle is immune to KillDriver. Request #733.
bool CanDrive
 Whether this TechnoType can act as the driver of vehicles whose driver has been killed. Request #733.
bool AlternateTheaterArt
bool PassengersGainExperience
bool ExperienceFromPassengers
float PassengerExperienceModifier
float MindControlExperienceSelfModifier
float MindControlExperienceVictimModifier
bool ExperienceFromAirstrike
float AirstrikeExperienceModifier
ValueableIdx< int, VocClass > VoiceRepair
Customizable< UnitTypeClass * > WaterImage
char CameoPCX [0x20]
char AltCameoPCX [0x20]
DynamicVectorClass< bool > ReversedByHouses
Valueable< bool > CanBeReversed
Valueable< int > RadarJamRadius
 Distance in cells to scan for & jam radars.
Valueable< bool > PassengerTurret
 Whether this unit's turret changes based on the number of people in its passenger hold.
DynamicVectorClass
< BuildingTypeClass * > 
PoweredBy
 The buildingtype this unit is powered by or NULL.

Constructor & Destructor Documentation

TechnoTypeExt::ExtData::ExtData ( const DWORD  Canary,
TT *const  OwnerObject 
) [inline]
virtual TechnoTypeExt::ExtData::~ExtData ( ) [inline, virtual]
{};

Member Function Documentation

bool TechnoTypeExt::ExtData::CameoIsElite ( )
{
        HouseClass * House = HouseClass::Player;
        HouseTypeClass *Country = House->Type;

        TechnoTypeClass * const T = this->AttachedToObject;
        TechnoTypeExt::ExtData* pExt = TechnoTypeExt::ExtMap.Find(T);

        if(!T->AltCameo && !*pExt->AltCameoPCX) {
                return false;
        }

        switch(T->WhatAmI()) {
                case abs_InfantryType:
                        if(House->BarracksInfiltrated && !T->Naval && T->Trainable) {
                                return true;
                        } else {
                                return Country->VeteranInfantry.FindItemIndex((InfantryTypeClass **)&T) != -1;
                        }
                case abs_UnitType:
                        if(House->WarFactoryInfiltrated && !T->Naval && T->Trainable) {
                                return true;
                        } else {
                                return Country->VeteranUnits.FindItemIndex((UnitTypeClass **)&T) != -1;
                        }
                case abs_AircraftType:
                        return Country->VeteranAircraft.FindItemIndex((AircraftTypeClass **)&T) != -1;
                case abs_BuildingType:
                        if(TechnoTypeClass *Item = T->UndeploysInto) {
                                return Country->VeteranUnits.FindItemIndex((UnitTypeClass **)&Item) != -1;
                        }
        }

        return false;
}
void TechnoTypeExt::ExtData::Initialize ( TT pThis) [virtual]
                                                            {
        this->Survivors_PilotChance.SetAll(int(RulesClass::Instance->CrewEscape * 100));
        this->Survivors_PassengerChance.SetAll(-1); // was (int)RulesClass::Global()->CrewEscape * 100); - changed to -1 to indicate "100% if this is a land transport"

        this->Survivors_Pilots.SetCapacity(SideClass::Array->Count, NULL);
        this->Survivors_Pilots.Count = SideClass::Array->Count;

        this->Survivors_PilotCount = pThis->Crewed; // should be 0 if false, 1 if true

        for(int i = 0; i < SideClass::Array->Count; ++i) {
                this->Survivors_Pilots[i] = SideExt::ExtMap.Find(SideClass::Array->Items[i])->Crew;
        }

        this->PrerequisiteLists.SetCapacity(0, NULL);
        this->PrerequisiteLists.AddItem(new DynamicVectorClass<int>);

        this->PrerequisiteTheaters = 0xFFFFFFFF;

        this->Secret_RequiredHouses = 0xFFFFFFFF;
        this->Secret_ForbiddenHouses = 0;

        this->Is_Deso = this->Is_Deso_Radiation = !strcmp(pThis->ID, "DESO");
        this->Is_Cow = !strcmp(pThis->ID, "COW");
}
virtual void TechnoTypeExt::ExtData::InvalidatePointer ( void *  ptr) [inline, virtual]

Implements Extension< TT >.

                                                          {
                        AnnounceInvalidPointer(Operator, ptr);
                }
void TechnoTypeExt::ExtData::LoadFromINIFile ( TT pThis,
CCINIClass *  pINI 
) [virtual]
{
        const char * section = pThis->ID;

        if(!pINI->GetSection(section)) {
                return;
        }

        // survivors
        this->Survivors_Pilots.SetCapacity(SideClass::Array->Count, NULL);
        this->Survivors_Pilots.Count = SideClass::Array->Count;

        this->Survivors_PilotCount = pINI->ReadInteger(section, "Survivor.Pilots", this->Survivors_PilotCount);

        this->Survivors_PilotChance.LoadFromINI(pINI, section, "Survivor.%sPilotChance");
        this->Survivors_PassengerChance.LoadFromINI(pINI, section, "Survivor.%sPassengerChance");

        char flag[256];
        for(int i = 0; i < SideClass::Array->Count; ++i) {
                _snprintf(flag, 256, "Survivor.Side%d", i);
                if(pINI->ReadString(section, flag, "", Ares::readBuffer, Ares::readLength)) {
                        if(!(this->Survivors_Pilots[i] = InfantryTypeClass::Find(Ares::readBuffer))) {
                                Debug::INIParseFailed(section, flag, Ares::readBuffer);
                        }
                }
        }

        // prereqs
        int PrereqListLen = pINI->ReadInteger(section, "Prerequisite.Lists", this->PrerequisiteLists.Count - 1);

        if(PrereqListLen < 1) {
                PrereqListLen = 0;
        }
        ++PrereqListLen;
        while(PrereqListLen > this->PrerequisiteLists.Count) {
                this->PrerequisiteLists.AddItem(new DynamicVectorClass<int>);
        }

        DynamicVectorClass<int> *dvc = this->PrerequisiteLists.GetItem(0);
        Prereqs::Parse(pINI, section, "Prerequisite", dvc);

        dvc = &pThis->PrerequisiteOverride;
        Prereqs::Parse(pINI, section, "PrerequisiteOverride", dvc);

        for(int i = 0; i < this->PrerequisiteLists.Count; ++i) {
                _snprintf(flag, 256, "Prerequisite.List%d", i);
                dvc = this->PrerequisiteLists.GetItem(i);
                Prereqs::Parse(pINI, section, flag, dvc);
        }

        dvc = &this->PrerequisiteNegatives;
        Prereqs::Parse(pINI, section, "Prerequisite.Negative", dvc);

        if(pINI->ReadString(section, "Prerequisite.RequiredTheaters", "", Ares::readBuffer, Ares::readLength)) {
                this->PrerequisiteTheaters = 0;
                for(char *cur = strtok(Ares::readBuffer, ","); cur; cur = strtok(NULL, ",")) {
                        signed int idx = Theater::FindIndex(cur);
                        if(idx != -1) {
                                this->PrerequisiteTheaters |= (1 << idx);
                        } else {
                                Debug::INIParseFailed(section, "Prerequisite.RequiredTheaters", cur);
                        }
                }
        }

        // new secret lab
        this->Secret_RequiredHouses
                = pINI->ReadHouseTypesList(section, "SecretLab.RequiredHouses", this->Secret_RequiredHouses);

        this->Secret_ForbiddenHouses
                = pINI->ReadHouseTypesList(section, "SecretLab.ForbiddenHouses", this->Secret_ForbiddenHouses);

        this->Is_Deso = pINI->ReadBool(section, "IsDesolator", this->Is_Deso);
        this->Is_Deso_Radiation = pINI->ReadBool(section, "IsDesolator.RadDependant", this->Is_Deso_Radiation);
        this->Is_Cow  = pINI->ReadBool(section, "IsCow", this->Is_Cow);

        this->Is_Spotlighted = pINI->ReadBool(section, "HasSpotlight", this->Is_Spotlighted);
        this->Spot_Height = pINI->ReadInteger(section, "Spotlight.StartHeight", this->Spot_Height);
        this->Spot_Distance = pINI->ReadInteger(section, "Spotlight.Distance", this->Spot_Distance);
        if(pINI->ReadString(section, "Spotlight.AttachedTo", "", Ares::readBuffer, Ares::readLength)) {
                if(!_strcmpi(Ares::readBuffer, "body")) {
                        this->Spot_AttachedTo = sa_Body;
                } else if(!_strcmpi(Ares::readBuffer, "turret")) {
                        this->Spot_AttachedTo = sa_Turret;
                } else if(!_strcmpi(Ares::readBuffer, "barrel")) {
                        this->Spot_AttachedTo = sa_Barrel;
                } else {
                        Debug::INIParseFailed(section, "Spotlight.AttachedTo", Ares::readBuffer);
                }
        }
        this->Spot_DisableR = pINI->ReadBool(section, "Spotlight.DisableRed", this->Spot_DisableR);
        this->Spot_DisableG = pINI->ReadBool(section, "Spotlight.DisableGreen", this->Spot_DisableG);
        this->Spot_DisableB = pINI->ReadBool(section, "Spotlight.DisableBlue", this->Spot_DisableB);
        this->Spot_Reverse = pINI->ReadBool(section, "Spotlight.IsInverted", this->Spot_Reverse);

        this->Is_Bomb = pINI->ReadBool(section, "IsBomb", this->Is_Bomb);

/*
        this is too late - Art files are loaded before this hook fires... brilliant
        if(pINI->ReadString(section, "WaterVoxel", "", buffer, 256)) {
                this->WaterAlt = 1;
        }
*/

        INI_EX exINI(pINI);
        this->Insignia.LoadFromINI(pINI, section, "Insignia.%s");
        this->Parachute_Anim.Parse(&exINI, section, "Parachute.Anim");

        // new on 08.11.09 for #342 (Operator=)
        if(pINI->ReadString(section, "Operator", "", Ares::readBuffer, Ares::readLength)) { // try to read the flag
                this->IsAPromiscuousWhoreAndLetsAnyoneRideIt = (strcmp(Ares::readBuffer, "_ANY_") == 0); // set whether this type accepts all operators
                if(!this->IsAPromiscuousWhoreAndLetsAnyoneRideIt) { // if not, find the specific operator it allows
                        if(auto Operator = InfantryTypeClass::Find(Ares::readBuffer)) {
                                this->Operator = Operator;
                        } else {
                                Debug::INIParseFailed(section, "Operator", Ares::readBuffer);
                        }
                }
        }

        this->CameoPal.LoadFromINI(CCINIClass::INI_Art, pThis->ImageFile, "CameoPalette");

        if(pINI->ReadString(section, "Prerequisite.StolenTechs", "", Ares::readBuffer, Ares::readLength)) {
                this->RequiredStolenTech.reset();
                for(char *cur = strtok(Ares::readBuffer, ","); cur; cur = strtok(NULL, ",")) {
                        signed int idx = atoi(cur);
                        if(idx > -1 && idx < 32) {
                                this->RequiredStolenTech.set(idx);
                        } else {
                                Debug::INIParseFailed(section, "Prerequisite.StolenTechs", cur, "Expected a number between 0 and 31 inclusive");
                        }
                }
        }

        // EMP immunity will be inferred after all type data has been read.
        // Not all needed properties have been parsed here. For instance: Cyborg.

        this->EMP_Modifier = (float)pINI->ReadDouble(section, "EMP.Modifier", this->EMP_Modifier);

        if(pINI->ReadString(section, "EMP.Threshold", "inair", Ares::readBuffer, Ares::readLength)) {
                if(_strcmpi(Ares::readBuffer, "inair") == 0) {
                        this->EMP_Threshold = -1;
                } else if((_strcmpi(Ares::readBuffer, "yes") == 0) || (_strcmpi(Ares::readBuffer, "true") == 0)) {
                        this->EMP_Threshold = 1;
                } else if((_strcmpi(Ares::readBuffer, "no") == 0) || (_strcmpi(Ares::readBuffer, "false") == 0)) {
                        this->EMP_Threshold = 0;
                } else {
                        this->EMP_Threshold = pINI->ReadInteger(section, "EMP.Threshold", this->EMP_Threshold);
                }
        }

        if(pINI->ReadString(section, "VeteranAbilities", "", Ares::readBuffer, Ares::readLength)) {
                for(char *cur = strtok(Ares::readBuffer, ","); cur; cur = strtok(NULL, ",")) {
                        if(!_strcmpi(cur, "empimmune")) {
                                this->VeteranAbilityEMPIMMUNE = true;
                                this->EliteAbilityEMPIMMUNE = true;
                        }
                }
        }

        if(pINI->ReadString(section, "EliteAbilities", "", Ares::readBuffer, Ares::readLength)) {
                for(char *cur = strtok(Ares::readBuffer, ","); cur; cur = strtok(NULL, ",")) {
                        if(!_strcmpi(cur, "empimmune")) {
                                this->EliteAbilityEMPIMMUNE = true;
                        }
                }
        }

        // #733
        this->ProtectedDriver = pINI->ReadBool(section, "ProtectedDriver", this->ProtectedDriver);
        this->CanDrive = pINI->ReadBool(section, "CanDrive", this->CanDrive);

        // #346, #464, #970, #1014
        this->PassengersGainExperience = pINI->ReadBool(section, "Experience.PromotePassengers", this->PassengersGainExperience);
        this->ExperienceFromPassengers = pINI->ReadBool(section, "Experience.FromPassengers", this->ExperienceFromPassengers);
        this->PassengerExperienceModifier = (float)pINI->ReadDouble(section, "Experience.PassengerModifier", this->PassengerExperienceModifier);
        this->MindControlExperienceSelfModifier = (float)pINI->ReadDouble(section, "Experience.MindControlSelfModifier", this->MindControlExperienceSelfModifier);
        this->MindControlExperienceVictimModifier = (float)pINI->ReadDouble(section, "Experience.MindControlVictimModifier", this->MindControlExperienceVictimModifier);
        this->ExperienceFromAirstrike = pINI->ReadBool(section, "Experience.FromAirstrike", this->ExperienceFromAirstrike);
        this->AirstrikeExperienceModifier = (float)pINI->ReadDouble(section, "Experience.AirstrikeModifier", this->AirstrikeExperienceModifier);

        this->VoiceRepair.Read(&exINI, section, "VoiceIFVRepair");

        this->IC_Modifier = (float)pINI->ReadDouble(section, "IronCurtain.Modifier", this->IC_Modifier);

        this->Chronoshift_Allow.Read(&exINI, section, "Chronoshift.Allow");
        this->Chronoshift_IsVehicle.Read(&exINI, section, "Chronoshift.IsVehicle");

        if(CCINIClass::INI_Art->ReadString(pThis->ImageFile, "CameoPCX", "", Ares::readBuffer, Ares::readLength)) {
                AresCRT::strCopy(this->CameoPCX, Ares::readBuffer, 0x20);
                _strlwr_s(this->CameoPCX, 0x20);
                if(!PCX::Instance->LoadFile(this->CameoPCX)) {
                        Debug::INIParseFailed(pThis->ImageFile, "CameoPCX", this->CameoPCX);
                }
        }

        if(CCINIClass::INI_Art->ReadString(pThis->ImageFile, "AltCameoPCX", "", Ares::readBuffer, Ares::readLength)) {
                AresCRT::strCopy(this->AltCameoPCX, Ares::readBuffer, 0x20);
                _strlwr_s(this->AltCameoPCX, 0x20);
                if(!PCX::Instance->LoadFile(this->AltCameoPCX)) {
                        Debug::INIParseFailed(pThis->ImageFile, "AltCameoPCX", this->AltCameoPCX);
                }
        }

        this->CanBeReversed.Read(&exINI, section, "CanBeReversed");

        // #305
        this->RadarJamRadius.Read(&exINI, section, "RadarJamRadius");

        // #1208
        this->PassengerTurret.Read(&exINI, section, "PassengerTurret");
        
        // #617 powered units
        if( pINI->ReadString(section, "PoweredBy", "", Ares::readBuffer, Ares::readLength) ) {
                for(char *cur = strtok(Ares::readBuffer, ","); cur; cur = strtok(NULL, ",")) {
                        BuildingTypeClass* b = BuildingTypeClass::Find(cur);
                        if(b) {
                                this->PoweredBy.AddItem(b);
                        } else {
                                Debug::INIParseFailed(pThis->ImageFile, "PoweredBy", "BuildingType not found");
                        }
                }
        }

        // quick fix - remove after the rest of weapon selector code is done
        return;
}
virtual size_t TechnoTypeExt::ExtData::Size ( ) const [inline, virtual]

Implements Extension< TT >.

{ return sizeof(*this); };

Member Data Documentation

Whether this TechnoType can act as the driver of vehicles whose driver has been killed. Request #733.

DynamicVectorClass<WeaponStruct> TechnoTypeExt::ExtData::EliteWeapons

If this is true, Operator= is not checked, and the object will work with any passenger, provided there is one.

See also:
InfantryTypeClass * Operator

Saves a pointer to an InfantryType required to be a passenger of this unit in order for it to work. Defaults to NULL.

See also:
TechnoClass_Update_CheckOperators, bool IsAPromiscuousWhoreAndLetsAnyoneRideIt

Whether this unit's turret changes based on the number of people in its passenger hold.

DynamicVectorClass<BuildingTypeClass*> TechnoTypeExt::ExtData::PoweredBy

The buildingtype this unit is powered by or NULL.

DynamicVectorClass< DynamicVectorClass<int>* > TechnoTypeExt::ExtData::PrerequisiteLists

Whether the driver of this vehicle cannot be killed, i.e. whether this vehicle is immune to KillDriver. Request #733.

Distance in cells to scan for & jam radars.

DynamicVectorClass<bool> TechnoTypeExt::ExtData::ReversedByHouses

Defines the number of pilots inside this vehicle if Crewed=yes; maximum number of pilots who can survive. Defaults to 0 if Crewed=no; defaults to 1 if Crewed=yes. // NOTE: Flag in INI is called Survivor.Pilots.

DynamicVectorClass<InfantryTypeClass *> TechnoTypeExt::ExtData::Survivors_Pilots
DynamicVectorClass<WeaponStruct> TechnoTypeExt::ExtData::Weapons

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