C2C - mass XML changes parser

@hydro
You must upload file with them. Check it in checkboxes with other unit files and click apply.
 
But what I cannot as easily do is establish that as a Combat Class.

Combat Classes can be designators that can qualify or disqualify promotions and equipments, can be qualifiers or disqualifiers for combat modifiers, and many more subtle game functions.
You can. There is only a small piece of code needed where combat classes are managed. Era can be made implicit "combat class" or more logical would be, if it would be just a value you can refer to from promotions and other places. But I would need to see an example, how you would like to refer to eras from XMLs to conclude, how it should be done.

For example: +10% vs Ancient Era Units becomes a use of a pre-existing CC tag for combat modifiers vs a particular CC rather than having to make a new tag for combat modifier vs a unit's era definition.
But are you sure, you want to make things like this. I know it is an easy-to-do approach, but it is not very logical. Era do not determine any feature of units, that could be used to fight against them. +10% vs short-range archers, +10% vs long-range archers, +10% vs heavy armored infantry, +10% fast mounted units, this everything looks ok for me. But +10% vs ancient era units? :eek2:
 
I have a challenge.

In BuildingInfos




This is a Prehistoric Building that requires Consumerism.
Would it be possible for this buiding to be autofilled have FreeStartEra be ANCIENT.

This would be based on the ERA of the PrereqTech

Prehistoric Buidings will have FreeStartEra be ANCIENT
Ancient Buildings will have it be CLASSICAL
Classical Buildings will have MEDIEVAL
and so on.

The code would be:

See PrereqTech in BuildInfos

Find Tech in TechInfos
Find <Era></Era> in Techinfos

Make a trigger rename list.

If TECH is PREHISTORIC put ANCIENT inside <PrereqTech><PrereqTech> of said building.

If TECH is ANCIENT put CLASSICAL inside <PrereqTech><PrereqTech> of said building.

Then we modders can edit select buildings to have NONE instead but the majority will be autofilled in.

This will allow us to really start at any Era.

See Modules/My_Mods (unloaded)/NewCityFree. I started doing this there. Things to consider
- no building that requires a population of more than 3 can ever be free

- a building may have other requirements if they are not there then the building wont be free eg if there is copper near the city but it does not already have a mine and route to the new city then none of the buildings that require such a mine will be free.

- if a building requires the resources or existence of another building but that building has not been checked as free yet then the building wont be free even if the required whatever do indeed become free at build.​

I have been doing some work on this and think I may have a better solution all round but it needs a lot of work.

The idea - When a city is built a "type of city" is identified (by the AI until you get City Planning then by you).

Initially this is likely to be "hunting" or "fishing" or "gathering" village. It will then get the initial buildings that are associated with that type of building and perhaps have some improvements nearby built. All would get the basic infrastructure and production buildings but would get different specialist buildings.

As you get more techs more types become available - "farming", "trade", "defensive", "admin" and so on.

This just determines the initial buildings. Perhaps you will be able to buy extra buildings at the time of building with money.
 
You can. There is only a small piece of code needed where combat classes are managed. Era can be made implicit "combat class" or more logical would be, if it would be just a value you can refer to from promotions and other places. But I would need to see an example, how you would like to refer to eras from XMLs to conclude, how it should be done.
Perhaps originally it would've been more logical but it is not now considering how many functions and features work off of combat class that to simply plug in an era cc would enable.

And yes, we could work out something in the coding that auto-includes the era CC even on the base of the unit but it'd be a bit more processing delay than would be necessary as NO delay should be acceptable from such a minor issue. Much easier to auto-assign it to the unit when the unit is manifested into the game.

You say 'where the combat classes are managed' but there's multiple places that takes place. You can have it on the specific in-game units or on the base unit definition, perhaps taking place as some kind of inheritance in the load process or in the return for the sub-combats function. Both of those latter methods would be a bit of a pain and could add some unnecessary processing time.

But are you sure, you want to make things like this. I know it is an easy-to-do approach, but it is not very logical. Era do not determine any feature of units, that could be used to fight against them. +10% vs short-range archers, +10% vs long-range archers, +10% vs heavy armored infantry, +10% fast mounted units, this everything looks ok for me. But +10% vs ancient era units? :eek2:
You're thinking too hard. This was an overly basic example since basic is easier to express. I want to include these because they can be a useful tool for compound evaluations, filters, and perhaps modifiers.

Consider this: A set of Leader traits that represents the leader fully embracing everything about a given era. It's the era he's born in or from or it's the era he's most drawn to and he naturally fits with that era. His people are thus more empowered by his efforts during this era and his troops are better trained. Thus, perhaps units OF that era gain a free promotion that states +10% Combat Modifier (to state something very basic) when owned by a Leader with that Era's trait.

You know how you have hundreds of ideas a day and you sometimes simply recall the end result of the thought, the conclusion, while moving on to forget the original concept for a while, knowing at some point you'll remember during some stage of further development down the road? That's really where this is stemming from.

You asked for examples and I tossed out some basic ones in hopes you'd begin to imagine forward from there rather than trying to find reason to suggest the mechanism wouldn't be useful enough to bother with. It's the potential it may open in our designs that inspires this set of CCs. All I can really say is I've often thought, 'if we had an era CC on the unit we could do that with ease...'

Anyhow, since it will be auto-assigned one way or another, I took it out of the list on the planning document.
 
  • Adding tags inline fix (Tranin condition inline adding now works correct :))
  • add function that recognize nested tags type (bbolean, number, text) for future use
 
And yes, we could work out something in the coding that auto-includes the era CC even on the base of the unit but it'd be a bit more processing delay than would be necessary as NO delay should be acceptable from such a minor issue. Much easier to auto-assign it to the unit when the unit is manifested into the game.
This is the worst attitude a programmer can have. Conceptual work and design is the most important part of software creating. Most of projects end up in a trash bin because of not doing this part properly. And no, it is not my opinion. I've seen statistics during my studies.

But ok, we will see. Maybe you have a good idea, but can't say it precisely. So where are you planing to put this "auto-assigned" era information? In CvUnitInfo or in CvUnit? -- I assume "auto-assigned" does not mean assigned from an XML tag, but somehow evaluated in the dll and then assigned.

Consider this: A set of Leader traits that represents the leader fully embracing everything about a given era. It's the era he's born in or from or it's the era he's most drawn to and he naturally fits with that era. His people are thus more empowered by his efforts during this era and his troops are better trained. Thus, perhaps units OF that era gain a free promotion that states +10% Combat Modifier (to state something very basic) when owned by a Leader with that Era's trait.
Ok ok. This one I can somehow buy.


Btw, perhaps you should try to reduce your cocksureness a little bit, when you are talking with someone more experienced then you? I am not talking here, because I do not have anything to do, but because I have some serious knowledge about how to do thing properly, which you probably don't.
 
This is the worst attitude a programmer can have. Conceptual work and design is the most important part of software creating. Most of projects end up in a trash bin because of not doing this part properly. And no, it is not my opinion. I've seen statistics during my studies.

But ok, we will see. Maybe you have a good idea, but can't say it precisely. So where are you planing to put this "auto-assigned" era information? In CvUnitInfo or in CvUnit? -- I assume "auto-assigned" does not mean assigned from an XML tag, but somehow evaluated in the dll and then assigned.
It would be very easy to do in CvUnit. It would be a little better for the pedia if it was done in CvUnitInfo. I'm a little worried it might be a bit difficult to plug in this extra add-on CC to the vector without potential bugs... it'd be on the fringe of my ability anyhow. I certainly wouldn't mind if it was auto assigned to the base unit definition there after all modules have been loaded but before the end of the mod load sequence- I'm just not sure where and how exactly to add it. CvUnit, when initializing the unit, would be the easiest for me. So if you can pinpoint how to best add to the base unit definition that would be appreciated.


Btw, perhaps you should try to reduce your cocksureness a little bit, when you are talking with someone more experienced then you? I am not talking here, because I do not have anything to do, but because I have some serious knowledge about how to do thing properly, which you probably don't.
I do debate as if I already know what the proper conclusions are but largely that's due to having put a lot of thought into things already and trying to remap that fragmented thought process for others can be a bit frustrating. That said, I don't doubt your knowledge of coding. I've been reading what you've been discussing with Koshling and I usually can't follow the first bit of it, which would lend me to assume you do have 'serious knowledge'. Furthermore, I figured I was simply answering your questions as best I could. I'm not closed minded to new approaches but I'll explain why I didn't want to use a particular approach if you present one and I've given it previous consideration - this is not to say I refuse to see some rational that would overpower the 'cons' I bring up.
 
It would be very easy to do in CvUnit. It would be a little better for the pedia if it was done in CvUnitInfo. I'm a little worried it might be a bit difficult to plug in this extra add-on CC to the vector without potential bugs... it'd be on the fringe of my ability anyhow. I certainly wouldn't mind if it was auto assigned to the base unit definition there after all modules have been loaded but before the end of the mod load sequence- I'm just not sure where and how exactly to add it. CvUnit, when initializing the unit, would be the easiest for me. So if you can pinpoint how to best add to the base unit definition that would be appreciated.
This is what I was afraid of. If you will add it to CvUnit each unit object in game will grow. Then think about what happens if you fatten unit objects each time you need some minor thing. According to Koshling the objects are already insanely big and you have quite plenty of them in the game. People do not have infinite RAM. -- This should be stored in CvUnitInfo.

Say me how do you store combat classes and how do you check if a unit has one. -- Names of classes, fields and methods, please.

I do debate as if I already know what the proper conclusions are but largely that's due to having put a lot of thought into things already and trying to remap that fragmented thought process for others can be a bit frustrating. That said, I don't doubt your knowledge of coding. I've been reading what you've been discussing with Koshling and I usually can't follow the first bit of it, which would lend me to assume you do have 'serious knowledge'. Furthermore, I figured I was simply answering your questions as best I could. I'm not closed minded to new approaches but I'll explain why I didn't want to use a particular approach if you present one and I've given it previous consideration - this is not to say I refuse to see some rational that would overpower the 'cons' I bring up.
Recall the situation with this additional column in your gdocs. You do not put enough attention to what you are reading and it often ends like you have a bad picture of things. So maybe precise reading and asking for more explanations before criticism would be a good idea?

For example, I always try to leave an open door, if I do not fully understand something. (Of course the case of Nimek is a special one. For him my door are more then open. -- It is easier to shoot then. :ar15: )
 
Say me how do you store combat classes and how do you check if a unit has one. -- Names of classes, fields and methods, please.
You're going to tell me this is a bit of a mess at the moment and to some extent it is but it's due to evolving methods here and trying to keep compatibility with older methods that overcomplicated this a bit.

In xml you have two tags that plug in unit combats. The first is <Combat>. This is the PRIMARY combat class - thus if a singular definition is all that's desired for the unit such as to help with sorting all units, this is the main class the unit will be defined by. This was the original only combat class assignment given to us from Vanilla BtS.

Then I added <SubCombatClassTypes> which enables us to add any number of additional UnitCombat definitions to the unit.

Those are all that plug into the base CvUnitInfo definition and they are worked in the code independantly of each other until processed in CvUnit.

SubCombats are stored as a vector:
CvInfos.h
Code:
	int getSubCombatType(int i) const;
	int getNumSubCombatTypes() const;
	bool isSubCombatType(int i);
and
Code:
bool hasUnitCombat(UnitCombatTypes eUnitCombat) const;
with the declaration:
Code:
std::vector<int> m_aiSubCombatTypes;

In CvUnitInfos it processes as such:
Code:
int CvUnitInfo::getSubCombatType(int i) const
{
	return m_aiSubCombatTypes[i];
}

int CvUnitInfo::getNumSubCombatTypes() const
{
	return (int)m_aiSubCombatTypes.size();
}

bool CvUnitInfo::isSubCombatType(int i)
{
	FAssert (i > -1 && i < GC.getNumUnitCombatInfos());
	if (find(m_aiSubCombatTypes.begin(), m_aiSubCombatTypes.end(), i) == m_aiSubCombatTypes.end())
	{
		return false;
	}
	return true;
}
Code:
	stream->Read(&iNumElements);
	m_aiSubCombatTypes.clear();
	for(int i=0; i<iNumElements;i++)
	{
		stream->Read(&iElement);
		m_aiSubCombatTypes.push_back(iElement);
	}
Code:
	stream->Write(m_aiSubCombatTypes.size());
	for (std::vector<int>::iterator it = m_aiSubCombatTypes.begin(); it != m_aiSubCombatTypes.end(); ++it)
	{
		stream->Write(*it);
	}
Code:
CheckSumC(iSum, m_aiSubCombatTypes);
Code:
	if (GETXML->SetToChildByTagName(pXML->GetXML(),"SubCombatTypes"))
	{
		if (pXML->SkipToNextVal())
		{
			int iNumSibs = GETXML->GetNumChildren(pXML->GetXML());
			m_aiSubCombatTypes.clear();

			if (0 < iNumSibs)
			{
				if (pXML->GetChildXmlVal(szTextVal))
				{
					for (int j = 0; j < iNumSibs; j++)
					{
						m_aiSubCombatTypes.push_back(pXML->FindInInfoClass(szTextVal));
						if (!pXML->GetNextXmlVal(szTextVal))
						{
							break;
						}
					}

					GETXML->SetToParent(pXML->GetXML());
				}
			}
		}

		GETXML->SetToParent(pXML->GetXML());
	}
Modular load
Code:
	if (getNumSubCombatTypes() == 0)
	{
		m_aiSubCombatTypes.clear();
		for ( int i = 0; i < pClassInfo->getNumSubCombatTypes(); i++)
		{
			m_aiSubCombatTypes.push_back(pClassInfo->getSubCombatType(i));
		}
	}
And Koshling added this recently so he could combine Combat and SubCombats into one list from the core unit definition. I could probably easily add in the era here except that I don't think it would plug in everywhere it should and it'd probably be better to add a step that adds the era cc to the subcombat vector even earlier.
Code:
bool CvUnitInfo::hasUnitCombat(UnitCombatTypes eUnitCombat) const
{
	FAssert(0 <= eUnitCombat && eUnitCombat < GC.getNumUnitCombatInfos());
	
	if ( m_abHasCombatType == NULL )
	{
		m_abHasCombatType = new bool[GC.getNumUnitCombatInfos()];
		memset(m_abHasCombatType, 0, GC.getNumUnitCombatInfos());

		for(int iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
		{
			if (getUnitCombatType() == iI)
			{
				m_abHasCombatType[iI] = true;
				continue;
			}
			//TB SubCombat Mod Begin
			for (int iJ = 0; iJ < getNumSubCombatTypes(); iJ++)
			{
				if (getSubCombatType(iJ) == iI)
				{
					m_abHasCombatType[iI] = true;
					break;
				}
			}
		}
	}

	return m_abHasCombatType[eUnitCombat];
}

Then you have two similar vectors in CvPromotionsInfo:
Code:
	int getSubCombatChangeType(int i) const;
	int getNumSubCombatChangeTypes() const;
	bool isSubCombatChangeType(int i);

	int getRemovesUnitCombatType(int i) const;
	int getNumRemovesUnitCombatTypes() const;
	bool isRemovesUnitCombatType(int i);

These allow promotions to add or subtract a combat class from the unit.

In CvUnit things come together.

This is an old method of combining them from when UnitCombats were not processed in and out of the unit - the recent change of making them capable of having unit altering tags enforced this be obsoleted but it's kept and the information drawn upon to help old games convert units to the new system:
Code:
bool CvUnit::hasCombatType(UnitCombatTypes eCombatType) const
{
	if (((getUnitCombatType() == eCombatType) || hasExtraSubCombatType(eCombatType)) && !hasRemovesUnitCombatType(eCombatType))
	{
		return true;
	}
	// AIAndy: That loop could be removed if the unit type sub combat types get added to the extra sub combat type counts
	for (int iI = 0; iI < m_pUnitInfo->getNumSubCombatTypes(); iI++)
	{
		if (m_pUnitInfo->getSubCombatType(iI) == ((int)eCombatType))
		{
			return true;
		}
	}
	return false;
}

bool CvUnit::hasSubCombatType(UnitCombatTypes eCombatType) const
{
	int iI;
	bool bSubCombat = false;
	for (iI = 0; iI < m_pUnitInfo->getNumSubCombatTypes(); iI++)
	{
		if (m_pUnitInfo->getSubCombatType(iI) == ((int)eCombatType))
		{
			bSubCombat = true;
		}
	}
	if ((((bSubCombat) || hasExtraSubCombatType(eCombatType)) && (m_pUnitInfo->getUnitCombatType() != eCombatType)) && !hasRemovesUnitCombatType(eCombatType))
	{
		return true;
	}
	return false;
}

For above method we'd keep track of the amount of reasons each unit has to have or not have a unit combat:
Code:
int CvUnit::getSubCombatTypeCount(UnitCombatTypes eCombatType) const
{
	FAssertMsg(eCombatType >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eCombatType < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	
	const UnitCombatKeyedInfo* info = findUnitCombatKeyedInfo(eCombatType);

	return info == NULL ? 0 : info->m_iSubCombatTypeCount;
}

bool CvUnit::hasExtraSubCombatType(UnitCombatTypes eCombatType) const
{
	FAssertMsg(eCombatType >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eCombatType < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	return (getSubCombatTypeCount(eCombatType) > 0);
}

void CvUnit::changeSubCombatTypeCount(UnitCombatTypes eCombatType, int iChange)
{
	FAssertMsg(eCombatType >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eCombatType < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");

	UnitCombatKeyedInfo* info = findOrCreateUnitCombatKeyedInfo(eCombatType);

	info->m_iSubCombatTypeCount += iChange;
	FAssert(info->m_iSubCombatTypeCount >= 0);
}

int CvUnit::getRemovesUnitCombatTypeCount(UnitCombatTypes eCombatType) const
{
	FAssertMsg(eCombatType >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eCombatType < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	
	const UnitCombatKeyedInfo* info = findUnitCombatKeyedInfo(eCombatType);

	return info == NULL ? 0 : info->m_iRemovesUnitCombatTypeCount;
}

bool CvUnit::hasRemovesUnitCombatType(UnitCombatTypes eCombatType) const
{
	FAssertMsg(eCombatType >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eCombatType < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	return (getRemovesUnitCombatTypeCount(eCombatType) > 0);
}

void CvUnit::changeRemovesUnitCombatTypeCount(UnitCombatTypes eCombatType, int iChange)
{
	FAssertMsg(eCombatType >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eCombatType < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");

	UnitCombatKeyedInfo* info = findOrCreateUnitCombatKeyedInfo(eCombatType);

	info->m_iRemovesUnitCombatTypeCount += iChange;
	FAssert(info->m_iRemovesUnitCombatTypeCount >= 0);
}
But that's fairly obsolete now as well.

Now we process in the combat classes to the unit and remove them as necessary. During the processing of a promotion on or off of a unit you'll find these:
Code:
	for (iI = 0; iI < kPromotion.getNumSubCombatChangeTypes(); iI++)
	{
		setHasUnitCombat(((UnitCombatTypes)kPromotion.getSubCombatChangeType(iI)), iChange);
	}
	
	for (iI = 0; iI < kPromotion.getNumRemovesUnitCombatTypes(); iI++)
	{
		setHasUnitCombat(((UnitCombatTypes)kPromotion.getRemovesUnitCombatType(iI)), -iChange);
	}
in void CvUnit::init(int iID, UnitTypes eUnit, UnitAITypes eUnitAI, PlayerTypes eOwner, int iX, int iY, DirectionTypes eFacingDirection, int iBirthmark)
we setup the unitcombats initially with:
doSetUnitCombats(); which calls to:
Code:
void CvUnit::doSetUnitCombats()
{
	if (getUnitCombatType() != NO_UNITCOMBAT)
	{
		setHasUnitCombat(getUnitCombatType(),true);	
		for (int iI = 0; iI < m_pUnitInfo->getNumSubCombatTypes(); iI++)
		{
			setHasUnitCombat((UnitCombatTypes)m_pUnitInfo->getSubCombatType(iI),true);
		}
	}
}
(Yes it's intentional that a unit must have a primary CC defined before any subcombats will be.)
It's here I could simply add the derived reference to the unit's era.

Ultimately, at this time this function returns a boolean on whether a unit has a cc or not:
Code:
bool CvUnit::isHasUnitCombat(UnitCombatTypes eIndex) const
{
	FAssertMsg(eIndex >= 0 || eIndex == NO_UNITCOMBAT, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < GC.getNumUnitCombatInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	const UnitCombatKeyedInfo* info = findUnitCombatKeyedInfo(eIndex);

	return (info != NULL && info->m_bHasUnitCombat);
}

void CvUnit::processUnitCombat(UnitCombatTypes eIndex, bool bAdding) is what takes place when a combat is added or removed from a unit.

and void CvUnit::setHasUnitCombat(UnitCombatTypes eIndex, bool bNewValue) is the call to add or subtract a unitcombat to or from the unit.

Hopefully this answer is sufficient. There's a lot more that could be expressed of course but this would key you in if you're looking into the code on the matter at all.
 
N47 what programming languages are you fluent in? How did you learn Python, self taught ?
 
I really deeply hate most of programmers. They are total morons. I've written a big post and lost it, because those idiots from this forum script did not think about storing post's body, when there is some session mismatch after submitting. I am rather an opponent of death penalty, but for bad programmers who provide commonly used code I would make an exception.

TD, in short, add the methods getEraInfo() and setEraSubCombat() to CvUnitInfo, use the first for the second and call the second in CvUnitInfo::read(CvXMLLoadUtility* pXML) after reading tech pre-requirements. If the code you posted is after the tech reading, I would put the call immediately after it.

Do not know how about CvUnitInfo::copyNonDefaults(CvUnitInfo* pClassInfo, CvXMLLoadUtility* pXML) . I would need to know when and for what it is called.

Rather do not need to touch CvUnitInfo::read(FDataStreamBase* stream). If it would be used to deserialize something from another game run, it can case errors anyway. At least at first glance.

And btw I would consider CvUnit::isHasUnitCombat -> CvUnit::hasUnitCombat, CvUnit::setHasUnitCombat -> CvUnit::setUnitCombat name change.

@MrAzure, give me a language specification and I will be fluent in it in few hours, or few days, depending how specific the language is (of course if it is not the Brainf-u-ck -- stupid filter, it is a programming language name). I am a programming language scientist after all.

Python I needed for some exercises from the Natural Language Processing during my studies. That is how I learned it. But I had already quite firm knowledge about imperative languages, so it was only learning its specific features. If you know some general mechanisms, you can easily learn most of programing languages.
 
TB, in short, add the methods getEraInfo() and setEraSubCombat() to CvUnitInfo, use the first for the second and call the second in CvUnitInfo::read(CvXMLLoadUtility* pXML) after reading tech pre-requirements. If the code you posted is after the tech reading, I would put the call immediately after it.

Do not know how about CvUnitInfo::copyNonDefaults(CvUnitInfo* pClassInfo, CvXMLLoadUtility* pXML) . I would need to know when and for what it is called.
Yeah that second part, copyNonDefaults becomes the problem for the method as you mention it. I mean, I get what you're saying to do but copyNonDefaults sorta throws a monkeywrench into the deal. I'll have to further consider the implications but I think something like it could be done - may just need another update after any Module potentially changes the era. That's what copyNonDefaults is for - it implements the modular edits we were talking about earlier.

I figured out I should use this same method for Religion and Culture CCs too. Those, in particular, will have some ability to change or be assigned in CvUnit eventually depending on the greater influence of the Religion or Culture in the city that generates the unit. But for those units that have a PREREQ of a given Religion or Culture this would be the appropriate place and would also let the system know that the unit when initialized cannot have it's Religion or Culture CC adjusted on initializing - it'll keep the CvUnitInfo derived definition.

Rather do not need to touch CvUnitInfo::read(FDataStreamBase* stream). If it would be used to deserialize something from another game run, it can case errors anyway. At least at first glance.
Yeah I don't think we'd need to touch anything there for this. I concur.

And btw I would consider CvUnit::isHasUnitCombat -> CvUnit::hasUnitCombat, CvUnit::setHasUnitCombat -> CvUnit::setUnitCombat name change.
isHasUnitCombat was named as such to help differentiate any potential confusion with the old hasCombatType call. setHasUnitCombat does have meaning over setUnitCombat. The first infers that any unit combat is possible on a unit and thus any number of unit combats may be added to the unit while the second infers that there's only one possible UnitCombat. Very minor and subtle difference and there's not much of a streamlined naming standard between both but I also tried to mirror what was already established for Promotions to make things easier for coders who follow. I mean, I get your point on both so I figured I'd share the rational that went into the naming choices as they are.

I really deeply hate most of programmers. They are total morons. I've written a big post and lost it, because those idiots from this forum script did not think about storing post's body, when there is some session mismatch after submitting. I am rather an opponent of death penalty, but for bad programmers who provide commonly used code I would make an exception.
Yeah, I hate when that happens too! :mad:
 
Yeah that second part, copyNonDefaults becomes the problem for the method as you mention it. I mean, I get what you're saying to do but copyNonDefaults sorta throws a monkeywrench into the deal. I'll have to further consider the implications but I think something like it could be done - may just need another update after any Module potentially changes the era. That's what copyNonDefaults is for - it implements the modular edits we were talking about earlier
Add setEraSubCombat() call after this code in copyNonDefaults.
Code:
	for ( int i = 0; i < GC.getNUM_UNIT_AND_TECH_PREREQS(); i++)
	{
		if ( getPrereqAndTechs(i) == NO_TECH && pClassInfo->getPrereqAndTechs(i) != NO_TECH)
		{
			if ( NULL == m_piPrereqAndTechs )
			{
				CvXMLLoadUtility::InitList(&m_piPrereqAndTechs,GC.getNUM_UNIT_AND_TECH_PREREQS(),(int)NO_TECH);
			}
			m_piPrereqAndTechs[i] = pClassInfo->getPrereqAndTechs(i);
		}
	}
But his method looks wrong. Especially for boolean values. If it is used for loading a module, it disallows to switch such values to false by the module. Do you know where is the code responsible for a module loading, where this method is called? I would take a look at it.

I figured out I should use this same method for Religion and Culture CCs too. Those, in particular, will have some ability to change or be assigned in CvUnit eventually depending on the greater influence of the Religion or Culture in the city that generates the unit. But for those units that have a PREREQ of a given Religion or Culture this would be the appropriate place and would also let the system know that the unit when initialized cannot have it's Religion or Culture CC adjusted on initializing - it'll keep the CvUnitInfo derived definition.
Probably yes, you should.

isHasUnitCombat was named as such to help differentiate any potential confusion with the old hasCombatType call
Doesn't it do semantically the same? The only difference is there can be more classes?

setHasUnitCombat does have meaning over setUnitCombat. The first infers that any unit combat is possible on a unit and thus any number of unit combats may be added to the unit while the second infers that there's only one possible UnitCombat. Very minor and subtle difference and there's not much of a streamlined naming standard between both but I also tried to mirror what was already established for Promotions to make things easier for coders who follow.
It is common to use such naming. It is like setting flags. You mostly can have many flags, but you sill say you set them. The type of this function also suggest, there are more combat classes that can be set at once.

I mean, I get your point on both so I figured I'd share the rational that went into the naming choices as they are.
I understand, but I rather haven't seen such naming even in such cases. It is not terribly awful, but less convenient then hasUnitCombat and setUnitCombat, I think.
 
If I'd make a list with all buildings (is there such a list?) and add the value for electricity production /consume to it, would the Parser be able to convert them in the correct XML as well?
 
Yes it will.

It will ba also good to have list of buildings categories and apply category to every building. I belive someone done buildings categorization but now it needs to be updated.
 
Remember that your building list must contain unique tag value. Script must somehow recognize to what building write the stats.

In buildings review thread i belive the list is stored.
 
Add setEraSubCombat() call after this code in copyNonDefaults.
Code:
	for ( int i = 0; i < GC.getNUM_UNIT_AND_TECH_PREREQS(); i++)
	{
		if ( getPrereqAndTechs(i) == NO_TECH && pClassInfo->getPrereqAndTechs(i) != NO_TECH)
		{
			if ( NULL == m_piPrereqAndTechs )
			{
				CvXMLLoadUtility::InitList(&m_piPrereqAndTechs,GC.getNUM_UNIT_AND_TECH_PREREQS(),(int)NO_TECH);
			}
			m_piPrereqAndTechs[i] = pClassInfo->getPrereqAndTechs(i);
		}
	}
Yeah, I figured I'd do something along those lines. Then I would NOT put it in the initial read sequence right?

But his method looks wrong. Especially for boolean values. If it is used for loading a module, it disallows to switch such values to false by the module. Do you know where is the code responsible for a module loading, where this method is called? I would take a look at it.
I don't know all that much about the WoC Modular loading beyond this but I can tell you that you are right... values are not capable of enabling editing a tag back to a null or zero with a modularized edit. This is so that the edits can ignore most of the tags on the object without that being interpreted as an attempt to set those tags to null.

We do have an alternative method of replacing an object's definitions however, that AIAndy developed at my request (ok I may have helped a little here and there to flesh it out some but I don't want to take much credit because he's the one who infused the magik there...) The replacement mechanism we worked out allows for a complete replacement of the game object with the new definition predicated on any possible trigger gamestate (usually a game option.) THAT is pretty cool stuff. It's currently in use on our alternative trait set that ls612 established. However, we're trying to get it to work for an alternative gamespeed set and it doesn't seem to be working quite as intended which is a bug I've been meaning to investigate for some time now.


Doesn't it do semantically the same? The only difference is there can be more classes?
I'm not saying it doesn't. I just wanted to avoid any possible ongoing confusing myself between hasCombatType and hasUnitCombat - the isHasUnitCombat helped to put it a step further away from that potential confusion. You're working with a guy in ADD recovery here! lol


It is common to use such naming. It is like setting flags. You mostly can have many flags, but you sill say you set them. The type of this function also suggest, there are more combat classes that can be set at once.
I would think inferring there were more that could be set at once would be setUnitCombats or setHasUnitCombats. Anyhow, setHasPromotion was the name of the mirrored function so I went with what was already established. Why change names once set unless it's really a very compelling reason to do so?


Yes it will.

It will also be good to have list of buildings categories and apply category to every building. I believe someone has already done building categorizations but now it needs to be updated.
Yeah, I asked Sargon to do this a while back and he did so... can't recall where the google doc list he made is but he got it done and yes it now just needs updated. And more. I need to get the generic category system in place so that we can assign categories to those buildings in the xml. Still, it's a good idea to update the list and put the buildings' <Type> tags in a column.

If anyone has the most recent list of buildings, please post it and I will update it.
SargontheGreat2 had it in his sigline. The list is here.
 
Yeah, I figured I'd do something along those lines. Then I would NOT put it in the initial read sequence right?
You mean CvUnitInfo::read(CvXMLLoadUtility* pXML)? Do you mean you want to there would be no era cc, if your module is not loaded? No it will not work correctly then. If any other module will call CvUnitInfo::copyNonDefaults, then this cc will be added. It seems this design of modules loading is against more complex modules. I need to see the code responsible for this module loading to be sure how to do it. -- I though ccs are not intended to be a module.


We do have an alternative method of replacing an object's definitions however, that AIAndy developed at my request (ok I may have helped a little here and there to flesh it out some but I don't want to take much credit because he's the one who infused the magik there...) The replacement mechanism we worked out allows for a complete replacement of the game object with the new definition predicated on any possible trigger gamestate (usually a game option.) THAT is pretty cool stuff. It's currently in use on our alternative trait set that ls612 established. However, we're trying to get it to work for an alternative gamespeed set and it doesn't seem to be working quite as intended which is a bug I've been meaning to investigate for some time now.
Modular loading is a heavy thing. A proper solution would even be able to require rewriting big part of the dll. *sigh* More I know about the dll code, more it looks like a piece of junk. Ok, we will see what can be done. But I need to find this loading code first.

You're working with a guy in ADD recovery here! lol
What a bullsh*t. Psychiatrists say to half to half of people they come to them they have ADD now. This is just putting money to the pharmaceutical corporations not a serious health care.

I would think inferring there were more that could be set at once would be setUnitCombats or setHasUnitCombats.
A language problem. I meant, that an object can be in a state, there are many combat classes set at same time. (Still am not sure isn't it ambiguous...)
 
Back
Top Bottom