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 */
17 int CreateConfigTable (databasebase
***ConfigTable
, databasebase
***TempTable
,
18 databasebase
**ConfigArray
, sLong
*TempTableInfo
, int Type
, int Configs
, int TempTables
)
20 memset(ConfigTable
, 0, CONFIG_TABLE_SIZE
*sizeof(databasebase
**));
21 for (int c
= 0; c
< Configs
; ++c
) {
22 int Config
= ConfigArray
[c
]->Config
;
23 int Hash
= (Config
>> 8) ^ (Config
& 0xFF);
24 if ((TempTableInfo
[Hash
] & 0xFFFF) != Type
) {
25 TempTable
[0][Hash
] = ConfigArray
[c
];
26 TempTableInfo
[Hash
] = Type
| 0x10000;
28 int Conflicts
= (TempTableInfo
[Hash
] & 0xFFFF0000) >> 16;
29 if (Conflicts
== TempTables
) TempTable
[TempTables
++] = new databasebase
*[CONFIG_TABLE_SIZE
];
30 TempTable
[Conflicts
][Hash
] = ConfigArray
[c
];
31 TempTableInfo
[Hash
] += 0x10000;
34 for (int c1
= 0; c1
< CONFIG_TABLE_SIZE
; ++c1
) {
35 if ((TempTableInfo
[c1
] & 0xFFFF) == Type
) {
36 int Entries
= (TempTableInfo
[c1
] & 0xFFFF0000) >> 16;
37 ConfigTable
[c1
] = new databasebase
*[Entries
+ 1];
38 for (int c2
= 0; c2
< Entries
; ++c2
) ConfigTable
[c1
][c2
] = TempTable
[c2
][c1
];
39 ConfigTable
[c1
][Entries
] = 0;
46 static void collectHandler (festring
&dest
, std::stack
<TextInput
*> &infStack
, TextInput
**iff
) {
47 TextInput
*inFile
= *iff
;
48 festring Word
= inFile
->ReadWord(true);
49 dest
<< "on " << Word
<< "\n{\n";
50 if (inFile
->ReadWord() != "{") ABORT("'{' missing in datafile %s line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
54 int ch
= inFile
->GetChar();
56 if (infStack
.empty()) ABORT("'}' missing in datafile %s line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
58 *iff
= inFile
= infStack
.top();
64 if (ch
== '"') inStr
= false;
65 else if (ch
== '\\') {
66 ch
= inFile
->GetChar();
67 if (ch
== EOF
) ABORT("Unexpected end of file %s!", inFile
->GetFileName().CStr());
74 } else if (ch
== '{') {
76 } else if (ch
== '"') {
84 template <class type
> void databasecreator
<type
>::ReadFrom (const festring
&baseFileName
) {
85 std::stack
<TextInput
*> infStack
;
86 for (int fno
= 99; fno
>= -1; fno
--) {
88 cfname
<< game::GetGameDir() << "script/" << baseFileName
;
91 sprintf(bnum
, "_%02d", fno
);
95 if (!inputfile::fileExists(cfname
)) continue;
96 TextInput
*ifl
= new TextInputFile(cfname
, &game::GetGlobalValueMap(), false);
105 for (size_t f = 0; f < infStack.size(); f++) {
106 inputfile *inFile = infStack.at(f);
107 fprintf(stderr, "found: %s\n", inFile->GetFileName().CStr());
111 typedef typename
type::prototype prototype
;
112 festring Word
, defName
;
113 database
*TempConfig
[1024];
114 databasebase
**TempTable
[1024];
115 sLong TempTableInfo
[CONFIG_TABLE_SIZE
];
117 databasebase
*FirstTempTable
[CONFIG_TABLE_SIZE
];
118 TempTable
[0] = FirstTempTable
;
119 memset(TempTableInfo
, 0, CONFIG_TABLE_SIZE
*sizeof(sLong
));
120 CreateDataBaseMemberMap();
121 while (!infStack
.empty()) {
122 TextInput
*inFile
= infStack
.top();
124 inFile
->setGetVarCB(game::ldrGetVar
);
125 //fprintf(stderr, "MAIN: %s\n", inFile->GetFileName().CStr());
126 for (inFile
->ReadWord(Word
, false); !inFile
->Eof(); inFile
->ReadWord(Word
, false)) {
127 if (Word
== "Include") {
128 Word
= inFile
->ReadWord();
129 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
130 //fprintf(stderr, "loading: %s\n", Word.CStr());
131 TextInput
*incf
= new TextInputFile(game::GetGameDir()+"script/"+Word
, &game::GetGlobalValueMap());
132 infStack
.push(inFile
);
134 inFile
->setGetVarCB(game::ldrGetVar
);
137 if (Word
== "Message") {
138 Word
= inFile
->ReadWord();
139 if (inFile
->ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", inFile
->GetFileName().CStr(), inFile
->TokenLine());
140 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
144 truth doExtend
= false, doOverride
= false;
145 if (Word
== "Extend") {
146 Word
= inFile
->ReadWord();
148 } else if (Word
== "Override" || Word
== "Redefine") {
149 Word
= inFile
->ReadWord();
154 int Type
= protocontainer
<type
>::SearchCodeName(Word
);
155 if (!Type
) ABORT("Odd term <%s> encountered in %s datafile %s line %d!", Word
.CStr(), protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
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(game::GetGameDir()+"script/"+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());
220 TextInput
*incf
= new TextInputFile(game::GetGameDir()+"script/"+fname
, &game::GetGlobalValueMap());
221 infStack
.push(inFile
);
224 //fprintf(stderr, "new config %d (%s) for %s\n", ConfigNumber, inFile->numStr().CStr(), defName.CStr());
225 database
*ConfigDataBase
= new database(*Proto
->ChooseBaseForConfig(TempConfig
, Configs
, ConfigNumber
));
226 festring cfgname
= inFile
->numStr();
227 festring infname
= inFile
->GetFileName();
228 ConfigDataBase
->InitDefaults(Proto
, ConfigNumber
, cfgname
);
229 TempConfig
[Configs
++] = ConfigDataBase
;
230 if (inFile
->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer
<type
>::GetMainClassID(), inFile
->GetFileName().CStr(), inFile
->TokenLine());
231 for (inFile
->ReadWord(Word
); Word
!= "}"; inFile
->ReadWord(Word
)) {
233 collectHandler(Proto
->mOnEvents
, infStack
, &inFile
);
236 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());
238 ConfigDataBase
->PostProcess();
243 collectHandler(Proto
->mOnEvents
, infStack
, &inFile
);
246 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());
248 DataBase
->PostProcess();
249 //Configs = Proto->CreateSpecialConfigurations(TempConfig, Configs);
250 Proto
->ConfigData
= new database
*[Configs
];
251 Proto
->ConfigSize
= Configs
;
252 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
258 for (c1
= 0; c1
< SPECIAL_CONFIGURATION_GENERATION_LEVELS
; ++c1
) {
259 for (int c2
= 1; c2
< protocontainer
<type
>::GetSize(); ++c2
) {
260 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c2
];
261 int Configs
= Proto
->ConfigSize
;
262 memmove(TempConfig
, Proto
->ConfigData
, Configs
*sizeof(database
*));
263 Configs
= Proto
->CreateSpecialConfigurations(TempConfig
, Configs
, c1
);
264 if (Proto
->ConfigSize
!= Configs
) {
265 delete [] Proto
->ConfigData
;
266 Proto
->ConfigData
= new database
*[Configs
];
267 Proto
->ConfigSize
= Configs
;
268 memmove(Proto
->ConfigData
, TempConfig
, Configs
*sizeof(database
*));
272 for (c1
= 1; c1
< protocontainer
<type
>::GetSize(); ++c1
) {
273 prototype
*Proto
= protocontainer
<type
>::GetProtoData()[c1
];
275 CreateConfigTable(reinterpret_cast<databasebase
***>(Proto
->ConfigTable
),
277 reinterpret_cast<databasebase
**>(Proto
->ConfigData
),
278 TempTableInfo
, c1
, Proto
->ConfigSize
, TempTables
);
280 for (c1
= 1; c1
< TempTables
; ++c1
) delete [] TempTable
[c1
];
281 GetDataBaseMemberMap().clear();
285 template <class type
> int databasecreator
<type
>::CreateDivineConfigurations (const prototype
*Proto
, database
**TempConfig
, int Configs
) {
286 int OldConfigs
= Configs
;
287 for (int c1
= 1; c1
< protocontainer
<god
>::GetSize(); ++c1
) {
288 database
*ConfigDataBase
= 0;
290 festring dcfgname
= "divine";
291 for (c2
= 1; c2
< OldConfigs
; ++c2
) {
292 ConfigDataBase
= TempConfig
[c2
];
293 if (ConfigDataBase
->Config
== c1
) {
295 dcfgname
<< ConfigDataBase
->CfgStrName
;
299 truth Created
= false;
300 if (c2
== OldConfigs
) {
301 ConfigDataBase
= new database(**TempConfig
);
302 ConfigDataBase
->InitDefaults(Proto
, c1
, dcfgname
);
305 ConfigDataBase
->AttachedGod
= c1
;
306 ConfigDataBase
->PostFix
<< "of " << festring(protocontainer
<god
>::GetProto(c1
)->GetClassID()).CapitalizeCopy();
307 if (Created
) TempConfig
[Configs
++] = ConfigDataBase
;
313 template int databasecreator
<character
>::CreateDivineConfigurations (const prototype
*, database
**, int);
314 template int databasecreator
<item
>::CreateDivineConfigurations (const prototype
*, database
**, int);
315 template int databasecreator
<olterrain
>::CreateDivineConfigurations (const prototype
*, database
**, int);
318 template <class database
, class member
> struct databasemember
: public databasememberbase
<database
> {
319 databasemember (member Member
) : Member(Member
) {}
320 virtual void ReadData (database
&DataBase
, TextInput
&SaveFile
) { ::ReadData(DataBase
.*Member
, SaveFile
); }
325 template <class database
, class member
> void AddMember(std::map
<festring
, databasememberbase
<database
>*>& Map
, cchar
* Str
, member Member
)
327 Map
.insert(std::pair
<festring
, databasememberbase
<database
>*>(Str
, new databasemember
<database
, member
>(Member
)));
331 /* Explicit instantiations seem to increase compile speed greatly here... */
333 #define INST_ADD_MEMBER(type, member) \
334 template void AddMember<type##database, member type##database::*>(std::map<festring, databasememberbase<type##database>*>&, cchar*, member type##database::*)
336 INST_ADD_MEMBER(character
, int);
337 //INST_ADD_MEMBER(character, sLong); //k8:64
338 INST_ADD_MEMBER(character
, packcol16
);
339 INST_ADD_MEMBER(character
, col24
);
340 INST_ADD_MEMBER(character
, packv2
);
341 INST_ADD_MEMBER(character
, festring
);
342 INST_ADD_MEMBER(character
, fearray
<sLong
>);
343 INST_ADD_MEMBER(character
, fearray
<festring
>);
344 INST_ADD_MEMBER(character
, contentscript
<item
>);
346 INST_ADD_MEMBER(item
, int);
347 //INST_ADD_MEMBER(item, sLong); //k8:64
348 INST_ADD_MEMBER(item
, col24
);
349 INST_ADD_MEMBER(item
, v2
);
350 INST_ADD_MEMBER(item
, festring
);
351 INST_ADD_MEMBER(item
, fearray
<sLong
>);
352 INST_ADD_MEMBER(item
, fearray
<festring
>);
354 INST_ADD_MEMBER(glterrain
, int);
355 //INST_ADD_MEMBER(glterrain, sLong); //k8:64
356 INST_ADD_MEMBER(glterrain
, v2
);
357 INST_ADD_MEMBER(glterrain
, festring
);
358 INST_ADD_MEMBER(glterrain
, fearray
<sLong
>);
360 INST_ADD_MEMBER(olterrain
, int);
361 //INST_ADD_MEMBER(olterrain, sLong); //k8:64
362 INST_ADD_MEMBER(olterrain
, v2
);
363 INST_ADD_MEMBER(olterrain
, festring
);
364 INST_ADD_MEMBER(olterrain
, fearray
<sLong
>);
365 INST_ADD_MEMBER(olterrain
, fearray
<contentscript
<item
> >);
367 INST_ADD_MEMBER(material
, int);
368 //INST_ADD_MEMBER(material, sLong); //k8:64
369 INST_ADD_MEMBER(material
, col24
);
370 INST_ADD_MEMBER(material
, festring
);
371 INST_ADD_MEMBER(material
, contentscript
<item
>);
373 #define ADD_MEMBER(data) AddMember(Map, #data, &database::data);
375 template<> void databasecreator
<character
>::CreateDataBaseMemberMap () {
376 databasemembermap
&Map
= GetDataBaseMemberMap();
377 ADD_MEMBER(DefaultArmStrength
);
378 ADD_MEMBER(DefaultLegStrength
);
379 ADD_MEMBER(DefaultDexterity
);
380 ADD_MEMBER(DefaultAgility
);
381 ADD_MEMBER(DefaultEndurance
);
382 ADD_MEMBER(DefaultPerception
);
383 ADD_MEMBER(DefaultIntelligence
);
384 ADD_MEMBER(DefaultWisdom
);
385 ADD_MEMBER(DefaultWillPower
);
386 ADD_MEMBER(DefaultCharisma
);
387 ADD_MEMBER(DefaultMana
);
388 ADD_MEMBER(DefaultMoney
);
389 ADD_MEMBER(TotalSize
);
392 ADD_MEMBER(CanBeGenerated
);
393 ADD_MEMBER(CriticalModifier
);
394 ADD_MEMBER(StandVerb
);
396 ADD_MEMBER(Frequency
);
397 ADD_MEMBER(EnergyResistance
);
398 ADD_MEMBER(FireResistance
);
399 ADD_MEMBER(PoisonResistance
);
400 ADD_MEMBER(ElectricityResistance
);
401 ADD_MEMBER(AcidResistance
);
402 ADD_MEMBER(SoundResistance
);
403 ADD_MEMBER(IsUnique
);
404 ADD_MEMBER(ConsumeFlags
);
405 ADD_MEMBER(TotalVolume
);
406 ADD_MEMBER(HeadBitmapPos
);
407 ADD_MEMBER(TorsoBitmapPos
);
408 ADD_MEMBER(ArmBitmapPos
);
409 ADD_MEMBER(LegBitmapPos
);
410 ADD_MEMBER(RightArmBitmapPos
);
411 ADD_MEMBER(LeftArmBitmapPos
);
412 ADD_MEMBER(RightLegBitmapPos
);
413 ADD_MEMBER(LeftLegBitmapPos
);
414 ADD_MEMBER(GroinBitmapPos
);
415 ADD_MEMBER(ClothColor
);
416 ADD_MEMBER(SkinColor
);
417 ADD_MEMBER(CapColor
);
418 ADD_MEMBER(HairColor
);
419 ADD_MEMBER(EyeColor
);
420 ADD_MEMBER(TorsoMainColor
);
421 ADD_MEMBER(BeltColor
);
422 ADD_MEMBER(BootColor
);
423 ADD_MEMBER(TorsoSpecialColor
);
424 ADD_MEMBER(ArmMainColor
);
425 ADD_MEMBER(GauntletColor
);
426 ADD_MEMBER(ArmSpecialColor
);
427 ADD_MEMBER(LegMainColor
);
428 ADD_MEMBER(LegSpecialColor
);
429 ADD_MEMBER(IsNameable
);
430 ADD_MEMBER(BaseEmitation
);
431 ADD_MEMBER(UsesLongArticle
);
432 ADD_MEMBER(Adjective
);
433 ADD_MEMBER(UsesLongAdjectiveArticle
);
434 ADD_MEMBER(NameSingular
);
435 ADD_MEMBER(NamePlural
);
437 ADD_MEMBER(ArticleMode
);
438 ADD_MEMBER(IsAbstract
);
439 ADD_MEMBER(IsPolymorphable
);
440 ADD_MEMBER(BaseUnarmedStrength
);
441 ADD_MEMBER(BaseBiteStrength
);
442 ADD_MEMBER(BaseKickStrength
);
443 ADD_MEMBER(AttackStyle
);
444 ADD_MEMBER(CanUseEquipment
);
447 ADD_MEMBER(ClassStates
);
448 ADD_MEMBER(CanBeWished
);
450 ADD_MEMBER(CreateDivineConfigurations
);
451 ADD_MEMBER(CreateGolemMaterialConfigurations
);
455 ADD_MEMBER(BodyArmor
);
457 ADD_MEMBER(RightWielded
);
458 ADD_MEMBER(LeftWielded
);
459 ADD_MEMBER(RightRing
);
460 ADD_MEMBER(LeftRing
);
461 ADD_MEMBER(RightGauntlet
);
462 ADD_MEMBER(LeftGauntlet
);
463 ADD_MEMBER(RightBoot
);
464 ADD_MEMBER(LeftBoot
);
465 ADD_MEMBER(AttributeBonus
);
466 ADD_MEMBER(KnownCWeaponSkills
);
467 ADD_MEMBER(CWeaponSkillHits
);
468 ADD_MEMBER(RightSWeaponSkillHits
);
469 ADD_MEMBER(LeftSWeaponSkillHits
);
470 ADD_MEMBER(PanicLevel
);
471 ADD_MEMBER(CanBeCloned
);
472 ADD_MEMBER(Inventory
);
473 ADD_MEMBER(DangerModifier
);
474 ADD_MEMBER(DefaultName
);
475 ADD_MEMBER(FriendlyReplies
);
476 ADD_MEMBER(HostileReplies
);
478 ADD_MEMBER(FleshMaterial
);
480 ADD_MEMBER(DeathMessage
);
481 ADD_MEMBER(IgnoreDanger
);
482 ADD_MEMBER(HPRequirementForGeneration
);
483 ADD_MEMBER(DayRequirementForGeneration
);
484 ADD_MEMBER(IsExtraCoward
);
485 ADD_MEMBER(SpillsBlood
);
488 ADD_MEMBER(CanThrow
);
489 ADD_MEMBER(UsesNutrition
);
490 ADD_MEMBER(AttackWisdomLimit
);
491 ADD_MEMBER(AttachedGod
);
492 ADD_MEMBER(BodyPartsDisappearWhenSevered
);
493 ADD_MEMBER(CanBeConfused
);
494 ADD_MEMBER(CanApply
);
495 ADD_MEMBER(WieldedPosition
);
496 ADD_MEMBER(NaturalSparkleFlags
);
497 ADD_MEMBER(BiteCapturesBodyPart
);
499 ADD_MEMBER(MoveType
);
500 ADD_MEMBER(DestroysWalls
);
501 ADD_MEMBER(IsRooted
);
502 ADD_MEMBER(BloodMaterial
);
503 ADD_MEMBER(VomitMaterial
);
504 ADD_MEMBER(HasSecondaryMaterial
);
505 ADD_MEMBER(IsImmuneToLeprosy
);
506 ADD_MEMBER(PolymorphIntelligenceRequirement
);
507 ADD_MEMBER(AutomaticallySeen
);
509 ADD_MEMBER(DefaultCommandFlags
);
510 ADD_MEMBER(ConstantCommandFlags
);
511 ADD_MEMBER(WillCarryItems
);
512 ADD_MEMBER(ForceVomitMessage
);
513 ADD_MEMBER(SweatMaterial
);
515 ADD_MEMBER(IsImmuneToItemTeleport
);
516 ADD_MEMBER(AlwaysUseMaterialAttributes
);
517 ADD_MEMBER(IsEnormous
);
518 ADD_MEMBER(ScienceTalkAdjectiveAttribute
);
519 ADD_MEMBER(ScienceTalkSubstantiveAttribute
);
520 ADD_MEMBER(ScienceTalkPrefix
);
521 ADD_MEMBER(ScienceTalkName
);
522 ADD_MEMBER(ScienceTalkPossibility
);
523 ADD_MEMBER(ScienceTalkIntelligenceModifier
);
524 ADD_MEMBER(ScienceTalkWisdomModifier
);
525 ADD_MEMBER(ScienceTalkCharismaModifier
);
526 ADD_MEMBER(ScienceTalkIntelligenceRequirement
);
527 ADD_MEMBER(ScienceTalkWisdomRequirement
);
528 ADD_MEMBER(ScienceTalkCharismaRequirement
);
529 ADD_MEMBER(IsExtraFragile
);
530 ADD_MEMBER(AllowUnconsciousness
);
531 ADD_MEMBER(CanChoke
);
532 ADD_MEMBER(IsImmuneToStickiness
);
533 ADD_MEMBER(DisplacePriority
);
534 ADD_MEMBER(RunDescriptionLineOne
);
535 ADD_MEMBER(RunDescriptionLineTwo
);
536 ADD_MEMBER(ForceCustomStandVerb
);
537 ADD_MEMBER(VomittingIsUnhealthy
);
538 ADD_MEMBER(AllowPlayerToChangeEquipment
);
539 ADD_MEMBER(TamingDifficulty
);
540 ADD_MEMBER(IsMasochist
);
541 ADD_MEMBER(IsSadist
);
542 ADD_MEMBER(IsCatacombCreature
);
543 ADD_MEMBER(CreateUndeadConfigurations
);
544 ADD_MEMBER(UndeadVersions
);
545 ADD_MEMBER(UndeadAttributeModifier
);
546 ADD_MEMBER(UndeadVolumeModifier
);
547 ADD_MEMBER(UndeadCopyMaterials
);
548 ADD_MEMBER(CanBeGeneratedOnlyInTheCatacombs
);
549 ADD_MEMBER(IsAlcoholic
);
550 ADD_MEMBER(IsImmuneToWhipOfThievery
);
551 ADD_MEMBER(IsRangedAttacker
);
552 ADD_MEMBER(WhatCategoryToThrow
);
553 ADD_MEMBER(WhatWeaponConfigToThrow
);
554 ADD_MEMBER(WhatThrowItemTypesToThrow
);
555 ADD_MEMBER(AllowedDungeons
);
556 ADD_MEMBER(LevelTags
);
557 ADD_MEMBER(HomeLevel
);
558 ADD_MEMBER(NaturalTeam
);
562 template<> void databasecreator
<item
>::CreateDataBaseMemberMap () {
563 databasemembermap
&Map
= GetDataBaseMemberMap();
564 ADD_MEMBER(Possibility
);
565 ADD_MEMBER(IsDestroyable
);
566 ADD_MEMBER(CanBeWished
);
567 ADD_MEMBER(IsMaterialChangeable
);
568 ADD_MEMBER(WeaponCategory
);
569 ADD_MEMBER(IsPolymorphSpawnable
);
570 ADD_MEMBER(IsAutoInitializable
);
571 ADD_MEMBER(Category
);
572 ADD_MEMBER(EnergyResistance
);
573 ADD_MEMBER(FireResistance
);
574 ADD_MEMBER(PoisonResistance
);
575 ADD_MEMBER(ElectricityResistance
);
576 ADD_MEMBER(AcidResistance
);
577 ADD_MEMBER(SoundResistance
);
578 ADD_MEMBER(StrengthModifier
);
579 ADD_MEMBER(FormModifier
);
580 ADD_MEMBER(DefaultSize
);
581 ADD_MEMBER(DefaultMainVolume
);
582 ADD_MEMBER(DefaultSecondaryVolume
);
583 ADD_MEMBER(BitmapPos
);
585 ADD_MEMBER(BaseEmitation
);
586 ADD_MEMBER(UsesLongArticle
);
587 ADD_MEMBER(Adjective
);
588 ADD_MEMBER(UsesLongAdjectiveArticle
);
589 ADD_MEMBER(NameSingular
);
590 ADD_MEMBER(NamePlural
);
592 ADD_MEMBER(ArticleMode
);
593 ADD_MEMBER(MainMaterialConfig
);
594 ADD_MEMBER(SecondaryMaterialConfig
);
595 ADD_MEMBER(MaterialConfigChances
);
596 ADD_MEMBER(IsAbstract
);
597 ADD_MEMBER(IsPolymorphable
);
599 ADD_MEMBER(OKVisualEffects
);
600 ADD_MEMBER(CanBeGeneratedInContainer
);
601 ADD_MEMBER(ForcedVisualEffects
);
602 ADD_MEMBER(Roundness
);
603 ADD_MEMBER(GearStates
);
604 ADD_MEMBER(IsTwoHanded
);
605 ADD_MEMBER(CreateDivineConfigurations
);
606 ADD_MEMBER(CanBeCloned
);
607 ADD_MEMBER(CanBeMirrored
);
608 ADD_MEMBER(BeamRange
);
609 ADD_MEMBER(CanBeBroken
);
610 ADD_MEMBER(WallBitmapPos
);
611 ADD_MEMBER(FlexibleNameSingular
);
612 ADD_MEMBER(MaxCharges
);
613 ADD_MEMBER(MinCharges
);
614 ADD_MEMBER(CanBePiled
);
615 ADD_MEMBER(StorageVolume
);
616 ADD_MEMBER(MaxGeneratedContainedItems
);
617 ADD_MEMBER(AffectsArmStrength
);
618 ADD_MEMBER(AffectsLegStrength
);
619 ADD_MEMBER(AffectsDexterity
);
620 ADD_MEMBER(AffectsAgility
);
621 ADD_MEMBER(AffectsEndurance
);
622 ADD_MEMBER(AffectsPerception
);
623 ADD_MEMBER(AffectsIntelligence
);
624 ADD_MEMBER(AffectsWisdom
);
625 ADD_MEMBER(AffectsWillPower
);
626 ADD_MEMBER(AffectsCharisma
);
627 ADD_MEMBER(AffectsMana
);
628 ADD_MEMBER(BaseEnchantment
);
629 ADD_MEMBER(PriceIsProportionalToEnchantment
);
630 ADD_MEMBER(InElasticityPenaltyModifier
);
631 ADD_MEMBER(CanBeUsedBySmith
);
632 ADD_MEMBER(AffectsCarryingCapacity
);
633 ADD_MEMBER(DamageDivider
);
634 ADD_MEMBER(HandleInPairs
);
635 ADD_MEMBER(CanBeEnchanted
);
636 ADD_MEMBER(BeamColor
);
637 ADD_MEMBER(BeamEffect
);
638 ADD_MEMBER(BeamStyle
);
639 ADD_MEMBER(WearWisdomLimit
);
640 ADD_MEMBER(AttachedGod
);
641 ADD_MEMBER(BreakEffectRangeSquare
);
642 ADD_MEMBER(WieldedBitmapPos
);
643 ADD_MEMBER(IsQuestItem
);
644 ADD_MEMBER(IsGoodWithPlants
);
645 ADD_MEMBER(CreateLockConfigurations
);
646 ADD_MEMBER(CanBePickedUp
);
647 ADD_MEMBER(CoverPercentile
);
648 ADD_MEMBER(TorsoArmorBitmapPos
);
649 ADD_MEMBER(ArmArmorBitmapPos
);
650 ADD_MEMBER(AthleteArmArmorBitmapPos
);
651 ADD_MEMBER(LegArmorBitmapPos
);
652 ADD_MEMBER(HelmetBitmapPos
);
653 ADD_MEMBER(CloakBitmapPos
);
654 ADD_MEMBER(BeltBitmapPos
);
655 ADD_MEMBER(GauntletBitmapPos
);
656 ADD_MEMBER(BootBitmapPos
);
657 ADD_MEMBER(HasSecondaryMaterial
);
658 ADD_MEMBER(AllowEquip
);
659 ADD_MEMBER(ReadDifficulty
);
660 ADD_MEMBER(IsValuable
);
661 ADD_MEMBER(EnchantmentMinusChance
);
662 ADD_MEMBER(EnchantmentPlusChance
);
663 ADD_MEMBER(TeleportPriority
);
664 ADD_MEMBER(HasNormalPictureDirection
);
665 ADD_MEMBER(DamageFlags
);
666 ADD_MEMBER(IsKamikazeWeapon
);
667 ADD_MEMBER(FlexibilityIsEssential
);
668 ADD_MEMBER(BreakMsg
);
669 ADD_MEMBER(IsSadistWeapon
);
670 ADD_MEMBER(IsThrowingWeapon
);
671 ADD_MEMBER(ThrowItemTypes
);
672 ADD_MEMBER(CanFlame
);
673 ADD_MEMBER(AllowedDungeons
);
674 ADD_MEMBER(LevelTags
);
678 template <class type
> void databasecreator
<type
>::CreateLTerrainDataBaseMemberMap () {
679 databasemembermap
&Map
= GetDataBaseMemberMap();
680 ADD_MEMBER(BitmapPos
);
681 ADD_MEMBER(UsesLongArticle
);
682 ADD_MEMBER(Adjective
);
683 ADD_MEMBER(UsesLongAdjectiveArticle
);
684 ADD_MEMBER(NameSingular
);
685 ADD_MEMBER(NamePlural
);
687 ADD_MEMBER(ArticleMode
);
688 ADD_MEMBER(MainMaterialConfig
);
689 ADD_MEMBER(SecondaryMaterialConfig
);
690 ADD_MEMBER(MaterialConfigChances
);
691 ADD_MEMBER(IsAbstract
);
692 ADD_MEMBER(OKVisualEffects
);
693 ADD_MEMBER(MaterialColorB
);
694 ADD_MEMBER(MaterialColorC
);
695 ADD_MEMBER(MaterialColorD
);
696 ADD_MEMBER(SitMessage
);
697 ADD_MEMBER(ShowMaterial
);
698 ADD_MEMBER(AttachedGod
);
699 ADD_MEMBER(Walkability
);
700 ADD_MEMBER(HasSecondaryMaterial
);
701 ADD_MEMBER(UseBorderTiles
);
702 ADD_MEMBER(BorderTilePriority
);
706 template<> void databasecreator
<glterrain
>::CreateDataBaseMemberMap () {
707 CreateLTerrainDataBaseMemberMap();
711 template<> void databasecreator
<olterrain
>::CreateDataBaseMemberMap () {
712 CreateLTerrainDataBaseMemberMap();
713 databasemembermap
&Map
= GetDataBaseMemberMap();
714 ADD_MEMBER(CreateDivineConfigurations
);
715 ADD_MEMBER(DigMessage
);
716 ADD_MEMBER(CanBeDestroyed
);
717 ADD_MEMBER(RestModifier
);
718 ADD_MEMBER(RestMessage
);
719 ADD_MEMBER(IsUpLink
);
720 ADD_MEMBER(StorageVolume
);
721 ADD_MEMBER(HPModifier
);
722 ADD_MEMBER(IsSafeToCreateDoor
);
723 ADD_MEMBER(OpenBitmapPos
);
724 ADD_MEMBER(CreateLockConfigurations
);
725 ADD_MEMBER(IsAlwaysTransparent
);
726 ADD_MEMBER(CreateWindowConfigurations
);
727 ADD_MEMBER(WindowBitmapPos
);
728 ADD_MEMBER(ShowThingsUnder
);
729 ADD_MEMBER(LeftOverItems
);
734 template<> void databasecreator
<material
>::CreateDataBaseMemberMap () {
735 databasemembermap
&Map
= GetDataBaseMemberMap();
736 ADD_MEMBER(CommonFlags
);
737 ADD_MEMBER(NameFlags
);
738 ADD_MEMBER(CategoryFlags
);
739 ADD_MEMBER(BodyFlags
);
740 ADD_MEMBER(InteractionFlags
);
741 ADD_MEMBER(StrengthValue
);
742 ADD_MEMBER(ConsumeType
);
745 ADD_MEMBER(RainColor
);
746 ADD_MEMBER(PriceModifier
);
747 ADD_MEMBER(Emitation
);
748 ADD_MEMBER(NutritionValue
);
749 ADD_MEMBER(NameStem
);
750 ADD_MEMBER(AdjectiveStem
);
752 ADD_MEMBER(ConsumeEndMessage
);
753 ADD_MEMBER(HitMessage
);
754 ADD_MEMBER(ExplosivePower
);
756 ADD_MEMBER(Flexibility
);
757 ADD_MEMBER(SpoilModifier
);
758 ADD_MEMBER(EffectStrength
);
759 ADD_MEMBER(DigProductMaterial
);
760 ADD_MEMBER(ConsumeWisdomLimit
);
761 ADD_MEMBER(AttachedGod
);
762 ADD_MEMBER(BreatheMessage
);
763 ADD_MEMBER(StepInWisdomLimit
);
764 ADD_MEMBER(RustModifier
);
765 ADD_MEMBER(Acidicity
);
766 ADD_MEMBER(NaturalForm
);
767 ADD_MEMBER(HardenedMaterial
);
768 ADD_MEMBER(SoftenedMaterial
);
769 ADD_MEMBER(IntelligenceRequirement
);
770 ADD_MEMBER(Stickiness
);
771 ADD_MEMBER(DisablesPanicWhenConsumed
);
772 ADD_MEMBER(BlockESP
);
776 #define ADD_BASE_VALUE(name)\
777 if (Word == #name) game::GetGlobalValueMap()[CONST_S("Base")] = DataBase.*static_cast<databasemember<database, feuLong database::*>*>(Data)->Member;
780 template <class type
> void databasecreator
<type
>::SetBaseValue(cfestring
&, databasememberbase
<database
> *, database
&) {}
782 template<> void databasecreator
<material
>::SetBaseValue(cfestring
&Word
, databasememberbase
<materialdatabase
> *Data
,
783 materialdatabase
&DataBase
)
785 ADD_BASE_VALUE(CommonFlags
);
786 ADD_BASE_VALUE(NameFlags
);
787 ADD_BASE_VALUE(CategoryFlags
);
788 ADD_BASE_VALUE(BodyFlags
);
789 ADD_BASE_VALUE(InteractionFlags
);
793 template <class type
> truth databasecreator
<type
>::AnalyzeData (TextInput
&SaveFile
, cfestring
&Word
, database
&DataBase
) {
794 typename
databasemembermap::iterator i
= GetDataBaseMemberMap().find(Word
);
795 if (i
!= GetDataBaseMemberMap().end()) {
796 SetBaseValue(Word
, i
->second
, DataBase
);
797 i
->second
->ReadData(DataBase
, SaveFile
);
798 CheckDefaults(Word
, DataBase
);
805 template <> void databasecreator
<character
>::CheckDefaults (cfestring
&Word
, character::database
&DataBase
) {
806 if (Word
== "ArmBitmapPos") { DataBase
.RightArmBitmapPos
= DataBase
.LeftArmBitmapPos
= DataBase
.ArmBitmapPos
; return; }
807 if (Word
== "LegBitmapPos") { DataBase
.GroinBitmapPos
= DataBase
.RightLegBitmapPos
= DataBase
.LeftLegBitmapPos
= DataBase
.LegBitmapPos
; return; }
808 if (Word
== "ClothColor") { DataBase
.CapColor
= DataBase
.TorsoMainColor
= DataBase
.ArmMainColor
= DataBase
.GauntletColor
= DataBase
.LegMainColor
= DataBase
.ClothColor
; return; }
809 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
810 if (Word
== "BaseUnarmedStrength") { DataBase
.BaseBiteStrength
= DataBase
.BaseUnarmedStrength
>>1; DataBase
.BaseKickStrength
= DataBase
.BaseUnarmedStrength
<<1; return; }
811 if (Word
== "RightGauntlet") { DataBase
.LeftGauntlet
= DataBase
.RightGauntlet
; return; }
812 if (Word
== "RightBoot") { DataBase
.LeftBoot
= DataBase
.RightBoot
; return; }
813 if (Word
== "IsUnique") { DataBase
.CanBeWished
= !DataBase
.IsUnique
; return; }
814 if (Word
== "DefaultName") {
815 // k8: don't add duplicate alias
816 for (uInt c
= 0; c
< DataBase
.Alias
.Size
; ++c
) {
817 if (DataBase
.Alias
[c
] == DataBase
.DefaultName
) return;
819 DataBase
.Alias
.Add(DataBase
.DefaultName
);
821 if (DataBase.Alias.Size != 1) {
822 printf("=== %s ===\n", DataBase.NameSingular.CStr());
823 for (uInt c = 0; c < DataBase.Alias.Size; ++c) {
824 printf(" %u: %s\n", c, DataBase.Alias[c].CStr());
833 template <> void databasecreator
<item
>::CheckDefaults (cfestring
&Word
, item::database
&DataBase
) {
834 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; DataBase
.FlexibleNameSingular
= DataBase
.NameSingular
; return; }
835 if (Word
== "BitmapPos") { DataBase
.WallBitmapPos
= DataBase
.BitmapPos
; return; }
836 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
837 if (Word
== "CanBeCloned") { DataBase
.CanBeMirrored
= DataBase
.CanBeCloned
; return; }
841 template <> void databasecreator
<glterrain
>::CheckDefaults (cfestring
&Word
, glterrain::database
&DataBase
) {
842 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
843 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
847 template <> void databasecreator
<olterrain
>::CheckDefaults (cfestring
&Word
, olterrain::database
&DataBase
) {
848 if (Word
== "NameSingular") { DataBase
.NamePlural
= DataBase
.NameSingular
+'s'; return; }
849 if (Word
== "MaterialConfigChances") { DataBase
.MaterialConfigChanceSum
= femath::SumArray(DataBase
.MaterialConfigChances
); return; }
853 template <> void databasecreator
<material
>::CheckDefaults (cfestring
&Word
, material::database
&DataBase
) {
854 if (Word
== "NameStem") { DataBase
.AdjectiveStem
= DataBase
.NameStem
; return; }
855 if (Word
== "Color") { DataBase
.RainColor
= DataBase
.Color
; return; }
859 void databasesystem::Initialize () {
860 /* Must be before character */
861 databasecreator
<material
>::ReadFrom("material");
862 databasecreator
<character
>::ReadFrom("char");
863 /* Must be before olterrain */
864 databasecreator
<item
>::ReadFrom("item");
865 databasecreator
<glterrain
>::ReadFrom("glterra");
866 databasecreator
<olterrain
>::ReadFrom("olterra");
870 template <class type
> inline void databasecreator
<type
>::FindDataBase (const database
*&DataBase
, const prototype
*Proto
, int Config
) {
871 database
**Table
= Proto
->ConfigTable
[(Config
>> 8) ^ (Config
& 0xFF)];
873 if ((*Table
)->Config
== Config
) {
877 for (++Table
; *Table
; ++Table
) {
878 if ((*Table
)->Config
== Config
) {
888 template void databasecreator
<character
>::FindDataBase (const database
*&, const prototype
*, int);
889 template void databasecreator
<material
>::FindDataBase (const database
*&, const prototype
*, int);
891 template <class type
> void databasecreator
<type
>::InstallDataBase (type
*Instance
, int Config
) {
892 const prototype
*Proto
= Instance
->FindProtoType();
893 FindDataBase(Instance
->DataBase
, Proto
, Config
);
894 if (!Instance
->DataBase
) {
896 ABORT("Undefined %s configuration #%08x sought!", Proto
->GetClassID(), (unsigned int)Config
);
900 #define INST_INSTALL_DATABASE(type) template void databasecreator<type>::InstallDataBase(type *, int)
902 INST_INSTALL_DATABASE(material
);
903 INST_INSTALL_DATABASE(character
);
904 INST_INSTALL_DATABASE(item
);
905 INST_INSTALL_DATABASE(glterrain
);
906 INST_INSTALL_DATABASE(olterrain
);