3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
12 /* Compiled through dataset.cpp */
18 int CreateConfigTable (databasebase
***ConfigTable
, databasebase
***TempTable
,
19 databasebase
**ConfigArray
, sLong
*TempTableInfo
, int Type
, int Configs
, int TempTables
)
21 memset(ConfigTable
, 0, CONFIG_TABLE_SIZE
*sizeof(databasebase
**));
22 for (int c
= 0; c
< Configs
; ++c
) {
23 int Config
= ConfigArray
[c
]->Config
;
24 int Hash
= (Config
>> 8) ^ (Config
& 0xFF);
25 if ((TempTableInfo
[Hash
] & 0xFFFF) != Type
) {
26 TempTable
[0][Hash
] = ConfigArray
[c
];
27 TempTableInfo
[Hash
] = Type
| 0x10000;
29 int Conflicts
= (TempTableInfo
[Hash
] & 0xFFFF0000) >> 16;
30 if (Conflicts
== TempTables
) TempTable
[TempTables
++] = new databasebase
*[CONFIG_TABLE_SIZE
];
31 TempTable
[Conflicts
][Hash
] = ConfigArray
[c
];
32 TempTableInfo
[Hash
] += 0x10000;
35 for (int c1
= 0; c1
< CONFIG_TABLE_SIZE
; ++c1
) {
36 if ((TempTableInfo
[c1
] & 0xFFFF) == Type
) {
37 int Entries
= (TempTableInfo
[c1
] & 0xFFFF0000) >> 16;
38 ConfigTable
[c1
] = new databasebase
*[Entries
+ 1];
39 for (int c2
= 0; c2
< Entries
; ++c2
) ConfigTable
[c1
][c2
] = TempTable
[c2
][c1
];
40 ConfigTable
[c1
][Entries
] = 0;
47 template <class type
> void databasecreator
<type
>::ReadFrom (const festring
&baseFileName
) {
48 std::stack
<TextInput
*> infStack
;
51 auto modlist
= game::GetModuleList();
52 for (unsigned idx
= modlist
.size(); idx
> 0; --idx
) {
53 festring infname
= game::GetGameDir()+"script/"+modlist
[idx
-1]+"/"+baseFileName
+".dat";
54 if (inputfile::fileExists(infname
)) {
55 TextInput
*ifl
= new TextInputFile(infname
, &game::GetGlobalValueMap());
56 ifl
->setGetVarCB(game::ldrGetVar
);
63 festring infname
= game::GetGameDir()+"script/"+baseFileName
+".dat";
64 TextInput
*ifl
= new TextInputFile(infname
, &game::GetGlobalValueMap());
65 ifl
->setGetVarCB(game::ldrGetVar
);
69 if (infStack
.size() == 0) ABORT("Cannot find '%s' scripts!", baseFileName
.CStr());
72 typedef typename
type::prototype prototype
;
73 festring Word
, defName
;
74 database
*TempConfig
[1024];
75 databasebase
**TempTable
[1024];
76 sLong TempTableInfo
[CONFIG_TABLE_SIZE
];
78 databasebase
*FirstTempTable
[CONFIG_TABLE_SIZE
];
79 TempTable
[0] = FirstTempTable
;
80 memset(TempTableInfo
, 0, sizeof(TempTableInfo
));
81 CreateDataBaseMemberMap();
82 while (!infStack
.empty()) {
83 TextInput
*inFile
= infStack
.top();
85 inFile
->setGetVarCB(game::ldrGetVar
);
86 //fprintf(stderr, "MAIN: %s\n", inFile->GetFileName().CStr());
87 for (inFile
->ReadWord(Word
, false); !inFile
->Eof(); inFile
->ReadWord(Word
, false)) {
88 if (Word
== "Include") {
89 Word
= inFile
->ReadWord();
90 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
91 //fprintf(stderr, "loading: %s\n", Word.CStr());
92 TextInput
*incf
= new TextInputFile(inputfile::buildIncludeName(inFile
->GetFileName(), Word
), &game::GetGlobalValueMap());
93 infStack
.push(inFile
);
95 inFile
->setGetVarCB(game::ldrGetVar
);
98 if (Word
== "Message") {
99 Word
= inFile
->ReadWord();
100 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
101 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
105 truth doExtend
= false, doOverride
= false;
106 if (Word
== "Extend") {
107 Word
= inFile
->ReadWord();
109 } else if (Word
== "Override" || Word
== "Redefine") {
110 Word
= inFile
->ReadWord();
115 int Type
= protocontainer
<type
>::SearchCodeName(Word
);
116 if (!Type
) ABORT("Odd term <%s> encountered in %s datafile %s line %d!", Word
.CStr(), protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
117 //fprintf(stderr, "class <%s>\n", Word.CStr());
118 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[Type
];
119 if (!Proto
) ABORT("Something weird with <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
123 if (!Proto
->ConfigData
) ABORT("Can't override undefined <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
124 delete [] Proto
->ConfigData
;
125 Proto
->ConfigData
= NULL
;
126 Proto
->ConfigSize
= 0;
129 if (!Proto
->ConfigData
) ABORT("Can't extend undefined <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
130 DataBase
= Proto
->ConfigData
[0];
131 Configs
= Proto
->ConfigSize
;
132 for (int f
= 0; f
< Configs
; f
++) TempConfig
[f
] = Proto
->ConfigData
[f
];
133 delete [] Proto
->ConfigData
;
134 Proto
->ConfigData
= NULL
;
135 Proto
->ConfigSize
= 0;
137 if (Proto
->ConfigData
) ABORT("Can't redefine <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
138 if (Proto
->Base
&& !Proto
->Base
->ConfigData
) ABORT("Database has no description of base prototype <%s> in file %s at line %d!", Proto
->Base
->GetClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
139 DataBase
= Proto
->Base
? new database(**Proto
->Base
->ConfigData
) : new database
;
140 DataBase
->InitDefaults(Proto
, 0, "default");
141 TempConfig
[0] = DataBase
;
144 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
145 //for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word))
147 inFile
->ReadWord(Word
, false);
148 if (Word
== "" && inFile
->Eof()) {
149 if (infStack
.empty()) ABORT("'}' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
151 inFile
= infStack
.top();
155 //fprintf(stderr, "D: %d; <%s>\n", (int)infStack.size(), Word.CStr());
156 if (Word
== "}") break;
158 if (Word
== "Include") {
159 Word
= inFile
->ReadWord();
160 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
161 //fprintf(stderr, "loading: %s\n", Word.CStr());
162 TextInput
*incf
= new TextInputFile(inputfile::buildIncludeName(inFile
->GetFileName(), Word
), &game::GetGlobalValueMap());
163 infStack
.push(inFile
);
165 inFile
->setGetVarCB(game::ldrGetVar
);
168 if (Word
== "Message") {
169 Word
= inFile
->ReadWord();
170 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
171 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
174 if (Word
== "Config") {
175 sLong ConfigNumber
= -1;
176 truth isString
= false;
178 fname
= inFile
->ReadStringOrNumberKeepStr(&ConfigNumber
, &isString
);
181 //fprintf(stderr, "loading: %s\n", fname.CStr());
183 TextInput *incf = new TextInputFile(game::GetGameDir()+"script/"+fname, &game::GetGlobalValueMap());
184 infStack.push(inFile);
187 ABORT("Config includes aren't supported yet!");
189 //fprintf(stderr, "new config %d (%s) for %s\n", ConfigNumber, inFile->numStr().CStr(), defName.CStr());
190 database
*ConfigDataBase
= new database(*Proto
->ChooseBaseForConfig(TempConfig
, Configs
, ConfigNumber
));
191 festring cfgname
= inFile
->numStr();
192 festring infname
= inFile
->GetFileName();
193 ConfigDataBase
->InitDefaults(Proto
, ConfigNumber
, cfgname
);
194 TempConfig
[Configs
++] = ConfigDataBase
;
195 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
196 for (inFile
->ReadWord(Word
); Word
!= "}"; inFile
->ReadWord(Word
)) {
198 Proto
->mOnEvents
.collectSource(infStack
, &inFile
);
201 if (!AnalyzeData(*inFile
, Word
, *ConfigDataBase
)) ABORT("Illegal datavalue %s found while building up %s config #%d (%s), file %s, line %d!", Word
.CStr(), Proto
->GetClassID(), ConfigNumber
, cfgname
.CStr(), infname
.CStr(), inFile
->TokenLine());
203 ConfigDataBase
->PostProcess();
208 Proto
->mOnEvents
.collectSource(infStack
, &inFile
);
211 if (!AnalyzeData(*inFile
, Word
, *DataBase
)) ABORT("Illegal datavalue %s found while building up %s, file %s, line %d!", Word
.CStr(), Proto
->GetClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
213 DataBase
->PostProcess();
214 //Configs = Proto->CreateSpecialConfigurations(TempConfig, Configs);
215 Proto
->ConfigData
= new database
*[Configs
];
216 Proto
->ConfigSize
= Configs
;
217 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
222 // remove undefined items
223 protocontainer
<type
>::Cleanup();
225 for (int c1
= 0; c1
< SPECIAL_CONFIGURATION_GENERATION_LEVELS
; ++c1
) {
226 for (int c2
= 1; c2
< protocontainer
<type
>::GetSize(); ++c2
) {
227 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c2
];
228 if (!Proto
) continue; // missing something
229 int Configs
= Proto
->ConfigSize
;
230 memmove(TempConfig
, Proto
->ConfigData
, Configs
*sizeof(database
*));
231 Configs
= Proto
->CreateSpecialConfigurations(TempConfig
, Configs
, c1
);
232 if (Proto
->ConfigSize
!= Configs
) {
233 delete [] Proto
->ConfigData
;
234 Proto
->ConfigData
= new database
*[Configs
];
235 Proto
->ConfigSize
= Configs
;
236 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
241 for (int c1
= 1; c1
< protocontainer
<type
>::GetSize(); ++c1
) {
242 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c1
];
243 if (!Proto
) continue; // missing something
245 CreateConfigTable(reinterpret_cast<databasebase
***>(Proto
->ConfigTable
),
247 reinterpret_cast<databasebase
**>(Proto
->ConfigData
),
248 TempTableInfo
, c1
, Proto
->ConfigSize
, TempTables
);
251 for (int c1
= 1; c1
< TempTables
; ++c1
) delete [] TempTable
[c1
];
253 GetDataBaseMemberMap().clear();
257 template <class type
> int databasecreator
<type
>::CreateDivineConfigurations (const prototype
*Proto
, database
**TempConfig
, int Configs
) {
258 int OldConfigs
= Configs
;
259 for (int c1
= 1; c1
< protocontainer
<god
>::GetSize(); ++c1
) {
260 database
*ConfigDataBase
= 0;
262 festring dcfgname
= "divine";
263 for (c2
= 1; c2
< OldConfigs
; ++c2
) {
264 ConfigDataBase
= TempConfig
[c2
];
265 if (ConfigDataBase
->Config
== c1
) {
267 dcfgname
<< ConfigDataBase
->CfgStrName
;
271 truth Created
= false;
272 if (c2
== OldConfigs
) {
273 ConfigDataBase
= new database(**TempConfig
);
274 ConfigDataBase
->InitDefaults(Proto
, c1
, dcfgname
);
277 ConfigDataBase
->AttachedGod
= c1
;
278 ConfigDataBase
->PostFix
<< "of " << festring(protocontainer
<god
>::GetProto(c1
)->GetClassID()).CapitalizeCopy();
279 if (Created
) TempConfig
[Configs
++] = ConfigDataBase
;
285 template int databasecreator
<character
>::CreateDivineConfigurations (const prototype
*, database
**, int);
286 template int databasecreator
<item
>::CreateDivineConfigurations (const prototype
*, database
**, int);
287 template int databasecreator
<olterrain
>::CreateDivineConfigurations (const prototype
*, database
**, int);
290 template <class database
, class member
> struct databasemember
: public databasememberbase
<database
> {
291 databasemember (member Member
) : Member(Member
) {}
292 virtual void ReadData (database
&DataBase
, TextInput
&SaveFile
) { ::ReadData(DataBase
.*Member
, SaveFile
); }
297 template <class database
, class member
> void AddMember(std::map
<festring
, databasememberbase
<database
>*>& Map
, cchar
* Str
, member Member
)
299 Map
.insert(std::pair
<festring
, databasememberbase
<database
>*>(Str
, new databasemember
<database
, member
>(Member
)));
303 /* Explicit instantiations seem to increase compile speed greatly here... */
305 #define INST_ADD_MEMBER(type, member) \
306 template void AddMember<type##database, member type##database::*>(std::map<festring, databasememberbase<type##database>*>&, cchar*, member type##database::*)
308 INST_ADD_MEMBER(character
, int);
309 //INST_ADD_MEMBER(character, sLong); //k8:64
310 INST_ADD_MEMBER(character
, packcol16
);
311 INST_ADD_MEMBER(character
, col24
);
312 INST_ADD_MEMBER(character
, packv2
);
313 INST_ADD_MEMBER(character
, festring
);
314 INST_ADD_MEMBER(character
, fearray
<sLong
>);
315 INST_ADD_MEMBER(character
, fearray
<festring
>);
316 INST_ADD_MEMBER(character
, contentscript
<item
>);
318 INST_ADD_MEMBER(item
, int);
319 //INST_ADD_MEMBER(item, sLong); //k8:64
320 INST_ADD_MEMBER(item
, col24
);
321 INST_ADD_MEMBER(item
, v2
);
322 INST_ADD_MEMBER(item
, festring
);
323 INST_ADD_MEMBER(item
, fearray
<sLong
>);
324 INST_ADD_MEMBER(item
, fearray
<festring
>);
325 INST_ADD_MEMBER(item
, RandomChance
);
327 INST_ADD_MEMBER(glterrain
, int);
328 //INST_ADD_MEMBER(glterrain, sLong); //k8:64
329 INST_ADD_MEMBER(glterrain
, v2
);
330 INST_ADD_MEMBER(glterrain
, festring
);
331 INST_ADD_MEMBER(glterrain
, fearray
<sLong
>);
333 INST_ADD_MEMBER(olterrain
, int);
334 //INST_ADD_MEMBER(olterrain, sLong); //k8:64
335 INST_ADD_MEMBER(olterrain
, v2
);
336 INST_ADD_MEMBER(olterrain
, festring
);
337 INST_ADD_MEMBER(olterrain
, fearray
<sLong
>);
338 INST_ADD_MEMBER(olterrain
, fearray
<contentscript
<item
> >);
340 INST_ADD_MEMBER(owterrain
, int);
341 //INST_ADD_MEMBER(owterrain, sLong); //k8:64
342 INST_ADD_MEMBER(owterrain
, v2
);
343 INST_ADD_MEMBER(owterrain
, festring
);
345 INST_ADD_MEMBER(gwterrain
, int);
346 //INST_ADD_MEMBER(gwterrain, sLong); //k8:64
347 INST_ADD_MEMBER(gwterrain
, v2
);
348 INST_ADD_MEMBER(gwterrain
, festring
);
349 INST_ADD_MEMBER(gwterrain
, float);
351 INST_ADD_MEMBER(material
, int);
352 //INST_ADD_MEMBER(material, sLong); //k8:64
353 INST_ADD_MEMBER(material
, col24
);
354 INST_ADD_MEMBER(material
, festring
);
355 INST_ADD_MEMBER(material
, contentscript
<item
>);
357 #define ADD_MEMBER(data) AddMember(Map, #data, &database::data);
359 template<> void databasecreator
<character
>::CreateDataBaseMemberMap () {
360 databasemembermap
&Map
= GetDataBaseMemberMap();
361 ADD_MEMBER(DefaultArmStrength
);
362 ADD_MEMBER(DefaultLegStrength
);
363 ADD_MEMBER(DefaultDexterity
);
364 ADD_MEMBER(DefaultAgility
);
365 ADD_MEMBER(DefaultEndurance
);
366 ADD_MEMBER(DefaultPerception
);
367 ADD_MEMBER(DefaultIntelligence
);
368 ADD_MEMBER(DefaultWisdom
);
369 ADD_MEMBER(DefaultWillPower
);
370 ADD_MEMBER(DefaultCharisma
);
371 ADD_MEMBER(DefaultMana
);
372 ADD_MEMBER(DefaultMoney
);
373 ADD_MEMBER(TotalSize
);
376 ADD_MEMBER(CanBeGenerated
);
377 ADD_MEMBER(CriticalModifier
);
378 ADD_MEMBER(StandVerb
);
380 ADD_MEMBER(Frequency
);
381 ADD_MEMBER(EnergyResistance
);
382 ADD_MEMBER(FireResistance
);
383 ADD_MEMBER(PoisonResistance
);
384 ADD_MEMBER(ElectricityResistance
);
385 ADD_MEMBER(AcidResistance
);
386 ADD_MEMBER(SoundResistance
);
387 ADD_MEMBER(IsUnique
);
388 ADD_MEMBER(ConsumeFlags
);
389 ADD_MEMBER(TotalVolume
);
390 ADD_MEMBER(HeadBitmapPos
);
391 ADD_MEMBER(TorsoBitmapPos
);
392 ADD_MEMBER(ArmBitmapPos
);
393 ADD_MEMBER(LegBitmapPos
);
394 ADD_MEMBER(RightArmBitmapPos
);
395 ADD_MEMBER(LeftArmBitmapPos
);
396 ADD_MEMBER(RightLegBitmapPos
);
397 ADD_MEMBER(LeftLegBitmapPos
);
398 ADD_MEMBER(GroinBitmapPos
);
399 ADD_MEMBER(ClothColor
);
400 ADD_MEMBER(SkinColor
);
401 ADD_MEMBER(CapColor
);
402 ADD_MEMBER(HairColor
);
403 ADD_MEMBER(EyeColor
);
404 ADD_MEMBER(TorsoMainColor
);
405 ADD_MEMBER(BeltColor
);
406 ADD_MEMBER(BootColor
);
407 ADD_MEMBER(TorsoSpecialColor
);
408 ADD_MEMBER(ArmMainColor
);
409 ADD_MEMBER(GauntletColor
);
410 ADD_MEMBER(ArmSpecialColor
);
411 ADD_MEMBER(LegMainColor
);
412 ADD_MEMBER(LegSpecialColor
);
413 ADD_MEMBER(IsNameable
);
414 ADD_MEMBER(BaseEmitation
);
415 ADD_MEMBER(UsesLongArticle
);
416 ADD_MEMBER(Adjective
);
417 ADD_MEMBER(UsesLongAdjectiveArticle
);
418 ADD_MEMBER(NameSingular
);
419 ADD_MEMBER(NamePlural
);
421 ADD_MEMBER(ArticleMode
);
422 ADD_MEMBER(IsAbstract
);
423 ADD_MEMBER(IsPolymorphable
);
424 ADD_MEMBER(BaseUnarmedStrength
);
425 ADD_MEMBER(BaseBiteStrength
);
426 ADD_MEMBER(BaseKickStrength
);
427 ADD_MEMBER(AttackStyle
);
428 ADD_MEMBER(CanUseEquipment
);
431 ADD_MEMBER(ClassStates
);
432 ADD_MEMBER(CanBeWished
);
434 ADD_MEMBER(CreateDivineConfigurations
);
435 ADD_MEMBER(CreateGolemMaterialConfigurations
);
439 ADD_MEMBER(BodyArmor
);
441 ADD_MEMBER(RightWielded
);
442 ADD_MEMBER(LeftWielded
);
443 ADD_MEMBER(RightRing
);
444 ADD_MEMBER(LeftRing
);
445 ADD_MEMBER(RightGauntlet
);
446 ADD_MEMBER(LeftGauntlet
);
447 ADD_MEMBER(RightBoot
);
448 ADD_MEMBER(LeftBoot
);
449 ADD_MEMBER(AttributeBonus
);
450 ADD_MEMBER(KnownCWeaponSkills
);
451 ADD_MEMBER(CWeaponSkillHits
);
452 ADD_MEMBER(RightSWeaponSkillHits
);
453 ADD_MEMBER(LeftSWeaponSkillHits
);
454 ADD_MEMBER(PanicLevel
);
455 ADD_MEMBER(CanBeCloned
);
456 ADD_MEMBER(Inventory
);
457 ADD_MEMBER(DangerModifier
);
458 ADD_MEMBER(DefaultName
);
459 ADD_MEMBER(FriendlyReplies
);
460 ADD_MEMBER(HostileReplies
);
462 ADD_MEMBER(FleshMaterial
);
464 ADD_MEMBER(DeathMessage
);
465 ADD_MEMBER(IgnoreDanger
);
466 ADD_MEMBER(HPRequirementForGeneration
);
467 ADD_MEMBER(DayRequirementForGeneration
);
468 ADD_MEMBER(IsExtraCoward
);
469 ADD_MEMBER(SpillsBlood
);
472 ADD_MEMBER(CanThrow
);
473 ADD_MEMBER(UsesNutrition
);
474 ADD_MEMBER(AttackWisdomLimit
);
475 ADD_MEMBER(AttachedGod
);
476 ADD_MEMBER(BodyPartsDisappearWhenSevered
);
477 ADD_MEMBER(CanBeConfused
);
478 ADD_MEMBER(CanApply
);
479 ADD_MEMBER(WieldedPosition
);
480 ADD_MEMBER(NaturalSparkleFlags
);
481 ADD_MEMBER(BiteCapturesBodyPart
);
483 ADD_MEMBER(MoveType
);
484 ADD_MEMBER(DestroysWalls
);
485 ADD_MEMBER(IsRooted
);
486 ADD_MEMBER(BloodMaterial
);
487 ADD_MEMBER(VomitMaterial
);
488 ADD_MEMBER(HasSecondaryMaterial
);
489 ADD_MEMBER(IsImmuneToLeprosy
);
490 ADD_MEMBER(PolymorphIntelligenceRequirement
);
491 ADD_MEMBER(AutomaticallySeen
);
493 ADD_MEMBER(DefaultCommandFlags
);
494 ADD_MEMBER(ConstantCommandFlags
);
495 ADD_MEMBER(WillCarryItems
);
496 ADD_MEMBER(ForceVomitMessage
);
497 ADD_MEMBER(SweatMaterial
);
499 ADD_MEMBER(IsImmuneToItemTeleport
);
500 ADD_MEMBER(AlwaysUseMaterialAttributes
);
501 ADD_MEMBER(IsEnormous
);
502 ADD_MEMBER(ScienceTalkAdjectiveAttribute
);
503 ADD_MEMBER(ScienceTalkSubstantiveAttribute
);
504 ADD_MEMBER(ScienceTalkPrefix
);
505 ADD_MEMBER(ScienceTalkName
);
506 ADD_MEMBER(ScienceTalkPossibility
);
507 ADD_MEMBER(ScienceTalkIntelligenceModifier
);
508 ADD_MEMBER(ScienceTalkWisdomModifier
);
509 ADD_MEMBER(ScienceTalkCharismaModifier
);
510 ADD_MEMBER(ScienceTalkIntelligenceRequirement
);
511 ADD_MEMBER(ScienceTalkWisdomRequirement
);
512 ADD_MEMBER(ScienceTalkCharismaRequirement
);
513 ADD_MEMBER(IsExtraFragile
);
514 ADD_MEMBER(AllowUnconsciousness
);
515 ADD_MEMBER(CanChoke
);
516 ADD_MEMBER(IsImmuneToStickiness
);
517 ADD_MEMBER(DisplacePriority
);
518 ADD_MEMBER(RunDescriptionLineOne
);
519 ADD_MEMBER(RunDescriptionLineTwo
);
520 ADD_MEMBER(ForceCustomStandVerb
);
521 ADD_MEMBER(VomittingIsUnhealthy
);
522 ADD_MEMBER(AllowPlayerToChangeEquipment
);
523 ADD_MEMBER(TamingDifficulty
);
524 ADD_MEMBER(IsMasochist
);
525 ADD_MEMBER(IsSadist
);
526 ADD_MEMBER(IsCatacombCreature
);
527 ADD_MEMBER(CreateUndeadConfigurations
);
528 ADD_MEMBER(UndeadVersions
);
529 ADD_MEMBER(UndeadAttributeModifier
);
530 ADD_MEMBER(UndeadVolumeModifier
);
531 ADD_MEMBER(UndeadCopyMaterials
);
532 ADD_MEMBER(CanBeGeneratedOnlyInTheCatacombs
);
533 ADD_MEMBER(IsAlcoholic
);
534 ADD_MEMBER(IsImmuneToWhipOfThievery
);
535 ADD_MEMBER(IsRangedAttacker
);
536 ADD_MEMBER(WhatCategoryToThrow
);
537 ADD_MEMBER(WhatWeaponConfigToThrow
);
538 ADD_MEMBER(WhatThrowItemTypesToThrow
);
539 ADD_MEMBER(AllowedDungeons
);
540 ADD_MEMBER(LevelTags
);
541 ADD_MEMBER(HomeLevel
);
542 ADD_MEMBER(NaturalTeam
);
546 template<> void databasecreator
<item
>::CreateDataBaseMemberMap () {
547 databasemembermap
&Map
= GetDataBaseMemberMap();
548 ADD_MEMBER(Possibility
);
549 ADD_MEMBER(IsDestroyable
);
550 ADD_MEMBER(CanBeWished
);
551 ADD_MEMBER(IsMaterialChangeable
);
552 ADD_MEMBER(WeaponCategory
);
553 ADD_MEMBER(IsPolymorphSpawnable
);
554 ADD_MEMBER(IsAutoInitializable
);
555 ADD_MEMBER(Category
);
556 ADD_MEMBER(EnergyResistance
);
557 ADD_MEMBER(FireResistance
);
558 ADD_MEMBER(PoisonResistance
);
559 ADD_MEMBER(ElectricityResistance
);
560 ADD_MEMBER(AcidResistance
);
561 ADD_MEMBER(SoundResistance
);
562 ADD_MEMBER(StrengthModifier
);
563 ADD_MEMBER(FormModifier
);
564 ADD_MEMBER(DefaultSize
);
565 ADD_MEMBER(DefaultMainVolume
);
566 ADD_MEMBER(DefaultSecondaryVolume
);
567 ADD_MEMBER(BitmapPos
);
569 ADD_MEMBER(BaseEmitation
);
570 ADD_MEMBER(UsesLongArticle
);
571 ADD_MEMBER(Adjective
);
572 ADD_MEMBER(UsesLongAdjectiveArticle
);
573 ADD_MEMBER(NameSingular
);
574 ADD_MEMBER(NamePlural
);
576 ADD_MEMBER(ArticleMode
);
577 ADD_MEMBER(MainMaterialConfig
);
578 ADD_MEMBER(SecondaryMaterialConfig
);
579 ADD_MEMBER(MaterialConfigChances
);
580 ADD_MEMBER(IsAbstract
);
581 ADD_MEMBER(IsPolymorphable
);
583 ADD_MEMBER(OKVisualEffects
);
584 ADD_MEMBER(CanBeGeneratedInContainer
);
585 ADD_MEMBER(ForcedVisualEffects
);
586 ADD_MEMBER(Roundness
);
587 ADD_MEMBER(GearStates
);
588 ADD_MEMBER(IsTwoHanded
);
589 ADD_MEMBER(CreateDivineConfigurations
);
590 ADD_MEMBER(CanBeCloned
);
591 ADD_MEMBER(CanBeMirrored
);
592 ADD_MEMBER(BeamRange
);
593 ADD_MEMBER(CanBeBroken
);
594 ADD_MEMBER(WallBitmapPos
);
595 ADD_MEMBER(FlexibleNameSingular
);
596 ADD_MEMBER(MaxCharges
);
597 ADD_MEMBER(MinCharges
);
598 ADD_MEMBER(CanBePiled
);
599 ADD_MEMBER(StorageVolume
);
600 ADD_MEMBER(MaxGeneratedContainedItems
);
601 ADD_MEMBER(AffectsArmStrength
);
602 ADD_MEMBER(AffectsLegStrength
);
603 ADD_MEMBER(AffectsDexterity
);
604 ADD_MEMBER(AffectsAgility
);
605 ADD_MEMBER(AffectsEndurance
);
606 ADD_MEMBER(AffectsPerception
);
607 ADD_MEMBER(AffectsIntelligence
);
608 ADD_MEMBER(AffectsWisdom
);
609 ADD_MEMBER(AffectsWillPower
);
610 ADD_MEMBER(AffectsCharisma
);
611 ADD_MEMBER(AffectsMana
);
612 ADD_MEMBER(BaseEnchantment
);
613 ADD_MEMBER(PriceIsProportionalToEnchantment
);
614 ADD_MEMBER(InElasticityPenaltyModifier
);
615 ADD_MEMBER(CanBeUsedBySmith
);
616 ADD_MEMBER(AffectsCarryingCapacity
);
617 ADD_MEMBER(DamageDivider
);
618 ADD_MEMBER(HandleInPairs
);
619 ADD_MEMBER(CanBeEnchanted
);
620 ADD_MEMBER(BeamColor
);
621 ADD_MEMBER(BeamEffect
);
622 ADD_MEMBER(BeamStyle
);
623 ADD_MEMBER(WearWisdomLimit
);
624 ADD_MEMBER(AttachedGod
);
625 ADD_MEMBER(BreakEffectRangeSquare
);
626 ADD_MEMBER(WieldedBitmapPos
);
627 ADD_MEMBER(IsQuestItem
);
628 ADD_MEMBER(IsGoodWithPlants
);
629 ADD_MEMBER(CreateLockConfigurations
);
630 ADD_MEMBER(CanBePickedUp
);
631 ADD_MEMBER(CoverPercentile
);
632 ADD_MEMBER(TorsoArmorBitmapPos
);
633 ADD_MEMBER(ArmArmorBitmapPos
);
634 ADD_MEMBER(AthleteArmArmorBitmapPos
);
635 ADD_MEMBER(LegArmorBitmapPos
);
636 ADD_MEMBER(HelmetBitmapPos
);
637 ADD_MEMBER(CloakBitmapPos
);
638 ADD_MEMBER(BeltBitmapPos
);
639 ADD_MEMBER(GauntletBitmapPos
);
640 ADD_MEMBER(BootBitmapPos
);
641 ADD_MEMBER(HasSecondaryMaterial
);
642 ADD_MEMBER(AllowEquip
);
643 ADD_MEMBER(ReadDifficulty
);
644 ADD_MEMBER(IsValuable
);
645 ADD_MEMBER(EnchantmentMinusChance
);
646 ADD_MEMBER(EnchantmentPlusChance
);
647 ADD_MEMBER(TeleportPriority
);
648 ADD_MEMBER(HasNormalPictureDirection
);
649 ADD_MEMBER(DamageFlags
);
650 ADD_MEMBER(IsKamikazeWeapon
);
651 ADD_MEMBER(FlexibilityIsEssential
);
652 ADD_MEMBER(BreakMsg
);
653 ADD_MEMBER(IsSadistWeapon
);
654 ADD_MEMBER(IsThrowingWeapon
);
655 ADD_MEMBER(ThrowItemTypes
);
656 ADD_MEMBER(CanFlame
);
657 ADD_MEMBER(MagicEffectDuration
);
658 ADD_MEMBER(MagicEffectChance
);
659 ADD_MEMBER(AllowedDungeons
);
660 ADD_MEMBER(LevelTags
);
664 template <class type
> void databasecreator
<type
>::CreateLTerrainDataBaseMemberMap () {
665 databasemembermap
&Map
= GetDataBaseMemberMap();
666 ADD_MEMBER(BitmapPos
);
667 ADD_MEMBER(UsesLongArticle
);
668 ADD_MEMBER(Adjective
);
669 ADD_MEMBER(UsesLongAdjectiveArticle
);
670 ADD_MEMBER(NameSingular
);
671 ADD_MEMBER(NamePlural
);
673 ADD_MEMBER(ArticleMode
);
674 ADD_MEMBER(MainMaterialConfig
);
675 ADD_MEMBER(SecondaryMaterialConfig
);
676 ADD_MEMBER(MaterialConfigChances
);
677 ADD_MEMBER(IsAbstract
);
678 ADD_MEMBER(OKVisualEffects
);
679 ADD_MEMBER(MaterialColorB
);
680 ADD_MEMBER(MaterialColorC
);
681 ADD_MEMBER(MaterialColorD
);
682 ADD_MEMBER(SitMessage
);
683 ADD_MEMBER(ShowMaterial
);
684 ADD_MEMBER(AttachedGod
);
685 ADD_MEMBER(Walkability
);
686 ADD_MEMBER(HasSecondaryMaterial
);
687 ADD_MEMBER(UseBorderTiles
);
688 ADD_MEMBER(BorderTilePriority
);
692 template<> void databasecreator
<glterrain
>::CreateDataBaseMemberMap () {
693 CreateLTerrainDataBaseMemberMap();
697 template<> void databasecreator
<olterrain
>::CreateDataBaseMemberMap () {
698 CreateLTerrainDataBaseMemberMap();
699 databasemembermap
&Map
= GetDataBaseMemberMap();
700 ADD_MEMBER(CreateDivineConfigurations
);
701 ADD_MEMBER(DigMessage
);
702 ADD_MEMBER(CanBeDestroyed
);
703 ADD_MEMBER(RestModifier
);
704 ADD_MEMBER(RestMessage
);
705 ADD_MEMBER(IsUpLink
);
706 ADD_MEMBER(StorageVolume
);
707 ADD_MEMBER(HPModifier
);
708 ADD_MEMBER(IsSafeToCreateDoor
);
709 ADD_MEMBER(OpenBitmapPos
);
710 ADD_MEMBER(CreateLockConfigurations
);
711 ADD_MEMBER(IsAlwaysTransparent
);
712 ADD_MEMBER(CreateWindowConfigurations
);
713 ADD_MEMBER(WindowBitmapPos
);
714 ADD_MEMBER(ShowThingsUnder
);
715 ADD_MEMBER(LeftOverItems
);
720 template<> void databasecreator
<gwterrain
>::CreateDataBaseMemberMap () {
721 databasemembermap
&Map
= GetDataBaseMemberMap();
722 ADD_MEMBER(BitmapPos
);
723 ADD_MEMBER(IsAbstract
);
724 ADD_MEMBER(NameStem
);
725 ADD_MEMBER(UsesLongArticle
);
726 ADD_MEMBER(Priority
);
727 ADD_MEMBER(AnimationFrames
);
728 ADD_MEMBER(IsFatalToStay
);
729 ADD_MEMBER(SurviveMessage
);
730 ADD_MEMBER(MonsterSurviveMessage
);
731 ADD_MEMBER(DeathMessage
);
732 ADD_MEMBER(MonsterDeathVerb
);
733 ADD_MEMBER(ScoreEntry
);
734 ADD_MEMBER(Walkability
);
735 //HACK: worldmap generation constants
736 ADD_MEMBER(MaxTemperature
);
737 ADD_MEMBER(LatitudeEffect
);
738 ADD_MEMBER(AltitudeEffect
);
739 ADD_MEMBER(TemperatureCold
);
740 ADD_MEMBER(TemperatureMedium
);
741 ADD_MEMBER(TemperatureWarm
);
742 ADD_MEMBER(TemperatureHot
);
746 template<> void databasecreator
<owterrain
>::CreateDataBaseMemberMap () {
747 databasemembermap
&Map
= GetDataBaseMemberMap();
748 ADD_MEMBER(BitmapPos
);
749 ADD_MEMBER(IsAbstract
);
750 ADD_MEMBER(NameSingular
);
751 ADD_MEMBER(NameStem
);
752 ADD_MEMBER(UsesLongArticle
);
753 ADD_MEMBER(AttachedDungeon
);
754 ADD_MEMBER(AttachedArea
);
755 ADD_MEMBER(CanBeGenerated
);
756 ADD_MEMBER(NativeGTerrainType
);
757 ADD_MEMBER(RevealEnvironmentInitially
);
758 ADD_MEMBER(CanBeOnAnyTerrain
);
759 ADD_MEMBER(WantContinentWith
);
760 ADD_MEMBER(Probability
);
761 ADD_MEMBER(CanBeSkipped
);
762 ADD_MEMBER(PlaceInitially
);
766 template<> void databasecreator
<material
>::CreateDataBaseMemberMap () {
767 databasemembermap
&Map
= GetDataBaseMemberMap();
768 ADD_MEMBER(CommonFlags
);
769 ADD_MEMBER(NameFlags
);
770 ADD_MEMBER(CategoryFlags
);
771 ADD_MEMBER(BodyFlags
);
772 ADD_MEMBER(InteractionFlags
);
773 ADD_MEMBER(StrengthValue
);
774 ADD_MEMBER(ConsumeType
);
777 ADD_MEMBER(RainColor
);
778 ADD_MEMBER(PriceModifier
);
779 ADD_MEMBER(Emitation
);
780 ADD_MEMBER(NutritionValue
);
781 ADD_MEMBER(NameStem
);
782 ADD_MEMBER(AdjectiveStem
);
784 ADD_MEMBER(ConsumeEndMessage
);
785 ADD_MEMBER(HitMessage
);
786 ADD_MEMBER(ExplosivePower
);
788 ADD_MEMBER(Flexibility
);
789 ADD_MEMBER(SpoilModifier
);
790 ADD_MEMBER(EffectStrength
);
791 ADD_MEMBER(DigProductMaterial
);
792 ADD_MEMBER(ConsumeWisdomLimit
);
793 ADD_MEMBER(AttachedGod
);
794 ADD_MEMBER(BreatheMessage
);
795 ADD_MEMBER(StepInWisdomLimit
);
796 ADD_MEMBER(RustModifier
);
797 ADD_MEMBER(Acidicity
);
798 ADD_MEMBER(NaturalForm
);
799 ADD_MEMBER(HardenedMaterial
);
800 ADD_MEMBER(SoftenedMaterial
);
801 ADD_MEMBER(IntelligenceRequirement
);
802 ADD_MEMBER(Stickiness
);
803 ADD_MEMBER(DisablesPanicWhenConsumed
);
804 ADD_MEMBER(BlockESP
);
808 #define ADD_BASE_VALUE(name)\
809 if (Word == #name) game::GetGlobalValueMap()[CONST_S("Base")] = DataBase.*static_cast<databasemember<database, feuLong database::*>*>(Data)->Member;
812 template <class type
> void databasecreator
<type
>::SetBaseValue(cfestring
&, databasememberbase
<database
> *, database
&) {}
814 template<> void databasecreator
<material
>::SetBaseValue(cfestring
&Word
, databasememberbase
<materialdatabase
> *Data
,
815 materialdatabase
&DataBase
)
817 ADD_BASE_VALUE(CommonFlags
);
818 ADD_BASE_VALUE(NameFlags
);
819 ADD_BASE_VALUE(CategoryFlags
);
820 ADD_BASE_VALUE(BodyFlags
);
821 ADD_BASE_VALUE(InteractionFlags
);
825 template <class type
> truth databasecreator
<type
>::AnalyzeData (TextInput
&SaveFile
, cfestring
&Word
, database
&DataBase
) {
826 typename
databasemembermap::iterator i
= GetDataBaseMemberMap().find(Word
);
827 if (i
!= GetDataBaseMemberMap().end()) {
828 SetBaseValue(Word
, i
->second
, DataBase
);
829 i
->second
->ReadData(DataBase
, SaveFile
);
830 CheckDefaults(Word
, DataBase
);
837 template <> void databasecreator
<character
>::CheckDefaults (cfestring
&Word
, character::database
&DataBase
) {
838 if (Word
== "ArmBitmapPos") { DataBase
.RightArmBitmapPos
= DataBase
.LeftArmBitmapPos
= DataBase
.ArmBitmapPos
; return; }
839 if (Word
== "LegBitmapPos") { DataBase
.GroinBitmapPos
= DataBase
.RightLegBitmapPos
= DataBase
.LeftLegBitmapPos
= DataBase
.LegBitmapPos
; return; }
840 if (Word
== "ClothColor") { DataBase
.CapColor
= DataBase
.TorsoMainColor
= DataBase
.ArmMainColor
= DataBase
.GauntletColor
= DataBase
.LegMainColor
= DataBase
.ClothColor
; return; }
841 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
842 if (Word
== "BaseUnarmedStrength") { DataBase
.BaseBiteStrength
= DataBase
.BaseUnarmedStrength
>>1; DataBase
.BaseKickStrength
= DataBase
.BaseUnarmedStrength
<<1; return; }
843 if (Word
== "RightGauntlet") { DataBase
.LeftGauntlet
= DataBase
.RightGauntlet
; return; }
844 if (Word
== "RightBoot") { DataBase
.LeftBoot
= DataBase
.RightBoot
; return; }
845 if (Word
== "IsUnique") { DataBase
.CanBeWished
= !DataBase
.IsUnique
; return; }
846 if (Word
== "DefaultName") {
847 // k8: don't add duplicate alias
848 for (uInt c
= 0; c
< DataBase
.Alias
.Size
; ++c
) {
849 if (DataBase
.Alias
[c
] == DataBase
.DefaultName
) return;
851 DataBase
.Alias
.Add(DataBase
.DefaultName
);
853 if (DataBase.Alias.Size != 1) {
854 printf("=== %s ===\n", DataBase.NameSingular.CStr());
855 for (uInt c = 0; c < DataBase.Alias.Size; ++c) {
856 printf(" %u: %s\n", c, DataBase.Alias[c].CStr());
865 template <> void databasecreator
<item
>::CheckDefaults (cfestring
&Word
, item::database
&DataBase
) {
866 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; DataBase
.FlexibleNameSingular
= DataBase
.NameSingular
; return; }
867 if (Word
== "BitmapPos") { DataBase
.WallBitmapPos
= DataBase
.BitmapPos
; return; }
868 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
869 if (Word
== "CanBeCloned") { DataBase
.CanBeMirrored
= DataBase
.CanBeCloned
; return; }
873 template <> void databasecreator
<glterrain
>::CheckDefaults (cfestring
&Word
, glterrain::database
&DataBase
) {
874 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
875 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
879 template <> void databasecreator
<olterrain
>::CheckDefaults (cfestring
&Word
, olterrain::database
&DataBase
) {
880 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
881 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
885 template <> void databasecreator
<material
>::CheckDefaults (cfestring
&Word
, material::database
&DataBase
) {
886 if (Word
== "NameStem") { DataBase
.AdjectiveStem
= DataBase
.NameStem
; return; }
887 if (Word
== "Color") { DataBase
.RainColor
= DataBase
.Color
; return; }
891 template<> void databasecreator
<owterrain
>::CheckDefaults (cfestring
& Word
, owterrain::database
& DataBase
) {
895 template<> void databasecreator
<gwterrain
>::CheckDefaults (cfestring
& Word
, gwterrain::database
& DataBase
) {
900 void databasesystem::Initialize () {
901 /* Must be before character */
902 databasecreator
<material
>::ReadFrom("material");
903 databasecreator
<character
>::ReadFrom("char");
904 /* Must be before olterrain */
905 databasecreator
<item
>::ReadFrom("item");
906 databasecreator
<glterrain
>::ReadFrom("glterra");
907 databasecreator
<olterrain
>::ReadFrom("olterra");
908 databasecreator
<gwterrain
>::ReadFrom("gwterra");
910 databasecreator
<owterrain
>::ReadFrom("owterra");
914 template <class type
> inline void databasecreator
<type
>::FindDataBase (const database
*&DataBase
, const prototype
*Proto
, int Config
) {
915 database
**Table
= Proto
->ConfigTable
[(Config
>> 8) ^ (Config
& 0xFF)];
917 if ((*Table
)->Config
== Config
) {
921 for (++Table
; *Table
; ++Table
) {
922 if ((*Table
)->Config
== Config
) {
932 template void databasecreator
<character
>::FindDataBase (const database
*&, const prototype
*, int);
933 template void databasecreator
<material
>::FindDataBase (const database
*&, const prototype
*, int);
935 template <class type
> void databasecreator
<type
>::InstallDataBase (type
*Instance
, int Config
) {
936 const prototype
*Proto
= Instance
->FindProtoType();
937 FindDataBase(Instance
->DataBase
, Proto
, Config
);
938 if (!Instance
->DataBase
) {
940 ABORT("Undefined %s configuration #%08x sought!", Proto
->GetClassID(), (unsigned int)Config
);
944 #define INST_INSTALL_DATABASE(type) template void databasecreator<type>::InstallDataBase(type *, int)
946 INST_INSTALL_DATABASE(material
);
947 INST_INSTALL_DATABASE(character
);
948 INST_INSTALL_DATABASE(item
);
949 INST_INSTALL_DATABASE(glterrain
);
950 INST_INSTALL_DATABASE(olterrain
);
951 INST_INSTALL_DATABASE(gwterrain
);
952 INST_INSTALL_DATABASE(owterrain
);