ModEnc is currently in Maintenance Mode: Changes could occur at any given moment, without advance warning.
Ares Developer Scrapbook
- When I get a random TechnoClass- or ObjectClass-derived class's pointer, how do I find out its exact (Building|Infantry|Vehicle|Aircraft)Class?
- When I get a random TechnoTypeClass- or ObjectTypeClass-derived class's pointer, how do I find out its exact (Building|Infantry|Vehicle|Aircraft)TypeClass?
-
- There is no magic mechanism to upcast the pointer properly (for now, one will be provided soon).
- ptr->WhatAmI() returns an enum value corresponding to this object's class. Refer to eAbstractType and its defines in GeneralDefinitions.h.
- So the resulting code could look like this:
if(ptr->WhatAmI() == abs_Building) { BuildingClass * pBuilding = reinterpret_cast<BuildingClass *>(ptr); } /* the intelligent casts like dynamic won't work, as they rely on the RTTI which is likely to be different between the game's and Ares's objects. Additionally, do not just (BuildingClass *)ptr instead. Seriously. */
- How do I get that class's extension?
-
- Unlike the game's classes which are in a hierarchy, Ares's extension classes are all siblings. That means that a BuildingExt doesn't contain TechnoExt even though it seems like it should.
- So the answer depends on which extension class you need. If you need data from TechnoTypeExt, you call TechnoTypeExt::ExtMap.Find(ptr) and receive a TechnoTypeExt * associated with this object.
Find might return NULL if there is no data associated with this object, but that shouldn't happen normally, all objects which can have extension data are attached to the ExtMap when they are created/destroyed. So you don't need to check for NULL when you fetch it.
- How do I best figure out stuff like "Is this object a BuildingType?"
-
- ptr->WhatAmI() == abs_BuildingType
- How do I best figure out stuff like "Is this object of this particular BuildingType?" (e.g. "Is this a GADEPT?")
-
- I'm assuming you are doing the smart thing and taking GADEPT from the INI, and not hardcoding it? Then this approach should work best:
// For example's sake, let's say the INI looks like this:
// [MySection]
// MyValue=GADEPT
// when parsing ini
void FooExt::ExtData::LoadFromINIFile(FooClass *pThis, CCINIClass *pINI) {
// note that the following read is performed from the owning object's INI section - the same way works in Rules, where an object called MTNK has a section [MTNK]
// if the value set on this flag is more than 0 characters long (iow, you set it to a non-whitespace value
if(pINI->ReadString(pThis->ID, "SomeValue", "", Ares::readBuffer, Ares::readLength)) {
// ::Find iterates the currently declared BuildingTypes array and returns pointer to the one with the ID given as argument
this->SomeValue = BuildingTypeClass::Find(Ares::readBuffer);
}
}
// and when you need to check, you do this:
// assuming pSomething is the pointer to FooExt::ExtData, iow what was called this in the reader function
// and pTarget is the building whose type you want to check against SomeValue
if(pTarget->Type == pSomething->SomeValue) {
// pTarget is a building of the same type as you specified SomeValue= to be
}
- If I have a UnitClass *, how do I get its UnitTypeClass *?
-
- ptr->GetType() returns an ObjectTypeClass * to the type data
- and ptr->GetTechnoType() returns a TechnoTypeClass * to the same type data (naturally only valid on TechnoClass and its derivates)
- and both of them are actually pointers to the final derived type of the object, just downcasted (this is a C++ covariant return type limitation). So if you know the exact type you need and are sure that the object's type is appropriate, you can use
- reinterpret_cast<TargetTypeClass *>(ptr->GetTechnoType()).