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 static void collectHandler (festring
&dest
, std::stack
<TextInput
*> &infStack
, TextInput
**iff
) {
48 TextInput
*inFile
= *iff
;
49 festring Word
= inFile
->ReadWord(true);
50 dest
<< "on " << Word
<< "\n{\n";
51 if (inFile
->ReadWord() != "{") ABORT("'{' missing in datafile %s line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
55 int ch
= inFile
->GetChar();
57 if (infStack
.empty()) ABORT("'}' missing in datafile %s line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
59 *iff
= inFile
= infStack
.top();
65 if (ch
== '"') inStr
= false;
66 else if (ch
== '\\') {
67 ch
= inFile
->GetChar();
68 if (ch
== EOF
) ABORT("Unexpected end of file %s!", inFile
->GetFileName().CStr());
75 } else if (ch
== '{') {
77 } else if (ch
== '"') {
85 template <class type
> void databasecreator
<type
>::ReadFrom (const festring
&baseFileName
) {
86 std::stack
<TextInput
*> infStack
;
89 auto modlist
= game::GetModuleList();
90 for (unsigned idx
= modlist
.size(); idx
> 0; --idx
) {
91 festring infname
= game::GetGameDir()+"script/"+modlist
[idx
-1]+"/"+baseFileName
+".dat";
92 if (inputfile::fileExists(infname
)) {
93 TextInput
*ifl
= new TextInputFile(infname
, &game::GetGlobalValueMap());
94 ifl
->setGetVarCB(game::ldrGetVar
);
101 festring infname
= game::GetGameDir()+"script/"+baseFileName
+".dat";
102 TextInput
*ifl
= new TextInputFile(infname
, &game::GetGlobalValueMap());
103 ifl
->setGetVarCB(game::ldrGetVar
);
107 if (infStack
.size() == 0) ABORT("Cannot find '%s' scripts!", baseFileName
.CStr());
110 typedef typename
type::prototype prototype
;
111 festring Word
, defName
;
112 database
*TempConfig
[1024];
113 databasebase
**TempTable
[1024];
114 sLong TempTableInfo
[CONFIG_TABLE_SIZE
];
116 databasebase
*FirstTempTable
[CONFIG_TABLE_SIZE
];
117 TempTable
[0] = FirstTempTable
;
118 memset(TempTableInfo
, 0, sizeof(TempTableInfo
));
119 CreateDataBaseMemberMap();
120 while (!infStack
.empty()) {
121 TextInput
*inFile
= infStack
.top();
123 inFile
->setGetVarCB(game::ldrGetVar
);
124 //fprintf(stderr, "MAIN: %s\n", inFile->GetFileName().CStr());
125 for (inFile
->ReadWord(Word
, false); !inFile
->Eof(); inFile
->ReadWord(Word
, false)) {
126 if (Word
== "Include") {
127 Word
= inFile
->ReadWord();
128 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
129 //fprintf(stderr, "loading: %s\n", Word.CStr());
130 TextInput
*incf
= new TextInputFile(inputfile::buildIncludeName(inFile
->GetFileName(), Word
), &game::GetGlobalValueMap());
131 infStack
.push(inFile
);
133 inFile
->setGetVarCB(game::ldrGetVar
);
136 if (Word
== "Message") {
137 Word
= inFile
->ReadWord();
138 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
139 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
143 truth doExtend
= false, doOverride
= false;
144 if (Word
== "Extend") {
145 Word
= inFile
->ReadWord();
147 } else if (Word
== "Override" || Word
== "Redefine") {
148 Word
= inFile
->ReadWord();
153 int Type
= protocontainer
<type
>::SearchCodeName(Word
);
154 if (!Type
) ABORT("Odd term <%s> encountered in %s datafile %s line %d!", Word
.CStr(), protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
155 //fprintf(stderr, "class <%s>\n", Word.CStr());
156 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[Type
];
157 if (!Proto
) ABORT("Something weird with <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
161 if (!Proto
->ConfigData
) ABORT("Can't override undefined <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
162 delete [] Proto
->ConfigData
;
163 Proto
->ConfigData
= NULL
;
164 Proto
->ConfigSize
= 0;
167 if (!Proto
->ConfigData
) ABORT("Can't extend undefined <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
168 DataBase
= Proto
->ConfigData
[0];
169 Configs
= Proto
->ConfigSize
;
170 for (int f
= 0; f
< Configs
; f
++) TempConfig
[f
] = Proto
->ConfigData
[f
];
171 delete [] Proto
->ConfigData
;
172 Proto
->ConfigData
= NULL
;
173 Proto
->ConfigSize
= 0;
175 if (Proto
->ConfigData
) ABORT("Can't redefine <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
176 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());
177 DataBase
= Proto
->Base
? new database(**Proto
->Base
->ConfigData
) : new database
;
178 DataBase
->InitDefaults(Proto
, 0, "default");
179 TempConfig
[0] = DataBase
;
182 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
183 //for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word))
185 inFile
->ReadWord(Word
, false);
186 if (Word
== "" && inFile
->Eof()) {
187 if (infStack
.empty()) ABORT("'}' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
189 inFile
= infStack
.top();
193 //fprintf(stderr, "D: %d; <%s>\n", (int)infStack.size(), Word.CStr());
194 if (Word
== "}") break;
196 if (Word
== "Include") {
197 Word
= inFile
->ReadWord();
198 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
199 //fprintf(stderr, "loading: %s\n", Word.CStr());
200 TextInput
*incf
= new TextInputFile(inputfile::buildIncludeName(inFile
->GetFileName(), Word
), &game::GetGlobalValueMap());
201 infStack
.push(inFile
);
203 inFile
->setGetVarCB(game::ldrGetVar
);
206 if (Word
== "Message") {
207 Word
= inFile
->ReadWord();
208 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
209 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
212 if (Word
== "Config") {
213 sLong ConfigNumber
= -1;
214 truth isString
= false;
216 fname
= inFile
->ReadStringOrNumberKeepStr(&ConfigNumber
, &isString
);
219 //fprintf(stderr, "loading: %s\n", fname.CStr());
221 TextInput *incf = new TextInputFile(game::GetGameDir()+"script/"+fname, &game::GetGlobalValueMap());
222 infStack.push(inFile);
225 ABORT("Config includes aren't supported yet!");
227 //fprintf(stderr, "new config %d (%s) for %s\n", ConfigNumber, inFile->numStr().CStr(), defName.CStr());
228 database
*ConfigDataBase
= new database(*Proto
->ChooseBaseForConfig(TempConfig
, Configs
, ConfigNumber
));
229 festring cfgname
= inFile
->numStr();
230 festring infname
= inFile
->GetFileName();
231 ConfigDataBase
->InitDefaults(Proto
, ConfigNumber
, cfgname
);
232 TempConfig
[Configs
++] = ConfigDataBase
;
233 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
234 for (inFile
->ReadWord(Word
); Word
!= "}"; inFile
->ReadWord(Word
)) {
236 collectHandler(Proto
->mOnEvents
, infStack
, &inFile
);
239 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());
241 ConfigDataBase
->PostProcess();
246 collectHandler(Proto
->mOnEvents
, infStack
, &inFile
);
249 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());
251 DataBase
->PostProcess();
252 //Configs = Proto->CreateSpecialConfigurations(TempConfig, Configs);
253 Proto
->ConfigData
= new database
*[Configs
];
254 Proto
->ConfigSize
= Configs
;
255 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
261 for (c1
= 0; c1
< SPECIAL_CONFIGURATION_GENERATION_LEVELS
; ++c1
) {
262 for (int c2
= 1; c2
< protocontainer
<type
>::GetSize(); ++c2
) {
263 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c2
];
264 int Configs
= Proto
->ConfigSize
;
265 memmove(TempConfig
, Proto
->ConfigData
, Configs
*sizeof(database
*));
266 Configs
= Proto
->CreateSpecialConfigurations(TempConfig
, Configs
, c1
);
267 if (Proto
->ConfigSize
!= Configs
) {
268 delete [] Proto
->ConfigData
;
269 Proto
->ConfigData
= new database
*[Configs
];
270 Proto
->ConfigSize
= Configs
;
271 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
275 for (c1
= 1; c1
< protocontainer
<type
>::GetSize(); ++c1
) {
276 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c1
];
278 CreateConfigTable(reinterpret_cast<databasebase
***>(Proto
->ConfigTable
),
280 reinterpret_cast<databasebase
**>(Proto
->ConfigData
),
281 TempTableInfo
, c1
, Proto
->ConfigSize
, TempTables
);
283 for (c1
= 1; c1
< TempTables
; ++c1
) delete [] TempTable
[c1
];
284 GetDataBaseMemberMap().clear();
288 template <class type
> int databasecreator
<type
>::CreateDivineConfigurations (const prototype
*Proto
, database
**TempConfig
, int Configs
) {
289 int OldConfigs
= Configs
;
290 for (int c1
= 1; c1
< protocontainer
<god
>::GetSize(); ++c1
) {
291 database
*ConfigDataBase
= 0;
293 festring dcfgname
= "divine";
294 for (c2
= 1; c2
< OldConfigs
; ++c2
) {
295 ConfigDataBase
= TempConfig
[c2
];
296 if (ConfigDataBase
->Config
== c1
) {
298 dcfgname
<< ConfigDataBase
->CfgStrName
;
302 truth Created
= false;
303 if (c2
== OldConfigs
) {
304 ConfigDataBase
= new database(**TempConfig
);
305 ConfigDataBase
->InitDefaults(Proto
, c1
, dcfgname
);
308 ConfigDataBase
->AttachedGod
= c1
;
309 ConfigDataBase
->PostFix
<< "of " << festring(protocontainer
<god
>::GetProto(c1
)->GetClassID()).CapitalizeCopy();
310 if (Created
) TempConfig
[Configs
++] = ConfigDataBase
;
316 template int databasecreator
<character
>::CreateDivineConfigurations (const prototype
*, database
**, int);
317 template int databasecreator
<item
>::CreateDivineConfigurations (const prototype
*, database
**, int);
318 template int databasecreator
<olterrain
>::CreateDivineConfigurations (const prototype
*, database
**, int);
321 template <class database
, class member
> struct databasemember
: public databasememberbase
<database
> {
322 databasemember (member Member
) : Member(Member
) {}
323 virtual void ReadData (database
&DataBase
, TextInput
&SaveFile
) { ::ReadData(DataBase
.*Member
, SaveFile
); }
328 template <class database
, class member
> void AddMember(std::map
<festring
, databasememberbase
<database
>*>& Map
, cchar
* Str
, member Member
)
330 Map
.insert(std::pair
<festring
, databasememberbase
<database
>*>(Str
, new databasemember
<database
, member
>(Member
)));
334 /* Explicit instantiations seem to increase compile speed greatly here... */
336 #define INST_ADD_MEMBER(type, member) \
337 template void AddMember<type##database, member type##database::*>(std::map<festring, databasememberbase<type##database>*>&, cchar*, member type##database::*)
339 INST_ADD_MEMBER(character
, int);
340 //INST_ADD_MEMBER(character, sLong); //k8:64
341 INST_ADD_MEMBER(character
, packcol16
);
342 INST_ADD_MEMBER(character
, col24
);
343 INST_ADD_MEMBER(character
, packv2
);
344 INST_ADD_MEMBER(character
, festring
);
345 INST_ADD_MEMBER(character
, fearray
<sLong
>);
346 INST_ADD_MEMBER(character
, fearray
<festring
>);
347 INST_ADD_MEMBER(character
, contentscript
<item
>);
349 INST_ADD_MEMBER(item
, int);
350 //INST_ADD_MEMBER(item, sLong); //k8:64
351 INST_ADD_MEMBER(item
, col24
);
352 INST_ADD_MEMBER(item
, v2
);
353 INST_ADD_MEMBER(item
, festring
);
354 INST_ADD_MEMBER(item
, fearray
<sLong
>);
355 INST_ADD_MEMBER(item
, fearray
<festring
>);
357 INST_ADD_MEMBER(glterrain
, int);
358 //INST_ADD_MEMBER(glterrain, sLong); //k8:64
359 INST_ADD_MEMBER(glterrain
, v2
);
360 INST_ADD_MEMBER(glterrain
, festring
);
361 INST_ADD_MEMBER(glterrain
, fearray
<sLong
>);
363 INST_ADD_MEMBER(olterrain
, int);
364 //INST_ADD_MEMBER(olterrain, sLong); //k8:64
365 INST_ADD_MEMBER(olterrain
, v2
);
366 INST_ADD_MEMBER(olterrain
, festring
);
367 INST_ADD_MEMBER(olterrain
, fearray
<sLong
>);
368 INST_ADD_MEMBER(olterrain
, fearray
<contentscript
<item
> >);
370 INST_ADD_MEMBER(owterrain
, int);
371 //INST_ADD_MEMBER(owterrain, sLong); //k8:64
372 INST_ADD_MEMBER(owterrain
, v2
);
373 INST_ADD_MEMBER(owterrain
, festring
);
375 INST_ADD_MEMBER(material
, int);
376 //INST_ADD_MEMBER(material, sLong); //k8:64
377 INST_ADD_MEMBER(material
, col24
);
378 INST_ADD_MEMBER(material
, festring
);
379 INST_ADD_MEMBER(material
, contentscript
<item
>);
381 #define ADD_MEMBER(data) AddMember(Map, #data, &database::data);
383 template<> void databasecreator
<character
>::CreateDataBaseMemberMap () {
384 databasemembermap
&Map
= GetDataBaseMemberMap();
385 ADD_MEMBER(DefaultArmStrength
);
386 ADD_MEMBER(DefaultLegStrength
);
387 ADD_MEMBER(DefaultDexterity
);
388 ADD_MEMBER(DefaultAgility
);
389 ADD_MEMBER(DefaultEndurance
);
390 ADD_MEMBER(DefaultPerception
);
391 ADD_MEMBER(DefaultIntelligence
);
392 ADD_MEMBER(DefaultWisdom
);
393 ADD_MEMBER(DefaultWillPower
);
394 ADD_MEMBER(DefaultCharisma
);
395 ADD_MEMBER(DefaultMana
);
396 ADD_MEMBER(DefaultMoney
);
397 ADD_MEMBER(TotalSize
);
400 ADD_MEMBER(CanBeGenerated
);
401 ADD_MEMBER(CriticalModifier
);
402 ADD_MEMBER(StandVerb
);
404 ADD_MEMBER(Frequency
);
405 ADD_MEMBER(EnergyResistance
);
406 ADD_MEMBER(FireResistance
);
407 ADD_MEMBER(PoisonResistance
);
408 ADD_MEMBER(ElectricityResistance
);
409 ADD_MEMBER(AcidResistance
);
410 ADD_MEMBER(SoundResistance
);
411 ADD_MEMBER(IsUnique
);
412 ADD_MEMBER(ConsumeFlags
);
413 ADD_MEMBER(TotalVolume
);
414 ADD_MEMBER(HeadBitmapPos
);
415 ADD_MEMBER(TorsoBitmapPos
);
416 ADD_MEMBER(ArmBitmapPos
);
417 ADD_MEMBER(LegBitmapPos
);
418 ADD_MEMBER(RightArmBitmapPos
);
419 ADD_MEMBER(LeftArmBitmapPos
);
420 ADD_MEMBER(RightLegBitmapPos
);
421 ADD_MEMBER(LeftLegBitmapPos
);
422 ADD_MEMBER(GroinBitmapPos
);
423 ADD_MEMBER(ClothColor
);
424 ADD_MEMBER(SkinColor
);
425 ADD_MEMBER(CapColor
);
426 ADD_MEMBER(HairColor
);
427 ADD_MEMBER(EyeColor
);
428 ADD_MEMBER(TorsoMainColor
);
429 ADD_MEMBER(BeltColor
);
430 ADD_MEMBER(BootColor
);
431 ADD_MEMBER(TorsoSpecialColor
);
432 ADD_MEMBER(ArmMainColor
);
433 ADD_MEMBER(GauntletColor
);
434 ADD_MEMBER(ArmSpecialColor
);
435 ADD_MEMBER(LegMainColor
);
436 ADD_MEMBER(LegSpecialColor
);
437 ADD_MEMBER(IsNameable
);
438 ADD_MEMBER(BaseEmitation
);
439 ADD_MEMBER(UsesLongArticle
);
440 ADD_MEMBER(Adjective
);
441 ADD_MEMBER(UsesLongAdjectiveArticle
);
442 ADD_MEMBER(NameSingular
);
443 ADD_MEMBER(NamePlural
);
445 ADD_MEMBER(ArticleMode
);
446 ADD_MEMBER(IsAbstract
);
447 ADD_MEMBER(IsPolymorphable
);
448 ADD_MEMBER(BaseUnarmedStrength
);
449 ADD_MEMBER(BaseBiteStrength
);
450 ADD_MEMBER(BaseKickStrength
);
451 ADD_MEMBER(AttackStyle
);
452 ADD_MEMBER(CanUseEquipment
);
455 ADD_MEMBER(ClassStates
);
456 ADD_MEMBER(CanBeWished
);
458 ADD_MEMBER(CreateDivineConfigurations
);
459 ADD_MEMBER(CreateGolemMaterialConfigurations
);
463 ADD_MEMBER(BodyArmor
);
465 ADD_MEMBER(RightWielded
);
466 ADD_MEMBER(LeftWielded
);
467 ADD_MEMBER(RightRing
);
468 ADD_MEMBER(LeftRing
);
469 ADD_MEMBER(RightGauntlet
);
470 ADD_MEMBER(LeftGauntlet
);
471 ADD_MEMBER(RightBoot
);
472 ADD_MEMBER(LeftBoot
);
473 ADD_MEMBER(AttributeBonus
);
474 ADD_MEMBER(KnownCWeaponSkills
);
475 ADD_MEMBER(CWeaponSkillHits
);
476 ADD_MEMBER(RightSWeaponSkillHits
);
477 ADD_MEMBER(LeftSWeaponSkillHits
);
478 ADD_MEMBER(PanicLevel
);
479 ADD_MEMBER(CanBeCloned
);
480 ADD_MEMBER(Inventory
);
481 ADD_MEMBER(DangerModifier
);
482 ADD_MEMBER(DefaultName
);
483 ADD_MEMBER(FriendlyReplies
);
484 ADD_MEMBER(HostileReplies
);
486 ADD_MEMBER(FleshMaterial
);
488 ADD_MEMBER(DeathMessage
);
489 ADD_MEMBER(IgnoreDanger
);
490 ADD_MEMBER(HPRequirementForGeneration
);
491 ADD_MEMBER(DayRequirementForGeneration
);
492 ADD_MEMBER(IsExtraCoward
);
493 ADD_MEMBER(SpillsBlood
);
496 ADD_MEMBER(CanThrow
);
497 ADD_MEMBER(UsesNutrition
);
498 ADD_MEMBER(AttackWisdomLimit
);
499 ADD_MEMBER(AttachedGod
);
500 ADD_MEMBER(BodyPartsDisappearWhenSevered
);
501 ADD_MEMBER(CanBeConfused
);
502 ADD_MEMBER(CanApply
);
503 ADD_MEMBER(WieldedPosition
);
504 ADD_MEMBER(NaturalSparkleFlags
);
505 ADD_MEMBER(BiteCapturesBodyPart
);
507 ADD_MEMBER(MoveType
);
508 ADD_MEMBER(DestroysWalls
);
509 ADD_MEMBER(IsRooted
);
510 ADD_MEMBER(BloodMaterial
);
511 ADD_MEMBER(VomitMaterial
);
512 ADD_MEMBER(HasSecondaryMaterial
);
513 ADD_MEMBER(IsImmuneToLeprosy
);
514 ADD_MEMBER(PolymorphIntelligenceRequirement
);
515 ADD_MEMBER(AutomaticallySeen
);
517 ADD_MEMBER(DefaultCommandFlags
);
518 ADD_MEMBER(ConstantCommandFlags
);
519 ADD_MEMBER(WillCarryItems
);
520 ADD_MEMBER(ForceVomitMessage
);
521 ADD_MEMBER(SweatMaterial
);
523 ADD_MEMBER(IsImmuneToItemTeleport
);
524 ADD_MEMBER(AlwaysUseMaterialAttributes
);
525 ADD_MEMBER(IsEnormous
);
526 ADD_MEMBER(ScienceTalkAdjectiveAttribute
);
527 ADD_MEMBER(ScienceTalkSubstantiveAttribute
);
528 ADD_MEMBER(ScienceTalkPrefix
);
529 ADD_MEMBER(ScienceTalkName
);
530 ADD_MEMBER(ScienceTalkPossibility
);
531 ADD_MEMBER(ScienceTalkIntelligenceModifier
);
532 ADD_MEMBER(ScienceTalkWisdomModifier
);
533 ADD_MEMBER(ScienceTalkCharismaModifier
);
534 ADD_MEMBER(ScienceTalkIntelligenceRequirement
);
535 ADD_MEMBER(ScienceTalkWisdomRequirement
);
536 ADD_MEMBER(ScienceTalkCharismaRequirement
);
537 ADD_MEMBER(IsExtraFragile
);
538 ADD_MEMBER(AllowUnconsciousness
);
539 ADD_MEMBER(CanChoke
);
540 ADD_MEMBER(IsImmuneToStickiness
);
541 ADD_MEMBER(DisplacePriority
);
542 ADD_MEMBER(RunDescriptionLineOne
);
543 ADD_MEMBER(RunDescriptionLineTwo
);
544 ADD_MEMBER(ForceCustomStandVerb
);
545 ADD_MEMBER(VomittingIsUnhealthy
);
546 ADD_MEMBER(AllowPlayerToChangeEquipment
);
547 ADD_MEMBER(TamingDifficulty
);
548 ADD_MEMBER(IsMasochist
);
549 ADD_MEMBER(IsSadist
);
550 ADD_MEMBER(IsCatacombCreature
);
551 ADD_MEMBER(CreateUndeadConfigurations
);
552 ADD_MEMBER(UndeadVersions
);
553 ADD_MEMBER(UndeadAttributeModifier
);
554 ADD_MEMBER(UndeadVolumeModifier
);
555 ADD_MEMBER(UndeadCopyMaterials
);
556 ADD_MEMBER(CanBeGeneratedOnlyInTheCatacombs
);
557 ADD_MEMBER(IsAlcoholic
);
558 ADD_MEMBER(IsImmuneToWhipOfThievery
);
559 ADD_MEMBER(IsRangedAttacker
);
560 ADD_MEMBER(WhatCategoryToThrow
);
561 ADD_MEMBER(WhatWeaponConfigToThrow
);
562 ADD_MEMBER(WhatThrowItemTypesToThrow
);
563 ADD_MEMBER(AllowedDungeons
);
564 ADD_MEMBER(LevelTags
);
565 ADD_MEMBER(HomeLevel
);
566 ADD_MEMBER(NaturalTeam
);
570 template<> void databasecreator
<item
>::CreateDataBaseMemberMap () {
571 databasemembermap
&Map
= GetDataBaseMemberMap();
572 ADD_MEMBER(Possibility
);
573 ADD_MEMBER(IsDestroyable
);
574 ADD_MEMBER(CanBeWished
);
575 ADD_MEMBER(IsMaterialChangeable
);
576 ADD_MEMBER(WeaponCategory
);
577 ADD_MEMBER(IsPolymorphSpawnable
);
578 ADD_MEMBER(IsAutoInitializable
);
579 ADD_MEMBER(Category
);
580 ADD_MEMBER(EnergyResistance
);
581 ADD_MEMBER(FireResistance
);
582 ADD_MEMBER(PoisonResistance
);
583 ADD_MEMBER(ElectricityResistance
);
584 ADD_MEMBER(AcidResistance
);
585 ADD_MEMBER(SoundResistance
);
586 ADD_MEMBER(StrengthModifier
);
587 ADD_MEMBER(FormModifier
);
588 ADD_MEMBER(DefaultSize
);
589 ADD_MEMBER(DefaultMainVolume
);
590 ADD_MEMBER(DefaultSecondaryVolume
);
591 ADD_MEMBER(BitmapPos
);
593 ADD_MEMBER(BaseEmitation
);
594 ADD_MEMBER(UsesLongArticle
);
595 ADD_MEMBER(Adjective
);
596 ADD_MEMBER(UsesLongAdjectiveArticle
);
597 ADD_MEMBER(NameSingular
);
598 ADD_MEMBER(NamePlural
);
600 ADD_MEMBER(ArticleMode
);
601 ADD_MEMBER(MainMaterialConfig
);
602 ADD_MEMBER(SecondaryMaterialConfig
);
603 ADD_MEMBER(MaterialConfigChances
);
604 ADD_MEMBER(IsAbstract
);
605 ADD_MEMBER(IsPolymorphable
);
607 ADD_MEMBER(OKVisualEffects
);
608 ADD_MEMBER(CanBeGeneratedInContainer
);
609 ADD_MEMBER(ForcedVisualEffects
);
610 ADD_MEMBER(Roundness
);
611 ADD_MEMBER(GearStates
);
612 ADD_MEMBER(IsTwoHanded
);
613 ADD_MEMBER(CreateDivineConfigurations
);
614 ADD_MEMBER(CanBeCloned
);
615 ADD_MEMBER(CanBeMirrored
);
616 ADD_MEMBER(BeamRange
);
617 ADD_MEMBER(CanBeBroken
);
618 ADD_MEMBER(WallBitmapPos
);
619 ADD_MEMBER(FlexibleNameSingular
);
620 ADD_MEMBER(MaxCharges
);
621 ADD_MEMBER(MinCharges
);
622 ADD_MEMBER(CanBePiled
);
623 ADD_MEMBER(StorageVolume
);
624 ADD_MEMBER(MaxGeneratedContainedItems
);
625 ADD_MEMBER(AffectsArmStrength
);
626 ADD_MEMBER(AffectsLegStrength
);
627 ADD_MEMBER(AffectsDexterity
);
628 ADD_MEMBER(AffectsAgility
);
629 ADD_MEMBER(AffectsEndurance
);
630 ADD_MEMBER(AffectsPerception
);
631 ADD_MEMBER(AffectsIntelligence
);
632 ADD_MEMBER(AffectsWisdom
);
633 ADD_MEMBER(AffectsWillPower
);
634 ADD_MEMBER(AffectsCharisma
);
635 ADD_MEMBER(AffectsMana
);
636 ADD_MEMBER(BaseEnchantment
);
637 ADD_MEMBER(PriceIsProportionalToEnchantment
);
638 ADD_MEMBER(InElasticityPenaltyModifier
);
639 ADD_MEMBER(CanBeUsedBySmith
);
640 ADD_MEMBER(AffectsCarryingCapacity
);
641 ADD_MEMBER(DamageDivider
);
642 ADD_MEMBER(HandleInPairs
);
643 ADD_MEMBER(CanBeEnchanted
);
644 ADD_MEMBER(BeamColor
);
645 ADD_MEMBER(BeamEffect
);
646 ADD_MEMBER(BeamStyle
);
647 ADD_MEMBER(WearWisdomLimit
);
648 ADD_MEMBER(AttachedGod
);
649 ADD_MEMBER(BreakEffectRangeSquare
);
650 ADD_MEMBER(WieldedBitmapPos
);
651 ADD_MEMBER(IsQuestItem
);
652 ADD_MEMBER(IsGoodWithPlants
);
653 ADD_MEMBER(CreateLockConfigurations
);
654 ADD_MEMBER(CanBePickedUp
);
655 ADD_MEMBER(CoverPercentile
);
656 ADD_MEMBER(TorsoArmorBitmapPos
);
657 ADD_MEMBER(ArmArmorBitmapPos
);
658 ADD_MEMBER(AthleteArmArmorBitmapPos
);
659 ADD_MEMBER(LegArmorBitmapPos
);
660 ADD_MEMBER(HelmetBitmapPos
);
661 ADD_MEMBER(CloakBitmapPos
);
662 ADD_MEMBER(BeltBitmapPos
);
663 ADD_MEMBER(GauntletBitmapPos
);
664 ADD_MEMBER(BootBitmapPos
);
665 ADD_MEMBER(HasSecondaryMaterial
);
666 ADD_MEMBER(AllowEquip
);
667 ADD_MEMBER(ReadDifficulty
);
668 ADD_MEMBER(IsValuable
);
669 ADD_MEMBER(EnchantmentMinusChance
);
670 ADD_MEMBER(EnchantmentPlusChance
);
671 ADD_MEMBER(TeleportPriority
);
672 ADD_MEMBER(HasNormalPictureDirection
);
673 ADD_MEMBER(DamageFlags
);
674 ADD_MEMBER(IsKamikazeWeapon
);
675 ADD_MEMBER(FlexibilityIsEssential
);
676 ADD_MEMBER(BreakMsg
);
677 ADD_MEMBER(IsSadistWeapon
);
678 ADD_MEMBER(IsThrowingWeapon
);
679 ADD_MEMBER(ThrowItemTypes
);
680 ADD_MEMBER(CanFlame
);
681 ADD_MEMBER(AllowedDungeons
);
682 ADD_MEMBER(LevelTags
);
686 template <class type
> void databasecreator
<type
>::CreateLTerrainDataBaseMemberMap () {
687 databasemembermap
&Map
= GetDataBaseMemberMap();
688 ADD_MEMBER(BitmapPos
);
689 ADD_MEMBER(UsesLongArticle
);
690 ADD_MEMBER(Adjective
);
691 ADD_MEMBER(UsesLongAdjectiveArticle
);
692 ADD_MEMBER(NameSingular
);
693 ADD_MEMBER(NamePlural
);
695 ADD_MEMBER(ArticleMode
);
696 ADD_MEMBER(MainMaterialConfig
);
697 ADD_MEMBER(SecondaryMaterialConfig
);
698 ADD_MEMBER(MaterialConfigChances
);
699 ADD_MEMBER(IsAbstract
);
700 ADD_MEMBER(OKVisualEffects
);
701 ADD_MEMBER(MaterialColorB
);
702 ADD_MEMBER(MaterialColorC
);
703 ADD_MEMBER(MaterialColorD
);
704 ADD_MEMBER(SitMessage
);
705 ADD_MEMBER(ShowMaterial
);
706 ADD_MEMBER(AttachedGod
);
707 ADD_MEMBER(Walkability
);
708 ADD_MEMBER(HasSecondaryMaterial
);
709 ADD_MEMBER(UseBorderTiles
);
710 ADD_MEMBER(BorderTilePriority
);
714 template<> void databasecreator
<glterrain
>::CreateDataBaseMemberMap () {
715 CreateLTerrainDataBaseMemberMap();
719 template<> void databasecreator
<olterrain
>::CreateDataBaseMemberMap () {
720 CreateLTerrainDataBaseMemberMap();
721 databasemembermap
&Map
= GetDataBaseMemberMap();
722 ADD_MEMBER(CreateDivineConfigurations
);
723 ADD_MEMBER(DigMessage
);
724 ADD_MEMBER(CanBeDestroyed
);
725 ADD_MEMBER(RestModifier
);
726 ADD_MEMBER(RestMessage
);
727 ADD_MEMBER(IsUpLink
);
728 ADD_MEMBER(StorageVolume
);
729 ADD_MEMBER(HPModifier
);
730 ADD_MEMBER(IsSafeToCreateDoor
);
731 ADD_MEMBER(OpenBitmapPos
);
732 ADD_MEMBER(CreateLockConfigurations
);
733 ADD_MEMBER(IsAlwaysTransparent
);
734 ADD_MEMBER(CreateWindowConfigurations
);
735 ADD_MEMBER(WindowBitmapPos
);
736 ADD_MEMBER(ShowThingsUnder
);
737 ADD_MEMBER(LeftOverItems
);
742 template<> void databasecreator
<owterrain
>::CreateDataBaseMemberMap () {
743 //CreateWTerrainDataBaseMemberMap();
744 databasemembermap
&Map
= GetDataBaseMemberMap();
745 ADD_MEMBER(BitmapPos
);
746 ADD_MEMBER(IsAbstract
);
747 ADD_MEMBER(NameSingular
);
748 ADD_MEMBER(NameStem
);
749 ADD_MEMBER(UsesLongArticle
);
750 ADD_MEMBER(AttachedDungeon
);
751 ADD_MEMBER(AttachedArea
);
752 ADD_MEMBER(CanBeGenerated
);
753 ADD_MEMBER(NativeGTerrainType
);
754 ADD_MEMBER(RevealEnvironmentInitially
);
755 ADD_MEMBER(CanBeOnAnyTerrain
);
756 ADD_MEMBER(WantContinentWith
);
757 ADD_MEMBER(Probability
);
758 ADD_MEMBER(CanBeSkipped
);
759 ADD_MEMBER(PlaceInitially
);
763 template<> void databasecreator
<material
>::CreateDataBaseMemberMap () {
764 databasemembermap
&Map
= GetDataBaseMemberMap();
765 ADD_MEMBER(CommonFlags
);
766 ADD_MEMBER(NameFlags
);
767 ADD_MEMBER(CategoryFlags
);
768 ADD_MEMBER(BodyFlags
);
769 ADD_MEMBER(InteractionFlags
);
770 ADD_MEMBER(StrengthValue
);
771 ADD_MEMBER(ConsumeType
);
774 ADD_MEMBER(RainColor
);
775 ADD_MEMBER(PriceModifier
);
776 ADD_MEMBER(Emitation
);
777 ADD_MEMBER(NutritionValue
);
778 ADD_MEMBER(NameStem
);
779 ADD_MEMBER(AdjectiveStem
);
781 ADD_MEMBER(ConsumeEndMessage
);
782 ADD_MEMBER(HitMessage
);
783 ADD_MEMBER(ExplosivePower
);
785 ADD_MEMBER(Flexibility
);
786 ADD_MEMBER(SpoilModifier
);
787 ADD_MEMBER(EffectStrength
);
788 ADD_MEMBER(DigProductMaterial
);
789 ADD_MEMBER(ConsumeWisdomLimit
);
790 ADD_MEMBER(AttachedGod
);
791 ADD_MEMBER(BreatheMessage
);
792 ADD_MEMBER(StepInWisdomLimit
);
793 ADD_MEMBER(RustModifier
);
794 ADD_MEMBER(Acidicity
);
795 ADD_MEMBER(NaturalForm
);
796 ADD_MEMBER(HardenedMaterial
);
797 ADD_MEMBER(SoftenedMaterial
);
798 ADD_MEMBER(IntelligenceRequirement
);
799 ADD_MEMBER(Stickiness
);
800 ADD_MEMBER(DisablesPanicWhenConsumed
);
801 ADD_MEMBER(BlockESP
);
805 #define ADD_BASE_VALUE(name)\
806 if (Word == #name) game::GetGlobalValueMap()[CONST_S("Base")] = DataBase.*static_cast<databasemember<database, feuLong database::*>*>(Data)->Member;
809 template <class type
> void databasecreator
<type
>::SetBaseValue(cfestring
&, databasememberbase
<database
> *, database
&) {}
811 template<> void databasecreator
<material
>::SetBaseValue(cfestring
&Word
, databasememberbase
<materialdatabase
> *Data
,
812 materialdatabase
&DataBase
)
814 ADD_BASE_VALUE(CommonFlags
);
815 ADD_BASE_VALUE(NameFlags
);
816 ADD_BASE_VALUE(CategoryFlags
);
817 ADD_BASE_VALUE(BodyFlags
);
818 ADD_BASE_VALUE(InteractionFlags
);
822 template <class type
> truth databasecreator
<type
>::AnalyzeData (TextInput
&SaveFile
, cfestring
&Word
, database
&DataBase
) {
823 typename
databasemembermap::iterator i
= GetDataBaseMemberMap().find(Word
);
824 if (i
!= GetDataBaseMemberMap().end()) {
825 SetBaseValue(Word
, i
->second
, DataBase
);
826 i
->second
->ReadData(DataBase
, SaveFile
);
827 CheckDefaults(Word
, DataBase
);
834 template <> void databasecreator
<character
>::CheckDefaults (cfestring
&Word
, character::database
&DataBase
) {
835 if (Word
== "ArmBitmapPos") { DataBase
.RightArmBitmapPos
= DataBase
.LeftArmBitmapPos
= DataBase
.ArmBitmapPos
; return; }
836 if (Word
== "LegBitmapPos") { DataBase
.GroinBitmapPos
= DataBase
.RightLegBitmapPos
= DataBase
.LeftLegBitmapPos
= DataBase
.LegBitmapPos
; return; }
837 if (Word
== "ClothColor") { DataBase
.CapColor
= DataBase
.TorsoMainColor
= DataBase
.ArmMainColor
= DataBase
.GauntletColor
= DataBase
.LegMainColor
= DataBase
.ClothColor
; return; }
838 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
839 if (Word
== "BaseUnarmedStrength") { DataBase
.BaseBiteStrength
= DataBase
.BaseUnarmedStrength
>>1; DataBase
.BaseKickStrength
= DataBase
.BaseUnarmedStrength
<<1; return; }
840 if (Word
== "RightGauntlet") { DataBase
.LeftGauntlet
= DataBase
.RightGauntlet
; return; }
841 if (Word
== "RightBoot") { DataBase
.LeftBoot
= DataBase
.RightBoot
; return; }
842 if (Word
== "IsUnique") { DataBase
.CanBeWished
= !DataBase
.IsUnique
; return; }
843 if (Word
== "DefaultName") {
844 // k8: don't add duplicate alias
845 for (uInt c
= 0; c
< DataBase
.Alias
.Size
; ++c
) {
846 if (DataBase
.Alias
[c
] == DataBase
.DefaultName
) return;
848 DataBase
.Alias
.Add(DataBase
.DefaultName
);
850 if (DataBase.Alias.Size != 1) {
851 printf("=== %s ===\n", DataBase.NameSingular.CStr());
852 for (uInt c = 0; c < DataBase.Alias.Size; ++c) {
853 printf(" %u: %s\n", c, DataBase.Alias[c].CStr());
862 template <> void databasecreator
<item
>::CheckDefaults (cfestring
&Word
, item::database
&DataBase
) {
863 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; DataBase
.FlexibleNameSingular
= DataBase
.NameSingular
; return; }
864 if (Word
== "BitmapPos") { DataBase
.WallBitmapPos
= DataBase
.BitmapPos
; return; }
865 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
866 if (Word
== "CanBeCloned") { DataBase
.CanBeMirrored
= DataBase
.CanBeCloned
; return; }
870 template <> void databasecreator
<glterrain
>::CheckDefaults (cfestring
&Word
, glterrain::database
&DataBase
) {
871 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
872 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
876 template <> void databasecreator
<olterrain
>::CheckDefaults (cfestring
&Word
, olterrain::database
&DataBase
) {
877 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
878 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
882 template <> void databasecreator
<material
>::CheckDefaults (cfestring
&Word
, material::database
&DataBase
) {
883 if (Word
== "NameStem") { DataBase
.AdjectiveStem
= DataBase
.NameStem
; return; }
884 if (Word
== "Color") { DataBase
.RainColor
= DataBase
.Color
; return; }
888 template<> void databasecreator
<owterrain
>::CheckDefaults (cfestring
& Word
, owterrain::database
& DataBase
) {
893 void databasesystem::Initialize () {
894 /* Must be before character */
895 databasecreator
<material
>::ReadFrom("material");
896 databasecreator
<character
>::ReadFrom("char");
897 /* Must be before olterrain */
898 databasecreator
<item
>::ReadFrom("item");
899 databasecreator
<glterrain
>::ReadFrom("glterra");
900 databasecreator
<olterrain
>::ReadFrom("olterra");
902 databasecreator
<owterrain
>::ReadFrom("owterra");
906 template <class type
> inline void databasecreator
<type
>::FindDataBase (const database
*&DataBase
, const prototype
*Proto
, int Config
) {
907 database
**Table
= Proto
->ConfigTable
[(Config
>> 8) ^ (Config
& 0xFF)];
909 if ((*Table
)->Config
== Config
) {
913 for (++Table
; *Table
; ++Table
) {
914 if ((*Table
)->Config
== Config
) {
924 template void databasecreator
<character
>::FindDataBase (const database
*&, const prototype
*, int);
925 template void databasecreator
<material
>::FindDataBase (const database
*&, const prototype
*, int);
927 template <class type
> void databasecreator
<type
>::InstallDataBase (type
*Instance
, int Config
) {
928 const prototype
*Proto
= Instance
->FindProtoType();
929 FindDataBase(Instance
->DataBase
, Proto
, Config
);
930 if (!Instance
->DataBase
) {
932 ABORT("Undefined %s configuration #%08x sought!", Proto
->GetClassID(), (unsigned int)Config
);
936 #define INST_INSTALL_DATABASE(type) template void databasecreator<type>::InstallDataBase(type *, int)
938 INST_INSTALL_DATABASE(material
);
939 INST_INSTALL_DATABASE(character
);
940 INST_INSTALL_DATABASE(item
);
941 INST_INSTALL_DATABASE(glterrain
);
942 INST_INSTALL_DATABASE(olterrain
);
943 INST_INSTALL_DATABASE(owterrain
);