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
20 script::datamap
posscript::DataMap
;
21 script::datamap
materialscript::DataMap
;
22 script::datamap
basecontentscript::DataMap
;
23 script::datamap contentscript
<character
>::DataMap
;
24 script::datamap contentscript
<item
>::DataMap
;
25 script::datamap contentscript
<glterrain
>::DataMap
;
26 script::datamap contentscript
<olterrain
>::DataMap
;
27 script::datamap
squarescript::DataMap
;
28 script::datamap
roomscript::DataMap
;
29 script::datamap
levelscript::DataMap
;
30 script::datamap
dungeonscript::DataMap
;
31 script::datamap
teamscript::DataMap
;
32 script::datamap
gamescript::DataMap
;
34 template <class type
, class contenttype
> script::datamap contentmap
<type
, contenttype
>::DataMap
;
36 template <class type
> void scriptmember
<type
>::ReadFrom (inputfile
&SaveFile
) {
37 if (!Member
) Member
= new type
;
38 ReadData(*Member
, SaveFile
);
42 template <class type
> void scriptmember
<type
>::Replace (scriptmemberbase
&Base
) {
43 scriptmember
<type
> &Data
= static_cast<scriptmember
<type
> &>(Base
);
52 template <class type
> void scriptmember
<type
>::Save(outputfile
&SaveFile
) const {
61 template <class type
> void scriptmember
<type
>::Load(inputfile
&SaveFile
) {
69 #define INST_SCRIPT_MEMBER(type)\
70 template void scriptmember< type >::ReadFrom(inputfile&);\
71 template void scriptmember< type >::Replace(scriptmemberbase&);\
72 template void scriptmember< type >::Save(outputfile&) const;\
73 template void scriptmember< type >::Load(inputfile&)
75 INST_SCRIPT_MEMBER(uChar
);
76 INST_SCRIPT_MEMBER(short);
77 INST_SCRIPT_MEMBER(int);
78 //INST_SCRIPT_MEMBER(sLong); //k8:64
79 INST_SCRIPT_MEMBER(v2
);
80 INST_SCRIPT_MEMBER(festring
);
81 INST_SCRIPT_MEMBER(fearray
<v2
>);
82 INST_SCRIPT_MEMBER(rect
);
83 INST_SCRIPT_MEMBER(interval
);
84 INST_SCRIPT_MEMBER(region
);
85 INST_SCRIPT_MEMBER(posscript
);
86 INST_SCRIPT_MEMBER(materialscript
);
87 INST_SCRIPT_MEMBER(squarescript
);
88 INST_SCRIPT_MEMBER(roomscript
);
89 INST_SCRIPT_MEMBER(levelscript
);
90 INST_SCRIPT_MEMBER(contentscript
<character
>);
91 INST_SCRIPT_MEMBER(fearray
<contentscript
<item
> >);
92 INST_SCRIPT_MEMBER(contentscript
<glterrain
>);
93 INST_SCRIPT_MEMBER(contentscript
<olterrain
>);
94 INST_SCRIPT_MEMBER(charactercontentmap
);
95 INST_SCRIPT_MEMBER(itemcontentmap
);
96 INST_SCRIPT_MEMBER(glterraincontentmap
);
97 INST_SCRIPT_MEMBER(olterraincontentmap
);
98 INST_SCRIPT_MEMBER(fearray
<packv2
>);
101 template <class type
> void fastscriptmember
<type
>::ReadFrom(inputfile
&SaveFile
) {
102 ReadData(*&Member
, SaveFile
); // gcc 3.4.1 sucks
106 template <class type
> void fastscriptmember
<type
>::Replace(scriptmemberbase
&Base
) {
107 fastscriptmember
<type
>& Data
= static_cast<fastscriptmember
<type
> &>(Base
);
108 Member
= Data
.Member
;
112 template <class type
> void fastscriptmember
<type
>::Save(outputfile
&SaveFile
) const {
117 template <class type
> void fastscriptmember
<type
>::Load(inputfile
&SaveFile
) {
118 SaveFile
>> *&Member
; // gcc 3.4.1 sucks
122 #define INST_FAST_SCRIPT_MEMBER(type)\
123 template void fastscriptmember< type >::ReadFrom(inputfile&);\
124 template void fastscriptmember< type >::Replace(scriptmemberbase&);\
125 template void fastscriptmember< type >::Save(outputfile&) const;\
126 template void fastscriptmember< type >::Load(inputfile&)
128 INST_FAST_SCRIPT_MEMBER(char);
129 INST_FAST_SCRIPT_MEMBER(uChar
);
130 INST_FAST_SCRIPT_MEMBER(int);
131 //INST_FAST_SCRIPT_MEMBER(sLong); //k8:64
132 INST_FAST_SCRIPT_MEMBER(uLong
);
133 INST_FAST_SCRIPT_MEMBER(packv2
);
136 truth
script::ReadMember (inputfile
&SaveFile
, cfestring
&Word
) {
137 scriptmemberbase
*Data
= GetData(Word
.CStr());
139 Data
->ReadFrom(SaveFile
);
146 scriptmemberbase
*script::GetDataFromMap (const datamap
&DataMap
, cchar
*Identifier
) {
147 datamap::const_iterator i
= DataMap
.find(Identifier
);
148 return i
!= DataMap
.end() ? &(this->*i
->second
) : 0;
152 void script::SaveDataMap (const datamap
&DataMap
, outputfile
&SaveFile
) const {
153 for (datamap::const_iterator i
= DataMap
.begin(); i
!= DataMap
.end(); ++i
) (this->*i
->second
).Save(SaveFile
);
157 void script::LoadDataMap (const datamap
&DataMap
, inputfile
&SaveFile
) {
158 for (datamap::const_iterator i
= DataMap
.begin(); i
!= DataMap
.end(); ++i
) (this->*i
->second
).Load(SaveFile
);
162 template <class scriptmemberptr
> void InitMember (script::datamap
&DataMap
, cchar
*Identifier
, scriptmemberptr DataMember
) {
163 DataMap
[Identifier
] = reinterpret_cast<scriptmemberbase
script::*>(DataMember
);
166 #define INIT_ENTRY(name) InitMember(DataMap, #name, &scripttype::name##Holder)
168 #define INIT(name, value) name##Holder(value)
171 void posscript::InitDataMap () {
178 void posscript::ReadFrom (inputfile
&SaveFile
) {
179 static festring Word
;
180 SaveFile
.ReadWord(Word
);
184 VectorHolder
.ReadFrom(SaveFile
);
187 if (Word
== "Random") {
189 FlagsHolder
.ReadFrom(SaveFile
);
192 if (Word
== "BoundedRandom") {
194 BordersHolder
.ReadFrom(SaveFile
);
195 FlagsHolder
.ReadFrom(SaveFile
);
200 void posscript::Save (outputfile
&SaveFile
) const {
201 script::Save(SaveFile
);
206 void posscript::Load (inputfile
&SaveFile
) {
207 script::Load(SaveFile
);
212 void materialscript::InitDataMap () {
217 void materialscript::ReadFrom (inputfile
&SaveFile
) {
218 static festring Word
;
220 SaveFile
.ReadWord(Word
);
221 if (Word
== "=") SaveFile
.ReadWord(Word
);
225 valuemap::const_iterator i
= game::GetGlobalValueMap().find(Word
);
227 if (i
!= game::GetGlobalValueMap().end()) Config
= i
->second
;
228 else ABORT("Unconfigured material script detected at line %d!", SaveFile
.TellLine());
230 if (SaveFile
.ReadWord() != "{") return;
231 for (SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
)) {
232 if (!ReadMember(SaveFile
, Word
)) {
233 ABORT("Odd script term %s encountered in material script line %d!", Word
.CStr(), SaveFile
.TellLine());
239 material
*materialscript::Instantiate () const {
240 return MAKE_MATERIAL(Config
, GetVolume() ? GetVolume()->Randomize() : 0);
244 void materialscript::Save (outputfile
&SaveFile
) const {
245 script::Save(SaveFile
);
246 SaveFile
<< (uShort
)Config
;
250 void materialscript::Load (inputfile
&SaveFile
) {
251 script::Load(SaveFile
);
259 void basecontentscript::InitDataMap () {
260 INIT_ENTRY(MainMaterial
);
261 INIT_ENTRY(SecondaryMaterial
);
262 INIT_ENTRY(Parameters
);
266 basecontentscript::basecontentscript () : ContentType(0), Random(false), Config(0), INIT(Parameters
, NO_PARAMETERS
) {
270 void basecontentscript::ReadFrom (inputfile
&SaveFile
) {
271 static festring Word
;
273 SaveFile
.ReadWord(Word
);
275 mCode
= SaveFile
.ReadCode();
276 SaveFile
.ReadWord(Word
);
278 if (Word
== "=" || Word
== ",") SaveFile
.ReadWord(Word
);
279 valuemap::const_iterator i
= game::GetGlobalValueMap().find(Word
);
280 if (i
!= game::GetGlobalValueMap().end()) {
281 if (!GetMainMaterial()) MainMaterialHolder
.Member
= new materialscript
;
282 MainMaterialHolder
.Member
->SetConfig(i
->second
);
283 SaveFile
.ReadWord(Word
);
284 i
= game::GetGlobalValueMap().find(Word
);
285 if (i
!= game::GetGlobalValueMap().end()) {
286 if (!GetSecondaryMaterial()) SecondaryMaterialHolder
.Member
= new materialscript
;
287 SecondaryMaterialHolder
.Member
->SetConfig(i
->second
);
288 SaveFile
.ReadWord(Word
);
291 if (Word
== "NaturalMaterialForm") {
293 ContentType
= NATURAL_MATERIAL_FORM
;
294 SaveFile
.ReadWord(Word
);
295 } else if (Word
== "Random") {
297 SaveFile
.ReadWord(Word
);
300 ContentType
= SearchCodeName(Word
);
301 if (ContentType
|| Word
== "0") SaveFile
.ReadWord(Word
);
302 else ABORT("Odd script term %s encountered in %s content script, file %s line %d!", Word
.CStr(), GetClassID(), SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
305 Config
= SaveFile
.ReadNumber();
306 SaveFile
.ReadWord(Word
);
311 for (SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
)) {
312 if (!ReadMember(SaveFile
, Word
)) ABORT("Odd script term %s encountered in %s content script, file %s line %d!", Word
.CStr(), GetClassID(), SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
316 mCode
= SaveFile
.ReadCode();
317 SaveFile
.ReadWord(Word
);
319 if (Word
!= ";" && Word
!= ",") ABORT("Odd terminator %s encountered in %s content script, file %s line %d!", Word
.CStr(), GetClassID(), SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
324 scriptmemberbase
*basecontentscript::GetData (cchar
*String
) {
325 scriptmemberbase
*Return
= GetDataFromMap(GetDataMap(), String
);
326 return Return
? Return
: GetDataFromMap(DataMap
, String
);
330 void basecontentscript::Save (outputfile
&SaveFile
) const {
331 SaveDataMap(GetDataMap(), SaveFile
);
332 SaveDataMap(DataMap
, SaveFile
);
333 SaveFile
<< ContentType
;
334 SaveFile
.Put(!!Random
);
339 void basecontentscript::Load (inputfile
&SaveFile
) {
340 LoadDataMap(GetDataMap(), SaveFile
);
341 LoadDataMap(DataMap
, SaveFile
);
342 ContentType
= ReadType
<uShort
>(SaveFile
);
343 Random
= SaveFile
.Get();
348 template <class type
> type
*contentscripttemplate
<type
>::BasicInstantiate (int SpecialFlags
) const {
350 const typename
type::prototype
*Proto
= protocontainer
<type
>::GetProto(ContentType
);
351 const typename
type::database
*const *ConfigData
= Proto
->GetConfigData();
352 const materialscript
*MainMaterial
= GetMainMaterial();
353 const materialscript
*SecondaryMaterial
= GetSecondaryMaterial();
354 const typename
type::database
*DataBase
= *ConfigData
;
355 truth UseOverriddenMaterials
= false;
357 if (!Config
&& DataBase
->IsAbstract
) {
359 DataBase
= ConfigData
[1+RAND()%(Proto
->GetConfigSize()-1)];
360 if (DataBase
->AllowRandomInstantiation()) {
361 if (!(SpecialFlags
& NO_MATERIALS
) && MainMaterial
&& (!DataBase
->HasSecondaryMaterial
|| SecondaryMaterial
)) {
362 SpecialFlags
|= NO_MATERIALS
;
363 UseOverriddenMaterials
= true;
365 Instance
= Proto
->Spawn(DataBase
->Config
, SpecialFlags
|NO_PIC_UPDATE
);
369 if (!(SpecialFlags
& NO_MATERIALS
) && MainMaterial
&& (!DataBase
->HasSecondaryMaterial
|| SecondaryMaterial
)) {
370 SpecialFlags
|= NO_MATERIALS
;
371 UseOverriddenMaterials
= true;
373 Instance
= Proto
->Spawn(Config
, SpecialFlags
|NO_PIC_UPDATE
);
375 if (GetParameters() != NO_PARAMETERS
) Instance
->SetParameters(GetParameters());
376 if (UseOverriddenMaterials
) {
377 Instance
->InitMaterials(MainMaterial
, SecondaryMaterial
, false);
379 if (MainMaterial
) Instance
->ChangeMainMaterial(MainMaterial
->Instantiate(), SpecialFlags
|NO_PIC_UPDATE
);
380 if (SecondaryMaterial
) Instance
->ChangeSecondaryMaterial(SecondaryMaterial
->Instantiate(), SpecialFlags
|NO_PIC_UPDATE
);
382 if (!(SpecialFlags
& NO_PIC_UPDATE
)) Instance
->UpdatePictures();
387 /* Called by an inline function in script.h... */
389 template glterrain
*contentscripttemplate
<glterrain
>::BasicInstantiate (int) const;
391 template <class type
> int contentscripttemplate
<type
>::SearchCodeName (cfestring
&String
) const {
392 return protocontainer
<type
>::SearchCodeName(String
);
395 /* GCC 2.952 SUCKS!!! IT MUST BURN!!! */
397 template int contentscripttemplate
<character
>::SearchCodeName(cfestring
&) const;
398 template int contentscripttemplate
<item
>::SearchCodeName(cfestring
&) const;
399 template int contentscripttemplate
<glterrain
>::SearchCodeName(cfestring
&) const;
400 template int contentscripttemplate
<olterrain
>::SearchCodeName(cfestring
&) const;
402 cchar
*contentscript
<character
>::GetClassID () const { return "character"; }
403 cchar
*contentscript
<item
>::GetClassID () const { return "item"; }
404 cchar
*contentscript
<glterrain
>::GetClassID () const { return "glterrain"; }
405 cchar
*contentscript
<olterrain
>::GetClassID () const { return "olterrain"; }
408 void contentscript
<character
>::InitDataMap () {
409 INIT_ENTRY(Inventory
);
410 INIT_ENTRY(WayPoint
);
416 contentscript
<character
>::contentscript () : INIT(Team
, DEFAULT_TEAM
), INIT(Flags
, 0) {
420 character
*contentscript
<character
>::Instantiate (int SpecialFlags
) const {
421 character
*Instance
= contentscripttemplate
<character
>::BasicInstantiate(SpecialFlags
);
423 //fprintf(stderr, "instantiating character '%s'\n", Instance->GetNameSingular().CStr());
426 if (Instance->GetNameSingular() == "vampire") {
432 if (!mCode
.IsEmpty()) {
433 game::ClearEventData();
434 if (!game::RunAllowScriptStr(mCode
)) {
435 //fprintf(stderr, "dropping character '%s'\n", Instance->GetNameSingular().CStr());
441 if (GetTeam() != DEFAULT_TEAM
) Instance
->SetTeam(game::GetTeam(GetTeam()));
442 const fearray
<contentscript
<item
> > *Inventory
= GetInventory();
443 if (Inventory
) Instance
->AddToInventory(*Inventory
, SpecialFlags
);
444 const fearray
<packv2
> *WayPoint
= GetWayPoint();
445 if (WayPoint
) Instance
->SetWayPoints(*WayPoint
);
446 Instance
->RestoreHP();
447 Instance
->RestoreStamina();
452 contentscript
<item
>::contentscript () :
453 INIT(Category
, ANY_CATEGORY
),
455 INIT(MaxPrice
, MAX_PRICE
),
456 INIT(Team
, DEFAULT_TEAM
),
457 INIT(SquarePosition
, CENTER
),
459 INIT(ConfigFlags
, 0),
460 INIT(SpoilPercentage
, 0),
461 INIT(Enchantment
, 0),
462 INIT(IsActive
, false)
467 void contentscript
<item
>::InitDataMap () {
468 INIT_ENTRY(ItemsInside
);
470 INIT_ENTRY(MinPrice
);
471 INIT_ENTRY(MaxPrice
);
472 INIT_ENTRY(LifeExpectancy
);
474 INIT_ENTRY(Category
);
475 INIT_ENTRY(SquarePosition
);
477 INIT_ENTRY(ConfigFlags
);
478 INIT_ENTRY(SpoilPercentage
);
479 INIT_ENTRY(Enchantment
);
480 INIT_ENTRY(IsActive
);
484 item
*contentscript
<item
>::InstantiateBasedOnMaterial (int MaterialConfig
, int SpecialFlags
) const {
485 if (ContentType
== NATURAL_MATERIAL_FORM
) {
486 const materialscript
*MainMaterial
= GetMainMaterial();
487 sLong Volume
= MainMaterial
&& MainMaterial
->GetVolume() ? MainMaterial
->GetVolume()->Randomize() : 0;
488 return material::CreateNaturalForm(MaterialConfig
, Volume
);
490 return Instantiate(SpecialFlags
);
494 item
*contentscript
<item
>::Instantiate (int SpecialFlags
) const {
495 int Chance
= GetChance();
498 if (!mCode
.IsEmpty()) {
499 game::ClearEventData();
500 if (!game::RunAllowScriptStr(mCode
)) return 0;
503 if (Chance
!= 100 && Chance
<= RAND_N(100)) return 0;
505 Instance
= protosystem::BalancedCreateItem(GetMinPrice(), GetMaxPrice(), GetCategory(), SpecialFlags
, GetConfigFlags());
507 Instance
= contentscripttemplate
<item
>::BasicInstantiate(SpecialFlags
);
509 if (GetLifeExpectancy()) Instance
->SetLifeExpectancy(GetLifeExpectancy()->Min
, (GetLifeExpectancy()->Max
- GetLifeExpectancy()->Min
) + 1);
510 if (GetTeam() != DEFAULT_TEAM
) Instance
->SetTeam(GetTeam());
511 if (IsActive()) Instance
->SetIsActive(true);
512 if (GetEnchantment() != 0) Instance
->SetEnchantment(GetEnchantment());
513 const fearray
<contentscript
<item
> > *ItemsInside
= GetItemsInside();
514 if (ItemsInside
) Instance
->SetItemsInside(*ItemsInside
, SpecialFlags
);
515 if (GetSpoilPercentage() != 0) Instance
->SetSpoilPercentage(GetSpoilPercentage());
520 truth
IsValidScript (const fearray
<contentscript
<item
> > *Array
) {
521 for (uInt c
= 0; c
< Array
->Size
; ++c
) if (IsValidScript(&Array
->Data
[c
])) return true;
526 void contentscript
<glterrain
>::InitDataMap () {
527 INIT_ENTRY(IsInside
);
531 contentscript
<olterrain
>::contentscript () :
532 INIT(VisualEffects
, 0),
533 INIT(AttachedArea
, DEFAULT_ATTACHED_AREA
),
534 INIT(AttachedEntry
, DEFAULT_ATTACHED_ENTRY
)
539 void contentscript
<olterrain
>::InitDataMap () {
540 INIT_ENTRY(ItemsInside
);
542 INIT_ENTRY(VisualEffects
);
543 INIT_ENTRY(AttachedArea
);
544 INIT_ENTRY(AttachedEntry
);
548 olterrain
*contentscript
<olterrain
>::Instantiate (int SpecialFlags
) const {
549 if (!ContentType
) return 0;
550 olterrain
*Instance
= contentscripttemplate
<olterrain
>::BasicInstantiate(SpecialFlags
);
551 if (GetVisualEffects()) {
552 Instance
->SetVisualEffects(GetVisualEffects());
553 Instance
->UpdatePictures();
555 if (GetAttachedArea() != DEFAULT_ATTACHED_AREA
) Instance
->SetAttachedArea(GetAttachedArea());
556 if (GetAttachedEntry() != DEFAULT_ATTACHED_ENTRY
) Instance
->SetAttachedEntry(GetAttachedEntry());
557 cfestring
*Text
= GetText();
558 if (Text
) Instance
->SetText(*Text
);
559 const fearray
<contentscript
<item
> > *ItemsInside
= GetItemsInside();
560 if (ItemsInside
) Instance
->SetItemsInside(*ItemsInside
, SpecialFlags
);
565 squarescript::squarescript () : INIT(EntryIndex
, NO_ENTRY
), INIT(AttachRequired
, false) {
569 void squarescript::InitDataMap () {
570 INIT_ENTRY(Position
);
571 INIT_ENTRY(Character
);
573 INIT_ENTRY(GTerrain
);
574 INIT_ENTRY(OTerrain
);
576 INIT_ENTRY(EntryIndex
);
577 INIT_ENTRY(AttachRequired
);
581 void squarescript::ReadFrom (inputfile
&SaveFile
) {
582 static festring Word
;
584 SaveFile
.ReadWord(Word
);
586 PositionHolder
.ReadFrom(SaveFile
);
587 if (SaveFile
.ReadWord() != "{") ABORT("Bracket missing in square script line %d!", SaveFile
.TellLine());
588 for (SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
)) {
589 if (!ReadMember(SaveFile
, Word
)) ABORT("Odd script term %s encountered in square script line %d!", Word
.CStr(), SaveFile
.TellLine());
592 GTerrainHolder
.ReadFrom(SaveFile
);
593 OTerrainHolder
.ReadFrom(SaveFile
);
597 template <class type
, class contenttype
> contentmap
<type
, contenttype
>::contentmap() : ContentMap(0) { }
599 template <class type
, class contenttype
> contentmap
<type
, contenttype
>::~contentmap
<type
, contenttype
>()
601 delete [] ContentMap
;
604 template <class type
, class contenttype
> void contentmap
<type
, contenttype
>::InitDataMap()
610 template <class type
, class contenttype
> void contentmap
<type
, contenttype
>::ReadFrom(inputfile
& SaveFile
)
612 typedef std::map
<int, contenttype
> maptype
;
613 typedef typename
maptype::iterator mapiterator
;
616 ABORT("Illegal %s content map redefinition on line %d!", protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
618 if(SaveFile
.ReadWord() != "{")
619 ABORT("Bracket missing in %s content map script line %d!", protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
621 SymbolMap
.insert(std::pair
<int, contenttype
>('.', contenttype()));
622 static festring Word1
, Word2
;
624 for(SaveFile
.ReadWord(Word1
); Word1
!= "}"; Word1
= SaveFile
.ReadWord())
628 if(SaveFile
.ReadWord() != "{")
629 ABORT("Missing bracket in %s content map script line %d!", protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
631 for(SaveFile
.ReadWord(Word2
); Word2
!= "}"; Word2
= SaveFile
.ReadWord())
633 std::pair
<mapiterator
, bool> Return
= SymbolMap
.insert(std::pair
<int, contenttype
>(Word2
[0], contenttype()));
636 ReadData(Return
.first
->second
, SaveFile
);
638 ABORT("Symbol %c defined again in %s content map script line %d!", Word2
[0], protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
644 if(!ReadMember(SaveFile
, Word1
))
645 ABORT("Odd script term %s encountered in %s content script line %d!", Word1
.CStr(), protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
648 v2 Size
= *GetSize();
649 Alloc2D(ContentMap
, Size
.X
, Size
.Y
);
651 if(SaveFile
.ReadWord() != "{")
652 ABORT("Missing bracket in %s content map script line %d!", protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
654 for(int y
= 0; y
< Size
.Y
; ++y
)
655 for(int x
= 0; x
< Size
.X
; ++x
)
657 int Char
= SaveFile
.ReadLetter();
658 typename
std::map
<int, contenttype
>::iterator i
= SymbolMap
.find(Char
);
660 if(i
!= SymbolMap
.end())
661 ContentMap
[x
][y
] = std::make_pair(Char
, &i
->second
);
663 ABORT("Illegal content %c in %s content map line %d!", Char
, protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
666 if(SaveFile
.ReadWord() != "}")
667 ABORT("Missing bracket in %s content map script line %d!", protocontainer
<type
>::GetMainClassID(), SaveFile
.TellLine());
670 template <class type
, class contenttype
> void contentmap
<type
, contenttype
>::Save(outputfile
& SaveFile
) const
672 script::Save(SaveFile
);
673 SaveFile
<< SymbolMap
;
674 v2 Size
= *GetSize();
676 for(int y
= 0; y
< Size
.Y
; ++y
)
677 for(int x
= 0; x
< Size
.X
; ++x
)
678 SaveFile
<< char(ContentMap
[x
][y
].first
);
681 template <class type
, class contenttype
> void contentmap
<type
, contenttype
>::Load(inputfile
& SaveFile
)
683 script::Load(SaveFile
);
684 SaveFile
>> SymbolMap
;
685 v2 Size
= *GetSize();
686 Alloc2D(ContentMap
, Size
.X
, Size
.Y
);
688 for(int y
= 0; y
< Size
.Y
; ++y
)
689 for(int x
= 0; x
< Size
.X
; ++x
)
691 int Char
= ReadType
<char>(SaveFile
);
692 ContentMap
[x
][y
] = std::make_pair(Char
, &SymbolMap
.find(Char
)->second
);
696 const std::list
<squarescript
>& roomscript::GetSquare() const { return Square
; }
698 void roomscript::InitDataMap()
700 INIT_ENTRY(CharacterMap
);
702 INIT_ENTRY(GTerrainMap
);
703 INIT_ENTRY(OTerrainMap
);
704 INIT_ENTRY(WallSquare
);
705 INIT_ENTRY(FloorSquare
);
706 INIT_ENTRY(DoorSquare
);
709 INIT_ENTRY(AltarPossible
);
710 INIT_ENTRY(GenerateDoor
);
711 INIT_ENTRY(GenerateTunnel
);
712 INIT_ENTRY(DivineMaster
);
713 INIT_ENTRY(GenerateLanterns
);
715 INIT_ENTRY(GenerateFountains
);
716 INIT_ENTRY(AllowLockedDoors
);
717 INIT_ENTRY(AllowBoobyTrappedDoors
);
719 INIT_ENTRY(IsInside
);
720 INIT_ENTRY(GenerateWindows
);
721 INIT_ENTRY(UseFillSquareWalls
);
723 INIT_ENTRY(GenerateWards
);
726 void roomscript::ReadFrom(inputfile
& SaveFile
)
728 if(SaveFile
.ReadWord() != "{")
729 ABORT("Bracket missing in room script line %d!", SaveFile
.TellLine());
731 static festring Word
;
733 for(SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
))
737 Square
.push_back(squarescript());
738 Square
.back().ReadFrom(SaveFile
);
742 if(!ReadMember(SaveFile
, Word
))
743 ABORT("Odd script term %s encountered in room script line %d!", Word
.CStr(), SaveFile
.TellLine());
747 void roomscript::Save(outputfile
& SaveFile
) const
749 script::Save(SaveFile
);
753 void roomscript::Load(inputfile
& SaveFile
)
755 script::Load(SaveFile
);
759 const std::list
<squarescript
>& levelscript::GetSquare() const { return Square
; }
760 const std::list
<roomscript
>& levelscript::GetRoom() const { return Room
; }
762 void levelscript::InitDataMap()
764 INIT_ENTRY(RoomDefault
);
765 INIT_ENTRY(FillSquare
);
766 INIT_ENTRY(TunnelSquare
);
767 INIT_ENTRY(LevelMessage
);
771 INIT_ENTRY(GenerateMonsters
);
772 INIT_ENTRY(IsOnGround
);
773 INIT_ENTRY(TeamDefault
);
774 INIT_ENTRY(Description
);
775 INIT_ENTRY(LOSModifier
);
776 INIT_ENTRY(IgnoreDefaultSpecialSquares
);
777 INIT_ENTRY(DifficultyBase
);
778 INIT_ENTRY(DifficultyDelta
);
779 INIT_ENTRY(MonsterAmountBase
);
780 INIT_ENTRY(MonsterAmountDelta
);
781 INIT_ENTRY(MonsterGenerationIntervalBase
);
782 INIT_ENTRY(MonsterGenerationIntervalDelta
);
783 INIT_ENTRY(AutoReveal
);
784 INIT_ENTRY(ShortDescription
);
785 INIT_ENTRY(CanGenerateBone
);
786 INIT_ENTRY(ItemMinPriceBase
);
787 INIT_ENTRY(ItemMinPriceDelta
);
789 INIT_ENTRY(EnchantmentMinusChanceBase
);
790 INIT_ENTRY(EnchantmentMinusChanceDelta
);
791 INIT_ENTRY(EnchantmentPlusChanceBase
);
792 INIT_ENTRY(EnchantmentPlusChanceDelta
);
793 INIT_ENTRY(BackGroundType
);
794 INIT_ENTRY(IsCatacomb
);
795 INIT_ENTRY(EnterImage
);
796 INIT_ENTRY(EnterTextDisplacement
);
799 void levelscript::ReadFrom(inputfile
& SaveFile
)
801 if(SaveFile
.ReadWord() != "{")
802 ABORT("Bracket missing in level script line %d!", SaveFile
.TellLine());
806 cv2
* Size
= static_cast<const levelscript
*>(Base
)->GetSize();
810 game::GetGlobalValueMap()["XSize"] = Size
->X
;
811 game::GetGlobalValueMap()["YSize"] = Size
->Y
;
815 static festring Word
;
817 for(SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
))
821 Square
.push_back(squarescript());
822 Square
.back().ReadFrom(SaveFile
);
828 Room
.push_back(roomscript());
829 const roomscript
* RoomDefault
= GetRoomDefault();
832 Room
.back().SetBase(RoomDefault
);
834 Room
.back().ReadFrom(SaveFile
);
838 if(!ReadMember(SaveFile
, Word
))
839 ABORT("Odd script term %s encountered in level script line %d!", Word
.CStr(), SaveFile
.TellLine());
843 game::GetGlobalValueMap()["XSize"] = GetSize()->X
;
844 game::GetGlobalValueMap()["YSize"] = GetSize()->Y
;
848 const levelscript
* LevelBase
= static_cast<const levelscript
*>(Base
);
850 if(LevelBase
&& RoomDefaultHolder
.Member
)
851 RoomDefaultHolder
.Member
->SetBase(LevelBase
->RoomDefaultHolder
.Member
);
853 valuemap::iterator i
= game::GetGlobalValueMap().find("XSize");
855 if(i
!= game::GetGlobalValueMap().end())
856 game::GetGlobalValueMap().erase(i
);
858 i
= game::GetGlobalValueMap().find("YSize");
860 if(i
!= game::GetGlobalValueMap().end())
861 game::GetGlobalValueMap().erase(i
);
864 void levelscript::Combine(levelscript
& Script
)
869 Square
.splice(Square
.end(), Script
.Square
);
870 Room
.splice(Room
.end(), Script
.Room
);
872 for(std::list
<roomscript
>::iterator i1
= Room
.begin(); i1
!= Room
.end(); ++i1
)
873 i1
->SetBase(GetRoomDefault());
875 for(datamap::const_iterator i2
= DataMap
.begin(); i2
!= DataMap
.end(); ++i2
)
876 (this->*i2
->second
).Replace(Script
.*i2
->second
);
879 void levelscript::SetBase(const scriptwithbase
* What
)
881 const levelscript
* LevelBase
= static_cast<const levelscript
*>(Base
= What
);
882 roomscript
* BaseRoomDefault
= LevelBase
->RoomDefaultHolder
.Member
;
886 roomscript
* ThisRoomDefault
= RoomDefaultHolder
.Member
;
889 for(std::list
<roomscript
>::iterator i
= Room
.begin(); i
!= Room
.end(); ++i
)
890 i
->SetBase(BaseRoomDefault
);
892 ThisRoomDefault
->SetBase(BaseRoomDefault
);
896 void levelscript::Save(outputfile
& SaveFile
) const
898 script::Save(SaveFile
);
899 SaveFile
<< Square
<< Room
;
902 void levelscript::Load(inputfile
& SaveFile
)
904 script::Load(SaveFile
);
905 SaveFile
>> Square
>> Room
;
906 const roomscript
* RoomDefault
= GetRoomDefault();
909 for(std::list
<roomscript
>::iterator i
= Room
.begin(); i
!= Room
.end(); ++i
)
910 i
->SetBase(RoomDefault
);
913 dungeonscript::dungeonscript() { }
914 dungeonscript::~dungeonscript() { }
915 const std::map
<int, levelscript
>& dungeonscript::GetLevel() const { return Level
; }
917 void dungeonscript::InitDataMap()
919 INIT_ENTRY(LevelDefault
);
921 INIT_ENTRY(Description
);
922 INIT_ENTRY(ShortDescription
);
925 void dungeonscript::ReadFrom(inputfile
& SaveFile
)
927 if(SaveFile
.ReadWord() != "{")
928 ABORT("Bracket missing in dungeon script line %d!", SaveFile
.TellLine());
930 static festring Word
;
932 for(SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
))
936 int Index
= SaveFile
.ReadNumber();
937 std::pair
<std::map
<int, levelscript
>::iterator
, bool> Return
= Level
.insert(std::make_pair(Index
, levelscript()));
941 levelscript
& LS
= Return
.first
->second
;
942 const levelscript
* LevelDefault
= GetLevelDefault();
945 LS
.SetBase(LevelDefault
);
947 LS
.ReadFrom(SaveFile
);
950 ABORT("Level #%d defined again in dungeon script line %d!", Index
, SaveFile
.TellLine());
955 if(Word
== "RandomLevel")
958 ReadData(Interval
, SaveFile
);
959 RandomLevel
.push_back(std::make_pair(Interval
, levelscript()));
960 const levelscript
* LevelDefault
= GetLevelDefault();
963 RandomLevel
.back().second
.SetBase(LevelDefault
);
965 RandomLevel
.back().second
.ReadFrom(SaveFile
);
969 if(!ReadMember(SaveFile
, Word
))
970 ABORT("Odd script term %s encountered in dungeon script line %d!", Word
.CStr(), SaveFile
.TellLine());
974 void dungeonscript::RandomizeLevels()
976 for(std::list
<std::pair
<interval
, levelscript
> >::iterator i
= RandomLevel
.begin(); i
!= RandomLevel
.end(); ++i
)
978 int Index
= i
->first
.Randomize();
979 Level
[Index
].Combine(i
->second
);
985 void dungeonscript::Save(outputfile
& SaveFile
) const
987 script::Save(SaveFile
);
988 SaveFile
<< Level
<< RandomLevel
;
991 void dungeonscript::Load(inputfile
& SaveFile
)
993 script::Load(SaveFile
);
994 SaveFile
>> Level
>> RandomLevel
;
995 const levelscript
* LevelDefault
= GetLevelDefault();
999 for(std::map
<int, levelscript
>::iterator i1
= Level
.begin(); i1
!= Level
.end(); ++i1
)
1000 i1
->second
.SetBase(LevelDefault
);
1002 for(std::list
<std::pair
<interval
, levelscript
> >::iterator i2
= RandomLevel
.begin(); i2
!= RandomLevel
.end(); ++i2
)
1003 i2
->second
.SetBase(LevelDefault
);
1007 const std::vector
<std::pair
<int, int> >& teamscript::GetRelation() const { return Relation
; }
1009 void teamscript::InitDataMap()
1011 INIT_ENTRY(KillEvilness
);
1014 void teamscript::ReadFrom(inputfile
& SaveFile
)
1016 if(SaveFile
.ReadWord() != "{")
1017 ABORT("Bracket missing in team script line %d!", SaveFile
.TellLine());
1019 static festring Word
;
1021 for(SaveFile
.ReadWord(Word
); Word
!= "}"; SaveFile
.ReadWord(Word
))
1023 if(Word
== "Relation")
1025 std::pair
<int, int> Rel
;
1026 Rel
.first
= SaveFile
.ReadNumber();
1027 Rel
.second
= SaveFile
.ReadNumber();
1028 Relation
.push_back(Rel
);
1032 if(!ReadMember(SaveFile
, Word
))
1033 ABORT("Odd script term %s encountered in team script line %d!", Word
.CStr(), SaveFile
.TellLine());
1037 void teamscript::Save(outputfile
& SaveFile
) const
1039 script::Save(SaveFile
);
1040 SaveFile
<< Relation
;
1043 void teamscript::Load(inputfile
& SaveFile
)
1045 script::Load(SaveFile
);
1046 SaveFile
>> Relation
;
1049 const std::list
<std::pair
<int, teamscript
> >& gamescript::GetTeam() const { return Team
; }
1050 const std::map
<int, dungeonscript
>& gamescript::GetDungeon() const { return Dungeon
; }
1053 void gamescript::InitDataMap () {
1054 INIT_ENTRY(Dungeons
);
1059 void gamescript::ReadFrom (inputfile
&SaveFile
) {
1061 SaveFile
.setGetVarCB(game::ldrGetVar
);
1062 for (SaveFile
.ReadWord(Word
, false); !SaveFile
.Eof(); SaveFile
.ReadWord(Word
, false)) {
1063 if (Word
== "Dungeon") {
1064 int Index
= SaveFile
.ReadNumber();
1065 std::pair
<std::map
<int, dungeonscript
>::iterator
, bool> Return
= Dungeon
.insert(std::make_pair(Index
, dungeonscript()));
1066 if (Return
.second
) Return
.first
->second
.ReadFrom(SaveFile
);
1067 else ABORT("Dungeon #%d defined again in game script file %s line %d!", Index
, SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
1070 if (Word
== "Team") {
1071 int Index
= SaveFile
.ReadNumber();
1072 Team
.push_back(std::pair
<int, teamscript
>(Index
, teamscript()));
1073 Team
.back().second
.ReadFrom(SaveFile
);
1076 if (Word
== "Include") {
1077 Word
= SaveFile
.ReadWord();
1078 if (SaveFile
.ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
1079 //fprintf(stderr, "loading: %s\n", Word.CStr());
1080 inputfile
incf(game::GetGameDir()+"Script/"+Word
, &game::GetGlobalValueMap());
1084 if (Word
== "Message") {
1085 Word
= SaveFile
.ReadWord();
1086 if (SaveFile
.ReadWord() != ";") ABORT("Invalid terminator in file %s at line %d!", SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
1087 fprintf(stderr
, "MESSAGE: %s\n", Word
.CStr());
1090 if (!ReadMember(SaveFile
, Word
)) ABORT("Odd script term %s encountered in game script file %s line %d!", Word
.CStr(), SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
1095 void gamescript::RandomizeLevels()
1097 for(std::map
<int, dungeonscript
>::iterator i
= Dungeon
.begin(); i
!= Dungeon
.end(); ++i
)
1098 i
->second
.RandomizeLevels();
1101 void gamescript::Save(outputfile
& SaveFile
) const
1103 script::Save(SaveFile
);
1104 SaveFile
<< Team
<< Dungeon
;
1107 void gamescript::Load(inputfile
& SaveFile
)
1109 script::Load(SaveFile
);
1110 SaveFile
>> Team
>> Dungeon
;
1113 outputfile
& operator<<(outputfile
& SaveFile
, const gamescript
* Script
)
1115 Script
->Save(SaveFile
);
1119 inputfile
& operator>>(inputfile
& SaveFile
, gamescript
*& Script
)
1121 Script
= new gamescript
;
1122 Script
->Load(SaveFile
);
1126 void scriptsystem::Initialize()
1128 posscript::InitDataMap();
1129 materialscript::InitDataMap();
1130 basecontentscript::InitDataMap();
1131 contentscript
<character
>::InitDataMap();
1132 contentscript
<item
>::InitDataMap();
1133 contentscript
<glterrain
>::InitDataMap();
1134 contentscript
<olterrain
>::InitDataMap();
1135 squarescript::InitDataMap();
1136 itemcontentmap::InitDataMap();
1137 charactercontentmap::InitDataMap();
1138 glterraincontentmap::InitDataMap();
1139 olterraincontentmap::InitDataMap();
1140 roomscript::InitDataMap();
1141 levelscript::InitDataMap();
1142 dungeonscript::InitDataMap();
1143 teamscript::InitDataMap();
1144 gamescript::InitDataMap();