memcpy() --> memmove(); added vampire and vampirism
[k8-i-v-a-n.git] / src / game / database.cpp
blob3d7a7ab075f85025aff271292828224172fbe228
1 /*
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
8 * See LICENSING which should be included
9 * along with this file for more details
12 /* Compiled through dataset.cpp */
13 #include <stack>
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;
26 } else {
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;
41 return TempTables;
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->TellLine());
50 int cnt = 1;
51 truth inStr = false;
52 for (;;) {
53 int ch = inFile->Get();
54 if (ch == EOF) {
55 if (infStack.empty()) ABORT("'}' missing in datafile %s line %d!", inFile->GetFileName().CStr(), inFile->TellLine());
56 delete inFile;
57 *iff = inFile = infStack.top();
58 infStack.pop();
59 continue;
61 dest << (char)ch;
62 if (inStr) {
63 if (ch == '"') inStr = false;
64 else if (ch == '\\') {
65 ch = inFile->Get();
66 if (ch == EOF) ABORT("Unexpected end of file %s!", inFile->GetFileName().CStr());
67 dest << (char)ch;
69 continue;
71 if (ch == '}') {
72 if (--cnt < 1) break;
73 } else if (ch == '{') {
74 cnt++;
75 } else if (ch == '"') {
76 inStr = true;
79 dest << "\n";
83 template <class type> void databasecreator<type>::ReadFrom (const festring &baseFileName) {
84 std::stack<inputfile *> infStack;
85 for (int fno = 99; fno >= -1; fno--) {
86 festring cfname;
87 cfname << game::GetGameDir() << "Script/" << baseFileName;
88 if (fno >= 0) {
89 char bnum[8];
90 sprintf(bnum, "_%02d", fno);
91 cfname << bnum;
93 cfname << ".dat";
94 if (!inputfile::fileExists(cfname)) continue;
95 inputfile *ifl = new inputfile(cfname, &game::GetGlobalValueMap(), false);
96 if (!ifl->IsOpen()) {
97 delete ifl;
98 continue;
100 infStack.push(ifl);
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];
115 int TempTables = 1;
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();
122 infStack.pop();
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->TellLine());
129 //fprintf(stderr, "loading: %s\n", Word.CStr());
130 inputfile *incf = new inputfile(game::GetGameDir()+"Script/"+Word, &game::GetGlobalValueMap());
131 infStack.push(inFile);
132 inFile = incf;
133 inFile->setGetVarCB(game::ldrGetVar);
134 continue;
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->TellLine());
139 fprintf(stderr, "MESSAGE: %s\n", Word.CStr());
140 continue;
142 ////////
143 truth doExtend = false, doOverride = false;
144 if (Word == "Extend") {
145 Word = inFile->ReadWord();
146 doExtend = true;
147 } else if (Word == "Override" || Word == "Redefine") {
148 Word = inFile->ReadWord();
149 doOverride = true;
151 ////////
152 defName = Word;
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->TellLine());
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->TellLine());
157 database *DataBase;
158 int Configs;
159 if (doOverride) {
160 if (!Proto->ConfigData) ABORT("Can't override undefined <%s> in file %s at line %d!", defName.CStr(), inFile->GetFileName().CStr(), inFile->TellLine());
161 delete [] Proto->ConfigData;
162 Proto->ConfigData = NULL;
163 Proto->ConfigSize = 0;
165 if (doExtend) {
166 if (!Proto->ConfigData) ABORT("Can't extend undefined <%s> in file %s at line %d!", defName.CStr(), inFile->GetFileName().CStr(), inFile->TellLine());
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;
173 } else {
174 if (Proto->ConfigData) ABORT("Can't redefine <%s> in file %s at line %d!", defName.CStr(), inFile->GetFileName().CStr(), inFile->TellLine());
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->TellLine());
176 DataBase = Proto->Base ? new database(**Proto->Base->ConfigData) : new database;
177 DataBase->InitDefaults(Proto, 0);
178 TempConfig[0] = DataBase;
179 Configs = 1;
181 if (inFile->ReadWord() != "{") ABORT("'{' missing in %s datafile %s line %d!", protocontainer<type>::GetMainClassID(), inFile->GetFileName().CStr(), inFile->TellLine());
182 //for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word))
183 for (;;) {
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->TellLine());
187 delete inFile;
188 inFile = infStack.top();
189 infStack.pop();
190 continue;
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->TellLine());
198 //fprintf(stderr, "loading: %s\n", Word.CStr());
199 inputfile *incf = new inputfile(game::GetGameDir()+"Script/"+Word, &game::GetGlobalValueMap());
200 infStack.push(inFile);
201 inFile = incf;
202 inFile->setGetVarCB(game::ldrGetVar);
203 continue;
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->TellLine());
208 fprintf(stderr, "MESSAGE: %s\n", Word.CStr());
209 continue;
211 if (Word == "Config") {
212 sLong ConfigNumber = -1;
213 truth isString = false;
214 festring fname;
215 fname = inFile->ReadStringOrNumber(&ConfigNumber, &isString);
216 if (isString) {
217 // include file
218 //fprintf(stderr, "loading: %s\n", fname.CStr());
219 inputfile *incf = new inputfile(game::GetGameDir()+"Script/"+fname, &game::GetGlobalValueMap());
220 infStack.push(inFile);
221 inFile = incf;
222 } else {
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->TellLine());
228 for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word)) {
229 if (Word == "on") {
230 collectHandler(Proto->mOnEvents, infStack, &inFile);
231 continue;
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->TellLine());
235 ConfigDataBase->PostProcess();
237 continue;
239 if (Word == "on") {
240 collectHandler(Proto->mOnEvents, infStack, &inFile);
241 continue;
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->TellLine());
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 *));
251 delete inFile;
254 int c1;
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];
271 TempTables =
272 CreateConfigTable(reinterpret_cast<databasebase ***>(Proto->ConfigTable),
273 TempTable,
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;
288 int c2;
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);
297 Created = true;
299 ConfigDataBase->AttachedGod = c1;
300 ConfigDataBase->PostFix << "of " << festring(protocontainer<god>::GetProto(c1)->GetClassID()).CapitalizeCopy();
301 if (Created) TempConfig[Configs++] = ConfigDataBase;
303 return Configs;
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); }
315 member Member;
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);
384 ADD_MEMBER(CanRead);
385 ADD_MEMBER(Sex);
386 ADD_MEMBER(CanBeGenerated);
387 ADD_MEMBER(CriticalModifier);
388 ADD_MEMBER(StandVerb);
389 ADD_MEMBER(CanOpen);
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);
429 ADD_MEMBER(PostFix);
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);
438 ADD_MEMBER(CanKick);
439 ADD_MEMBER(CanTalk);
440 ADD_MEMBER(ClassStates);
441 ADD_MEMBER(CanBeWished);
442 ADD_MEMBER(Alias);
443 ADD_MEMBER(CreateDivineConfigurations);
444 ADD_MEMBER(CreateGolemMaterialConfigurations);
445 ADD_MEMBER(Helmet);
446 ADD_MEMBER(Amulet);
447 ADD_MEMBER(Cloak);
448 ADD_MEMBER(BodyArmor);
449 ADD_MEMBER(Belt);
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);
470 ADD_MEMBER(CanZap);
471 ADD_MEMBER(FleshMaterial);
472 ADD_MEMBER(HasALeg);
473 ADD_MEMBER(DeathMessage);
474 ADD_MEMBER(IgnoreDanger);
475 ADD_MEMBER(HPRequirementForGeneration);
476 ADD_MEMBER(DayRequirementForGeneration);
477 ADD_MEMBER(IsExtraCoward);
478 ADD_MEMBER(SpillsBlood);
479 ADD_MEMBER(HasEyes);
480 ADD_MEMBER(HasHead);
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);
491 ADD_MEMBER(IsPlant);
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);
501 ADD_MEMBER(CanHear);
502 ADD_MEMBER(DefaultCommandFlags);
503 ADD_MEMBER(ConstantCommandFlags);
504 ADD_MEMBER(WillCarryItems);
505 ADD_MEMBER(ForceVomitMessage);
506 ADD_MEMBER(SweatMaterial);
507 ADD_MEMBER(Sweats);
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);
551 template<> void databasecreator<item>::CreateDataBaseMemberMap () {
552 databasemembermap &Map = GetDataBaseMemberMap();
553 ADD_MEMBER(Possibility);
554 ADD_MEMBER(IsDestroyable);
555 ADD_MEMBER(CanBeWished);
556 ADD_MEMBER(IsMaterialChangeable);
557 ADD_MEMBER(WeaponCategory);
558 ADD_MEMBER(IsPolymorphSpawnable);
559 ADD_MEMBER(IsAutoInitializable);
560 ADD_MEMBER(Category);
561 ADD_MEMBER(FireResistance);
562 ADD_MEMBER(PoisonResistance);
563 ADD_MEMBER(ElectricityResistance);
564 ADD_MEMBER(AcidResistance);
565 ADD_MEMBER(StrengthModifier);
566 ADD_MEMBER(FormModifier);
567 ADD_MEMBER(DefaultSize);
568 ADD_MEMBER(DefaultMainVolume);
569 ADD_MEMBER(DefaultSecondaryVolume);
570 ADD_MEMBER(BitmapPos);
571 ADD_MEMBER(Price);
572 ADD_MEMBER(BaseEmitation);
573 ADD_MEMBER(UsesLongArticle);
574 ADD_MEMBER(Adjective);
575 ADD_MEMBER(UsesLongAdjectiveArticle);
576 ADD_MEMBER(NameSingular);
577 ADD_MEMBER(NamePlural);
578 ADD_MEMBER(PostFix);
579 ADD_MEMBER(ArticleMode);
580 ADD_MEMBER(MainMaterialConfig);
581 ADD_MEMBER(SecondaryMaterialConfig);
582 ADD_MEMBER(MaterialConfigChances);
583 ADD_MEMBER(IsAbstract);
584 ADD_MEMBER(IsPolymorphable);
585 ADD_MEMBER(Alias);
586 ADD_MEMBER(OKVisualEffects);
587 ADD_MEMBER(CanBeGeneratedInContainer);
588 ADD_MEMBER(ForcedVisualEffects);
589 ADD_MEMBER(Roundness);
590 ADD_MEMBER(GearStates);
591 ADD_MEMBER(IsTwoHanded);
592 ADD_MEMBER(CreateDivineConfigurations);
593 ADD_MEMBER(CanBeCloned);
594 ADD_MEMBER(CanBeMirrored);
595 ADD_MEMBER(BeamRange);
596 ADD_MEMBER(CanBeBroken);
597 ADD_MEMBER(WallBitmapPos);
598 ADD_MEMBER(FlexibleNameSingular);
599 ADD_MEMBER(MaxCharges);
600 ADD_MEMBER(MinCharges);
601 ADD_MEMBER(CanBePiled);
602 ADD_MEMBER(StorageVolume);
603 ADD_MEMBER(MaxGeneratedContainedItems);
604 ADD_MEMBER(AffectsArmStrength);
605 ADD_MEMBER(AffectsLegStrength);
606 ADD_MEMBER(AffectsDexterity);
607 ADD_MEMBER(AffectsAgility);
608 ADD_MEMBER(AffectsEndurance);
609 ADD_MEMBER(AffectsPerception);
610 ADD_MEMBER(AffectsIntelligence);
611 ADD_MEMBER(AffectsWisdom);
612 ADD_MEMBER(AffectsWillPower);
613 ADD_MEMBER(AffectsCharisma);
614 ADD_MEMBER(AffectsMana);
615 ADD_MEMBER(BaseEnchantment);
616 ADD_MEMBER(PriceIsProportionalToEnchantment);
617 ADD_MEMBER(InElasticityPenaltyModifier);
618 ADD_MEMBER(CanBeUsedBySmith);
619 ADD_MEMBER(AffectsCarryingCapacity);
620 ADD_MEMBER(DamageDivider);
621 ADD_MEMBER(HandleInPairs);
622 ADD_MEMBER(CanBeEnchanted);
623 ADD_MEMBER(BeamColor);
624 ADD_MEMBER(BeamEffect);
625 ADD_MEMBER(BeamStyle);
626 ADD_MEMBER(WearWisdomLimit);
627 ADD_MEMBER(AttachedGod);
628 ADD_MEMBER(BreakEffectRangeSquare);
629 ADD_MEMBER(WieldedBitmapPos);
630 ADD_MEMBER(IsQuestItem);
631 ADD_MEMBER(IsGoodWithPlants);
632 ADD_MEMBER(CreateLockConfigurations);
633 ADD_MEMBER(CanBePickedUp);
634 ADD_MEMBER(CoverPercentile);
635 ADD_MEMBER(TorsoArmorBitmapPos);
636 ADD_MEMBER(ArmArmorBitmapPos);
637 ADD_MEMBER(AthleteArmArmorBitmapPos);
638 ADD_MEMBER(LegArmorBitmapPos);
639 ADD_MEMBER(HelmetBitmapPos);
640 ADD_MEMBER(CloakBitmapPos);
641 ADD_MEMBER(BeltBitmapPos);
642 ADD_MEMBER(GauntletBitmapPos);
643 ADD_MEMBER(BootBitmapPos);
644 ADD_MEMBER(HasSecondaryMaterial);
645 ADD_MEMBER(AllowEquip);
646 ADD_MEMBER(ReadDifficulty);
647 ADD_MEMBER(IsValuable);
648 ADD_MEMBER(EnchantmentMinusChance);
649 ADD_MEMBER(EnchantmentPlusChance);
650 ADD_MEMBER(TeleportPriority);
651 ADD_MEMBER(HasNormalPictureDirection);
652 ADD_MEMBER(DamageFlags);
653 ADD_MEMBER(IsKamikazeWeapon);
654 ADD_MEMBER(FlexibilityIsEssential);
655 ADD_MEMBER(BreakMsg);
656 ADD_MEMBER(IsSadistWeapon);
657 ADD_MEMBER(IsThrowingWeapon);
658 ADD_MEMBER(ThrowItemTypes);
662 template <class type> void databasecreator<type>::CreateLTerrainDataBaseMemberMap () {
663 databasemembermap &Map = GetDataBaseMemberMap();
664 ADD_MEMBER(BitmapPos);
665 ADD_MEMBER(UsesLongArticle);
666 ADD_MEMBER(Adjective);
667 ADD_MEMBER(UsesLongAdjectiveArticle);
668 ADD_MEMBER(NameSingular);
669 ADD_MEMBER(NamePlural);
670 ADD_MEMBER(PostFix);
671 ADD_MEMBER(ArticleMode);
672 ADD_MEMBER(MainMaterialConfig);
673 ADD_MEMBER(SecondaryMaterialConfig);
674 ADD_MEMBER(MaterialConfigChances);
675 ADD_MEMBER(IsAbstract);
676 ADD_MEMBER(OKVisualEffects);
677 ADD_MEMBER(MaterialColorB);
678 ADD_MEMBER(MaterialColorC);
679 ADD_MEMBER(MaterialColorD);
680 ADD_MEMBER(SitMessage);
681 ADD_MEMBER(ShowMaterial);
682 ADD_MEMBER(AttachedGod);
683 ADD_MEMBER(Walkability);
684 ADD_MEMBER(HasSecondaryMaterial);
685 ADD_MEMBER(UseBorderTiles);
686 ADD_MEMBER(BorderTilePriority);
690 template<> void databasecreator<glterrain>::CreateDataBaseMemberMap () {
691 CreateLTerrainDataBaseMemberMap();
695 template<> void databasecreator<olterrain>::CreateDataBaseMemberMap () {
696 CreateLTerrainDataBaseMemberMap();
697 databasemembermap &Map = GetDataBaseMemberMap();
698 ADD_MEMBER(CreateDivineConfigurations);
699 ADD_MEMBER(DigMessage);
700 ADD_MEMBER(CanBeDestroyed);
701 ADD_MEMBER(RestModifier);
702 ADD_MEMBER(RestMessage);
703 ADD_MEMBER(IsUpLink);
704 ADD_MEMBER(StorageVolume);
705 ADD_MEMBER(HPModifier);
706 ADD_MEMBER(IsSafeToCreateDoor);
707 ADD_MEMBER(OpenBitmapPos);
708 ADD_MEMBER(CreateLockConfigurations);
709 ADD_MEMBER(IsAlwaysTransparent);
710 ADD_MEMBER(CreateWindowConfigurations);
711 ADD_MEMBER(WindowBitmapPos);
712 ADD_MEMBER(ShowThingsUnder);
713 ADD_MEMBER(LeftOverItems);
714 ADD_MEMBER(IsWall);
718 template<> void databasecreator<material>::CreateDataBaseMemberMap () {
719 databasemembermap &Map = GetDataBaseMemberMap();
720 ADD_MEMBER(CommonFlags);
721 ADD_MEMBER(NameFlags);
722 ADD_MEMBER(CategoryFlags);
723 ADD_MEMBER(BodyFlags);
724 ADD_MEMBER(InteractionFlags);
725 ADD_MEMBER(StrengthValue);
726 ADD_MEMBER(ConsumeType);
727 ADD_MEMBER(Density);
728 ADD_MEMBER(Color);
729 ADD_MEMBER(RainColor);
730 ADD_MEMBER(PriceModifier);
731 ADD_MEMBER(Emitation);
732 ADD_MEMBER(NutritionValue);
733 ADD_MEMBER(NameStem);
734 ADD_MEMBER(AdjectiveStem);
735 ADD_MEMBER(Effect);
736 ADD_MEMBER(ConsumeEndMessage);
737 ADD_MEMBER(HitMessage);
738 ADD_MEMBER(ExplosivePower);
739 ADD_MEMBER(Alpha);
740 ADD_MEMBER(Flexibility);
741 ADD_MEMBER(SpoilModifier);
742 ADD_MEMBER(EffectStrength);
743 ADD_MEMBER(DigProductMaterial);
744 ADD_MEMBER(ConsumeWisdomLimit);
745 ADD_MEMBER(AttachedGod);
746 ADD_MEMBER(BreatheMessage);
747 ADD_MEMBER(StepInWisdomLimit);
748 ADD_MEMBER(RustModifier);
749 ADD_MEMBER(Acidicity);
750 ADD_MEMBER(NaturalForm);
751 ADD_MEMBER(HardenedMaterial);
752 ADD_MEMBER(SoftenedMaterial);
753 ADD_MEMBER(IntelligenceRequirement);
754 ADD_MEMBER(Stickiness);
755 ADD_MEMBER(DisablesPanicWhenConsumed);
759 #define ADD_BASE_VALUE(name)\
760 if (Word == #name) game::GetGlobalValueMap()[CONST_S("Base")] = DataBase.*static_cast<databasemember<database, uLong database::*>*>(Data)->Member;
763 template <class type> void databasecreator<type>::SetBaseValue(cfestring &, databasememberbase<database> *, database &) {}
765 template<> void databasecreator<material>::SetBaseValue(cfestring &Word, databasememberbase<materialdatabase> *Data,
766 materialdatabase &DataBase)
768 ADD_BASE_VALUE(CommonFlags);
769 ADD_BASE_VALUE(NameFlags);
770 ADD_BASE_VALUE(CategoryFlags);
771 ADD_BASE_VALUE(BodyFlags);
772 ADD_BASE_VALUE(InteractionFlags);
776 template <class type> truth databasecreator<type>::AnalyzeData (inputfile &SaveFile, cfestring &Word, database &DataBase) {
777 typename databasemembermap::iterator i = GetDataBaseMemberMap().find(Word);
778 if (i != GetDataBaseMemberMap().end()) {
779 SetBaseValue(Word, i->second, DataBase);
780 i->second->ReadData(DataBase, SaveFile);
781 CheckDefaults(Word, DataBase);
782 return true;
784 return false;
788 template <> void databasecreator<character>::CheckDefaults (cfestring &Word, character::database &DataBase) {
789 if (Word == "ArmBitmapPos") DataBase.RightArmBitmapPos = DataBase.LeftArmBitmapPos = DataBase.ArmBitmapPos;
790 else if (Word == "LegBitmapPos") DataBase.GroinBitmapPos = DataBase.RightLegBitmapPos = DataBase.LeftLegBitmapPos = DataBase.LegBitmapPos;
791 else if (Word == "ClothColor") DataBase.CapColor = DataBase.TorsoMainColor = DataBase.ArmMainColor = DataBase.GauntletColor = DataBase.LegMainColor = DataBase.ClothColor;
792 else if (Word == "NameSingular") DataBase.NamePlural = DataBase.NameSingular+'s';
793 else if (Word == "BaseUnarmedStrength") {
794 DataBase.BaseBiteStrength = DataBase.BaseUnarmedStrength>>1;
795 DataBase.BaseKickStrength = DataBase.BaseUnarmedStrength<<1;
796 } else if (Word == "RightGauntlet") DataBase.LeftGauntlet = DataBase.RightGauntlet;
797 else if (Word == "RightBoot") DataBase.LeftBoot = DataBase.RightBoot;
798 else if (Word == "DefaultName") DataBase.Alias.Add(DataBase.DefaultName);
799 else if (Word == "IsUnique") DataBase.CanBeWished = !DataBase.IsUnique;
803 template <> void databasecreator<item>::CheckDefaults (cfestring &Word, item::database &DataBase) {
804 if (Word == "NameSingular") {
805 DataBase.NamePlural = DataBase.NameSingular+'s';
806 DataBase.FlexibleNameSingular = DataBase.NameSingular;
807 } else if (Word == "BitmapPos") DataBase.WallBitmapPos = DataBase.BitmapPos;
808 else if (Word == "MaterialConfigChances") DataBase.MaterialConfigChanceSum = femath::SumArray(DataBase.MaterialConfigChances);
809 else if (Word == "CanBeCloned") DataBase.CanBeMirrored = DataBase.CanBeCloned;
813 template <> void databasecreator<glterrain>::CheckDefaults (cfestring &Word, glterrain::database &DataBase) {
814 if (Word == "NameSingular") DataBase.NamePlural = DataBase.NameSingular+'s';
815 else if (Word == "MaterialConfigChances") DataBase.MaterialConfigChanceSum = femath::SumArray(DataBase.MaterialConfigChances);
819 template <> void databasecreator<olterrain>::CheckDefaults (cfestring &Word, olterrain::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<material>::CheckDefaults (cfestring &Word, material::database &DataBase) {
826 if (Word == "NameStem") DataBase.AdjectiveStem = DataBase.NameStem;
827 else if (Word == "Color") DataBase.RainColor = DataBase.Color;
831 void databasesystem::Initialize () {
832 /* Must be before character */
833 databasecreator<material>::ReadFrom("material");
834 databasecreator<character>::ReadFrom("char");
835 /* Must be before olterrain */
836 databasecreator<item>::ReadFrom("item");
837 databasecreator<glterrain>::ReadFrom("glterra");
838 databasecreator<olterrain>::ReadFrom("olterra");
842 template <class type> inline void databasecreator<type>::FindDataBase (const database *&DataBase,
843 const prototype *Proto, int Config)
845 database **Table = Proto->ConfigTable[(Config >> 8) ^ (Config & 0xFF)];
846 if (Table) {
847 if ((*Table)->Config == Config) {
848 DataBase = *Table;
849 return;
851 for (++Table; *Table; ++Table) {
852 if ((*Table)->Config == Config) {
853 DataBase = *Table;
854 return;
858 DataBase = 0;
862 template void databasecreator<character>::FindDataBase (const database *&, const prototype *, int);
863 template void databasecreator<material>::FindDataBase (const database *&, const prototype *, int);
865 template <class type> void databasecreator<type>::InstallDataBase (type *Instance, int Config) {
866 const prototype *Proto = Instance->FindProtoType();
867 FindDataBase(Instance->DataBase, Proto, Config);
868 if (!Instance->DataBase) {
869 //*((int *)0) = 0;
870 ABORT("Undefined %s configuration #%08x sought!", Proto->GetClassID(), (unsigned int)Config);
874 #define INST_INSTALL_DATABASE(type) template void databasecreator<type>::InstallDataBase(type *, int)
876 INST_INSTALL_DATABASE(material);
877 INST_INSTALL_DATABASE(character);
878 INST_INSTALL_DATABASE(item);
879 INST_INSTALL_DATABASE(glterrain);
880 INST_INSTALL_DATABASE(olterrain);