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 */
16 int CreateConfigTable (databasebase
***ConfigTable
, databasebase
***TempTable
,
17 databasebase
**ConfigArray
, sLong
*TempTableInfo
, int Type
, int Configs
, int TempTables
)
19 memset(ConfigTable
, 0, CONFIG_TABLE_SIZE
*sizeof(databasebase
**));
20 for (int c
= 0; c
< Configs
; ++c
) {
21 int Config
= ConfigArray
[c
]->Config
;
22 int Hash
= (Config
>> 8) ^ (Config
& 0xFF);
23 if ((TempTableInfo
[Hash
] & 0xFFFF) != Type
) {
24 TempTable
[0][Hash
] = ConfigArray
[c
];
25 TempTableInfo
[Hash
] = Type
| 0x10000;
27 int Conflicts
= (TempTableInfo
[Hash
] & 0xFFFF0000) >> 16;
28 if (Conflicts
== TempTables
) TempTable
[TempTables
++] = new databasebase
*[CONFIG_TABLE_SIZE
];
29 TempTable
[Conflicts
][Hash
] = ConfigArray
[c
];
30 TempTableInfo
[Hash
] += 0x10000;
33 for (int c1
= 0; c1
< CONFIG_TABLE_SIZE
; ++c1
) {
34 if ((TempTableInfo
[c1
] & 0xFFFF) == Type
) {
35 int Entries
= (TempTableInfo
[c1
] & 0xFFFF0000) >> 16;
36 ConfigTable
[c1
] = new databasebase
*[Entries
+ 1];
37 for (int c2
= 0; c2
< Entries
; ++c2
) ConfigTable
[c1
][c2
] = TempTable
[c2
][c1
];
38 ConfigTable
[c1
][Entries
] = 0;
45 static void collectHandler (festring
&dest
, std::stack
<inputfile
*> &infStack
, inputfile
**iff
) {
46 inputfile
*inFile
= *iff
;
47 festring Word
= inFile
->ReadWord(true);
48 dest
<< "on " << Word
<< "\n{\n";
49 if (inFile
->ReadWord() != "{") ABORT("'{' missing in datafile %s line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
53 int ch
= inFile
->Get();
55 if (infStack
.empty()) ABORT("'}' missing in datafile %s line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
57 *iff
= inFile
= infStack
.top();
63 if (ch
== '"') inStr
= false;
64 else if (ch
== '\\') {
66 if (ch
== EOF
) ABORT("Unexpected end of file %s!", inFile
->GetFileName().CStr());
73 } else if (ch
== '{') {
75 } else if (ch
== '"') {
83 template <class type
> void databasecreator
<type
>::ReadFrom (const festring
&baseFileName
) {
84 std::stack
<inputfile
*> infStack
;
85 for (int fno
= 99; fno
>= -1; fno
--) {
87 cfname
<< game::GetGameDir() << "Script/" << baseFileName
;
90 sprintf(bnum
, "_%02d", fno
);
94 if (!inputfile::fileExists(cfname
)) continue;
95 inputfile
*ifl
= new inputfile(cfname
, &game::GetGlobalValueMap(), false);
104 for (size_t f = 0; f < infStack.size(); f++) {
105 inputfile *inFile = infStack.at(f);
106 fprintf(stderr, "found: %s\n", inFile->GetFileName().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, CONFIG_TABLE_SIZE
*sizeof(sLong
));
119 CreateDataBaseMemberMap();
120 while (!infStack
.empty()) {
121 inputfile
*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 inputfile
*incf
= new inputfile(game::GetGameDir()+"Script/"+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 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[Type
];
156 if (!Proto
) ABORT("Something weird with <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
160 if (!Proto
->ConfigData
) ABORT("Can't override undefined <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
161 delete [] Proto
->ConfigData
;
162 Proto
->ConfigData
= NULL
;
163 Proto
->ConfigSize
= 0;
166 if (!Proto
->ConfigData
) ABORT("Can't extend undefined <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
167 DataBase
= Proto
->ConfigData
[0];
168 Configs
= Proto
->ConfigSize
;
169 for (int f
= 0; f
< Configs
; f
++) TempConfig
[f
] = Proto
->ConfigData
[f
];
170 delete [] Proto
->ConfigData
;
171 Proto
->ConfigData
= NULL
;
172 Proto
->ConfigSize
= 0;
174 if (Proto
->ConfigData
) ABORT("Can't redefine <%s> in file %s at line %d!", defName
.CStr(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
175 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());
176 DataBase
= Proto
->Base
? new database(**Proto
->Base
->ConfigData
) : new database
;
177 DataBase
->InitDefaults(Proto
, 0);
178 TempConfig
[0] = DataBase
;
181 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
182 //for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word))
184 inFile
->ReadWord(Word
, false);
185 if (Word
== "" && inFile
->Eof()) {
186 if (infStack
.empty()) ABORT("'}' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
188 inFile
= infStack
.top();
192 //fprintf(stderr, "D: %d; <%s>\n", (int)infStack.size(), Word.CStr());
193 if (Word
== "}") break;
195 if (Word
== "Include") {
196 Word
= inFile
->ReadWord();
197 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
198 //fprintf(stderr, "loading: %s\n", Word.CStr());
199 inputfile
*incf
= new inputfile(game::GetGameDir()+"Script/"+Word
, &game::GetGlobalValueMap());
200 infStack
.push(inFile
);
202 inFile
->setGetVarCB(game::ldrGetVar
);
205 if (Word
== "Message") {
206 Word
= inFile
->ReadWord();
207 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
208 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
211 if (Word
== "Config") {
212 sLong ConfigNumber
= -1;
213 truth isString
= false;
215 fname
= inFile
->ReadStringOrNumber(&ConfigNumber
, &isString
);
218 //fprintf(stderr, "loading: %s\n", fname.CStr());
219 inputfile
*incf
= new inputfile(game::GetGameDir()+"Script/"+fname
, &game::GetGlobalValueMap());
220 infStack
.push(inFile
);
223 //fprintf(stderr, "new config %d for %s\n", ConfigNumber, defName.CStr());
224 database
*ConfigDataBase
= new database(*Proto
->ChooseBaseForConfig(TempConfig
, Configs
, ConfigNumber
));
225 ConfigDataBase
->InitDefaults(Proto
, ConfigNumber
);
226 TempConfig
[Configs
++] = ConfigDataBase
;
227 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
228 for (inFile
->ReadWord(Word
); Word
!= "}"; inFile
->ReadWord(Word
)) {
230 collectHandler(Proto
->mOnEvents
, infStack
, &inFile
);
233 if (!AnalyzeData(*inFile
, Word
, *ConfigDataBase
)) ABORT("Illegal datavalue %s found while building up %s config #%d, file %s, line %d!", Word
.CStr(), Proto
->GetClassID(), ConfigNumber
, inFile
->GetFileName().CStr(), inFile
->TokenLine());
235 ConfigDataBase
->PostProcess();
240 collectHandler(Proto
->mOnEvents
, infStack
, &inFile
);
243 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());
245 DataBase
->PostProcess();
246 //Configs = Proto->CreateSpecialConfigurations(TempConfig, Configs);
247 Proto
->ConfigData
= new database
*[Configs
];
248 Proto
->ConfigSize
= Configs
;
249 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
255 for (c1
= 0; c1
< SPECIAL_CONFIGURATION_GENERATION_LEVELS
; ++c1
) {
256 for (int c2
= 1; c2
< protocontainer
<type
>::GetSize(); ++c2
) {
257 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c2
];
258 int Configs
= Proto
->ConfigSize
;
259 memmove(TempConfig
, Proto
->ConfigData
, Configs
*sizeof(database
*));
260 Configs
= Proto
->CreateSpecialConfigurations(TempConfig
, Configs
, c1
);
261 if (Proto
->ConfigSize
!= Configs
) {
262 delete [] Proto
->ConfigData
;
263 Proto
->ConfigData
= new database
*[Configs
];
264 Proto
->ConfigSize
= Configs
;
265 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
269 for (c1
= 1; c1
< protocontainer
<type
>::GetSize(); ++c1
) {
270 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c1
];
272 CreateConfigTable(reinterpret_cast<databasebase
***>(Proto
->ConfigTable
),
274 reinterpret_cast<databasebase
**>(Proto
->ConfigData
),
275 TempTableInfo
, c1
, Proto
->ConfigSize
, TempTables
);
277 for (c1
= 1; c1
< TempTables
; ++c1
) delete [] TempTable
[c1
];
278 GetDataBaseMemberMap().clear();
282 template <class type
> int databasecreator
<type
>::CreateDivineConfigurations (const prototype
*Proto
,
283 database
**TempConfig
, int Configs
)
285 int OldConfigs
= Configs
;
286 for (int c1
= 1; c1
< protocontainer
<god
>::GetSize(); ++c1
) {
287 database
*ConfigDataBase
= 0;
289 for (c2
= 1; c2
< OldConfigs
; ++c2
) {
290 ConfigDataBase
= TempConfig
[c2
];
291 if (ConfigDataBase
->Config
== c1
) break;
293 truth Created
= false;
294 if (c2
== OldConfigs
) {
295 ConfigDataBase
= new database(**TempConfig
);
296 ConfigDataBase
->InitDefaults(Proto
, c1
);
299 ConfigDataBase
->AttachedGod
= c1
;
300 ConfigDataBase
->PostFix
<< "of " << festring(protocontainer
<god
>::GetProto(c1
)->GetClassID()).CapitalizeCopy();
301 if (Created
) TempConfig
[Configs
++] = ConfigDataBase
;
307 template int databasecreator
<character
>::CreateDivineConfigurations (const prototype
*, database
**, int);
308 template int databasecreator
<item
>::CreateDivineConfigurations (const prototype
*, database
**, int);
309 template int databasecreator
<olterrain
>::CreateDivineConfigurations (const prototype
*, database
**, int);
312 template <class database
, class member
> struct databasemember
: public databasememberbase
<database
> {
313 databasemember (member Member
) : Member(Member
) {}
314 virtual void ReadData (database
&DataBase
, inputfile
&SaveFile
) { ::ReadData(DataBase
.*Member
, SaveFile
); }
319 template <class database
, class member
> void AddMember(std::map
<festring
, databasememberbase
<database
>*>& Map
, cchar
* Str
, member Member
)
321 Map
.insert(std::pair
<festring
, databasememberbase
<database
>*>(Str
, new databasemember
<database
, member
>(Member
)));
325 /* Explicit instantiations seem to increase compile speed greatly here... */
327 #define INST_ADD_MEMBER(type, member) \
328 template void AddMember<type##database, member type##database::*>(std::map<festring, databasememberbase<type##database>*>&, cchar*, member type##database::*)
330 INST_ADD_MEMBER(character
, int);
331 //INST_ADD_MEMBER(character, sLong); //k8:64
332 INST_ADD_MEMBER(character
, packcol16
);
333 INST_ADD_MEMBER(character
, col24
);
334 INST_ADD_MEMBER(character
, packv2
);
335 INST_ADD_MEMBER(character
, festring
);
336 INST_ADD_MEMBER(character
, fearray
<sLong
>);
337 INST_ADD_MEMBER(character
, fearray
<festring
>);
338 INST_ADD_MEMBER(character
, contentscript
<item
>);
340 INST_ADD_MEMBER(item
, int);
341 //INST_ADD_MEMBER(item, sLong); //k8:64
342 INST_ADD_MEMBER(item
, col24
);
343 INST_ADD_MEMBER(item
, v2
);
344 INST_ADD_MEMBER(item
, festring
);
345 INST_ADD_MEMBER(item
, fearray
<sLong
>);
346 INST_ADD_MEMBER(item
, fearray
<festring
>);
348 INST_ADD_MEMBER(glterrain
, int);
349 //INST_ADD_MEMBER(glterrain, sLong); //k8:64
350 INST_ADD_MEMBER(glterrain
, v2
);
351 INST_ADD_MEMBER(glterrain
, festring
);
352 INST_ADD_MEMBER(glterrain
, fearray
<sLong
>);
354 INST_ADD_MEMBER(olterrain
, int);
355 //INST_ADD_MEMBER(olterrain, sLong); //k8:64
356 INST_ADD_MEMBER(olterrain
, v2
);
357 INST_ADD_MEMBER(olterrain
, festring
);
358 INST_ADD_MEMBER(olterrain
, fearray
<sLong
>);
359 INST_ADD_MEMBER(olterrain
, fearray
<contentscript
<item
> >);
361 INST_ADD_MEMBER(material
, int);
362 //INST_ADD_MEMBER(material, sLong); //k8:64
363 INST_ADD_MEMBER(material
, col24
);
364 INST_ADD_MEMBER(material
, festring
);
365 INST_ADD_MEMBER(material
, contentscript
<item
>);
367 #define ADD_MEMBER(data) AddMember(Map, #data, &database::data);
369 template<> void databasecreator
<character
>::CreateDataBaseMemberMap () {
370 databasemembermap
&Map
= GetDataBaseMemberMap();
371 ADD_MEMBER(DefaultArmStrength
);
372 ADD_MEMBER(DefaultLegStrength
);
373 ADD_MEMBER(DefaultDexterity
);
374 ADD_MEMBER(DefaultAgility
);
375 ADD_MEMBER(DefaultEndurance
);
376 ADD_MEMBER(DefaultPerception
);
377 ADD_MEMBER(DefaultIntelligence
);
378 ADD_MEMBER(DefaultWisdom
);
379 ADD_MEMBER(DefaultWillPower
);
380 ADD_MEMBER(DefaultCharisma
);
381 ADD_MEMBER(DefaultMana
);
382 ADD_MEMBER(DefaultMoney
);
383 ADD_MEMBER(TotalSize
);
386 ADD_MEMBER(CanBeGenerated
);
387 ADD_MEMBER(CriticalModifier
);
388 ADD_MEMBER(StandVerb
);
390 ADD_MEMBER(Frequency
);
391 ADD_MEMBER(EnergyResistance
);
392 ADD_MEMBER(FireResistance
);
393 ADD_MEMBER(PoisonResistance
);
394 ADD_MEMBER(ElectricityResistance
);
395 ADD_MEMBER(AcidResistance
);
396 ADD_MEMBER(IsUnique
);
397 ADD_MEMBER(ConsumeFlags
);
398 ADD_MEMBER(TotalVolume
);
399 ADD_MEMBER(HeadBitmapPos
);
400 ADD_MEMBER(TorsoBitmapPos
);
401 ADD_MEMBER(ArmBitmapPos
);
402 ADD_MEMBER(LegBitmapPos
);
403 ADD_MEMBER(RightArmBitmapPos
);
404 ADD_MEMBER(LeftArmBitmapPos
);
405 ADD_MEMBER(RightLegBitmapPos
);
406 ADD_MEMBER(LeftLegBitmapPos
);
407 ADD_MEMBER(GroinBitmapPos
);
408 ADD_MEMBER(ClothColor
);
409 ADD_MEMBER(SkinColor
);
410 ADD_MEMBER(CapColor
);
411 ADD_MEMBER(HairColor
);
412 ADD_MEMBER(EyeColor
);
413 ADD_MEMBER(TorsoMainColor
);
414 ADD_MEMBER(BeltColor
);
415 ADD_MEMBER(BootColor
);
416 ADD_MEMBER(TorsoSpecialColor
);
417 ADD_MEMBER(ArmMainColor
);
418 ADD_MEMBER(GauntletColor
);
419 ADD_MEMBER(ArmSpecialColor
);
420 ADD_MEMBER(LegMainColor
);
421 ADD_MEMBER(LegSpecialColor
);
422 ADD_MEMBER(IsNameable
);
423 ADD_MEMBER(BaseEmitation
);
424 ADD_MEMBER(UsesLongArticle
);
425 ADD_MEMBER(Adjective
);
426 ADD_MEMBER(UsesLongAdjectiveArticle
);
427 ADD_MEMBER(NameSingular
);
428 ADD_MEMBER(NamePlural
);
430 ADD_MEMBER(ArticleMode
);
431 ADD_MEMBER(IsAbstract
);
432 ADD_MEMBER(IsPolymorphable
);
433 ADD_MEMBER(BaseUnarmedStrength
);
434 ADD_MEMBER(BaseBiteStrength
);
435 ADD_MEMBER(BaseKickStrength
);
436 ADD_MEMBER(AttackStyle
);
437 ADD_MEMBER(CanUseEquipment
);
440 ADD_MEMBER(ClassStates
);
441 ADD_MEMBER(CanBeWished
);
443 ADD_MEMBER(CreateDivineConfigurations
);
444 ADD_MEMBER(CreateGolemMaterialConfigurations
);
448 ADD_MEMBER(BodyArmor
);
450 ADD_MEMBER(RightWielded
);
451 ADD_MEMBER(LeftWielded
);
452 ADD_MEMBER(RightRing
);
453 ADD_MEMBER(LeftRing
);
454 ADD_MEMBER(RightGauntlet
);
455 ADD_MEMBER(LeftGauntlet
);
456 ADD_MEMBER(RightBoot
);
457 ADD_MEMBER(LeftBoot
);
458 ADD_MEMBER(AttributeBonus
);
459 ADD_MEMBER(KnownCWeaponSkills
);
460 ADD_MEMBER(CWeaponSkillHits
);
461 ADD_MEMBER(RightSWeaponSkillHits
);
462 ADD_MEMBER(LeftSWeaponSkillHits
);
463 ADD_MEMBER(PanicLevel
);
464 ADD_MEMBER(CanBeCloned
);
465 ADD_MEMBER(Inventory
);
466 ADD_MEMBER(DangerModifier
);
467 ADD_MEMBER(DefaultName
);
468 ADD_MEMBER(FriendlyReplies
);
469 ADD_MEMBER(HostileReplies
);
471 ADD_MEMBER(FleshMaterial
);
473 ADD_MEMBER(DeathMessage
);
474 ADD_MEMBER(IgnoreDanger
);
475 ADD_MEMBER(HPRequirementForGeneration
);
476 ADD_MEMBER(DayRequirementForGeneration
);
477 ADD_MEMBER(IsExtraCoward
);
478 ADD_MEMBER(SpillsBlood
);
481 ADD_MEMBER(CanThrow
);
482 ADD_MEMBER(UsesNutrition
);
483 ADD_MEMBER(AttackWisdomLimit
);
484 ADD_MEMBER(AttachedGod
);
485 ADD_MEMBER(BodyPartsDisappearWhenSevered
);
486 ADD_MEMBER(CanBeConfused
);
487 ADD_MEMBER(CanApply
);
488 ADD_MEMBER(WieldedPosition
);
489 ADD_MEMBER(NaturalSparkleFlags
);
490 ADD_MEMBER(BiteCapturesBodyPart
);
492 ADD_MEMBER(MoveType
);
493 ADD_MEMBER(DestroysWalls
);
494 ADD_MEMBER(IsRooted
);
495 ADD_MEMBER(BloodMaterial
);
496 ADD_MEMBER(VomitMaterial
);
497 ADD_MEMBER(HasSecondaryMaterial
);
498 ADD_MEMBER(IsImmuneToLeprosy
);
499 ADD_MEMBER(PolymorphIntelligenceRequirement
);
500 ADD_MEMBER(AutomaticallySeen
);
502 ADD_MEMBER(DefaultCommandFlags
);
503 ADD_MEMBER(ConstantCommandFlags
);
504 ADD_MEMBER(WillCarryItems
);
505 ADD_MEMBER(ForceVomitMessage
);
506 ADD_MEMBER(SweatMaterial
);
508 ADD_MEMBER(IsImmuneToItemTeleport
);
509 ADD_MEMBER(AlwaysUseMaterialAttributes
);
510 ADD_MEMBER(IsEnormous
);
511 ADD_MEMBER(ScienceTalkAdjectiveAttribute
);
512 ADD_MEMBER(ScienceTalkSubstantiveAttribute
);
513 ADD_MEMBER(ScienceTalkPrefix
);
514 ADD_MEMBER(ScienceTalkName
);
515 ADD_MEMBER(ScienceTalkPossibility
);
516 ADD_MEMBER(ScienceTalkIntelligenceModifier
);
517 ADD_MEMBER(ScienceTalkWisdomModifier
);
518 ADD_MEMBER(ScienceTalkCharismaModifier
);
519 ADD_MEMBER(ScienceTalkIntelligenceRequirement
);
520 ADD_MEMBER(ScienceTalkWisdomRequirement
);
521 ADD_MEMBER(ScienceTalkCharismaRequirement
);
522 ADD_MEMBER(IsExtraFragile
);
523 ADD_MEMBER(AllowUnconsciousness
);
524 ADD_MEMBER(CanChoke
);
525 ADD_MEMBER(IsImmuneToStickiness
);
526 ADD_MEMBER(DisplacePriority
);
527 ADD_MEMBER(RunDescriptionLineOne
);
528 ADD_MEMBER(RunDescriptionLineTwo
);
529 ADD_MEMBER(ForceCustomStandVerb
);
530 ADD_MEMBER(VomittingIsUnhealthy
);
531 ADD_MEMBER(AllowPlayerToChangeEquipment
);
532 ADD_MEMBER(TamingDifficulty
);
533 ADD_MEMBER(IsMasochist
);
534 ADD_MEMBER(IsSadist
);
535 ADD_MEMBER(IsCatacombCreature
);
536 ADD_MEMBER(CreateUndeadConfigurations
);
537 ADD_MEMBER(UndeadVersions
);
538 ADD_MEMBER(UndeadAttributeModifier
);
539 ADD_MEMBER(UndeadVolumeModifier
);
540 ADD_MEMBER(UndeadCopyMaterials
);
541 ADD_MEMBER(CanBeGeneratedOnlyInTheCatacombs
);
542 ADD_MEMBER(IsAlcoholic
);
543 ADD_MEMBER(IsImmuneToWhipOfThievery
);
544 ADD_MEMBER(IsRangedAttacker
);
545 ADD_MEMBER(WhatCategoryToThrow
);
546 ADD_MEMBER(WhatWeaponConfigToThrow
);
547 ADD_MEMBER(WhatThrowItemTypesToThrow
);
548 ADD_MEMBER(AllowedDungeons
);
549 ADD_MEMBER(LevelTags
);
553 template<> void databasecreator
<item
>::CreateDataBaseMemberMap () {
554 databasemembermap
&Map
= GetDataBaseMemberMap();
555 ADD_MEMBER(Possibility
);
556 ADD_MEMBER(IsDestroyable
);
557 ADD_MEMBER(CanBeWished
);
558 ADD_MEMBER(IsMaterialChangeable
);
559 ADD_MEMBER(WeaponCategory
);
560 ADD_MEMBER(IsPolymorphSpawnable
);
561 ADD_MEMBER(IsAutoInitializable
);
562 ADD_MEMBER(Category
);
563 ADD_MEMBER(FireResistance
);
564 ADD_MEMBER(PoisonResistance
);
565 ADD_MEMBER(ElectricityResistance
);
566 ADD_MEMBER(AcidResistance
);
567 ADD_MEMBER(StrengthModifier
);
568 ADD_MEMBER(FormModifier
);
569 ADD_MEMBER(DefaultSize
);
570 ADD_MEMBER(DefaultMainVolume
);
571 ADD_MEMBER(DefaultSecondaryVolume
);
572 ADD_MEMBER(BitmapPos
);
574 ADD_MEMBER(BaseEmitation
);
575 ADD_MEMBER(UsesLongArticle
);
576 ADD_MEMBER(Adjective
);
577 ADD_MEMBER(UsesLongAdjectiveArticle
);
578 ADD_MEMBER(NameSingular
);
579 ADD_MEMBER(NamePlural
);
581 ADD_MEMBER(ArticleMode
);
582 ADD_MEMBER(MainMaterialConfig
);
583 ADD_MEMBER(SecondaryMaterialConfig
);
584 ADD_MEMBER(MaterialConfigChances
);
585 ADD_MEMBER(IsAbstract
);
586 ADD_MEMBER(IsPolymorphable
);
588 ADD_MEMBER(OKVisualEffects
);
589 ADD_MEMBER(CanBeGeneratedInContainer
);
590 ADD_MEMBER(ForcedVisualEffects
);
591 ADD_MEMBER(Roundness
);
592 ADD_MEMBER(GearStates
);
593 ADD_MEMBER(IsTwoHanded
);
594 ADD_MEMBER(CreateDivineConfigurations
);
595 ADD_MEMBER(CanBeCloned
);
596 ADD_MEMBER(CanBeMirrored
);
597 ADD_MEMBER(BeamRange
);
598 ADD_MEMBER(CanBeBroken
);
599 ADD_MEMBER(WallBitmapPos
);
600 ADD_MEMBER(FlexibleNameSingular
);
601 ADD_MEMBER(MaxCharges
);
602 ADD_MEMBER(MinCharges
);
603 ADD_MEMBER(CanBePiled
);
604 ADD_MEMBER(StorageVolume
);
605 ADD_MEMBER(MaxGeneratedContainedItems
);
606 ADD_MEMBER(AffectsArmStrength
);
607 ADD_MEMBER(AffectsLegStrength
);
608 ADD_MEMBER(AffectsDexterity
);
609 ADD_MEMBER(AffectsAgility
);
610 ADD_MEMBER(AffectsEndurance
);
611 ADD_MEMBER(AffectsPerception
);
612 ADD_MEMBER(AffectsIntelligence
);
613 ADD_MEMBER(AffectsWisdom
);
614 ADD_MEMBER(AffectsWillPower
);
615 ADD_MEMBER(AffectsCharisma
);
616 ADD_MEMBER(AffectsMana
);
617 ADD_MEMBER(BaseEnchantment
);
618 ADD_MEMBER(PriceIsProportionalToEnchantment
);
619 ADD_MEMBER(InElasticityPenaltyModifier
);
620 ADD_MEMBER(CanBeUsedBySmith
);
621 ADD_MEMBER(AffectsCarryingCapacity
);
622 ADD_MEMBER(DamageDivider
);
623 ADD_MEMBER(HandleInPairs
);
624 ADD_MEMBER(CanBeEnchanted
);
625 ADD_MEMBER(BeamColor
);
626 ADD_MEMBER(BeamEffect
);
627 ADD_MEMBER(BeamStyle
);
628 ADD_MEMBER(WearWisdomLimit
);
629 ADD_MEMBER(AttachedGod
);
630 ADD_MEMBER(BreakEffectRangeSquare
);
631 ADD_MEMBER(WieldedBitmapPos
);
632 ADD_MEMBER(IsQuestItem
);
633 ADD_MEMBER(IsGoodWithPlants
);
634 ADD_MEMBER(CreateLockConfigurations
);
635 ADD_MEMBER(CanBePickedUp
);
636 ADD_MEMBER(CoverPercentile
);
637 ADD_MEMBER(TorsoArmorBitmapPos
);
638 ADD_MEMBER(ArmArmorBitmapPos
);
639 ADD_MEMBER(AthleteArmArmorBitmapPos
);
640 ADD_MEMBER(LegArmorBitmapPos
);
641 ADD_MEMBER(HelmetBitmapPos
);
642 ADD_MEMBER(CloakBitmapPos
);
643 ADD_MEMBER(BeltBitmapPos
);
644 ADD_MEMBER(GauntletBitmapPos
);
645 ADD_MEMBER(BootBitmapPos
);
646 ADD_MEMBER(HasSecondaryMaterial
);
647 ADD_MEMBER(AllowEquip
);
648 ADD_MEMBER(ReadDifficulty
);
649 ADD_MEMBER(IsValuable
);
650 ADD_MEMBER(EnchantmentMinusChance
);
651 ADD_MEMBER(EnchantmentPlusChance
);
652 ADD_MEMBER(TeleportPriority
);
653 ADD_MEMBER(HasNormalPictureDirection
);
654 ADD_MEMBER(DamageFlags
);
655 ADD_MEMBER(IsKamikazeWeapon
);
656 ADD_MEMBER(FlexibilityIsEssential
);
657 ADD_MEMBER(BreakMsg
);
658 ADD_MEMBER(IsSadistWeapon
);
659 ADD_MEMBER(IsThrowingWeapon
);
660 ADD_MEMBER(ThrowItemTypes
);
661 ADD_MEMBER(CanFlame
);
662 ADD_MEMBER(LevelTags
);
663 ADD_MEMBER(AllowedDungeons
);
667 template <class type
> void databasecreator
<type
>::CreateLTerrainDataBaseMemberMap () {
668 databasemembermap
&Map
= GetDataBaseMemberMap();
669 ADD_MEMBER(BitmapPos
);
670 ADD_MEMBER(UsesLongArticle
);
671 ADD_MEMBER(Adjective
);
672 ADD_MEMBER(UsesLongAdjectiveArticle
);
673 ADD_MEMBER(NameSingular
);
674 ADD_MEMBER(NamePlural
);
676 ADD_MEMBER(ArticleMode
);
677 ADD_MEMBER(MainMaterialConfig
);
678 ADD_MEMBER(SecondaryMaterialConfig
);
679 ADD_MEMBER(MaterialConfigChances
);
680 ADD_MEMBER(IsAbstract
);
681 ADD_MEMBER(OKVisualEffects
);
682 ADD_MEMBER(MaterialColorB
);
683 ADD_MEMBER(MaterialColorC
);
684 ADD_MEMBER(MaterialColorD
);
685 ADD_MEMBER(SitMessage
);
686 ADD_MEMBER(ShowMaterial
);
687 ADD_MEMBER(AttachedGod
);
688 ADD_MEMBER(Walkability
);
689 ADD_MEMBER(HasSecondaryMaterial
);
690 ADD_MEMBER(UseBorderTiles
);
691 ADD_MEMBER(BorderTilePriority
);
695 template<> void databasecreator
<glterrain
>::CreateDataBaseMemberMap () {
696 CreateLTerrainDataBaseMemberMap();
700 template<> void databasecreator
<olterrain
>::CreateDataBaseMemberMap () {
701 CreateLTerrainDataBaseMemberMap();
702 databasemembermap
&Map
= GetDataBaseMemberMap();
703 ADD_MEMBER(CreateDivineConfigurations
);
704 ADD_MEMBER(DigMessage
);
705 ADD_MEMBER(CanBeDestroyed
);
706 ADD_MEMBER(RestModifier
);
707 ADD_MEMBER(RestMessage
);
708 ADD_MEMBER(IsUpLink
);
709 ADD_MEMBER(StorageVolume
);
710 ADD_MEMBER(HPModifier
);
711 ADD_MEMBER(IsSafeToCreateDoor
);
712 ADD_MEMBER(OpenBitmapPos
);
713 ADD_MEMBER(CreateLockConfigurations
);
714 ADD_MEMBER(IsAlwaysTransparent
);
715 ADD_MEMBER(CreateWindowConfigurations
);
716 ADD_MEMBER(WindowBitmapPos
);
717 ADD_MEMBER(ShowThingsUnder
);
718 ADD_MEMBER(LeftOverItems
);
723 template<> void databasecreator
<material
>::CreateDataBaseMemberMap () {
724 databasemembermap
&Map
= GetDataBaseMemberMap();
725 ADD_MEMBER(CommonFlags
);
726 ADD_MEMBER(NameFlags
);
727 ADD_MEMBER(CategoryFlags
);
728 ADD_MEMBER(BodyFlags
);
729 ADD_MEMBER(InteractionFlags
);
730 ADD_MEMBER(StrengthValue
);
731 ADD_MEMBER(ConsumeType
);
734 ADD_MEMBER(RainColor
);
735 ADD_MEMBER(PriceModifier
);
736 ADD_MEMBER(Emitation
);
737 ADD_MEMBER(NutritionValue
);
738 ADD_MEMBER(NameStem
);
739 ADD_MEMBER(AdjectiveStem
);
741 ADD_MEMBER(ConsumeEndMessage
);
742 ADD_MEMBER(HitMessage
);
743 ADD_MEMBER(ExplosivePower
);
745 ADD_MEMBER(Flexibility
);
746 ADD_MEMBER(SpoilModifier
);
747 ADD_MEMBER(EffectStrength
);
748 ADD_MEMBER(DigProductMaterial
);
749 ADD_MEMBER(ConsumeWisdomLimit
);
750 ADD_MEMBER(AttachedGod
);
751 ADD_MEMBER(BreatheMessage
);
752 ADD_MEMBER(StepInWisdomLimit
);
753 ADD_MEMBER(RustModifier
);
754 ADD_MEMBER(Acidicity
);
755 ADD_MEMBER(NaturalForm
);
756 ADD_MEMBER(HardenedMaterial
);
757 ADD_MEMBER(SoftenedMaterial
);
758 ADD_MEMBER(IntelligenceRequirement
);
759 ADD_MEMBER(Stickiness
);
760 ADD_MEMBER(DisablesPanicWhenConsumed
);
761 ADD_MEMBER(BlockESP
);
765 #define ADD_BASE_VALUE(name)\
766 if (Word == #name) game::GetGlobalValueMap()[CONST_S("Base")] = DataBase.*static_cast<databasemember<database, feuLong database::*>*>(Data)->Member;
769 template <class type
> void databasecreator
<type
>::SetBaseValue(cfestring
&, databasememberbase
<database
> *, database
&) {}
771 template<> void databasecreator
<material
>::SetBaseValue(cfestring
&Word
, databasememberbase
<materialdatabase
> *Data
,
772 materialdatabase
&DataBase
)
774 ADD_BASE_VALUE(CommonFlags
);
775 ADD_BASE_VALUE(NameFlags
);
776 ADD_BASE_VALUE(CategoryFlags
);
777 ADD_BASE_VALUE(BodyFlags
);
778 ADD_BASE_VALUE(InteractionFlags
);
782 template <class type
> truth databasecreator
<type
>::AnalyzeData (inputfile
&SaveFile
, cfestring
&Word
, database
&DataBase
) {
783 typename
databasemembermap::iterator i
= GetDataBaseMemberMap().find(Word
);
784 if (i
!= GetDataBaseMemberMap().end()) {
785 SetBaseValue(Word
, i
->second
, DataBase
);
786 i
->second
->ReadData(DataBase
, SaveFile
);
787 CheckDefaults(Word
, DataBase
);
794 template <> void databasecreator
<character
>::CheckDefaults (cfestring
&Word
, character::database
&DataBase
) {
795 if (Word
== "ArmBitmapPos") DataBase
.RightArmBitmapPos
= DataBase
.LeftArmBitmapPos
= DataBase
.ArmBitmapPos
;
796 else if (Word
== "LegBitmapPos") DataBase
.GroinBitmapPos
= DataBase
.RightLegBitmapPos
= DataBase
.LeftLegBitmapPos
= DataBase
.LegBitmapPos
;
797 else if (Word
== "ClothColor") DataBase
.CapColor
= DataBase
.TorsoMainColor
= DataBase
.ArmMainColor
= DataBase
.GauntletColor
= DataBase
.LegMainColor
= DataBase
.ClothColor
;
798 else if (Word
== "NameSingular") DataBase
.NamePlural
= DataBase
.NameSingular
+'s';
799 else if (Word
== "BaseUnarmedStrength") {
800 DataBase
.BaseBiteStrength
= DataBase
.BaseUnarmedStrength
>>1;
801 DataBase
.BaseKickStrength
= DataBase
.BaseUnarmedStrength
<<1;
802 } else if (Word
== "RightGauntlet") DataBase
.LeftGauntlet
= DataBase
.RightGauntlet
;
803 else if (Word
== "RightBoot") DataBase
.LeftBoot
= DataBase
.RightBoot
;
804 else if (Word
== "DefaultName") DataBase
.Alias
.Add(DataBase
.DefaultName
);
805 else if (Word
== "IsUnique") DataBase
.CanBeWished
= !DataBase
.IsUnique
;
809 template <> void databasecreator
<item
>::CheckDefaults (cfestring
&Word
, item::database
&DataBase
) {
810 if (Word
== "NameSingular") {
811 DataBase
.NamePlural
= DataBase
.NameSingular
+'s';
812 DataBase
.FlexibleNameSingular
= DataBase
.NameSingular
;
813 } else if (Word
== "BitmapPos") DataBase
.WallBitmapPos
= DataBase
.BitmapPos
;
814 else if (Word
== "MaterialConfigChances") DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
);
815 else if (Word
== "CanBeCloned") DataBase
.CanBeMirrored
= DataBase
.CanBeCloned
;
819 template <> void databasecreator
<glterrain
>::CheckDefaults (cfestring
&Word
, glterrain::database
&DataBase
) {
820 if (Word
== "NameSingular") DataBase
.NamePlural
= DataBase
.NameSingular
+'s';
821 else if (Word
== "MaterialConfigChances") DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
);
825 template <> void databasecreator
<olterrain
>::CheckDefaults (cfestring
&Word
, olterrain::database
&DataBase
) {
826 if (Word
== "NameSingular") DataBase
.NamePlural
= DataBase
.NameSingular
+'s';
827 else if (Word
== "MaterialConfigChances") DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
);
831 template <> void databasecreator
<material
>::CheckDefaults (cfestring
&Word
, material::database
&DataBase
) {
832 if (Word
== "NameStem") DataBase
.AdjectiveStem
= DataBase
.NameStem
;
833 else if (Word
== "Color") DataBase
.RainColor
= DataBase
.Color
;
837 void databasesystem::Initialize () {
838 /* Must be before character */
839 databasecreator
<material
>::ReadFrom("material");
840 databasecreator
<character
>::ReadFrom("char");
841 /* Must be before olterrain */
842 databasecreator
<item
>::ReadFrom("item");
843 databasecreator
<glterrain
>::ReadFrom("glterra");
844 databasecreator
<olterrain
>::ReadFrom("olterra");
848 template <class type
> inline void databasecreator
<type
>::FindDataBase (const database
*&DataBase
,
849 const prototype
*Proto
, int Config
)
851 database
**Table
= Proto
->ConfigTable
[(Config
>> 8) ^ (Config
& 0xFF)];
853 if ((*Table
)->Config
== Config
) {
857 for (++Table
; *Table
; ++Table
) {
858 if ((*Table
)->Config
== Config
) {
868 template void databasecreator
<character
>::FindDataBase (const database
*&, const prototype
*, int);
869 template void databasecreator
<material
>::FindDataBase (const database
*&, const prototype
*, int);
871 template <class type
> void databasecreator
<type
>::InstallDataBase (type
*Instance
, int Config
) {
872 const prototype
*Proto
= Instance
->FindProtoType();
873 FindDataBase(Instance
->DataBase
, Proto
, Config
);
874 if (!Instance
->DataBase
) {
876 ABORT("Undefined %s configuration #%08x sought!", Proto
->GetClassID(), (unsigned int)Config
);
880 #define INST_INSTALL_DATABASE(type) template void databasecreator<type>::InstallDataBase(type *, int)
882 INST_INSTALL_DATABASE(material
);
883 INST_INSTALL_DATABASE(character
);
884 INST_INSTALL_DATABASE(item
);
885 INST_INSTALL_DATABASE(glterrain
);
886 INST_INSTALL_DATABASE(olterrain
);