/* * * Iter Vehemens ad Necem (IVAN) * Copyright (C) Timo Kiviluoto * Released under the GNU General * Public License * * See LICENSING which should be included * along with this file for more details * */ #ifndef __SCRIPT_H__ #define __SCRIPT_H__ #include #include #include "rect.h" #include "femath.h" #include "festring.h" #define SCRIPT_MEMBER(type, name)\ public:\ const type* Get##name() const { return name##Holder.Member; }\ protected:\ scriptmember< type > name##Holder #define SCRIPT_MEMBER_WITH_BASE(type, name)\ public:\ const type* Get##name() const { return GetMemberOf(name##Holder, Base, &scripttype::Get##name); }\ protected:\ scriptmember< type > name##Holder #define FAST_SCRIPT_MEMBER(type, name)\ public:\ type Get##name() const { return name##Holder.Member; }\ protected:\ fastscriptmember< type > name##Holder #define SCRIPT_TRUTH(name)\ public:\ const truth* name() const { return name##Holder.Member; }\ protected:\ scriptmember name##Holder #define SCRIPT_TRUTH_WITH_BASE(name)\ public:\ const truth* name() const { return GetMemberOf(name##Holder, Base, &scripttype::name); }\ protected:\ scriptmember name##Holder #define FAST_SCRIPT_TRUTH(name)\ public:\ truth name() const { return name##Holder.Member; }\ protected:\ fastscriptmember name##Holder class glterrain; class olterrain; class character; class item; class material; class scriptwithbase; class outputfile; class inputfile; struct scriptmemberbase { virtual ~scriptmemberbase() { } virtual void ReadFrom(inputfile&) = 0; virtual void Save(outputfile&) const = 0; virtual void Load(inputfile&) = 0; virtual void Replace(scriptmemberbase&) = 0; }; template struct scriptmember : public scriptmemberbase { virtual ~scriptmember() { delete Member; } scriptmember() : Member(0) { } scriptmember(const scriptmember& Data) : scriptmemberbase(Data), Member(Data.Member ? new type(*Data.Member) : 0) { } scriptmember& operator=(const scriptmember&); virtual void ReadFrom(inputfile&); virtual void Replace(scriptmemberbase&); virtual void Save(outputfile&) const; virtual void Load(inputfile&); type* Member; }; template inline const type* GetMemberOf(const scriptmember& Data, const scriptwithbase* Base, const type* (scripttype::*MemberRetriever)() const) { return Data.Member ? Data.Member : Base ? (static_cast(Base)->*MemberRetriever)() : 0; } template inline scriptmember& scriptmember::operator=(const scriptmember& Data) { if(Member) { if(Data.Member) *Member = *Data.Member; else { delete Member; Member = 0; } } else if(Data.Member) Member = new type(*Data.Member); return *this; } #ifdef VC #pragma pack(1) #endif template struct fastscriptmember : public scriptmemberbase { fastscriptmember() { } fastscriptmember(type Member) : Member(Member) { } virtual void ReadFrom(inputfile&); virtual void Replace(scriptmemberbase&); virtual void Save(outputfile&) const; virtual void Load(inputfile&); type Member NO_ALIGNMENT; }; #ifdef VC #pragma pack() #endif class script { public: typedef std::map datamap; virtual ~script() { } virtual void ReadFrom(inputfile&) = 0; virtual void Save(outputfile& SaveFile) const { SaveDataMap(GetDataMap(), SaveFile); } virtual void Load(inputfile& SaveFile) { LoadDataMap(GetDataMap(), SaveFile); } protected: truth ReadMember(inputfile&, const festring&); virtual scriptmemberbase* GetDataFromMap(const datamap&, const char*); virtual scriptmemberbase* GetData(const char* String) { return GetDataFromMap(GetDataMap(), String); } virtual const datamap& GetDataMap() const = 0; virtual void SaveDataMap(const datamap&, outputfile&) const; virtual void LoadDataMap(const datamap&, inputfile&); }; inline void ReadData(script& Type, inputfile& SaveFile) { Type.ReadFrom(SaveFile); } inline outputfile& operator<<(outputfile& SaveFile, const script& Script) { Script.Save(SaveFile); return SaveFile; } inline inputfile& operator>>(inputfile& SaveFile, script& Script) { Script.Load(SaveFile); return SaveFile; } class scriptwithbase : public script { public: scriptwithbase() : Base(0) { } const scriptwithbase* GetBase() const { return Base; } virtual void SetBase(const scriptwithbase* What) { Base = What; } protected: const scriptwithbase* Base; }; class posscript : public script { public: typedef posscript scripttype; virtual void ReadFrom(inputfile&); truth GetRandom() const { return Random; } static void InitDataMap(); virtual void Save(outputfile&) const; virtual void Load(inputfile&); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; SCRIPT_MEMBER(rect, Borders); FAST_SCRIPT_MEMBER(packv2, Vector); FAST_SCRIPT_MEMBER(uchar, Flags); truth Random; }; class materialscript : public script { public: typedef materialscript scripttype; virtual void ReadFrom(inputfile&); int GetConfig() const { return Config; } void SetConfig(int What) { Config = What; } material* Instantiate() const; virtual void Save(outputfile&) const; virtual void Load(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; SCRIPT_MEMBER(interval, Volume); int Config; }; class basecontentscript : public script { public: typedef basecontentscript scripttype; basecontentscript(); virtual void ReadFrom(inputfile&); int GetContentType() const { return ContentType; } truth IsValid() const { return ContentType || Random; } virtual void Save(outputfile&) const; virtual void Load(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } virtual scriptmemberbase* GetData(const char*); virtual int SearchCodeName(const festring&) const = 0; virtual const char* GetClassID() const = 0; static datamap DataMap; SCRIPT_MEMBER(materialscript, MainMaterial); SCRIPT_MEMBER(materialscript, SecondaryMaterial); ushort ContentType : 15; truth Random : 1; ushort Config; FAST_SCRIPT_MEMBER(uchar, Parameters); }; inline truth IsValidScript(const basecontentscript* S) { return S->IsValid(); } template class contentscripttemplate : public basecontentscript { protected: type* BasicInstantiate(int) const; virtual int SearchCodeName(const festring&) const; }; template class contentscript; template<> class contentscript : public contentscripttemplate { public: typedef contentscript scripttype; contentscript(); item* InstantiateBasedOnMaterial(int, int = 0) const; item* Instantiate(int = 0) const; static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } virtual const char* GetClassID() const; static datamap DataMap; SCRIPT_MEMBER(fearray >, ItemsInside); SCRIPT_MEMBER(interval, Times); SCRIPT_MEMBER(interval, LifeExpectancy); FAST_SCRIPT_MEMBER(ulong, Category); FAST_SCRIPT_MEMBER(long, MinPrice); FAST_SCRIPT_MEMBER(long, MaxPrice); FAST_SCRIPT_MEMBER(uchar, Team); FAST_SCRIPT_MEMBER(uchar, SquarePosition); FAST_SCRIPT_MEMBER(uchar, Chance); FAST_SCRIPT_MEMBER(uchar, ConfigFlags); FAST_SCRIPT_MEMBER(uchar, SpoilPercentage); FAST_SCRIPT_MEMBER(char, Enchantment); FAST_SCRIPT_TRUTH(IsActive); }; truth IsValidScript(const fearray >*); template <> class contentscript : public contentscripttemplate { public: typedef contentscript scripttype; contentscript(); character* Instantiate(int = 0) const; static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } virtual const char* GetClassID() const; static datamap DataMap; SCRIPT_MEMBER(fearray >, Inventory); SCRIPT_MEMBER(fearray, WayPoint); FAST_SCRIPT_MEMBER(uchar, Team); FAST_SCRIPT_MEMBER(uchar, Flags); }; template <> class contentscript : public contentscripttemplate { public: typedef contentscript scripttype; glterrain* Instantiate(int SpecialFlags = 0) const { return contentscripttemplate::BasicInstantiate(SpecialFlags); } static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; virtual const char* GetClassID() const; SCRIPT_TRUTH(IsInside); }; template <> class contentscript : public contentscripttemplate { public: typedef contentscript scripttype; contentscript(); olterrain* Instantiate(int = 0) const; static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; virtual const char* GetClassID() const; SCRIPT_MEMBER(fearray >, ItemsInside); SCRIPT_MEMBER(festring, Text); FAST_SCRIPT_MEMBER(uchar, VisualEffects); FAST_SCRIPT_MEMBER(uchar, AttachedArea); FAST_SCRIPT_MEMBER(uchar, AttachedEntry); }; class squarescript : public script { public: typedef squarescript scripttype; squarescript(); virtual void ReadFrom(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; SCRIPT_MEMBER(posscript, Position); SCRIPT_MEMBER(contentscript, Character); SCRIPT_MEMBER(fearray >, Items); SCRIPT_MEMBER(contentscript, GTerrain); SCRIPT_MEMBER(contentscript, OTerrain); SCRIPT_MEMBER(interval, Times); FAST_SCRIPT_MEMBER(uchar, EntryIndex); FAST_SCRIPT_TRUTH(AttachRequired); }; template > class contentmap : public script { public: typedef contentmap scripttype; contentmap(); virtual ~contentmap(); virtual void ReadFrom(inputfile&); const contenttype* GetContentScript(int X, int Y) const { return ContentMap[X][Y].second; } virtual void Save(outputfile&) const; virtual void Load(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; std::pair** ContentMap; std::map SymbolMap; SCRIPT_MEMBER(v2, Size); SCRIPT_MEMBER(v2, Pos); }; typedef contentmap > > itemcontentmap; typedef contentmap charactercontentmap; typedef contentmap glterraincontentmap; typedef contentmap olterraincontentmap; class roomscript : public scriptwithbase { public: typedef roomscript scripttype; void ReadFrom(inputfile&); const std::list& GetSquare() const; virtual void Save(outputfile&) const; virtual void Load(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; std::list Square; SCRIPT_MEMBER_WITH_BASE(charactercontentmap, CharacterMap); SCRIPT_MEMBER_WITH_BASE(itemcontentmap, ItemMap); SCRIPT_MEMBER_WITH_BASE(glterraincontentmap, GTerrainMap); SCRIPT_MEMBER_WITH_BASE(olterraincontentmap, OTerrainMap); SCRIPT_MEMBER_WITH_BASE(squarescript, WallSquare); SCRIPT_MEMBER_WITH_BASE(squarescript, FloorSquare); SCRIPT_MEMBER_WITH_BASE(squarescript, DoorSquare); SCRIPT_MEMBER_WITH_BASE(region, Size); SCRIPT_MEMBER_WITH_BASE(region, Pos); SCRIPT_TRUTH_WITH_BASE(AltarPossible); SCRIPT_TRUTH_WITH_BASE(GenerateDoor); SCRIPT_TRUTH_WITH_BASE(GenerateTunnel); SCRIPT_MEMBER_WITH_BASE(int, DivineMaster); SCRIPT_TRUTH_WITH_BASE(GenerateLanterns); SCRIPT_MEMBER_WITH_BASE(int, Type); SCRIPT_TRUTH_WITH_BASE(GenerateFountains); SCRIPT_TRUTH_WITH_BASE(AllowLockedDoors); SCRIPT_TRUTH_WITH_BASE(AllowBoobyTrappedDoors); SCRIPT_MEMBER_WITH_BASE(int, Shape); SCRIPT_TRUTH_WITH_BASE(IsInside); SCRIPT_TRUTH_WITH_BASE(GenerateWindows); SCRIPT_TRUTH_WITH_BASE(UseFillSquareWalls); SCRIPT_MEMBER_WITH_BASE(ulong, Flags); }; class levelscript : public scriptwithbase { public: typedef levelscript scripttype; void ReadFrom(inputfile&); const std::list& GetSquare() const; const std::list& GetRoom() const; void Combine(levelscript&); virtual void Save(outputfile&) const; virtual void Load(inputfile&); virtual void SetBase(const scriptwithbase*); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; std::list Square; std::list Room; SCRIPT_MEMBER_WITH_BASE(roomscript, RoomDefault); SCRIPT_MEMBER_WITH_BASE(squarescript, FillSquare); SCRIPT_MEMBER_WITH_BASE(squarescript, TunnelSquare); SCRIPT_MEMBER_WITH_BASE(festring, LevelMessage); SCRIPT_MEMBER_WITH_BASE(v2, Size); SCRIPT_MEMBER_WITH_BASE(interval, Items); SCRIPT_MEMBER_WITH_BASE(interval, Rooms); SCRIPT_TRUTH_WITH_BASE(GenerateMonsters); SCRIPT_TRUTH_WITH_BASE(IsOnGround); SCRIPT_MEMBER_WITH_BASE(int, TeamDefault); SCRIPT_MEMBER_WITH_BASE(festring, Description); SCRIPT_MEMBER_WITH_BASE(int, LOSModifier); SCRIPT_TRUTH_WITH_BASE(IgnoreDefaultSpecialSquares); SCRIPT_MEMBER_WITH_BASE(int, DifficultyBase); SCRIPT_MEMBER_WITH_BASE(int, DifficultyDelta); SCRIPT_MEMBER_WITH_BASE(int, MonsterAmountBase); SCRIPT_MEMBER_WITH_BASE(int, MonsterAmountDelta); SCRIPT_MEMBER_WITH_BASE(int, MonsterGenerationIntervalBase); SCRIPT_MEMBER_WITH_BASE(int, MonsterGenerationIntervalDelta); SCRIPT_TRUTH_WITH_BASE(AutoReveal); SCRIPT_MEMBER_WITH_BASE(festring, ShortDescription); SCRIPT_TRUTH_WITH_BASE(CanGenerateBone); SCRIPT_MEMBER_WITH_BASE(int, ItemMinPriceBase); SCRIPT_MEMBER_WITH_BASE(int, ItemMinPriceDelta); SCRIPT_MEMBER_WITH_BASE(int, Type); SCRIPT_MEMBER_WITH_BASE(int, EnchantmentMinusChanceBase); SCRIPT_MEMBER_WITH_BASE(int, EnchantmentMinusChanceDelta); SCRIPT_MEMBER_WITH_BASE(int, EnchantmentPlusChanceBase); SCRIPT_MEMBER_WITH_BASE(int, EnchantmentPlusChanceDelta); SCRIPT_MEMBER_WITH_BASE(int, BackGroundType); }; class dungeonscript : public script { public: typedef dungeonscript scripttype; dungeonscript(); virtual ~dungeonscript(); virtual void ReadFrom(inputfile&); const std::map& GetLevel() const; void RandomizeLevels(); virtual void Save(outputfile&) const; virtual void Load(inputfile&); virtual const datamap& GetDataMap() const { return DataMap; } static void InitDataMap(); protected: static datamap DataMap; std::map Level; std::list > RandomLevel; SCRIPT_MEMBER(levelscript, LevelDefault); SCRIPT_MEMBER(int, Levels); SCRIPT_MEMBER(festring, Description); SCRIPT_MEMBER(festring, ShortDescription); }; class teamscript : public script { public: typedef teamscript scripttype; virtual void ReadFrom(inputfile&); const std::vector >& GetRelation() const; virtual void Save(outputfile&) const; virtual void Load(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; std::vector > Relation; SCRIPT_MEMBER(int, KillEvilness); }; class gamescript : public script { public: typedef gamescript scripttype; virtual void ReadFrom(inputfile&); const std::list >& GetTeam() const; const std::map& GetDungeon() const; void RandomizeLevels(); virtual void Save(outputfile&) const; virtual void Load(inputfile&); static void InitDataMap(); protected: virtual const datamap& GetDataMap() const { return DataMap; } static datamap DataMap; std::list > Team; std::map Dungeon; SCRIPT_MEMBER(int, Dungeons); SCRIPT_MEMBER(int, Teams); }; outputfile& operator<<(outputfile&, const gamescript*); inputfile& operator>>(inputfile&, gamescript*&); class scriptsystem { public: static void Initialize(); }; #endif