 |
|  |
 |
|
MrBaggins
|
|
|
|
Intro
The GovernmentsModified concept was an idea to allow for flexibility in the structure of the text file databases (for units, buildings, etc.)
Specifically it was an idea that the syntax of these be extended to allow for modifications to the individual records, based on government... so for a particular City Improvement, say a Granary, you might have another modified record (of the same improvement) for the Tyranny government... maybe making it cheaper, perhaps.
Using this system, you could make Factories more productive, but more polluting under Communism, or Tanks more powerful under Fascism, all without any SLIC, additional identifiers, or code.
I altered the db creation code, lexer definitions, and the base template class to achieve this.
Caveat... one small issue remains... I was having issues with dynamic resizing (growth) of a pointerlist array, using an optimized algorithm. I used a workaround, since I was so close to completion, but it needs to be sorted to avoid a limited memory leak. Fixed.
Tracing code also needs to be removed. Fixed.
---
What is the syntax?
The following would be the standard defintion of the courthouse.
code:
IMPROVE_COURTHOUSE {
DefaultIcon ICON_IMPROVE_COURTHOUSE
Description DESCRIPTION_IMPROVE_COURTHOUSE
EnableAdvance ADVANCE_JURISPRUDENCE
ProductionCost 330
Upkeep 1
LowerCrime -0.1
}
If you wished to have a courthouse that operated slightly differently under monarchy you'd do the following:
code:
IMPROVE_COURTHOUSE {
DefaultIcon ICON_IMPROVE_COURTHOUSE
Description DESCRIPTION_IMPROVE_COURTHOUSE
EnableAdvance ADVANCE_JURISPRUDENCE
ProductionCost 330
Upkeep 1
LowerCrime -0.1
}
IMPROVE_COURTHOUSE > GOVERNMENT_MONARCHY {
DefaultIcon ICON_IMPROVE_COURTHOUSE
Description DESCRIPTION_IMPROVE_COURTHOUSE
EnableAdvance ADVANCE_JURISPRUDENCE
ProductionCost 330
Upkeep 3
LowerCrime -0.3
HappyInc -1
}
You should note that this is a modification to an existing record. There must be an record with the same name to allow for a modified record.
The syntax using the '>' character allows for multiple government types, separated by commas.
It also allows for alpha-numeric (no space) descriptions, which are ignored for purposes of parsing... so
code: IMPROVE_COURTHOUSE > DecreasedCrime_and_Happy_HarshGovs ,
GOVERNMENT_MONARCHY, GOVERNMENT_THEOCRACY {
is perfectly valid, and modifies the courthouse record, for the Monarchy and Theocracy govs. Invalid Governments are also ignored, at parsing.
There is an additional syntax that can be used within the record structure, that can be used instead of, or as well as, the above syntax...
code:
IMPROVE_COURTHOUSE {
DefaultIcon ICON_IMPROVE_COURTHOUSE
Description DESCRIPTION_IMPROVE_COURTHOUSE
EnableAdvance ADVANCE_JURISPRUDENCE
ProductionCost 330
Upkeep 1
LowerCrime -0.1
}
IMPROVE_COURTHOUSE > Monarchy {
DefaultIcon ICON_IMPROVE_COURTHOUSE
Description DESCRIPTION_IMPROVE_COURTHOUSE
EnableAdvance ADVANCE_JURISPRUDENCE
GovernmentsModified GOVERNMENT_MONARCHY
ProductionCost 330
Upkeep 3
LowerCrime -0.3
HappyInc -1
}
It has been mentioned that there are only 64 buildings and 64 wonders. This is actually unrelated to the parser, and has to do with their storage and use within the city data.
The GovernmentsModified system ignores this limitation for the modified records. You can still only have 65 buildings, but each of those buildings can have as many modified governments as you need. Essentially the system increases the number of buildings available.
There was a suggestion for another syntax suggested a while back, but from my investigations, its impossible given the current lex definitions, would require a pretty thorough rewrite of the parser, plus would be much more costly in terms of access... something I wanted to avoid... however if a bison/flex pro would like to take a shot...
---
Code access
This whole system is only half the issue. The database records are accessed via 2 member functions... Get and Access. Get returns a const record, Access the record.
While it would be nice to just rewrite the existing Get and Access functions to access the government subrecords, we don't have the context of what government is applicable to do that.
I therefore made two overloaded functions...
code:
template const T *CTPDatabase::Get(sint32 index,sint32 govIndex)
and
template T *CTPDatabase::Access(sint32 index,sint32 govIndex)
which work alongside the existing
code:
template const T *CTPDatabase::Get(sint32 index)
and
template T *CTPDatabase::Access(sint32 index)
Notice the extra govIndex parameter. These are overloaded functions, so the existing functions can still be used.
Work we (or maybe just I ) need to do
None of the existing record access in the code (1700 hundred instances of ->Get( and ->Access(, not all of which are applicable,) use the new method... so they need to be changed...
This, however, isn't complicated... just a lot of repetition.
Here's an example of a couple of changes, that I used to test that the system was working fine...
code:
Original (from CityData::CanBuildBuilding):
const BuildingRecord* irec = g_theBuildingDB->Get(type);
New:
const BuildingRecord* irec = g_theBuildingDB->Get(type,g_player[m_owner]->GetGovernmentType());
and, from CityData::CanBuildUnit
const UnitRecord *rec = g_theUnitDB->Get(type);
becomes
const UnitRecord *rec = g_theUnitDB->Get(type,g_player[m_owner]->GetGovernmentType());
Last edited by MrBaggins on 06-02-2004 at 20:07
|
|
|  |
 |
|
Moderator
Berlin, Germany
|
Mar 2001 time: 10:09
| |
|
|
I found a problem with memory leaks with this, for brevity just the SoundRecord but in fact they leak all.
-Martin
quote:
1089 8 8712 0x00454061 [void * __cdecl DebugMemory_GuardedBlockAlloc(char const *,int,struct MemoryHeapDescriptor *,int,bool,unsigned char,bool)+0x121] / 0x00455954 [DebugMemory_GuardedMalloc+0x34] / 0x00455c92 [void * __cdecl operator new(unsigned int)+0x22] / 0x006ebcfc [public: void __thiscall CTPDatabase::Add(class SoundRecord *)+0x33c] / 0x006eb696 [public: long __thiscall CTPDatabase::Parse(class DBLexer *)+0xa6] / 0x0045f3cc [public: long __thiscall CivApp::InitializeAppDB(class CivArchive &)+0xe6c] / 0x00462bf4 [public: long __thiscall CivApp::InitializeApp(struct HINSTANCE__ *,int)+0x314] / 0x0045c51a [int __stdcall CivWinMain(struct HINSTANCE__ *,struct HINSTANCE__ *,char *,int)+0x3aa] / 0x0045bb64 [WinMain@16+0x74] / 0x00addf83 [WinMainCRTStartup+0x1b3] / 0xbff8b560 [(kernel)+0x0] / public: void __thiscall CTPDatabase::Add(class SoundRecord *) |
|
|
|  |
 |
|
MrBaggins
|
|
|
|
Since I'm destructing every object thats created in the same code, along side the existing destructor code... either theres a problem with the destructor method I used in CTPDatabase, or the code doesn't destruct created DB objects properly to begin with.
Last edited by MrBaggins on 21-02-2004 at 20:10
|
|
|  |
 |
|
Moderator
Berlin, Germany
|
Mar 2001 time: 10:09
| |
|
|
Well I wonder what these lines should do in CTPDatabase.h, I commented them out without any problems.
code:
/* sint32* m_recordsModifiedLink;
sint32 m_numRecordsModifiedLink;
sint32 m_allocatedRecordsModifiedLinkSize;
sint32* m_modList;
sint32 m_numModList;
sint32 m_allocatedListSize;*/
-Martin
|
|
|  |
 |
|
Emperor
England
|
Jul 2001 time: 09:09
| |
|
|
quote: Originally posted by Martin Gühmann
Well I wonder what these lines should do in CTPDatabase.h, I commented them out without any problems.
[snip]
|
A leftover from CTP1, perhaps? They changed most of the database access code between CTP1 and 2, so I guess there's lots of useless old stuff lying around...
|
|
|  |
 |
|
Moderator
Berlin, Germany
|
Mar 2001 time: 10:09
| |
|
|
quote: Originally posted by J Bytheway
A leftover from CTP1, perhaps? They changed most of the database access code between CTP1 and 2, so I guess there's lots of useless old stuff lying around... |
Maybe I should have said that this piece of code was part of MrBaggins' GovernmentsModified modification, he added that part of code but didn't use it.
-Martin
|
|
|  |
 |
|
Moderator
Berlin, Germany
|
Mar 2001 time: 10:09
| |
|
|
quote: Originally posted by E
I ran across the link to this in the code. Has anyone tried this? Have they made govt specific buildings and improvements? |
As far as I know noone has tried.
quote: Originally posted by E
(I guess you could do it by making available for the normal building with subneural adds and then make it available at other techs for different governments)... |
No, it doesn't work like this. MrBaggins posted the syntax here, nothing with different techs and so on, just a different government.
-Martin
|
|
|  |
 |
|
Moderator
Berlin, Germany
|
Mar 2001 time: 10:09
| |
|
|
quote: Originally posted by Maquiladora
I just tried it and it doesn't work. It doesn't crash the game or give anything invalid, but it's not finished. Just like it (seems) MrBaggins says in the opening post. |
Well, that's what MrBaggins says about.
quote: Originally posted by Maquiladora
None of the existing record access in the code (1700 hundred instances of ->Get( and ->Access(, not all of which are applicable,) use the new method... so they need to be changed... |
So here you have the problem, so far I made it working or it least it should work with the UnitDB. Maybe there are also other databases but there is no guaranty.
-Martin
|
|
|  |
 |
|  |
 |
|  |
 |
|  |
 |
|  |
 |
|
Maquiladora
|
|
 |
|
Emperor
Monterrey, Mexico
|
Jun 2001 time: 03:09
| |
|
|
quote: Originally posted by Martin Gühmann
Looks like I only modified the game object files themselves and forgot the UI. :D The file you are looking for is called editqueue.cpp. |
There are many instances of ->Get( in that file, but I have no idea which to change or what to change it to, because I can't read the code yet.
quote: It looks rather like that that isn't even a valid index for without government modified stuff. So what was its value? And what was the function call stack. Both can be figured out with the debugger. But you can find the stuff also in the log files you find in log directory. |
I guess this is the important part from the debugger log:
code: armydata.cpp@6228: Army 0xd0000005 Executing order ORDER_MOVE_TO @ (1,8), turn=6
wrlunit.cpp@93 : World::RemoveUnitReference: id: 0x10000007
armydata.cpp@6228: Army 0xd0000005 Executing order ORDER_MOVE_TO @ (0,10), turn=6
c3debug.cpp@315 : Assertion (index < m_numRecords) Failed in File:c:\ctp2\ctp2_code\gs\newdb\ctpdatabase.cpp, Line:356
c3debug.cpp@316 : Stack Trace: ' 0x008c460a [char * __cdecl c3debug_StackTrace(void) + 0x2a]
0x008beeed [void __cdecl c3debug_Assert(char const *,char const *,int) + 0x5d]
0x00bb5618 [public: class UnitRecord * __thiscall CTPDatabase::Access(int) + 0x48]
0x00bb5538 [public: class UnitRecord * __thiscall CTPDatabase::Access(int,int) + 0x18]
0x00bb550c [public: class UnitRecord const * __thiscall CTPDatabase::Get(int,int) + 0x1c]
0x00a3fcaa [bool __cdecl UDUnitTypeCanSettle(int,int,class MapPoint const &,bool) + 0x4a]
0x00a3ff06 [public: bool __thiscall UnitData::CanSettle(class MapPoint const &,bool)const + 0x36]
0x00a35c44 [public: bool __thiscall Unit::CanSettle(class MapPoint const &,bool)const + 0x24]
0x0091ec47 [public: int __thiscall TiledMap::RepaintLayerSprites(struct tagRECT *,int) + 0x477]
0x0091fb4f [public: int __thiscall TiledMap::RepaintSprites(class aui_Surface *,struct tagRECT *,bool) + 0x8f]
0x00e9a698 [enum AUI_ERRCODE __cdecl background_draw_handler(void *) + 0xf8]
0x00dfbe17 [public: virtual enum AUI_ERRCODE __thiscall Background::DrawThis(class aui_Surface *,int,int) + 0x27]
0x00da7058 [public: virtual enum AUI_ERRCODE __thiscall aui_Region::Draw(class aui_Surface *,int,int) + 0x38]
0x00dcdb58 [public: virtual enum AUI_ERRCODE __thiscall aui_Window::Draw(class aui_Surface *,int,int) + 0x28]
0x008a38c3 [private: int __thiscall CivApp::ProcessUI(unsigned int,unsigned int &) + 0x1f3]
0x008a3e9a [public: int __thiscall CivApp::Process(void) + 0xca]
0x0089959d [int __stdcall CivMain(struct HINSTANCE__ *,struct HINSTANCE__ *,char *,int) + 0x3ad]
0x00898bf7 [WinMain@16 + 0x87]
0x010d7968 [WinMainCRTStartup + 0x2a8]
0x010d76cf [WinMainCRTStartup + 0xf]
0x7c816fd7 [\177zlib1_NULL_THUNK_DATA + 0x7b41952f]
but I don't know which is the value of the warrior. There is mention of a "stack trace", but I would have no idea what to do with that either.
|
|
|  |
 |
|
Moderator
Berlin, Germany
|
Mar 2001 time: 10:09
| |
|
|
| |
|
|