Ares
|
#include <src/Ext/BuildingType/Body.h>
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 | CompleteInitialization (TT *pThis) |
virtual void | InvalidatePointer (void *ptr) |
bool | IsLinkable () |
bool | CanBeOccupiedBy (InfantryClass *whom) |
Public Attributes | |
int | Solid_Height |
bool | IsCustom |
int | CustomWidth |
int | CustomHeight |
int | OutlineLength |
CellStruct * | CustomData |
CellStruct * | OutlineData |
DynamicVectorClass < TechnoTypeClass * > | Secret_Boons |
bool | Secret_RecalcOnCapture |
bool | Secret_Placed |
bool | Firewall_Is |
double | LightningRod_Modifier |
double | UCPassThrough |
How many percent of the shots pass through the building to the occupants? 0.0 = 0%, 1.0 = 100%; Defaults to 0.0. | |
double | UCFatalRate |
Chance of an occupant getting killed instantly when a bullet passes through. 0.0 = 0%, 1.0 = 100%; Defaults to 0.0. | |
double | UCDamageMultiplier |
How many percent of normal damage are applied if an occupant is hit when a bullet passes through. 0.0 = 0%, 1.0 = 100%; Defaults to 1.0. | |
bool | BunkerRaidable |
Can this BuildingType be occupied by hostile forces despite being owned by a player, if empty? | |
signed int | IsTrench |
Enables moving between segments - saves ID of a kind of trench. | |
BuildingTypeClass * | RubbleIntact |
What BuildingType to turn into when reconstructed. (This is the normal building, set on rubble.) | |
BuildingTypeClass * | RubbleDestroyed |
What BuildingType to turn into when destroyed. (This is the rubble, set on normal buildings.) | |
Valueable< bool > | InfiltrateCustom |
Valueable< bool > | RevealProduction |
Valueable< bool > | ResetSW |
Valueable< bool > | ResetRadar |
Valueable< bool > | RevealRadar |
Valueable< bool > | GainVeterancy |
Valueable< bool > | UnReverseEngineer |
Valueable< int > | StolenTechIndex |
Valueable< int > | StolenMoneyAmount |
Valueable< int > | StolenMoneyPercentage |
Valueable< int > | PowerOutageDuration |
ValueableVector < InfantryTypeClass * > | AllowedOccupiers |
cPrismForwarding | PrismForwarding |
Valueable< bool > | ReverseEngineersVictims |
Static Public Attributes | |
static std::vector< std::string > | trenchKinds |
Vector of strings associating known trench names with IsTrench IDs. |
BuildingTypeExt::ExtData::ExtData | ( | const DWORD | Canary, |
TT *const | OwnerObject | ||
) | [inline] |
: Extension<TT>(Canary, OwnerObject), Solid_Height (0), IsCustom (false), CustomWidth (0), CustomHeight (0), OutlineLength (0), CustomData (NULL), OutlineData (NULL), Firewall_Is (false), UCPassThrough (0.0), UCFatalRate (0.0), UCDamageMultiplier (1.0), BunkerRaidable (false), IsTrench (-1), RubbleIntact (NULL), RubbleDestroyed (NULL), LightningRod_Modifier (1.0), InfiltrateCustom (false), RevealProduction (false), ResetSW (false), ResetRadar (false), RevealRadar (false), GainVeterancy (false), UnReverseEngineer (false), StolenTechIndex (-1), StolenMoneyAmount (0), StolenMoneyPercentage (0), PowerOutageDuration (0), AllowedOccupiers (), PrismForwarding(), ReverseEngineersVictims (false) { };
virtual BuildingTypeExt::ExtData::~ExtData | ( | ) | [inline, virtual] |
{ delete [] CustomData; delete [] OutlineData; }
bool BuildingTypeExt::ExtData::CanBeOccupiedBy | ( | InfantryClass * | whom | ) |
{ // if CanBeOccupiedBy isn't empty, we have to check if this soldier is allowed in return this->AllowedOccupiers.empty() || (this->AllowedOccupiers == whom->Type); }
void BuildingTypeExt::ExtData::CompleteInitialization | ( | TT * | pThis | ) | [virtual] |
{ // enforce same foundations for rubble/intact building pairs if(this->RubbleDestroyed && !BuildingTypeExt::IsFoundationEqual(this->AttachedToObject, this->RubbleDestroyed)) { Debug::FatalErrorAndExit("BuildingType %s and its Rubble.Destroyed %s don't have the same foundation.", this->AttachedToObject->ID, this->RubbleDestroyed->ID); } if(this->RubbleIntact && !BuildingTypeExt::IsFoundationEqual(this->AttachedToObject, this->RubbleIntact)) { Debug::FatalErrorAndExit("BuildingType %s and its Rubble.Intact %s don't have the same foundation.", this->AttachedToObject->ID, this->RubbleIntact->ID); } }
void BuildingTypeExt::ExtData::Initialize | ( | TT * | pThis | ) | [virtual] |
{ if(pThis->SecretLab) { this->Secret_Boons.Clear(); DynamicVectorClass<TechnoTypeClass *> *Options = (DynamicVectorClass<TechnoTypeClass *> *)&RulesClass::Instance->SecretInfantry; for(int i = 0; i < Options->Count; ++i) { this->Secret_Boons.AddItem(Options->GetItem(i)); } Options = (DynamicVectorClass<TechnoTypeClass *> *)&RulesClass::Instance->SecretUnits; for(int i = 0; i < Options->Count; ++i) { this->Secret_Boons.AddItem(Options->GetItem(i)); } Options = (DynamicVectorClass<TechnoTypeClass *> *)&RulesClass::Instance->SecretBuildings; for(int i = 0; i < Options->Count; ++i) { this->Secret_Boons.AddItem(Options->GetItem(i)); } } this->PrismForwarding.Initialize(pThis); }
virtual void BuildingTypeExt::ExtData::InvalidatePointer | ( | void * | ptr | ) | [inline, virtual] |
Implements Extension< TT >.
{ AnnounceInvalidPointer(RubbleIntact, ptr); AnnounceInvalidPointer(RubbleDestroyed, ptr); }
bool BuildingTypeExt::ExtData::IsLinkable | ( | ) |
{ return this->Firewall_Is || (this->IsTrench > -1); }
void BuildingTypeExt::ExtData::LoadFromINIFile | ( | TT * | pThis, |
CCINIClass * | pINI | ||
) | [virtual] |
{ char* pArtID = pThis->ImageFile; char* pID = pThis->ID; this->PrismForwarding.LoadFromINIFile(pThis, pINI); if(pThis->UnitRepair && pThis->Factory == abs_AircraftType) { Debug::FatalErrorAndExit( "BuildingType [%s] has both UnitRepair=yes and Factory=AircraftType.\n" "This combination causes Internal Errors and other unwanted behaviour.", pID); } this->Firewall_Is = pINI->ReadBool(pID, "Firestorm.Wall", this->Firewall_Is); CCINIClass* pArtINI = CCINIClass::INI_Art; this->Solid_Height = pArtINI->ReadInteger(pArtID, "SolidHeight", this->Solid_Height); if(this->IsCustom) { //Reset pThis->Foundation = FOUNDATION_CUSTOM; pThis->FoundationData = this->CustomData; } else if(pArtINI) { char str[0x80]="\0"; if(pArtINI->ReadString(pArtID, "Foundation", "", str, 0x80) && !_strcmpi(str,"Custom")) { //Custom Foundation! this->IsCustom = true; pThis->Foundation = FOUNDATION_CUSTOM; //Load Width and Height this->CustomWidth = pArtINI->ReadInteger(pArtID, "Foundation.X", 0); this->CustomHeight = pArtINI->ReadInteger(pArtID, "Foundation.Y", 0); this->OutlineLength = pArtINI->ReadInteger(pArtID, "FoundationOutline.Length", 0); // at len < 10, things will end very badly for weapons factories if(this->OutlineLength < 10) { this->OutlineLength = 10; } //Allocate CellStruct array if(this->CustomData) { delete [] this->CustomData; } if(this->OutlineData) { delete [] this->OutlineData; } CellStruct* pFoundationData = new CellStruct[this->CustomWidth * this->CustomHeight + 1]; CellStruct* pOutlineData = new CellStruct[this->OutlineLength + 1]; this->CustomData = pFoundationData; this->OutlineData = pOutlineData; pThis->FoundationData = pFoundationData; pThis->FoundationOutside = pOutlineData; //Load FoundationData CellStruct* pCurrent = pFoundationData; char key[0x20]; for(int i = 0; i < this->CustomWidth * this->CustomHeight; ++i) { _snprintf(key, 32, "Foundation.%d", i); if(pArtINI->ReadString(pArtID, key, "", str, 0x80)) { short x = 0, y = 0; sscanf(str, "%d,%d", &x, &y); pCurrent->X = x; pCurrent->Y = y; ++pCurrent; } else { break; } } //Set end vector pCurrent->X = 0x7FFF; pCurrent->Y = 0x7FFF; pCurrent = pOutlineData; for(int i = 0; i < this->OutlineLength; ++i) { _snprintf(key, 32, "FoundationOutline.%d", i); if(pArtINI->ReadString(pArtID, key, "", str, 0x80)) { short x = 0, y = 0; sscanf(str, "%d,%d", &x, &y); pCurrent->X = x; pCurrent->Y = y; ++pCurrent; } else { //Set end vector // can't break, some stupid functions access fixed offsets without checking if that offset is within the valid range pCurrent->X = 0x7FFF; pCurrent->Y = 0x7FFF; ++pCurrent; } } //Set end vector pCurrent->X = 0x7FFF; pCurrent->Y = 0x7FFF; } } if(pINI->ReadString(pID, "SecretLab.PossibleBoons", "", Ares::readBuffer, Ares::readLength)) { this->Secret_Boons.Clear(); for(char *cur = strtok(Ares::readBuffer, ","); cur; cur = strtok(NULL, ",")) { TechnoTypeClass *pTechno = TechnoTypeClass::Find(cur); if(pTechno) { this->Secret_Boons.AddItem(pTechno); } else { Debug::INIParseFailed(pID, "SecretLab.PossibleBoons", cur); } } } this->Secret_RecalcOnCapture = pINI->ReadBool(pID, "SecretLab.GenerateOnCapture", this->Secret_RecalcOnCapture); // added on 11.11.09 for #221 and children (Trenches) this->UCPassThrough = pINI->ReadDouble(pID, "UC.PassThrough", this->UCPassThrough); this->UCFatalRate = pINI->ReadDouble(pID, "UC.FatalRate", this->UCFatalRate); this->UCDamageMultiplier = pINI->ReadDouble(pID, "UC.DamageMultiplier", this->UCDamageMultiplier); this->BunkerRaidable = pINI->ReadBool(pID, "Bunker.Raidable", this->BunkerRaidable); if(pINI->ReadString(pID, "IsTrench", "", Ares::readBuffer, Ares::readLength)) { /* If the list of kinds is empty so far, just add this kind as the first one; if there already are kinds in it, compare the current kind against the kinds in the list; if it was found, assign that kind's ID to this type; if it wasn't found, add this kind at the end of the list and assign the ID. I originally thought of using a map here, but I figured the probability that the kinds list grows so long that the search through all kinds takes up significant time is very low, and vectors are far simpler to use in this situation. */ if(trenchKinds.size()) { signed int foundMatch = -1; for(unsigned int i = 0; i < trenchKinds.size(); ++i) { if(trenchKinds.at(i).compare(Ares::readBuffer) == 0) { foundMatch = i; break; } } if(foundMatch > -1) { this->IsTrench = foundMatch; } else { this->IsTrench = trenchKinds.size(); trenchKinds.push_back(Ares::readBuffer); } } else { this->IsTrench = 0; trenchKinds.push_back(Ares::readBuffer); } } if(pINI->ReadString(pID, "Rubble.Intact", "", Ares::readBuffer, Ares::readLength)) { this->RubbleIntact = BuildingTypeClass::Find(Ares::readBuffer); } if(pINI->ReadString(pID, "Rubble.Destroyed", "", Ares::readBuffer, Ares::readLength)) { this->RubbleDestroyed = BuildingTypeClass::Find(Ares::readBuffer); this->RubbleDestroyed->Capturable = false; this->RubbleDestroyed->TogglePower = false; this->RubbleDestroyed->Unsellable = true; this->RubbleDestroyed->CanBeOccupied = false; } this->LightningRod_Modifier = pINI->ReadDouble(pID, "LightningRod.Modifier", this->LightningRod_Modifier); // this->LegacyRadarEffect = pINI->ReadBool(pID, "SpyEffect.LegacyRadar", this->LegacyRadarEffect); // this->DisplayProduction = pINI->ReadBool(pID, "SpyEffect.DisplayProduction", this->DisplayProduction); INI_EX exINI(pINI); this->InfiltrateCustom.Read(&exINI, pID, "SpyEffect.Custom"); if(this->InfiltrateCustom) { this->RevealProduction.Read(&exINI, pID, "SpyEffect.RevealProduction"); this->ResetSW.Read(&exINI, pID, "SpyEffect.ResetSuperweapons"); this->ResetRadar.Read(&exINI, pID, "SpyEffect.ResetRadar"); this->RevealRadar.Read(&exINI, pID, "SpyEffect.RevealRadar"); this->GainVeterancy.Read(&exINI, pID, "SpyEffect.UnitVeterancy"); this->StolenTechIndex.Read(&exINI, pID, "SpyEffect.StolenTechIndex"); this->PowerOutageDuration.Read(&exINI, pID, "SpyEffect.PowerOutageDuration"); this->StolenMoneyAmount.Read(&exINI, pID, "SpyEffect.StolenMoneyAmount"); this->StolenMoneyPercentage.Read(&exINI, pID, "SpyEffect.StolenMoneyPercentage"); this->UnReverseEngineer.Read(&exINI, pID, "SpyEffect.UndoReverseEngineer"); } // #218 Specific Occupiers this->AllowedOccupiers.Read(&exINI, pID, "CanBeOccupiedBy"); if(!this->AllowedOccupiers.empty()) { // having a specific occupier list implies that this building is supposed to be occupiable pThis->CanBeOccupied = true; } this->ReverseEngineersVictims.Read(&exINI, pID, "ReverseEngineersVictims"); }
virtual size_t BuildingTypeExt::ExtData::Size | ( | ) | const [inline, virtual] |
Implements Extension< TT >.
{ return sizeof(*this); };
ValueableVector<InfantryTypeClass *> BuildingTypeExt::ExtData::AllowedOccupiers |
Can this BuildingType be occupied by hostile forces despite being owned by a player, if empty?
CellStruct* BuildingTypeExt::ExtData::CustomData |
signed int BuildingTypeExt::ExtData::IsTrench |
Enables moving between segments - saves ID of a kind of trench.
CellStruct* BuildingTypeExt::ExtData::OutlineData |
BuildingTypeClass* BuildingTypeExt::ExtData::RubbleDestroyed |
What BuildingType to turn into when destroyed. (This is the rubble, set on normal buildings.)
BuildingTypeClass* BuildingTypeExt::ExtData::RubbleIntact |
What BuildingType to turn into when reconstructed. (This is the normal building, set on rubble.)
DynamicVectorClass<TechnoTypeClass *> BuildingTypeExt::ExtData::Secret_Boons |
std::vector< std::string > BuildingTypeExt::ExtData::trenchKinds [static] |
Vector of strings associating known trench names with IsTrench IDs.
How many percent of normal damage are applied if an occupant is hit when a bullet passes through. 0.0 = 0%, 1.0 = 100%; Defaults to 1.0.
Chance of an occupant getting killed instantly when a bullet passes through. 0.0 = 0%, 1.0 = 100%; Defaults to 0.0.
How many percent of the shots pass through the building to the occupants? 0.0 = 0%, 1.0 = 100%; Defaults to 0.0.