From 82abdab69566abb26996bb399d629ec1b0d10de5 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 00:24:29 -0400 Subject: [PATCH 01/11] Major code reorganization This commit only updates the XCode project for the changes. A later commit each will update it for scons and MSVC. A few actual changes are mixed in: - Add a prefix header for a handful of common definitions - Moved current_cursor into the Cursor class as a static member - Removed the make_cursor_sword and make_cursor_watch functions - Include tests in the All target - Remove redundant -l flags for Common and Common-Party (since they're included in the Link phases anyway) --- .gitignore | 2 +- src/BoE.xcodeproj/project.pbxproj | 394 +++--- src/alchemy.hpp | 36 + src/classes/monster.hpp | 178 --- src/classes/simpletypes.hpp | 1133 ----------------- src/classes/special.hpp | 76 -- src/classes/spell.hpp | 53 - src/damage.hpp | 122 ++ src/dialogxml/{ => dialogs}/3choice.cpp | 0 src/dialogxml/{ => dialogs}/3choice.hpp | 0 src/dialogxml/{ => dialogs}/choicedlog.cpp | 0 src/dialogxml/{ => dialogs}/choicedlog.hpp | 0 src/dialogxml/{ => dialogs}/dialog.cpp | 10 +- src/dialogxml/{ => dialogs}/dialog.hpp | 0 src/dialogxml/{ => dialogs}/dialog.keys.hpp | 0 src/dialogxml/{ => dialogs}/dlogevt.hpp | 0 src/dialogxml/{ => dialogs}/pictchoice.cpp | 0 src/dialogxml/{ => dialogs}/pictchoice.hpp | 0 src/dialogxml/{ => dialogs}/strchoice.cpp | 0 src/dialogxml/{ => dialogs}/strchoice.hpp | 0 src/dialogxml/{ => dialogs}/strdlog.cpp | 0 src/dialogxml/{ => dialogs}/strdlog.hpp | 2 +- src/dialogxml/{ => widgets}/basicbtns.cpp | 0 src/dialogxml/{ => widgets}/button.cpp | 2 +- src/dialogxml/{ => widgets}/button.hpp | 0 src/dialogxml/{ => widgets}/control.cpp | 5 +- src/dialogxml/{ => widgets}/control.hpp | 0 src/dialogxml/{ => widgets}/field.cpp | 0 src/dialogxml/{ => widgets}/field.hpp | 0 src/dialogxml/{ => widgets}/message.cpp | 0 src/dialogxml/{ => widgets}/message.hpp | 0 src/dialogxml/{ => widgets}/pict.cpp | 2 +- src/dialogxml/{ => widgets}/pict.hpp | 0 src/dialogxml/{ => widgets}/pictypes.hpp | 0 src/dialogxml/{ => widgets}/scrollbar.cpp | 3 +- src/dialogxml/{ => widgets}/scrollbar.hpp | 0 src/dialogxml/{ => widgets}/scrollpane.cpp | 0 src/dialogxml/{ => widgets}/scrollpane.hpp | 0 src/dialogxml/{ => widgets}/stack.cpp | 0 src/dialogxml/{ => widgets}/stack.hpp | 0 src/fields.hpp | 103 ++ src/{classes => fileio}/estreams.cpp | 29 +- src/{tools => fileio}/fileio.cpp | 18 +- src/{tools => fileio}/fileio.hpp | 2 - src/{tools => fileio}/fileio_party.cpp | 0 src/{tools => fileio}/fileio_scen.cpp | 5 +- src/{tools => fileio}/gzstream/COPYING.LIB | 0 src/{tools => fileio}/gzstream/Makefile | 0 src/{tools => fileio}/gzstream/README | 0 src/{tools => fileio}/gzstream/gzstream.cpp | 0 src/{tools => fileio}/gzstream/gzstream.h | 0 src/{tools => fileio}/gzstream/index.html | 0 .../gzstream/test_gunzip.cpp | 0 src/{tools => fileio}/gzstream/test_gzip.cpp | 0 src/{tools => fileio}/gzstream/version | 0 src/{tools => fileio}/map_parse.cpp | 0 src/{tools => fileio}/map_parse.hpp | 0 .../resmgr/res_cursor.hpp} | 61 +- src/fileio/resmgr/res_font.hpp | 31 + src/fileio/resmgr/res_image.hpp | 31 + src/fileio/resmgr/res_sound.hpp | 31 + src/fileio/resmgr/res_strings.hpp | 41 + src/{tools => fileio}/resmgr/resmgr.hpp | 1 - src/{tools => fileio}/resmgr/restypes.cpp | 6 +- .../special_parse.cpp} | 0 src/{tools => fileio}/special_parse.hpp | 0 src/{tools => fileio}/tarball.cpp | 0 src/{tools => fileio}/tarball.hpp | 0 .../xml-parser/build_instructions.txt | 0 .../xml-parser/changes.txt | 0 src/{dialogxml => fileio}/xml-parser/dox | 0 .../xml-parser/readme.txt | 0 .../xml-parser/ticpp.cpp | 0 src/{dialogxml => fileio}/xml-parser/ticpp.h | 0 .../xml-parser/ticpp.lua | 0 .../xml-parser/ticppapi.h | 0 .../xml-parser/ticpprc.h | 0 .../xml-parser/tinyprint.cpp | 0 .../xml-parser/tinyprint.h | 0 .../xml-parser/tinystr.cpp | 0 .../xml-parser/tinystr.h | 0 .../xml-parser/tinyxml.cpp | 0 .../xml-parser/tinyxml.h | 0 .../xml-parser/tinyxmlerror.cpp | 0 .../xml-parser/tinyxmlparser.cpp | 0 .../xml-parser/tutorial_gettingStarted.txt | 0 .../xml-parser/tutorial_ticpp.txt | 0 src/{ => game}/boe.actions.cpp | 6 +- src/{ => game}/boe.actions.hpp | 1 - src/{ => game}/boe.appleevents.mm | 0 src/{ => game}/boe.combat.cpp | 2 +- src/{ => game}/boe.combat.hpp | 0 src/{ => game}/boe.consts.hpp | 0 src/{ => game}/boe.dlgutil.cpp | 18 +- src/{ => game}/boe.dlgutil.hpp | 1 - src/{ => game}/boe.fileio.cpp | 14 +- src/{ => game}/boe.fileio.hpp | 5 +- src/{ => game}/boe.global.hpp | 0 src/{ => game}/boe.graphics.cpp | 4 +- src/{ => game}/boe.graphics.hpp | 1 - src/{ => game}/boe.graphutil.cpp | 4 +- src/{ => game}/boe.graphutil.hpp | 1 - src/{ => game}/boe.infodlg.cpp | 22 +- src/{ => game}/boe.infodlg.hpp | 1 - src/{ => game}/boe.items.cpp | 20 +- src/{ => game}/boe.items.hpp | 1 - src/{ => game}/boe.locutils.cpp | 0 src/{ => game}/boe.locutils.hpp | 0 src/{ => game}/boe.main.cpp | 13 +- src/{ => game}/boe.main.hpp | 0 src/{ => game}/boe.menus.hpp | 0 src/{ => game}/boe.menus.mac.mm | 0 src/{ => game}/boe.menus.win.cpp | 0 src/{ => game}/boe.monster.cpp | 2 +- src/{ => game}/boe.monster.hpp | 0 src/{ => game}/boe.newgraph.cpp | 4 +- src/{ => game}/boe.newgraph.hpp | 0 src/{ => game}/boe.party.cpp | 17 +- src/{ => game}/boe.party.hpp | 0 src/{ => game}/boe.specials.cpp | 2 +- src/{ => game}/boe.specials.hpp | 0 src/{ => game}/boe.startup.cpp | 9 +- src/{ => game}/boe.text.cpp | 8 +- src/{ => game}/boe.text.hpp | 1 - src/{ => game}/boe.town.cpp | 4 +- src/{ => game}/boe.town.hpp | 0 src/{ => game}/boe.townspec.cpp | 2 +- src/{ => game}/boe.townspec.hpp | 0 src/{tools => gfx}/graphtool.cpp | 5 +- src/{tools => gfx}/graphtool.hpp | 2 - src/{tools => gfx}/mask.frag | 0 src/{tools => gfx}/mask.vert | 0 src/{tools => gfx}/qdpict.mac.cpp | 2 - src/global.hpp | 27 + src/{classes => }/location.cpp | 5 + src/{classes => }/location.hpp | 16 + src/{tools => }/mathutil.cpp | 0 src/{tools => }/mathutil.hpp | 2 +- src/pcedit/pc.action.cpp | 9 +- src/pcedit/pc.editors.cpp | 9 +- src/pcedit/pc.fileio.cpp | 3 +- src/pcedit/pc.graphics.cpp | 9 +- src/pcedit/pc.graphics.hpp | 1 - src/pcedit/pc.main.cpp | 4 +- src/{tools => }/porting.cpp | 0 src/{tools => }/porting.hpp | 0 src/race.hpp | 53 + src/{classes => scenario}/area.hpp | 0 src/{classes => scenario}/item.cpp | 5 +- src/{classes => scenario}/item.hpp | 5 +- src/scenario/item_abilities.hpp | 114 ++ src/scenario/item_variety.hpp | 65 + src/{classes => scenario}/monster.cpp | 0 src/scenario/monster.hpp | 108 ++ src/scenario/monster_abilities.hpp | 129 ++ src/{classes => scenario}/outdoors.cpp | 0 src/{classes => scenario}/outdoors.hpp | 1 - src/scenario/quest.hpp | 25 + src/{classes => scenario}/scenario.cpp | 0 src/{classes => scenario}/scenario.hpp | 14 +- src/{classes => scenario}/shop.cpp | 0 src/{classes => scenario}/shop.hpp | 29 + src/{classes => scenario}/special.cpp | 24 + src/scenario/special.hpp | 140 ++ src/{classes => scenario}/talking.cpp | 0 src/{classes => scenario}/talking.hpp | 32 +- src/{classes => scenario}/terrain.cpp | 1 + src/{classes => scenario}/terrain.hpp | 3 +- src/scenario/terrain_abilities.hpp | 89 ++ src/{classes => scenario}/town.cpp | 0 src/{classes => scenario}/town.hpp | 8 +- src/{classes => scenario}/town_import.tpp | 0 src/{classes => scenario}/vehicle.cpp | 0 src/{classes => scenario}/vehicle.hpp | 0 src/scenedit/scen.actions.cpp | 2 +- src/scenedit/scen.core.cpp | 5 +- src/scenedit/scen.fileio.cpp | 2 +- src/scenedit/scen.graphics.cpp | 5 +- src/scenedit/scen.graphics.hpp | 2 +- src/scenedit/scen.keydlgs.cpp | 6 +- src/scenedit/scen.keydlgs.hpp | 1 - src/scenedit/scen.main.cpp | 4 +- src/skills_traits.hpp | 63 + src/{tools/soundtool.cpp => sounds.cpp} | 4 +- src/{tools/soundtool.hpp => sounds.hpp} | 0 src/{classes => }/spell.cpp | 0 src/spell.hpp | 102 ++ src/tools/cursors.hpp | 9 +- src/tools/cursors.mac.mm | 8 +- src/tools/prefs.win.cpp | 1 - src/tools/winutil.hpp | 2 - src/{classes => universe}/creature.cpp | 0 src/{classes => universe}/creature.hpp | 1 - src/{classes => universe}/living.cpp | 0 src/{classes => universe}/living.hpp | 2 +- src/{classes => universe}/party.cpp | 0 src/{classes => universe}/party.hpp | 9 +- src/{classes => universe}/pc.cpp | 0 src/{classes => universe}/pc.hpp | 4 +- .../creatlist.cpp => universe/population.cpp} | 2 +- .../creatlist.hpp => universe/population.hpp} | 0 src/{classes => universe}/universe.cpp | 0 src/{classes => universe}/universe.hpp | 5 +- src/{tools => }/view_dialogs.cpp | 0 src/{tools => }/view_dialogs.hpp | 0 test/init.cpp | 2 +- test/item_legacy.cpp | 2 + test/scen_read.cpp | 2 +- test/scen_write.cpp | 2 +- test/spec_legacy.cpp | 9 +- test/ter_legacy.cpp | 1 + 211 files changed, 1855 insertions(+), 1881 deletions(-) create mode 100644 src/alchemy.hpp delete mode 100644 src/classes/monster.hpp delete mode 100644 src/classes/simpletypes.hpp delete mode 100644 src/classes/special.hpp delete mode 100644 src/classes/spell.hpp create mode 100644 src/damage.hpp rename src/dialogxml/{ => dialogs}/3choice.cpp (100%) rename src/dialogxml/{ => dialogs}/3choice.hpp (100%) rename src/dialogxml/{ => dialogs}/choicedlog.cpp (100%) rename src/dialogxml/{ => dialogs}/choicedlog.hpp (100%) rename src/dialogxml/{ => dialogs}/dialog.cpp (99%) rename src/dialogxml/{ => dialogs}/dialog.hpp (100%) rename src/dialogxml/{ => dialogs}/dialog.keys.hpp (100%) rename src/dialogxml/{ => dialogs}/dlogevt.hpp (100%) rename src/dialogxml/{ => dialogs}/pictchoice.cpp (100%) rename src/dialogxml/{ => dialogs}/pictchoice.hpp (100%) rename src/dialogxml/{ => dialogs}/strchoice.cpp (100%) rename src/dialogxml/{ => dialogs}/strchoice.hpp (100%) rename src/dialogxml/{ => dialogs}/strdlog.cpp (100%) rename src/dialogxml/{ => dialogs}/strdlog.hpp (98%) rename src/dialogxml/{ => widgets}/basicbtns.cpp (100%) rename src/dialogxml/{ => widgets}/button.cpp (99%) rename src/dialogxml/{ => widgets}/button.hpp (100%) rename src/dialogxml/{ => widgets}/control.cpp (99%) rename src/dialogxml/{ => widgets}/control.hpp (100%) rename src/dialogxml/{ => widgets}/field.cpp (100%) rename src/dialogxml/{ => widgets}/field.hpp (100%) rename src/dialogxml/{ => widgets}/message.cpp (100%) rename src/dialogxml/{ => widgets}/message.hpp (100%) rename src/dialogxml/{ => widgets}/pict.cpp (99%) rename src/dialogxml/{ => widgets}/pict.hpp (100%) rename src/dialogxml/{ => widgets}/pictypes.hpp (100%) rename src/dialogxml/{ => widgets}/scrollbar.cpp (99%) rename src/dialogxml/{ => widgets}/scrollbar.hpp (100%) rename src/dialogxml/{ => widgets}/scrollpane.cpp (100%) rename src/dialogxml/{ => widgets}/scrollpane.hpp (100%) rename src/dialogxml/{ => widgets}/stack.cpp (100%) rename src/dialogxml/{ => widgets}/stack.hpp (100%) create mode 100644 src/fields.hpp rename src/{classes => fileio}/estreams.cpp (96%) rename src/{tools => fileio}/fileio.cpp (93%) rename src/{tools => fileio}/fileio.hpp (97%) rename src/{tools => fileio}/fileio_party.cpp (100%) rename src/{tools => fileio}/fileio_scen.cpp (99%) rename src/{tools => fileio}/gzstream/COPYING.LIB (100%) rename src/{tools => fileio}/gzstream/Makefile (100%) rename src/{tools => fileio}/gzstream/README (100%) rename src/{tools => fileio}/gzstream/gzstream.cpp (100%) rename src/{tools => fileio}/gzstream/gzstream.h (100%) rename src/{tools => fileio}/gzstream/index.html (100%) rename src/{tools => fileio}/gzstream/test_gunzip.cpp (100%) rename src/{tools => fileio}/gzstream/test_gzip.cpp (100%) rename src/{tools => fileio}/gzstream/version (100%) rename src/{tools => fileio}/map_parse.cpp (100%) rename src/{tools => fileio}/map_parse.hpp (100%) rename src/{tools/resmgr/restypes.hpp => fileio/resmgr/res_cursor.hpp} (53%) create mode 100644 src/fileio/resmgr/res_font.hpp create mode 100644 src/fileio/resmgr/res_image.hpp create mode 100644 src/fileio/resmgr/res_sound.hpp create mode 100644 src/fileio/resmgr/res_strings.hpp rename src/{tools => fileio}/resmgr/resmgr.hpp (99%) rename src/{tools => fileio}/resmgr/restypes.cpp (78%) rename src/{tools/specials_parse.cpp => fileio/special_parse.cpp} (100%) rename src/{tools => fileio}/special_parse.hpp (100%) rename src/{tools => fileio}/tarball.cpp (100%) rename src/{tools => fileio}/tarball.hpp (100%) rename src/{dialogxml => fileio}/xml-parser/build_instructions.txt (100%) rename src/{dialogxml => fileio}/xml-parser/changes.txt (100%) rename src/{dialogxml => fileio}/xml-parser/dox (100%) rename src/{dialogxml => fileio}/xml-parser/readme.txt (100%) rename src/{dialogxml => fileio}/xml-parser/ticpp.cpp (100%) rename src/{dialogxml => fileio}/xml-parser/ticpp.h (100%) rename src/{dialogxml => fileio}/xml-parser/ticpp.lua (100%) rename src/{dialogxml => fileio}/xml-parser/ticppapi.h (100%) rename src/{dialogxml => fileio}/xml-parser/ticpprc.h (100%) rename src/{dialogxml => fileio}/xml-parser/tinyprint.cpp (100%) rename src/{dialogxml => fileio}/xml-parser/tinyprint.h (100%) rename src/{dialogxml => fileio}/xml-parser/tinystr.cpp (100%) rename src/{dialogxml => fileio}/xml-parser/tinystr.h (100%) rename src/{dialogxml => fileio}/xml-parser/tinyxml.cpp (100%) rename src/{dialogxml => fileio}/xml-parser/tinyxml.h (100%) rename src/{dialogxml => fileio}/xml-parser/tinyxmlerror.cpp (100%) rename src/{dialogxml => fileio}/xml-parser/tinyxmlparser.cpp (100%) rename src/{dialogxml => fileio}/xml-parser/tutorial_gettingStarted.txt (100%) rename src/{dialogxml => fileio}/xml-parser/tutorial_ticpp.txt (100%) rename src/{ => game}/boe.actions.cpp (99%) rename src/{ => game}/boe.actions.hpp (97%) rename src/{ => game}/boe.appleevents.mm (100%) rename src/{ => game}/boe.combat.cpp (99%) rename src/{ => game}/boe.combat.hpp (100%) rename src/{ => game}/boe.consts.hpp (100%) rename src/{ => game}/boe.dlgutil.cpp (99%) rename src/{ => game}/boe.dlgutil.hpp (97%) rename src/{ => game}/boe.fileio.cpp (98%) rename src/{ => game}/boe.fileio.hpp (87%) rename src/{ => game}/boe.global.hpp (100%) rename src/{ => game}/boe.graphics.cpp (99%) rename src/{ => game}/boe.graphics.hpp (98%) rename src/{ => game}/boe.graphutil.cpp (99%) rename src/{ => game}/boe.graphutil.hpp (97%) rename src/{ => game}/boe.infodlg.cpp (98%) rename src/{ => game}/boe.infodlg.hpp (98%) rename src/{ => game}/boe.items.cpp (99%) rename src/{ => game}/boe.items.hpp (98%) rename src/{ => game}/boe.locutils.cpp (100%) rename src/{ => game}/boe.locutils.hpp (100%) rename src/{ => game}/boe.main.cpp (98%) rename src/{ => game}/boe.main.hpp (100%) rename src/{ => game}/boe.menus.hpp (100%) rename src/{ => game}/boe.menus.mac.mm (100%) rename src/{ => game}/boe.menus.win.cpp (100%) rename src/{ => game}/boe.monster.cpp (99%) rename src/{ => game}/boe.monster.hpp (100%) rename src/{ => game}/boe.newgraph.cpp (99%) rename src/{ => game}/boe.newgraph.hpp (100%) rename src/{ => game}/boe.party.cpp (99%) rename src/{ => game}/boe.party.hpp (100%) rename src/{ => game}/boe.specials.cpp (99%) rename src/{ => game}/boe.specials.hpp (100%) rename src/{ => game}/boe.startup.cpp (97%) rename src/{ => game}/boe.text.cpp (99%) rename src/{ => game}/boe.text.hpp (98%) rename src/{ => game}/boe.town.cpp (99%) rename src/{ => game}/boe.town.hpp (100%) rename src/{ => game}/boe.townspec.cpp (99%) rename src/{ => game}/boe.townspec.hpp (100%) rename src/{tools => gfx}/graphtool.cpp (99%) rename src/{tools => gfx}/graphtool.hpp (99%) rename src/{tools => gfx}/mask.frag (100%) rename src/{tools => gfx}/mask.vert (100%) rename src/{tools => gfx}/qdpict.mac.cpp (99%) create mode 100644 src/global.hpp rename src/{classes => }/location.cpp (97%) rename src/{classes => }/location.hpp (94%) rename src/{tools => }/mathutil.cpp (100%) rename src/{tools => }/mathutil.hpp (95%) rename src/{tools => }/porting.cpp (100%) rename src/{tools => }/porting.hpp (100%) create mode 100644 src/race.hpp rename src/{classes => scenario}/area.hpp (100%) rename src/{classes => scenario}/item.cpp (99%) rename src/{classes => scenario}/item.hpp (94%) create mode 100644 src/scenario/item_abilities.hpp create mode 100644 src/scenario/item_variety.hpp rename src/{classes => scenario}/monster.cpp (100%) create mode 100644 src/scenario/monster.hpp create mode 100644 src/scenario/monster_abilities.hpp rename src/{classes => scenario}/outdoors.cpp (100%) rename src/{classes => scenario}/outdoors.hpp (98%) create mode 100644 src/scenario/quest.hpp rename src/{classes => scenario}/scenario.cpp (100%) rename src/{classes => scenario}/scenario.hpp (86%) rename src/{classes => scenario}/shop.cpp (100%) rename src/{classes => scenario}/shop.hpp (76%) rename src/{classes => scenario}/special.cpp (97%) create mode 100644 src/scenario/special.hpp rename src/{classes => scenario}/talking.cpp (100%) rename src/{classes => scenario}/talking.hpp (69%) rename src/{classes => scenario}/terrain.cpp (99%) rename src/{classes => scenario}/terrain.hpp (96%) create mode 100644 src/scenario/terrain_abilities.hpp rename src/{classes => scenario}/town.cpp (100%) rename src/{classes => scenario}/town.hpp (96%) rename src/{classes => scenario}/town_import.tpp (100%) rename src/{classes => scenario}/vehicle.cpp (100%) rename src/{classes => scenario}/vehicle.hpp (100%) create mode 100644 src/skills_traits.hpp rename src/{tools/soundtool.cpp => sounds.cpp} (97%) rename src/{tools/soundtool.hpp => sounds.hpp} (100%) rename src/{classes => }/spell.cpp (100%) create mode 100644 src/spell.hpp rename src/{classes => universe}/creature.cpp (100%) rename src/{classes => universe}/creature.hpp (98%) rename src/{classes => universe}/living.cpp (100%) rename src/{classes => universe}/living.hpp (98%) rename src/{classes => universe}/party.cpp (100%) rename src/{classes => universe}/party.hpp (98%) rename src/{classes => universe}/pc.cpp (100%) rename src/{classes => universe}/pc.hpp (98%) rename src/{classes/creatlist.cpp => universe/population.cpp} (98%) rename src/{classes/creatlist.hpp => universe/population.hpp} (100%) rename src/{classes => universe}/universe.cpp (100%) rename src/{classes => universe}/universe.hpp (98%) rename src/{tools => }/view_dialogs.cpp (100%) rename src/{tools => }/view_dialogs.hpp (100%) diff --git a/.gitignore b/.gitignore index 490a50b7..0b3c6f94 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,7 @@ pkg/win/data.nsi # Shader Builder projects # It's an sqlite3 database and not particularly important, so exclude it -src/tools/*.sbproj +*.sbproj # Doxygen stuff src/doxy/html/ diff --git a/src/BoE.xcodeproj/project.pbxproj b/src/BoE.xcodeproj/project.pbxproj index 5425b88a..3314034a 100755 --- a/src/BoE.xcodeproj/project.pbxproj +++ b/src/BoE.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 91EBE9DE0F9A33A6002356F2 /* PBXTargetDependency */, 91EBE9E00F9A33A8002356F2 /* PBXTargetDependency */, 91EBE9E20F9A33AC002356F2 /* PBXTargetDependency */, + 9185BDAA1EA06A150027C346 /* PBXTargetDependency */, ); name = All; productName = All; @@ -137,7 +138,7 @@ 919B13A21BBCDF14009905A4 /* monst_legacy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919B13A11BBCDE18009905A4 /* monst_legacy.cpp */; }; 919B13A41BBD8854009905A4 /* item_legacy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919B13A31BBD8849009905A4 /* item_legacy.cpp */; }; 919B13A61BBDE986009905A4 /* spec_legacy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919B13A51BBDE985009905A4 /* spec_legacy.cpp */; }; - 919CC2481B3772F300273FDA /* creatlist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC620A0FA2853700EEAE67 /* creatlist.cpp */; }; + 919CC2481B3772F300273FDA /* population.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC620A0FA2853700EEAE67 /* population.cpp */; }; 919CC2491B3772FB00273FDA /* creature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914698FE1A747C4500F20F5E /* creature.cpp */; }; 919CC24B1B37730300273FDA /* item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91279D3D0F9D1D6A007B0D52 /* item.cpp */; }; 919CC24C1B37730900273FDA /* living.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914698FB1A7362D900F20F5E /* living.cpp */; }; @@ -181,8 +182,8 @@ 919CC2781B37741A00273FDA /* porting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D005A0F9FEEC200184C18 /* porting.cpp */; }; 919CC2791B37742200273FDA /* prefs.mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91EC481018FBABB100BB1E86 /* prefs.mac.mm */; }; 919CC27A1B37742800273FDA /* qdpict.mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91F6F8F518F8DE6300E3EA15 /* qdpict.mac.cpp */; }; - 919CC27B1B37742D00273FDA /* soundtool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F10F0F9779D000BF5B67 /* soundtool.cpp */; }; - 919CC27C1B37743200273FDA /* specials_parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 915325181A2E37EE000A9A1C /* specials_parse.cpp */; }; + 919CC27B1B37742D00273FDA /* sounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F10F0F9779D000BF5B67 /* sounds.cpp */; }; + 919CC27C1B37743200273FDA /* special_parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 915325181A2E37EE000A9A1C /* special_parse.cpp */; }; 919CC27D1B37743700273FDA /* tarball.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3D81902AD78001686E4 /* tarball.cpp */; }; 919CC27E1B37743B00273FDA /* undo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 912283C80FD0E16C00B21642 /* undo.cpp */; }; 919CC27F1B37744000273FDA /* winutil.mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 919145FF18E63B70005CF3A4 /* winutil.mac.mm */; }; @@ -354,6 +355,13 @@ remoteGlobalIDString = 919CC22C1B37721400273FDA; remoteInfo = "Common-Party"; }; + 9185BDA91EA06A150027C346 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2BF04AA10BF51845006C0831 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 91CC172C1B421C0A003D9A69; + remoteInfo = boe_test; + }; 91BC33931B4390E40008882C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2BF04AA10BF51845006C0831 /* Project object */; @@ -563,7 +571,6 @@ 911F2DA41B98FF2300E3102E /* sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; path = sounds; sourceTree = ""; }; 911F2DA51B98FF2700E3102E /* fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = fonts; sourceTree = ""; }; 912283C80FD0E16C00B21642 /* undo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = undo.cpp; sourceTree = ""; }; - 912287850FD41A2300B21642 /* simpletypes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = simpletypes.hpp; sourceTree = ""; }; 91279BAD0F9CFCBA007B0D52 /* boescenario.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = boescenario.icns; path = ../rsrc/icons/mac/boescenario.icns; sourceTree = SOURCE_ROOT; }; 91279BB30F9D03B6007B0D52 /* boesave.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = boesave.icns; path = icons/mac/boesave.icns; sourceTree = ""; }; 91279BB40F9D03B7007B0D52 /* boesounds.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = boesounds.icns; path = icons/mac/boesounds.icns; sourceTree = ""; }; @@ -583,7 +590,7 @@ 91279D3C0F9D1D6A007B0D52 /* item.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = item.hpp; sourceTree = ""; }; 91279D3D0F9D1D6A007B0D52 /* item.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = item.cpp; sourceTree = ""; }; 912DFE8918E24B4C00B00D75 /* resmgr.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = resmgr.hpp; sourceTree = ""; }; - 912DFE8A18E24B4C00B00D75 /* restypes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = restypes.hpp; sourceTree = ""; }; + 912DFE8A18E24B4C00B00D75 /* res_image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = res_image.hpp; sourceTree = ""; }; 912DFE8E18E2872300B00D75 /* boe.menus.mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = boe.menus.mac.mm; sourceTree = ""; }; 913D00590F9FEEC200184C18 /* porting.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = porting.hpp; sourceTree = ""; }; 913D005A0F9FEEC200184C18 /* porting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = porting.cpp; sourceTree = ""; }; @@ -604,8 +611,8 @@ 914CA45719074D0A00B6ADD1 /* scen.menus.mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = scen.menus.mac.mm; sourceTree = ""; }; 914CA4641909B00100B6ADD1 /* scen.menus.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = scen.menus.hpp; sourceTree = ""; }; 914CA49F190C4E9200B6ADD1 /* scenedit.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = scenedit.xib; path = menus/scenedit.xib; sourceTree = ""; }; - 915325161A2E1DA8000A9A1C /* oldstructs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = oldstructs.cpp; path = ../oldstructs.cpp; sourceTree = ""; }; - 915325181A2E37EE000A9A1C /* specials_parse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = specials_parse.cpp; sourceTree = ""; }; + 915325161A2E1DA8000A9A1C /* oldstructs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = oldstructs.cpp; sourceTree = ""; }; + 915325181A2E37EE000A9A1C /* special_parse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = special_parse.cpp; sourceTree = ""; }; 91597A6C1A3BED2D00BE7BF9 /* spell.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = spell.hpp; sourceTree = ""; }; 91597A6E1A3BEDC700BE7BF9 /* spell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spell.cpp; sourceTree = ""; }; 915AF9E91BC04171008AEF49 /* dlogevt.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = dlogevt.hpp; sourceTree = ""; }; @@ -627,6 +634,21 @@ 9179A4631A4867E200FEF872 /* stack.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = stack.hpp; sourceTree = ""; }; 9179A4641A48681800FEF872 /* stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stack.cpp; sourceTree = ""; }; 917B573F100B956C0096C978 /* undo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = undo.hpp; sourceTree = ""; }; + 9185BD951EA020B70027C346 /* monster_abilities.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = monster_abilities.hpp; sourceTree = ""; }; + 9185BD961EA0234A0027C346 /* damage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = damage.hpp; sourceTree = ""; }; + 9185BD971EA025720027C346 /* race.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = race.hpp; sourceTree = ""; }; + 9185BD991EA027B80027C346 /* fields.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = fields.hpp; sourceTree = ""; }; + 9185BD9A1EA02B840027C346 /* skills_traits.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = skills_traits.hpp; sourceTree = ""; }; + 9185BD9B1EA02B8F0027C346 /* alchemy.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = alchemy.hpp; sourceTree = ""; }; + 9185BD9C1EA02BA20027C346 /* terrain_abilities.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = terrain_abilities.hpp; sourceTree = ""; }; + 9185BD9D1EA02C320027C346 /* item_abilities.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = item_abilities.hpp; sourceTree = ""; }; + 9185BD9E1EA02C3D0027C346 /* item_variety.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = item_variety.hpp; sourceTree = ""; }; + 9185BD9F1EA02E5C0027C346 /* quest.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = quest.hpp; sourceTree = ""; }; + 9185BDA01EA02FF80027C346 /* global.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = global.hpp; sourceTree = ""; }; + 9185BDA51EA055180027C346 /* res_cursor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = res_cursor.hpp; sourceTree = ""; }; + 9185BDA61EA055180027C346 /* res_font.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = res_font.hpp; sourceTree = ""; }; + 9185BDA71EA055180027C346 /* res_sound.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = res_sound.hpp; sourceTree = ""; }; + 9185BDA81EA055180027C346 /* res_strings.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = res_strings.hpp; sourceTree = ""; }; 918D59A718EA513900735B66 /* dialog.keys.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = dialog.keys.hpp; sourceTree = ""; }; 919086DF1A65C8E30071F7A0 /* tinyprint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyprint.cpp; sourceTree = ""; }; 919086E11A65D3250071F7A0 /* tinyprint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyprint.h; sourceTree = ""; }; @@ -652,8 +674,8 @@ 91AC607F0FA26A3B00EEAE67 /* town_import.tpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = town_import.tpp; sourceTree = ""; }; 91AC61C40FA2729900EEAE67 /* universe.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = universe.hpp; sourceTree = ""; }; 91AC61C50FA2729900EEAE67 /* universe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = universe.cpp; sourceTree = ""; }; - 91AC62090FA2853700EEAE67 /* creatlist.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = creatlist.hpp; sourceTree = ""; }; - 91AC620A0FA2853700EEAE67 /* creatlist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = creatlist.cpp; sourceTree = ""; }; + 91AC62090FA2853700EEAE67 /* population.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = population.hpp; sourceTree = ""; }; + 91AC620A0FA2853700EEAE67 /* population.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = population.cpp; sourceTree = ""; }; 91ACCE82190032E000FAEF8B /* fix_dylibs.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = fix_dylibs.sh; sourceTree = ""; }; 91B0D5CB1E33E579002BE4DA /* bladbase */ = {isa = PBXFileReference; lastKnownFileType = folder; name = bladbase; path = ../bases/bladbase; sourceTree = ""; }; 91B0D5CC1E3408AB002BE4DA /* busywork */ = {isa = PBXFileReference; lastKnownFileType = folder; path = busywork; sourceTree = ""; }; @@ -694,8 +716,8 @@ 91B3EF130F969BD300BF5B67 /* BoECharEd-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "BoECharEd-Info.plist"; path = "pcedit/BoECharEd-Info.plist"; sourceTree = SOURCE_ROOT; }; 91B3F1090F9779C300BF5B67 /* graphtool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = graphtool.hpp; sourceTree = ""; }; 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphtool.cpp; sourceTree = ""; }; - 91B3F10E0F9779D000BF5B67 /* soundtool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = soundtool.hpp; sourceTree = ""; }; - 91B3F10F0F9779D000BF5B67 /* soundtool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = soundtool.cpp; sourceTree = ""; }; + 91B3F10E0F9779D000BF5B67 /* sounds.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = sounds.hpp; sourceTree = ""; }; + 91B3F10F0F9779D000BF5B67 /* sounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sounds.cpp; sourceTree = ""; }; 91B3F11D0F97801F00BF5B67 /* mathutil.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = mathutil.hpp; sourceTree = ""; }; 91B3F11E0F97801F00BF5B67 /* mathutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mathutil.cpp; sourceTree = ""; }; 91BC33971B439BEA0008882C /* files */ = {isa = PBXFileReference; lastKnownFileType = folder; path = files; sourceTree = ""; }; @@ -740,7 +762,7 @@ 91E381451B97671E00F69B81 /* town_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = town_write.cpp; sourceTree = ""; }; 91E381471B97675900F69B81 /* talk_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = talk_write.cpp; sourceTree = ""; }; 91E381491B97678D00F69B81 /* out_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = out_write.cpp; sourceTree = ""; }; - 91E5C5A10F9EACE200C21460 /* oldstructs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = oldstructs.hpp; path = ../oldstructs.hpp; sourceTree = ""; }; + 91E5C5A10F9EACE200C21460 /* oldstructs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = oldstructs.hpp; sourceTree = ""; }; 91E5C7970F9F60EC00C21460 /* town.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = town.hpp; sourceTree = ""; }; 91E5C7980F9F60EC00C21460 /* town.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = town.cpp; sourceTree = ""; }; 91E5C79C0F9F60FA00C21460 /* outdoors.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = outdoors.hpp; sourceTree = ""; }; @@ -891,9 +913,8 @@ 2BF04A9F0BF51845006C0831 = { isa = PBXGroup; children = ( - 91279BAB0F9CFB18007B0D52 /* classes */, - 91B3F0FF0F97797200BF5B67 /* tools */, - 91B3EF380F969E4A00BF5B67 /* osx */, + 91279BAB0F9CFB18007B0D52 /* common */, + 91B3EF380F969E4A00BF5B67 /* Game */, 91B3EEF90F969BBD00BF5B67 /* CharEd */, 91B3EECD0F969B7000BF5B67 /* ScenEd */, 91CC17281B421BD5003D9A69 /* test */, @@ -906,57 +927,56 @@ 910BBA130FB8BE66001E34EA /* dialogxml */ = { isa = PBXGroup; children = ( - 910BBA190FB8C43E001E34EA /* xml-parser */, - 910BBA140FB8BE7D001E34EA /* headers */, - 910BBA150FB8BE88001E34EA /* src */, + 910BBA140FB8BE7D001E34EA /* widgets */, + 910BBA150FB8BE88001E34EA /* dialogs */, ); path = dialogxml; sourceTree = SOURCE_ROOT; }; - 910BBA140FB8BE7D001E34EA /* headers */ = { + 910BBA140FB8BE7D001E34EA /* widgets */ = { isa = PBXGroup; children = ( - 91E128F21BC2077600C8BE1D /* 3choice.hpp */, + 91A32BD10FDB797B00C4E957 /* basicbtns.cpp */, + 910BBA890FB8EC57001E34EA /* button.cpp */, + 910BBA3C0FB8DA8E001E34EA /* control.cpp */, + 910BBAB50FB91A26001E34EA /* field.cpp */, + 910BBAB90FB91ADB001E34EA /* message.cpp */, + 910BBAA90FB8F733001E34EA /* pict.cpp */, + 9191460018E63D8E005CF3A4 /* scrollbar.cpp */, + 919B13A81BBE2B54009905A4 /* scrollpane.cpp */, + 9179A4641A48681800FEF872 /* stack.cpp */, 910BBA880FB8EC57001E34EA /* button.hpp */, - 91E128F31BC2077700C8BE1D /* choicedlog.hpp */, 910BBA3B0FB8DA8E001E34EA /* control.hpp */, - 910BBA170FB8BECA001E34EA /* dialog.hpp */, - 918D59A718EA513900735B66 /* dialog.keys.hpp */, - 915AF9E91BC04171008AEF49 /* dlogevt.hpp */, 910BBAB40FB91A26001E34EA /* field.hpp */, 910BBAB80FB91ADB001E34EA /* message.hpp */, 910BBAA80FB8F733001E34EA /* pict.hpp */, - 91E128F41BC2077700C8BE1D /* pictchoice.hpp */, 913FB40A1A5C90840067B9D2 /* pictypes.hpp */, 919145FD18E3C750005CF3A4 /* scrollbar.hpp */, 919B13A71BBE297B009905A4 /* scrollpane.hpp */, 9179A4631A4867E200FEF872 /* stack.hpp */, - 91E128F51BC2077700C8BE1D /* strchoice.hpp */, - 91E128F61BC2077700C8BE1D /* strdlog.hpp */, ); - name = headers; + path = widgets; sourceTree = ""; }; - 910BBA150FB8BE88001E34EA /* src */ = { + 910BBA150FB8BE88001E34EA /* dialogs */ = { isa = PBXGroup; children = ( 91E128E81BC2076B00C8BE1D /* 3choice.cpp */, - 91A32BD10FDB797B00C4E957 /* basicbtns.cpp */, - 910BBA890FB8EC57001E34EA /* button.cpp */, 91E128E91BC2076B00C8BE1D /* choicedlog.cpp */, - 910BBA3C0FB8DA8E001E34EA /* control.cpp */, 910BBA180FB8BECA001E34EA /* dialog.cpp */, - 910BBAB50FB91A26001E34EA /* field.cpp */, - 910BBAB90FB91ADB001E34EA /* message.cpp */, - 910BBAA90FB8F733001E34EA /* pict.cpp */, 91E128EA1BC2076B00C8BE1D /* pictchoice.cpp */, - 9191460018E63D8E005CF3A4 /* scrollbar.cpp */, - 919B13A81BBE2B54009905A4 /* scrollpane.cpp */, - 9179A4641A48681800FEF872 /* stack.cpp */, 91E128EB1BC2076B00C8BE1D /* strchoice.cpp */, 91E128EC1BC2076B00C8BE1D /* strdlog.cpp */, + 91E128F21BC2077600C8BE1D /* 3choice.hpp */, + 91E128F31BC2077700C8BE1D /* choicedlog.hpp */, + 910BBA170FB8BECA001E34EA /* dialog.hpp */, + 918D59A718EA513900735B66 /* dialog.keys.hpp */, + 915AF9E91BC04171008AEF49 /* dlogevt.hpp */, + 91E128F41BC2077700C8BE1D /* pictchoice.hpp */, + 91E128F51BC2077700C8BE1D /* strchoice.hpp */, + 91E128F61BC2077700C8BE1D /* strdlog.hpp */, ); - name = src; + path = dialogs; sourceTree = ""; }; 910BBA190FB8C43E001E34EA /* xml-parser */ = { @@ -990,128 +1010,34 @@ name = Products; sourceTree = BUILT_PRODUCTS_DIR; }; - 91279BAB0F9CFB18007B0D52 /* classes */ = { + 91279BAB0F9CFB18007B0D52 /* common */ = { isa = PBXGroup; children = ( - 913D03330FA0FFE800184C18 /* headers */, - 913D03320FA0FFE700184C18 /* src */, - 91E5C5A10F9EACE200C21460 /* oldstructs.hpp */, - 915325161A2E1DA8000A9A1C /* oldstructs.cpp */, + 910BBA130FB8BE66001E34EA /* dialogxml */, + 9185BDA31EA044790027C346 /* fileio */, + 9185BDA21EA042BE0027C346 /* gfx */, + 9185BDA41EA053E00027C346 /* misc */, + 9185BD941EA01BCC0027C346 /* scenario */, + 9185BDA11EA041570027C346 /* tools */, + 9185BD931EA01BB50027C346 /* universe */, ); - path = classes; + name = common; sourceTree = ""; }; 912DFE8718E24B0B00B00D75 /* resmgr */ = { isa = PBXGroup; children = ( - 912DFE8918E24B4C00B00D75 /* resmgr.hpp */, 91960ED31BB613E5008AF8F4 /* restypes.cpp */, - 912DFE8A18E24B4C00B00D75 /* restypes.hpp */, + 9185BDA51EA055180027C346 /* res_cursor.hpp */, + 9185BDA61EA055180027C346 /* res_font.hpp */, + 912DFE8A18E24B4C00B00D75 /* res_image.hpp */, + 9185BDA71EA055180027C346 /* res_sound.hpp */, + 9185BDA81EA055180027C346 /* res_strings.hpp */, + 912DFE8918E24B4C00B00D75 /* resmgr.hpp */, ); path = resmgr; sourceTree = ""; }; - 913D03320FA0FFE700184C18 /* src */ = { - isa = PBXGroup; - children = ( - 91AC620A0FA2853700EEAE67 /* creatlist.cpp */, - 914698FE1A747C4500F20F5E /* creature.cpp */, - 91E1862B1B2B2AC0006A99EA /* estreams.cpp */, - 91279D3D0F9D1D6A007B0D52 /* item.cpp */, - 914698FB1A7362D900F20F5E /* living.cpp */, - 91279BE10F9D0F73007B0D52 /* location.cpp */, - 91279CC10F9D19DA007B0D52 /* monster.cpp */, - 91E5C79D0F9F60FA00C21460 /* outdoors.cpp */, - 913D05B50FA1E9E300184C18 /* party.cpp */, - 913D05BB0FA1EA0A00184C18 /* pc.cpp */, - 91279C580F9D1253007B0D52 /* scenario.cpp */, - 91FDB5791A4E774E00DE5983 /* shop.cpp */, - 91279CC60F9D1A02007B0D52 /* special.cpp */, - 91597A6E1A3BEDC700BE7BF9 /* spell.cpp */, - 91E5C7B70F9F619D00C21460 /* talking.cpp */, - 91279C660F9D12D6007B0D52 /* terrain.cpp */, - 91E5C7980F9F60EC00C21460 /* town.cpp */, - 91AC607F0FA26A3B00EEAE67 /* town_import.tpp */, - 91AC61C50FA2729900EEAE67 /* universe.cpp */, - 91279C750F9D15E5007B0D52 /* vehicle.cpp */, - ); - name = src; - sourceTree = ""; - }; - 913D03330FA0FFE800184C18 /* headers */ = { - isa = PBXGroup; - children = ( - 91AC607E0FA26A3B00EEAE67 /* area.hpp */, - 91AC62090FA2853700EEAE67 /* creatlist.hpp */, - 914698FD1A747BED00F20F5E /* creature.hpp */, - 91279D3C0F9D1D6A007B0D52 /* item.hpp */, - 914698FA1A7362C200F20F5E /* living.hpp */, - 91279BE00F9D0F73007B0D52 /* location.hpp */, - 91279CC00F9D19DA007B0D52 /* monster.hpp */, - 91E5C79C0F9F60FA00C21460 /* outdoors.hpp */, - 913D05B40FA1E9E200184C18 /* party.hpp */, - 913D05BA0FA1EA0A00184C18 /* pc.hpp */, - 91279C570F9D1253007B0D52 /* scenario.hpp */, - 91FDB5771A4E71A900DE5983 /* shop.hpp */, - 912287850FD41A2300B21642 /* simpletypes.hpp */, - 91279CC50F9D1A02007B0D52 /* special.hpp */, - 91597A6C1A3BED2D00BE7BF9 /* spell.hpp */, - 91E5C7B60F9F619D00C21460 /* talking.hpp */, - 91279C650F9D12D6007B0D52 /* terrain.hpp */, - 91E5C7970F9F60EC00C21460 /* town.hpp */, - 91AC61C40FA2729900EEAE67 /* universe.hpp */, - 91279C740F9D15E4007B0D52 /* vehicle.hpp */, - ); - name = headers; - sourceTree = ""; - }; - 913D03340FA0FFFF00184C18 /* src */ = { - isa = PBXGroup; - children = ( - 91C688E70FD702B9000F6D01 /* cursors.mac.mm */, - 91E30F2D1A7481C20057C54A /* fileio.cpp */, - 91E30F2A1A74819B0057C54A /* fileio_party.cpp */, - 91E5C7A60F9F615400C21460 /* fileio_scen.cpp */, - 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */, - 915E09081A316D89008BDF00 /* map_parse.cpp */, - 91A0B15A1900F73E00EF438F /* mask.frag */, - 91BFA3D61901B024001686E4 /* mask.vert */, - 91B3F11E0F97801F00BF5B67 /* mathutil.cpp */, - 913D005A0F9FEEC200184C18 /* porting.cpp */, - 91EC481018FBABB100BB1E86 /* prefs.mac.mm */, - 91F6F8F518F8DE6300E3EA15 /* qdpict.mac.cpp */, - 91B3F10F0F9779D000BF5B67 /* soundtool.cpp */, - 915325181A2E37EE000A9A1C /* specials_parse.cpp */, - 91BFA3D81902AD78001686E4 /* tarball.cpp */, - 912283C80FD0E16C00B21642 /* undo.cpp */, - 91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */, - 919145FF18E63B70005CF3A4 /* winutil.mac.mm */, - ); - name = src; - sourceTree = ""; - }; - 913D03350FA1000200184C18 /* headers */ = { - isa = PBXGroup; - children = ( - 91C688E60FD702B9000F6D01 /* cursors.hpp */, - 91E5C7A50F9F615400C21460 /* fileio.hpp */, - 91C2A6E21B8244F700346948 /* gitrev.hpp */, - 91B3F1090F9779C300BF5B67 /* graphtool.hpp */, - 915E09071A316D6A008BDF00 /* map_parse.hpp */, - 91B3F11D0F97801F00BF5B67 /* mathutil.hpp */, - 913D00590F9FEEC200184C18 /* porting.hpp */, - 91EC480E18FBAA8700BB1E86 /* prefs.hpp */, - 91B3F10E0F9779D000BF5B67 /* soundtool.hpp */, - 91F06E8F1A2EBEE70038E902 /* special_parse.hpp */, - 91BFA3D91902ADD5001686E4 /* tarball.hpp */, - 917B573F100B956C0096C978 /* undo.hpp */, - 9179A4621A47D4E200FEF872 /* vector2d.hpp */, - 91B0D5D31E3446CF002BE4DA /* view_dialogs.hpp */, - 919145FE18E63B41005CF3A4 /* winutil.hpp */, - ); - name = headers; - sourceTree = ""; - }; 914B2AA018E7E4A3007B6799 /* Linked Frameworks */ = { isa = PBXGroup; children = ( @@ -1137,6 +1063,137 @@ name = "Linked Frameworks"; sourceTree = ""; }; + 9185BD931EA01BB50027C346 /* universe */ = { + isa = PBXGroup; + children = ( + 914698FE1A747C4500F20F5E /* creature.cpp */, + 914698FB1A7362D900F20F5E /* living.cpp */, + 913D05B50FA1E9E300184C18 /* party.cpp */, + 913D05BB0FA1EA0A00184C18 /* pc.cpp */, + 91AC620A0FA2853700EEAE67 /* population.cpp */, + 91AC61C50FA2729900EEAE67 /* universe.cpp */, + 914698FD1A747BED00F20F5E /* creature.hpp */, + 914698FA1A7362C200F20F5E /* living.hpp */, + 913D05B40FA1E9E200184C18 /* party.hpp */, + 913D05BA0FA1EA0A00184C18 /* pc.hpp */, + 91AC62090FA2853700EEAE67 /* population.hpp */, + 91AC61C40FA2729900EEAE67 /* universe.hpp */, + ); + path = universe; + sourceTree = ""; + }; + 9185BD941EA01BCC0027C346 /* scenario */ = { + isa = PBXGroup; + children = ( + 91279D3D0F9D1D6A007B0D52 /* item.cpp */, + 91279CC10F9D19DA007B0D52 /* monster.cpp */, + 91E5C79D0F9F60FA00C21460 /* outdoors.cpp */, + 91279C580F9D1253007B0D52 /* scenario.cpp */, + 91FDB5791A4E774E00DE5983 /* shop.cpp */, + 91279CC60F9D1A02007B0D52 /* special.cpp */, + 91E5C7B70F9F619D00C21460 /* talking.cpp */, + 91279C660F9D12D6007B0D52 /* terrain.cpp */, + 91E5C7980F9F60EC00C21460 /* town.cpp */, + 91279C750F9D15E5007B0D52 /* vehicle.cpp */, + 91AC607E0FA26A3B00EEAE67 /* area.hpp */, + 91279D3C0F9D1D6A007B0D52 /* item.hpp */, + 9185BD9D1EA02C320027C346 /* item_abilities.hpp */, + 9185BD9E1EA02C3D0027C346 /* item_variety.hpp */, + 91279CC00F9D19DA007B0D52 /* monster.hpp */, + 9185BD951EA020B70027C346 /* monster_abilities.hpp */, + 91E5C79C0F9F60FA00C21460 /* outdoors.hpp */, + 9185BD9F1EA02E5C0027C346 /* quest.hpp */, + 91279C570F9D1253007B0D52 /* scenario.hpp */, + 91FDB5771A4E71A900DE5983 /* shop.hpp */, + 91279CC50F9D1A02007B0D52 /* special.hpp */, + 91E5C7B60F9F619D00C21460 /* talking.hpp */, + 91279C650F9D12D6007B0D52 /* terrain.hpp */, + 9185BD9C1EA02BA20027C346 /* terrain_abilities.hpp */, + 91E5C7970F9F60EC00C21460 /* town.hpp */, + 91AC607F0FA26A3B00EEAE67 /* town_import.tpp */, + 91279C740F9D15E4007B0D52 /* vehicle.hpp */, + ); + path = scenario; + sourceTree = ""; + }; + 9185BDA11EA041570027C346 /* tools */ = { + isa = PBXGroup; + children = ( + 91C688E70FD702B9000F6D01 /* cursors.mac.mm */, + 91EC481018FBABB100BB1E86 /* prefs.mac.mm */, + 912283C80FD0E16C00B21642 /* undo.cpp */, + 919145FF18E63B70005CF3A4 /* winutil.mac.mm */, + 91C688E60FD702B9000F6D01 /* cursors.hpp */, + 91C2A6E21B8244F700346948 /* gitrev.hpp */, + 91EC480E18FBAA8700BB1E86 /* prefs.hpp */, + 917B573F100B956C0096C978 /* undo.hpp */, + 9179A4621A47D4E200FEF872 /* vector2d.hpp */, + 919145FE18E63B41005CF3A4 /* winutil.hpp */, + 91C2A6E11B823CCD00346948 /* gitrev.sh */, + ); + path = tools; + sourceTree = ""; + }; + 9185BDA21EA042BE0027C346 /* gfx */ = { + isa = PBXGroup; + children = ( + 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */, + 91F6F8F518F8DE6300E3EA15 /* qdpict.mac.cpp */, + 91B3F1090F9779C300BF5B67 /* graphtool.hpp */, + 91A0B15A1900F73E00EF438F /* mask.frag */, + 91BFA3D61901B024001686E4 /* mask.vert */, + ); + path = gfx; + sourceTree = ""; + }; + 9185BDA31EA044790027C346 /* fileio */ = { + isa = PBXGroup; + children = ( + 91E1862B1B2B2AC0006A99EA /* estreams.cpp */, + 91E30F2D1A7481C20057C54A /* fileio.cpp */, + 91E30F2A1A74819B0057C54A /* fileio_party.cpp */, + 91E5C7A60F9F615400C21460 /* fileio_scen.cpp */, + 915E09081A316D89008BDF00 /* map_parse.cpp */, + 915325181A2E37EE000A9A1C /* special_parse.cpp */, + 91BFA3D81902AD78001686E4 /* tarball.cpp */, + 91E5C7A50F9F615400C21460 /* fileio.hpp */, + 915E09071A316D6A008BDF00 /* map_parse.hpp */, + 91F06E8F1A2EBEE70038E902 /* special_parse.hpp */, + 91BFA3D91902ADD5001686E4 /* tarball.hpp */, + 91BFA3DC19033E00001686E4 /* gzstream */, + 912DFE8718E24B0B00B00D75 /* resmgr */, + 910BBA190FB8C43E001E34EA /* xml-parser */, + ); + path = fileio; + sourceTree = ""; + }; + 9185BDA41EA053E00027C346 /* misc */ = { + isa = PBXGroup; + children = ( + 91279BE10F9D0F73007B0D52 /* location.cpp */, + 91B3F11E0F97801F00BF5B67 /* mathutil.cpp */, + 915325161A2E1DA8000A9A1C /* oldstructs.cpp */, + 913D005A0F9FEEC200184C18 /* porting.cpp */, + 91B3F10F0F9779D000BF5B67 /* sounds.cpp */, + 91597A6E1A3BEDC700BE7BF9 /* spell.cpp */, + 91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */, + 9185BD9B1EA02B8F0027C346 /* alchemy.hpp */, + 9185BD961EA0234A0027C346 /* damage.hpp */, + 9185BD991EA027B80027C346 /* fields.hpp */, + 9185BDA01EA02FF80027C346 /* global.hpp */, + 91279BE00F9D0F73007B0D52 /* location.hpp */, + 91B3F11D0F97801F00BF5B67 /* mathutil.hpp */, + 91E5C5A10F9EACE200C21460 /* oldstructs.hpp */, + 913D00590F9FEEC200184C18 /* porting.hpp */, + 9185BD971EA025720027C346 /* race.hpp */, + 9185BD9A1EA02B840027C346 /* skills_traits.hpp */, + 91B3F10E0F9779D000BF5B67 /* sounds.hpp */, + 91597A6C1A3BED2D00BE7BF9 /* spell.hpp */, + 91B0D5D31E3446CF002BE4DA /* view_dialogs.hpp */, + ); + name = misc; + sourceTree = ""; + }; 91B3EECD0F969B7000BF5B67 /* ScenEd */ = { isa = PBXGroup; children = ( @@ -1258,27 +1315,15 @@ path = ../rsrc; sourceTree = SOURCE_ROOT; }; - 91B3EF380F969E4A00BF5B67 /* osx */ = { + 91B3EF380F969E4A00BF5B67 /* Game */ = { isa = PBXGroup; children = ( 91D62F2C0F8EB7AB00674AB3 /* src */, 91D62F2D0F8EB7BA00674AB3 /* headers */, 91D62F2E0F8EB80200674AB3 /* rsrc */, ); - name = osx; - sourceTree = ""; - }; - 91B3F0FF0F97797200BF5B67 /* tools */ = { - isa = PBXGroup; - children = ( - 91C2A6E11B823CCD00346948 /* gitrev.sh */, - 91BFA3DC19033E00001686E4 /* gzstream */, - 912DFE8718E24B0B00B00D75 /* resmgr */, - 910BBA130FB8BE66001E34EA /* dialogxml */, - 913D03350FA1000200184C18 /* headers */, - 913D03340FA0FFFF00184C18 /* src */, - ); - path = tools; + name = Game; + path = game; sourceTree = ""; }; 91BFA3DC19033E00001686E4 /* gzstream */ = { @@ -1765,7 +1810,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 919CC2481B3772F300273FDA /* creatlist.cpp in Sources */, + 919CC2481B3772F300273FDA /* population.cpp in Sources */, 919CC2491B3772FB00273FDA /* creature.cpp in Sources */, 919CC24C1B37730900273FDA /* living.cpp in Sources */, 919CC2501B37731D00273FDA /* party.cpp in Sources */, @@ -1817,8 +1862,8 @@ 919CC2781B37741A00273FDA /* porting.cpp in Sources */, 919CC2791B37742200273FDA /* prefs.mac.mm in Sources */, 919CC27A1B37742800273FDA /* qdpict.mac.cpp in Sources */, - 919CC27B1B37742D00273FDA /* soundtool.cpp in Sources */, - 919CC27C1B37743200273FDA /* specials_parse.cpp in Sources */, + 919CC27B1B37742D00273FDA /* sounds.cpp in Sources */, + 919CC27C1B37743200273FDA /* special_parse.cpp in Sources */, 919CC27D1B37743700273FDA /* tarball.cpp in Sources */, 919CC27E1B37743B00273FDA /* undo.cpp in Sources */, 919CC27F1B37744000273FDA /* winutil.mac.mm in Sources */, @@ -1944,6 +1989,11 @@ target = 919CC22C1B37721400273FDA /* Common-Party */; targetProxy = 9169C3081B379E8B0041002B /* PBXContainerItemProxy */; }; + 9185BDAA1EA06A150027C346 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 91CC172C1B421C0A003D9A69 /* boe_test */; + targetProxy = 9185BDA91EA06A150027C346 /* PBXContainerItemProxy */; + }; 91BC33941B4390E40008882C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 919CC23A1B3772B700273FDA /* Common */; @@ -1987,6 +2037,7 @@ GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_INPUT_FILETYPE = automatic; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREFIX_HEADER = global.hpp; GCC_PREPROCESSOR_DEFINITIONS = TIXML_USE_TICPP; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -2049,6 +2100,7 @@ GCC_ENABLE_PASCAL_STRINGS = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_INPUT_FILETYPE = automatic; + GCC_PREFIX_HEADER = global.hpp; GCC_PREPROCESSOR_DEFINITIONS = TIXML_USE_TICPP; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; @@ -2108,8 +2160,6 @@ "-lboost_system", "-lboost_filesystem", "$(OTHER_LDFLAGS_QUOTED_FOR_PROJECT_1)", - "-lCommon", - "-lCommon-Party", ); PRODUCT_NAME = "Blades of Exile"; WRAPPER_EXTENSION = app; @@ -2132,8 +2182,6 @@ "-lboost_system", "-lboost_filesystem", "$(OTHER_LDFLAGS_QUOTED_FOR_PROJECT_1)", - "-lCommon", - "-lCommon-Party", ); PRODUCT_NAME = "Blades of Exile"; WRAPPER_EXTENSION = app; @@ -2217,8 +2265,6 @@ "-lboost_system", "-lboost_filesystem", "$(OTHER_LDFLAGS_QUOTED_FOR_PROJECT_1)", - "-lCommon-Party", - "-lCommon", ); OTHER_LDFLAGS_QUOTED_FOR_TARGET_1 = "-L\"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/\""; PRODUCT_NAME = "BoE Character Editor"; @@ -2242,8 +2288,6 @@ "-lboost_system", "-lboost_filesystem", "$(OTHER_LDFLAGS_QUOTED_FOR_PROJECT_1)", - "-lCommon-Party", - "-lCommon", ); OTHER_LDFLAGS_QUOTED_FOR_TARGET_1 = "-L\"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/\""; PRODUCT_NAME = "BoE Character Editor"; @@ -2311,8 +2355,6 @@ "-lboost_system", "-lboost_filesystem", "$(OTHER_LDFLAGS_QUOTED_FOR_PROJECT_1)", - "-lCommon", - "-lCommon-Party", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/src/alchemy.hpp b/src/alchemy.hpp new file mode 100644 index 00000000..dd324482 --- /dev/null +++ b/src/alchemy.hpp @@ -0,0 +1,36 @@ +// +// alchemy.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_ALCHEMY_HPP +#define BoE_ALCHEMY_HPP + +enum class eAlchemy { + NONE = -1, + CURE_WEAK = 0, + HEAL_WEAK = 1, + POISON_WEAK = 2, + SPEED_WEAK = 3, + POISON_MED = 4, + HEAL_MED = 5, + CURE_STRONG = 6, + SPEED_MED = 7, + GRAYMOLD = 8, + POWER_WEAK = 9, + CLARITY = 10, + POISON_STRONG = 11, + HEAL_STRONG = 12, + POISON_KILL = 13, + RESURRECT = 14, + POWER_MED = 15, + KNOWLEDGE = 16, + STRENGTH = 17, + BLISS = 18, + POWER_STRONG = 19, +}; + +#endif diff --git a/src/classes/monster.hpp b/src/classes/monster.hpp deleted file mode 100644 index 6d8e82c2..00000000 --- a/src/classes/monster.hpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * monster.h - * BoE - * - * Created by Celtic Minstrel on 20/04/09. - * - */ - -#ifndef BOE_DATA_MONSTER_H -#define BOE_DATA_MONSTER_H - -#include -#include -#include -#include - -#include "soundtool.hpp" -#include "simpletypes.hpp" -#include "graphtool.hpp" -#include "living.hpp" -#include "spell.hpp" - -namespace legacy { - struct monster_record_type; - struct creature_data_type; - struct creature_start_type; -}; - -class cScenario; -class cUniverse; - -enum class eMonstAbilTemplate { - // Non-magical missiles - THROWS_DARTS, SHOOTS_ARROWS, THROWS_SPEARS, THROWS_ROCKS1, THROWS_ROCKS2, THROWS_ROCKS3, - THROWS_RAZORDISKS, THROWS_KNIVES, GOOD_ARCHER, SHOOTS_SPINES, CROSSBOWMAN, SLINGER, - // Magical missiles - RAY_PETRIFY, RAY_SP_DRAIN, RAY_HEAT, RAY_PARALYSIS, - BREATH_FIRE, BREATH_FROST, BREATH_ELECTRICITY, BREATH_DARKNESS, BREATH_FOUL, BREATH_SLEEP, - SPIT_ACID, SHOOTS_WEB, - // Touch abilities - TOUCH_POISON, TOUCH_ACID, TOUCH_DISEASE, TOUCH_WEB, TOUCH_SLEEP, TOUCH_DUMB, TOUCH_PARALYSIS, - TOUCH_PETRIFY, TOUCH_DEATH, TOUCH_XP_DRAIN, TOUCH_ICY, TOUCH_ICY_DRAINING, TOUCH_STUN, TOUCH_STEAL_FOOD, TOUCH_STEAL_GOLD, - // Misc abilities - SPLITS, MARTYRS_SHIELD, ABSORB_SPELLS, SUMMON_5, SUMMON_20, SUMMON_50, SPECIAL, HIT_TRIGGERS, DEATH_TRIGGERS, - // Radiate abilities - RADIATE_FIRE, RADIATE_ICE, RADIATE_SHOCK, RADIATE_ANTIMAGIC, RADIATE_SLEEP, RADIATE_STINK, RADIATE_BLADE, RADIATE_WEB, - // Advanced abilities - CUSTOM_MISSILE, CUSTOM_DAMAGE, CUSTOM_STATUS, CUSTOM_FIELD, CUSTOM_PETRIFY, CUSTOM_SP_DRAIN, CUSTOM_XP_DRAIN, - CUSTOM_KILL, CUSTOM_STEAL_FOOD, CUSTOM_STEAL_GOLD, CUSTOM_STUN, CUSTOM_STATUS2, CUSTOM_RADIATE, CUSTOM_SUMMON, - CUSTOM_DAMAGE2, -}; - -union uAbility { - bool active; - struct { - bool active; - eMonstMissile type; - miss_num_t pic; - int dice, sides, skill, range, odds; - } missile; - struct { - bool active; - eMonstGen type; - miss_num_t pic; - int strength, range, odds; - union { - eDamageType dmg; - eStatus stat; - eFieldType fld; - }; - } gen; - struct { - bool active; - eMonstSummon type; - mon_num_t what; - int min, max, len, chance; - } summon; - struct { - bool active; - eFieldType type; - int chance; - eSpellPat pat; - } radiate; - struct { - bool active; - int extra1, extra2, extra3; - } special; - std::string to_string(eMonstAbil myKey) const; - int get_ap_cost(eMonstAbil key) const; -}; - -class cMonster { -public: - struct cAttack{ - unsigned short dice = 0, sides = 0; - eMonstMelee type = eMonstMelee::SWING; - }; - unsigned int level; - std::string m_name; - short m_health; - unsigned int armor; - unsigned int skill; - std::array a; - eRace m_type; - unsigned int speed; - unsigned int mu; - unsigned int cl; - unsigned int treasure; - // HACK: This is only really marked mutable so that I can use operator[] from const methods - mutable std::map abil; - item_num_t corpse_item; - short corpse_item_chance; - std::map resist; - bool mindless, invuln, invisible, guard, amorphous; - unsigned int x_width,y_width; - eAttitude default_attitude; - unsigned int summon_type; - pic_num_t default_facial_pic; - pic_num_t picture_num; - snd_num_t ambient_sound; // has a chance of being played every move - spec_num_t see_spec; - - std::map::iterator addAbil(eMonstAbilTemplate what, int param = 0); - int addAttack(unsigned short dice, unsigned short sides, eMonstMelee type = eMonstMelee::SWING); - - void import_legacy(legacy::monster_record_type& old); - cMonster(); - void writeTo(std::ostream& file) const; - void readFrom(std::istream& file); -}; - -class cTownperson { -public: - mon_num_t number; - eAttitude start_attitude; - location start_loc; - unsigned short mobility; - eMonstTime time_flag; - short spec1, spec2; - short spec_enc_code, time_code; - short monster_time, personality; - short special_on_kill, special_on_talk; - pic_num_t facial_pic; - - void import_legacy(legacy::creature_start_type old); - cTownperson(); - cTownperson(location loc, mon_num_t num, const cMonster& monst); -}; - -std::ostream& operator << (std::ostream& out, eStatus e); -std::istream& operator >> (std::istream& in, eStatus& e); -std::ostream& operator << (std::ostream& out, eRace e); -std::istream& operator >> (std::istream& in, eRace& e); -std::ostream& operator << (std::ostream& out, eMonstAbil e); -std::istream& operator >> (std::istream& in, eMonstAbil& e); -std::ostream& operator << (std::ostream& out, eMonstMissile e); -std::istream& operator >> (std::istream& in, eMonstMissile& e); -std::ostream& operator << (std::ostream& out, eMonstSummon e); -std::istream& operator >> (std::istream& in, eMonstSummon& e); -std::ostream& operator << (std::ostream& out, eMonstMelee e); -std::istream& operator >> (std::istream& in, eMonstMelee& e); -std::ostream& operator << (std::ostream& out, eMonstGen e); -std::istream& operator >> (std::istream& in, eMonstGen& e); -std::ostream& operator << (std::ostream& out, eDirection e); -std::istream& operator >> (std::istream& in, eDirection& e); -std::ostream& operator << (std::ostream& out, eDamageType e); -std::istream& operator >> (std::istream& in, eDamageType& e); -std::ostream& operator << (std::ostream& out, eFieldType e); -std::istream& operator >> (std::istream& in, eFieldType& e); -std::ostream& operator << (std::ostream& out, eMonstTime e); -std::istream& operator >> (std::istream& in, eMonstTime& e); -std::ostream& operator<< (std::ostream& out, eAttitude node); -std::istream& operator>> (std::istream& in, eAttitude& node); -std::ostream& operator<<(std::ostream& out, const cMonster::cAttack& att); -std::ostream& operator<< (std::ostream& out, eSpellPat pat); -std::istream& operator>> (std::istream& in, eSpellPat& pat); - -#endif diff --git a/src/classes/simpletypes.hpp b/src/classes/simpletypes.hpp deleted file mode 100644 index c4e82cbf..00000000 --- a/src/classes/simpletypes.hpp +++ /dev/null @@ -1,1133 +0,0 @@ -/* - * simpletypes.h - * BoE - * - * Created by Celtic Minstrel on 01/06/09. - * - */ - -#ifndef BOE_DATA_SIMPLETYPES_H -#define BOE_DATA_SIMPLETYPES_H - -typedef unsigned short mon_num_t; -typedef signed short miss_num_t; -typedef unsigned short ter_num_t; -typedef signed short spec_num_t; -typedef signed short item_num_t; -typedef unsigned short str_num_t; - -// OBoE Current Version -const unsigned long long OBOE_CURRENT_VERSION = 0x020000; // MMmmff; M - major, m - minor, f - bugfix -std::string oboeVersionString(); - -// MARK: Directions! -enum eDirection { - DIR_N = 0, - DIR_NE = 1, - DIR_E = 2, - DIR_SE = 3, - DIR_S = 4, - DIR_SW = 5, - DIR_W = 6, - DIR_NW = 7, - DIR_HERE = 8, -}; - -inline eDirection& operator++ (eDirection& me, int) { - if(me == DIR_HERE) return me = DIR_N; - else return me = (eDirection)(1 + (int)me); -} - -enum eContentRating {G, PG, R, NC17}; - -enum class eQuestStatus {AVAILABLE, STARTED, COMPLETED, FAILED}; - -enum class eMainStatus { - ABSENT = 0, // absent, empty slot - ALIVE = 1, - DEAD = 2, - DUST = 3, - STONE = 4, - FLED = 5, - SURFACE = 6, // fled to surface? - WON = 7, - SPLIT = 10, - SPLIT_ABSENT = SPLIT + ABSENT, - SPLIT_ALIVE = SPLIT + ALIVE, - SPLIT_DEAD = SPLIT + DEAD, - SPLIT_DUST = SPLIT + DUST, - SPLIT_STONE = SPLIT + STONE, - SPLIT_FLED = SPLIT + FLED, - SPLIT_SURFACE = SPLIT + SURFACE, - SPLIT_WON = SPLIT + WON, -}; - -inline eMainStatus exceptSplit(eMainStatus stat) { - if(int(stat) >= 10) - return (eMainStatus) (-10 + (int)stat); - return stat; -} - -inline bool isSplit(eMainStatus stat) { - return int(stat) >= 10; -} - -inline bool isAbsent(eMainStatus stat) { - return stat == eMainStatus::ABSENT || int(stat) > 4; -} - -inline bool isDead(eMainStatus stat) { - int code = (int) stat; - return code > 1 && code < 5; -} - -/* adven[i].race */ //complete -enum class eRace { - UNKNOWN = -1, // for parameters to some functions; not valid in the class - HUMAN = 0, - NEPHIL = 1, - SLITH = 2, - VAHNATAI = 3, // Former value from eMonsterType - REPTILE = 4, // 1 - BEAST = 5, // 2 - IMPORTANT = 6, // 3 - MAGE = 7, // 4 - PRIEST = 8, // 5 - HUMANOID = 9, // 6 - DEMON = 10, // 7 - UNDEAD = 11, // 8 - GIANT = 12, // 9 - SLIME = 13, // 10 - STONE = 14, // 11 - BUG = 15, // 12 - DRAGON = 16, // 13 - MAGICAL = 17, // 14 - PLANT = 18, - BIRD = 19, - SKELETAL = 20, - GOBLIN = 21, -}; - -// Types IMPORTANT, MAGE, and PRIEST are implicitly human -inline bool isHuman(eRace race) { - int code = (int) race; - return code == 0 || (code >= 6 && code <= 8); -} - -// Types NEPHIL, SLITH, and VAHNATAI are implicitly humanoid -inline bool isHumanoid(eRace race) { - int code = (int) race; - return (code >= 0 && code <= 3) || (code >= 6 && code <= 9) || code == 21; -} - -/* adven[i].status*/ //complete - assign a positive value for a help pc effect, a negative for harm pc -enum class eStatus { - MAIN = -1, // For saved games only - POISONED_WEAPON = 0, - BLESS_CURSE = 1, - POISON = 2, - HASTE_SLOW = 3, - INVULNERABLE = 4, - MAGIC_RESISTANCE = 5, - WEBS = 6, - DISEASE = 7, - INVISIBLE = 8, //sanctuary - DUMB = 9, - MARTYRS_SHIELD = 10, - ASLEEP = 11, - PARALYZED = 12, - ACID = 13, - FORCECAGE = 14, - // This one is new - // It's not quite a real status effect since it doesn't expire - CHARM = 15, -}; - -inline bool isStatusNegative(eStatus stat) { - switch(stat) { - case eStatus::MAIN: return false; - case eStatus::POISONED_WEAPON: return false; - case eStatus::BLESS_CURSE: return false; - case eStatus::POISON: return true; - case eStatus::HASTE_SLOW: return false; - case eStatus::INVULNERABLE: return false; - case eStatus::MAGIC_RESISTANCE: return false; - case eStatus::WEBS: return true; - case eStatus::DISEASE: return true; - case eStatus::INVISIBLE: return false; - case eStatus::DUMB: return true; - case eStatus::MARTYRS_SHIELD: return false; - case eStatus::ASLEEP: return true; - case eStatus::PARALYZED: return true; - case eStatus::ACID: return true; - case eStatus::FORCECAGE: return true; - case eStatus::CHARM: return true; - } - return false; -} - -enum class ePartyStatus { - STEALTH, - FLIGHT, - DETECT_LIFE, - FIREWALK, -}; - -enum class eAttitude { - DOCILE, HOSTILE_A, FRIENDLY, HOSTILE_B -}; - -enum class eMonstAbil { - NO_ABIL, - MISSILE, - - DAMAGE, - STATUS, - FIELD, - PETRIFY, - DRAIN_SP, - DRAIN_XP, - KILL, - STEAL_FOOD, - STEAL_GOLD, - STUN, - DAMAGE2, - STATUS2, - - SPLITS, - MARTYRS_SHIELD, - ABSORB_SPELLS, - MISSILE_WEB, - RAY_HEAT, - SPECIAL, - HIT_TRIGGER, - DEATH_TRIGGER, - - RADIATE, - SUMMON, -}; - -enum class eMonstMelee {SWING, CLAW, BITE, SLIME, PUNCH, STING, CLUB, BURN, HARM, STAB}; - -enum class eMonstMissile {DART, ARROW, SPEAR, ROCK, RAZORDISK, SPINE, KNIFE, BOLT, BOULDER, RAPID_ARROW}; - -enum class eMonstGen {RAY, TOUCH, GAZE, BREATH, SPIT}; - -enum class eMonstSummon {TYPE, LEVEL, SPECIES}; - -enum class eMonstAbilCat { - INVALID, MISSILE, GENERAL, SUMMON, RADIATE, SPECIAL -}; - -inline eMonstAbilCat getMonstAbilCategory(eMonstAbil what) { - if(what == eMonstAbil::NO_ABIL) - return eMonstAbilCat::SPECIAL; - if(what == eMonstAbil::MISSILE) - return eMonstAbilCat::MISSILE; - if(what >= eMonstAbil::DAMAGE && what <= eMonstAbil::STATUS2) - return eMonstAbilCat::GENERAL; - if(what >= eMonstAbil::SPLITS && what <= eMonstAbil::DEATH_TRIGGER) - return eMonstAbilCat::SPECIAL; - if(what == eMonstAbil::RADIATE) - return eMonstAbilCat::RADIATE; - if(what == eMonstAbil::SUMMON) - return eMonstAbilCat::SUMMON; - return eMonstAbilCat::INVALID; -} - -enum class eMonstTime { - ALWAYS, - APPEAR_ON_DAY, DISAPPEAR_ON_DAY, - SOMETIMES_C, SOMETIMES_A, SOMETIMES_B, - APPEAR_WHEN_EVENT, DISAPPEAR_WHEN_EVENT, - APPEAR_AFTER_CHOP, -}; - -/* Terrains Special Properties : scenario.ter_types[i].special */ //complete - -enum class eTerSpec { - NONE = 0, - CHANGE_WHEN_STEP_ON = 1, - DAMAGING = 2, // formerly "fire damage" - BRIDGE = 3, // new; formerly "cold damage" - BED = 4, // new; formerly "magic damage" - DANGEROUS = 5, // formerly "poison land" - UNUSED1 = 6, // formerly "disease land" - CRUMBLING = 7, - LOCKABLE = 8, - UNLOCKABLE = 9, - UNUSED2 = 10, // formerly "unlockable + bashable" - IS_A_SIGN = 11, - CALL_SPECIAL = 12, // formerly "call local special" - UNUSED3 = 13, // formerly "call scenario special" - IS_A_CONTAINER = 14, - WILDERNESS_CAVE = 15, - WILDERNESS_SURFACE = 16, // formerly "conveyor north" - WATERFALL_CAVE = 17, // formerly "conveyor east" - WATERFALL_SURFACE = 18, // formerly "conveyor south" - CONVEYOR = 19, // formerly "conveyor west" - BLOCKED_TO_MONSTERS = 20, - TOWN_ENTRANCE = 21, - CHANGE_WHEN_USED = 22, - CALL_SPECIAL_WHEN_USED = 23, - // 1. Change when step on (What to change to, number of sound, Unused) - // 2. Damaging terrain; can't rest here (Amount of damage done, multiplier, damage type) - // 3. Bridge - if the party boats over it, they get the option to land. (Unused, Unused, Unused) - // 4. Bed - change party graphic when they stand on this space - // 5. Dangerous land; can't rest here; percentage chance may be 0 (Strength, Percentage chance, status type) - // 6. Reserved - // 7. Crumbling terrain (Terrain to change to, strength?, destroyed by what - quickfire, shatter/move mountains, or both) - // 8. Lockable terrain (Terrain to change to when locked, Unused, Unused) - // 9. Unlockable terrain (Terrain to change to when locked, Difficulty, can be bashed) - // 10. Reserved - // 11. Sign (Unused, Unused, Unused) - // 12. Call special (Special to call, local or scenario?, Unused) - // 13. Reserved - // 14. Container (Unused, Unused, Unused) - // 15. Waterfall (Direction, Unused, Unused) - // 16. Conveyor Belt (Direction, Unused, Unused) - // 17. Reserved - // 18. Reserved - // 19. Reserved - // 20. Blocked to Monsters (Unused, Unused, Unused) - // 21. Town entrance (Terrain type if hidden, Unused, Unused) - // 22. Change when Used (Terrain to change to when used, Number of sound, Unused) - // 23. Call special when used (Special to call, local or scenario?, Unused) -}; - -enum class eTrimType { - NONE = 0, - WALL = 1, // not a trim, but trims will conform to it as if it's the same ground type (eg stone wall) - S, SE, E, NE, N, NW, W, SW, - NE_INNER, SE_INNER, SW_INNER, NW_INNER, - FRILLS = 14, // like on lava and underground water; no trim_ter required - WALKWAY = 16, // the game will draw walkway corners; trim_ter is base terrain to draw on - WATERFALL = 17, // special case for waterfalls - CITY = 18, // the game will join roads up to this space but not draw roads on the space -}; - -enum class eTerObstruct { - CLEAR = 0, - BLOCK_SIGHT = 1, - BLOCK_MONSTERS = 2, - BLOCK_MOVE = 3, - BLOCK_MOVE_AND_SHOOT = 4, - BLOCK_MOVE_AND_SIGHT = 5, -}; - -inline bool blocksMove(eTerObstruct block) { - int code = (int) block; - return code > 2; -} - -enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH}; - -/* items[i].variety a.k.a item type (in editor) */ -enum class eItemType { - NO_ITEM = 0, - ONE_HANDED = 1, - TWO_HANDED = 2, - GOLD = 3, - BOW = 4, - ARROW = 5, - THROWN_MISSILE = 6, - POTION = 7, // potion/magic item - SCROLL = 8, // scroll/magic item - WAND = 9, - TOOL = 10, - FOOD = 11, - SHIELD = 12, - ARMOR = 13, - HELM = 14, - GLOVES = 15, - SHIELD_2 = 16, - // don't know why a second type of shield is used ; it is actually checked - // in the armor code -- see below - // and you can't equip another (12) shield while wearing it ... I didn't - // find a single item with this property in the bladbase.exs ... - BOOTS = 17, - RING = 18, - NECKLACE = 19, - WEAPON_POISON = 20, - NON_USE_OBJECT = 21, - PANTS = 22, - CROSSBOW = 23, - BOLTS = 24, - MISSILE_NO_AMMO = 25, //e.g slings - SPECIAL = 26, - QUEST = 27, -}; - -inline bool isArmourType(eItemType type) { - int code = (int) type; - return code >= 12 && code <= 17; -} - -inline bool isWeaponType(eItemType type) { - int code = (int) type; - return (code >= 1 && code <= 6 && code != 3) || (code >= 23 && code <= 25); -} - -inline bool isMissileType(eItemType type) { - return type == eItemType::ARROW || type == eItemType::BOLTS || type == eItemType::THROWN_MISSILE || type == eItemType::MISSILE_NO_AMMO; -} - -enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL}; - -enum class eEnchant {PLUS_ONE, PLUS_TWO, PLUS_THREE, SHOOT_FLAME, FLAMING, PLUS_FIVE, BLESSED}; - -/* items[i].ability */ -enum class eItemAbil { - // Weapon abilities - NONE = 0, - DAMAGING_WEAPON = 1, - SLAYER_WEAPON = 2, - HEALING_WEAPON = 3, - EXPLODING_WEAPON = 4, - RETURNING_MISSILE = 5, - DISTANCE_MISSILE = 6, - SEEKING_MISSILE = 7, - ANTIMAGIC_WEAPON = 8, - STATUS_WEAPON = 9, - SOULSUCKER = 10, - UNUSED = 11, - WEAK_WEAPON = 12, - CAUSES_FEAR = 13, - WEAPON_CALL_SPECIAL = 14, - HP_DAMAGE = 15, - HP_DAMAGE_REVERSE = 16, - SP_DAMAGE = 17, - SP_DAMAGE_REVERSE = 18, - // General abilities - DAMAGE_PROTECTION = 30, - FULL_PROTECTION = 31, - MAGERY = 32, - EVASION = 33, - MARTYRS_SHIELD = 34, - ENCUMBERING = 35, - STATUS_PROTECTION = 36, - SKILL = 37, - BOOST_STAT = 38, - BOOST_WAR = 39, - BOOST_MAGIC = 40, - ACCURACY = 41, - THIEVING = 42, - GIANT_STRENGTH = 43, - LIGHTER_OBJECT = 44, - HEAVIER_OBJECT = 45, - OCCASIONAL_STATUS = 46, - HIT_CALL_SPECIAL = 47, - LIFE_SAVING = 48, - PROTECT_FROM_PETRIFY = 49, - REGENERATE = 50, - POISON_AUGMENT = 51, - RADIANT = 52, - WILL = 53, - FREE_ACTION = 54, - SPEED = 55, - SLOW_WEARER = 56, - PROTECT_FROM_SPECIES = 57, - LOCKPICKS = 58, - DRAIN_MISSILES = 59, - DROP_CALL_SPECIAL = 60, - // Usable - POISON_WEAPON = 70, - AFFECT_STATUS = 71, - CAST_SPELL = 72, - BLISS_DOOM = 73, - AFFECT_EXPERIENCE = 74, - AFFECT_SKILL_POINTS = 75, - AFFECT_HEALTH = 76, - AFFECT_SPELL_POINTS = 77, - LIGHT = 78, - AFFECT_PARTY_STATUS = 79, - HEALTH_POISON = 80, - CALL_SPECIAL = 81, - SUMMONING = 82, - MASS_SUMMONING = 83, - QUICKFIRE = 84, - MESSAGE = 85, - // Reagents - HOLLY = 150, // Holly/Toadstool - COMFREY = 151, // Comfrey Root - NETTLE = 152, // Glowing Nettle - WORMGRASS = 153, // Crypt Shroom/Wormgrass - ASPTONGUE = 154, // Asptongue Mold - EMBERF = 155, // Ember Flower - GRAYMOLD = 156, - MANDRAKE = 157, - SAPPHIRE = 158, - SMOKY_CRYSTAL = 159, - RESURRECTION_BALM = 160, -}; - -enum class eItemAbilCat { - INVALID = -1, - WEAPON, GENERAL, USABLE, REAGENT -}; - -inline eItemAbilCat getItemAbilCategory(eItemAbil abil) { - int code = (int) abil; - if(code >= 0 && code <= 13) - return eItemAbilCat::WEAPON; - if(code >= 30 && code <= 57) - return eItemAbilCat::GENERAL; - if(code >= 70 && code <= 129) - return eItemAbilCat::USABLE; - if(code >= 150 && code <= 161) - return eItemAbilCat::REAGENT; - return eItemAbilCat::INVALID; -} - -/* adven[i].skills */ //complete -enum class eSkill { - INVALID = -1, - STRENGTH = 0, - DEXTERITY = 1, - INTELLIGENCE = 2, - EDGED_WEAPONS = 3, - BASHING_WEAPONS = 4, - POLE_WEAPONS = 5, - THROWN_MISSILES = 6, - ARCHERY = 7, - DEFENSE = 8, - MAGE_SPELLS = 9, - PRIEST_SPELLS = 10, - MAGE_LORE = 11, - ALCHEMY = 12, - ITEM_LORE = 13, - DISARM_TRAPS = 14, - LOCKPICKING = 15, - ASSASSINATION = 16, - POISON = 17, - LUCK = 18, - MAX_HP = 19, - MAX_SP = 20, - // Magic values; only for check_party_stat() - CUR_HP = 100, - CUR_SP = 101, - CUR_XP = 102, - CUR_SKILL = 103, - CUR_LEVEL = 104, -}; - -/* adven[i].traits */ //complete -enum class eTrait { - TOUGHNESS = 0, - MAGICALLY_APT = 1, - AMBIDEXTROUS = 2, - NIMBLE = 3, - CAVE_LORE = 4, - WOODSMAN = 5, - GOOD_CONST = 6, - HIGHLY_ALERT = 7, - STRENGTH = 8, - RECUPERATION = 9, - SLUGGISH = 10, - MAGICALLY_INEPT = 11, - FRAIL = 12, - CHRONIC_DISEASE = 13, - BAD_BACK = 14, - PACIFIST = 15, - ANAMA = 16, -}; - - -/* damage type*/ -/* used as parameter to some functions */ -enum class eDamageType { - WEAPON = 0, - FIRE = 1, - POISON = 2, - MAGIC = 3, - UNBLOCKABLE = 4, - COLD = 5, - UNDEAD = 6, - DEMON = 7, - // Keep these two last - SPECIAL = 8, // Completely unblockable damage from assassination skill - MARKED = 10, -}; - -enum class eSpecCtx { - OUT_MOVE = 0, - TOWN_MOVE = 1, - COMBAT_MOVE = 2, - OUT_LOOK = 3, - TOWN_LOOK = 4, - ENTER_TOWN = 5, - LEAVE_TOWN = 6, - TALK = 7, // Special called during conversation - USE_SPEC_ITEM = 8, - TOWN_TIMER = 9, - SCEN_TIMER = 10, - PARTY_TIMER = 11, - KILL_MONST = 12, - OUTDOOR_ENC = 13, - FLEE_ENCOUNTER = 14, - WIN_ENCOUNTER = 15, - TARGET = 16, - USE_SPACE = 17, - SEE_MONST = 18, - MONST_SPEC_ABIL = 19, - TOWN_HOSTILE = 20, - ATTACKING_MELEE = 21, - ATTACKING_RANGE = 22, - ATTACKED_MELEE = 23, - ATTACKED_RANGE = 24, - HAIL = 25, // Special called by trying to initiate conversation - SHOPPING = 26, - DROP_ITEM = 27, - STARTUP = 28, -}; - -enum class eSpecType { - INVALID = -1, // A magic value used while processing nodes - NONE = 0, - SET_SDF = 1, - INC_SDF = 2, - DISPLAY_MSG = 3, - ENTER_SHOP = 4, - DISPLAY_SM_MSG = 5, - FLIP_SDF = 6, - SDF_RANDOM = 7, - SDF_ADD = 8, - SDF_DIFF = 9, - STORY_DIALOG = 10, - CANT_ENTER = 11, - CHANGE_TIME = 12, - SCEN_TIMER_START = 13, - PLAY_SOUND = 14, - CHANGE_HORSE_OWNER = 15, - CHANGE_BOAT_OWNER = 16, - SET_TOWN_VISIBILITY = 17, - MAJOR_EVENT_OCCURRED = 18, - FORCED_GIVE = 19, - BUY_ITEMS_OF_TYPE = 20, - CALL_GLOBAL = 21, - SET_SDF_ROW = 22, - COPY_SDF = 23, - DISPLAY_PICTURE = 24, - REST = 25, - TITLED_MSG = 26, - END_SCENARIO = 27, // add "win/lose" option - SET_POINTER = 28, - SET_CAMP_FLAG = 29, - PRINT_NUMS = 30, // For debugging - SDF_TIMES = 31, - SDF_DIVIDE = 32, // Computes both quotient and remainder - SDF_POWER = 33, - CHANGE_TER = 34, - SWAP_TER = 35, - TRANS_TER = 36, - CLEAR_BUF = 37, - APPEND_STRING = 38, - APPEND_NUM = 39, - APPEND_MONST = 40, - APPEND_ITEM = 41, - APPEND_TER = 42, - PAUSE = 43, - START_TALK = 44, - UPDATE_QUEST = 45, - SWAP_STR_BUF = 46, - STR_BUF_TO_SIGN = 47, - ONCE_GIVE_ITEM = 50, - ONCE_GIVE_SPEC_ITEM = 51, - ONCE_NULL = 52, - ONCE_SET_SDF = 53, - ONCE_DISPLAY_MSG = 54, - ONCE_DIALOG = 55, - UNUSED13 = 56, - UNUSED14 = 57, - ONCE_GIVE_ITEM_DIALOG = 58, - UNUSED15 = 59, - UNUSED16 = 60, - ONCE_OUT_ENCOUNTER = 61, - ONCE_TOWN_ENCOUNTER = 62, - ONCE_TRAP = 63, - SELECT_TARGET = 80, - DAMAGE = 81, - AFFECT_HP = 82, - AFFECT_SP = 83, - AFFECT_XP = 84, - AFFECT_SKILL_PTS = 85, - AFFECT_DEADNESS = 86, - AFFECT_STATUS = 87, - AFFECT_TRAITS = 88, - AFFECT_AP = 89, - AFFECT_NAME = 90, - AFFECT_LEVEL = 91, - AFFECT_MORALE = 92, - AFFECT_SOUL_CRYSTAL = 93, - GIVE_ITEM = 94, - AFFECT_MONST_TARG = 95, - AFFECT_MONST_ATT = 96, - AFFECT_MONST_STAT = 97, - AFFECT_STAT = 98, - AFFECT_MAGE_SPELL = 99, - AFFECT_PRIEST_SPELL = 100, - AFFECT_GOLD = 101, - AFFECT_FOOD = 102, - AFFECT_ALCHEMY = 103, - AFFECT_PARTY_STATUS = 104, - CREATE_NEW_PC = 105, - STORE_PC = 106, - UNSTORE_PC = 107, - IF_SDF = 130, - IF_TOWN_NUM = 131, - IF_RANDOM = 132, - IF_HAVE_SPECIAL_ITEM = 133, - IF_SDF_COMPARE = 134, - IF_TER_TYPE = 135, - IF_ALIVE = 136, - IF_HAS_GOLD = 137, - IF_HAS_FOOD = 138, - IF_ITEM_CLASS_ON_SPACE = 139, - IF_HAVE_ITEM_CLASS = 140, - IF_EQUIP_ITEM_CLASS = 141, - IF_MAGE_SPELL = 142, - IF_PRIEST_SPELL = 143, - IF_RECIPE = 144, - IF_STATUS = 145, - IF_LOOKING = 146, - IF_DAY_REACHED = 147, - IF_FIELDS = 148, - IF_PARTY_SIZE = 149, - IF_EVENT_OCCURRED = 150, - IF_SPECIES = 151, - IF_TRAIT = 152, - IF_STATISTIC = 153, - IF_TEXT_RESPONSE = 154, - IF_SDF_EQ = 155, - IF_CONTEXT = 156, - IF_NUM_RESPONSE = 157, - IF_IN_BOAT = 158, - IF_ON_HORSE = 159, - IF_QUEST = 160, - MAKE_TOWN_HOSTILE = 170, - TOWN_RUN_MISSILE = 171, - TOWN_MONST_ATTACK = 172, - TOWN_BOOM_SPACE = 173, - TOWN_MOVE_PARTY = 174, - TOWN_HIT_SPACE = 175, - TOWN_EXPLODE_SPACE = 176, - TOWN_LOCK_SPACE = 177, - TOWN_UNLOCK_SPACE = 178, - TOWN_SFX_BURST = 179, - TOWN_CREATE_WANDERING = 180, - TOWN_PLACE_MONST = 181, - TOWN_DESTROY_MONST = 182, - TOWN_NUKE_MONSTS = 183, - TOWN_GENERIC_LEVER = 184, - TOWN_GENERIC_PORTAL = 185, - TOWN_GENERIC_BUTTON = 186, - TOWN_GENERIC_STAIR = 187, - TOWN_LEVER = 188, - TOWN_PORTAL = 189, - TOWN_STAIR = 190, - TOWN_RELOCATE = 191, // Relocate outdoors - TOWN_PLACE_ITEM = 192, - TOWN_SPLIT_PARTY = 193, - TOWN_REUNITE_PARTY = 194, - TOWN_TIMER_START = 195, - TOWN_CHANGE_LIGHTING = 196, - TOWN_SET_ATTITUDE = 197, - TOWN_SET_CENTER = 198, - TOWN_LIFT_FOG = 199, - TOWN_START_TARGETING = 200, - TOWN_SPELL_PAT_FIELD = 201, - TOWN_SPELL_PAT_BOOM = 202, - TOWN_RELOCATE_CREATURE = 203, - TOWN_PLACE_LABEL = 204, - RECT_PLACE_FIELD = 210, - RECT_SET_EXPLORED = 211, - RECT_MOVE_ITEMS = 212, - RECT_DESTROY_ITEMS = 213, - RECT_CHANGE_TER = 214, - RECT_SWAP_TER = 215, - RECT_TRANS_TER = 216, - RECT_LOCK = 217, - RECT_UNLOCK = 218, - OUT_MAKE_WANDER = 225, - OUT_FORCE_TOWN = 226, - OUT_PLACE_ENCOUNTER = 227, - OUT_MOVE_PARTY = 228, // allow change sector -}; - -enum class eSpecCat { - INVALID = -1, - GENERAL, ONCE, AFFECT, IF_THEN, TOWN, RECT, OUTDOOR -}; - -inline eSpecCat getNodeCategory(eSpecType node) { - int code = (int) node; - if(code >= 0 && code <= 47) - return eSpecCat::GENERAL; - if(code >= 50 && code <= 63) - return eSpecCat::ONCE; - if(code >= 80 && code <= 107) - return eSpecCat::AFFECT; - if(code >= 130 && code <= 160) - return eSpecCat::IF_THEN; - if(code >= 170 && code <= 204) - return eSpecCat::TOWN; - if(code >= 210 && code <= 218) - return eSpecCat::RECT; - if(code >= 225 && code <= 228) - return eSpecCat::OUTDOOR; - return eSpecCat::INVALID; -} - -enum class eTalkNode { - REGULAR = 0, - DEP_ON_SDF = 1, - SET_SDF = 2, - INN = 3, - DEP_ON_TIME = 4, - DEP_ON_TIME_AND_EVENT = 5, - DEP_ON_TOWN = 6, - SHOP = 7, - TRAINING = 8, - JOB_BANK = 9, - SELL_WEAPONS = 13, - SELL_ARMOR = 14, - SELL_ITEMS = 15, - IDENTIFY = 16, - ENCHANT = 17, - BUY_INFO = 18, - BUY_SDF = 19, - BUY_SHIP = 20, - BUY_HORSE = 21, - BUY_SPEC_ITEM = 22, - RECEIVE_QUEST = 23, - BUY_TOWN_LOC = 24, - END_FORCE = 25, - END_FIGHT = 26, - END_ALARM = 27, // Town hostile - END_DIE = 28, - CALL_TOWN_SPEC = 29, - CALL_SCEN_SPEC = 30, -}; - -enum class eShopType {NORMAL, ALLOW_DEAD, RANDOM}; - -enum class eShopPrompt {SHOPPING, HEALING, MAGE, PRIEST, SPELLS, ALCHEMY, TRAINING}; - -enum class eShopItemType { - EMPTY, - // These ones must have these numbers in order for old scenarios to be ported correctly - ITEM = 1, - MAGE_SPELL = 2, - PRIEST_SPELL = 3, - ALCHEMY = 4, - SKILL, - TREASURE, - CLASS, - OPT_ITEM, - CALL_SPECIAL, - // All non-healing types must be above here and all healing types below, with HEAL_WOUNDS kept first - HEAL_WOUNDS, - CURE_POISON, - CURE_DISEASE, - CURE_ACID, - CURE_PARALYSIS, - REMOVE_CURSE, - DESTONE, - RAISE_DEAD, - RESURRECT, - CURE_DUMBFOUNDING, -}; - -// MARK: eEncNoteType -enum eEncNoteType { - NOTE_SCEN, - NOTE_OUT, - NOTE_TOWN, -}; - -// MARK: eFieldType -// This is a slight misnomer, as a couple of these are not true fields. -enum eFieldType { - SPECIAL_EXPLORED = 0, - WALL_FORCE = 1, - WALL_FIRE = 2, - FIELD_ANTIMAGIC = 3, - CLOUD_STINK = 4, - WALL_ICE = 5, - WALL_BLADES = 6, - CLOUD_SLEEP = 7, - // Begin fields saved in town setup - OBJECT_BLOCK = 8, - SPECIAL_SPOT = 9, // Space contains a white special spot - FIELD_WEB = 10, - OBJECT_CRATE = 11, - OBJECT_BARREL = 12, - BARRIER_FIRE = 13, - BARRIER_FORCE = 14, - FIELD_QUICKFIRE = 15, - // End fields saved in town setup - SFX_SMALL_BLOOD = 16, - SFX_MEDIUM_BLOOD = 17, - SFX_LARGE_BLOOD = 18, - SFX_SMALL_SLIME = 19, - SFX_LARGE_SLIME = 20, - SFX_ASH = 21, - SFX_BONES = 22, - SFX_RUBBLE = 23, - BARRIER_CAGE = 24, - SPECIAL_ROAD = 25, - // From here on are special values that don't index anything. - // Thus, they start at 32. - FIELD_DISPEL = 32, // Dispel field - FIELD_SMASH = 33, // Move Mountains - // Mustn't have anything >= 50 -}; - -// Field types are used to index bit fields. -// In this case, their values should be taken as a bit index that is set. -inline unsigned long operator&(unsigned long a, eFieldType b) { - return a & (1 << b); -} -inline unsigned long operator&(eFieldType a, unsigned long b) { - return (1 << a) & b; -} -inline unsigned long operator&(eFieldType a, eFieldType b) { - return (1 << a) & (1 << b); -} -inline unsigned long& operator &=(unsigned long& a, eFieldType b) { - a = a & b; - return a; -} -inline unsigned long operator|(unsigned long a, eFieldType b) { - return a | (1 << b); -} -inline unsigned long operator|(eFieldType a, unsigned long b) { - return (1 << a) | b; -} -inline unsigned long operator|(eFieldType a, eFieldType b) { - return (1 << a) | (1 << b); -} -inline unsigned long& operator |=(unsigned long& a, eFieldType b) { - a = a | b; - return a; -} -inline unsigned long operator^(unsigned long a, eFieldType b) { - return a ^ (1 << b); -} -inline unsigned long operator^(eFieldType a, unsigned long b) { - return (1 << a) ^ b; -} -inline unsigned long operator^(eFieldType a, eFieldType b) { - return (1 << a) ^ (1 << b); -} -inline unsigned long& operator ^=(unsigned long& a, eFieldType b) { - a = a ^ b; - return a; -} -inline unsigned long operator>>(eFieldType a, unsigned long b) { - return (1 << a) >> b; -} -inline unsigned long operator<<(eFieldType a, unsigned long b) { - return (1 << a) << b; -} -inline unsigned long operator~(eFieldType f) { - return ~(1 << f); -} - -enum class eSpell { - NONE = -1, - // Mage spells - LIGHT = 0, - SPARK = 1, - HASTE_MINOR = 2, - STRENGTH = 3, - SCARE = 4, - CLOUD_FLAME = 5, - IDENTIFY = 6, - SCRY_MONSTER = 7, - GOO = 8, - TRUE_SIGHT = 9, - POISON_MINOR = 10, - FLAME = 11, - SLOW = 12, - DUMBFOUND = 13, - ENVENOM = 14, - CLOUD_STINK = 15, - SUMMON_BEAST = 16, - CONFLAGRATION = 17, - DISPEL_SQUARE = 18, - CLOUD_SLEEP = 19, - UNLOCK = 20, - HASTE = 21, - FIREBALL = 22, - LIGHT_LONG = 23, - FEAR = 24, - WALL_FORCE = 25, - SUMMON_WEAK = 26, - ARROWS_FLAME = 27, - WEB = 28, - RESIST_MAGIC = 29, - POISON = 30, - ICE_BOLT = 31, - SLOW_GROUP = 32, - MAGIC_MAP = 33, - CAPTURE_SOUL = 34, - SIMULACRUM = 35, - ARROWS_VENOM = 36, - WALL_ICE = 37, - STEALTH = 38, - HASTE_MAJOR = 39, - FIRESTORM = 40, - DISPEL_BARRIER = 41, - BARRIER_FIRE = 42, - SUMMON = 43, - SHOCKSTORM = 44, - SPRAY_FIELDS = 45, - POISON_MAJOR = 46, - FEAR_GROUP = 47, - KILL = 48, - PARALYZE = 49, - DEMON = 50, - ANTIMAGIC = 51, - MINDDUEL = 52, - FLIGHT = 53, - SHOCKWAVE = 54, - BLESS_MAJOR = 55, - PARALYSIS_MASS = 56, - PROTECTION = 57, - SUMMON_MAJOR = 58, - BARRIER_FORCE = 59, - QUICKFIRE = 60, - ARROWS_DEATH = 61, - // Special spells - STRENGTHEN_TARGET = 62, - SUMMON_RAT = 63, - WALL_ICE_BALL = 64, - GOO_BOMB = 65, - FOUL_VAPOR = 66, - CLOUD_SLEEP_LARGE = 67, - ACID_SPRAY = 68, - PARALYZE_BEAM = 69, - SLEEP_MASS = 70, - RAVAGE_ENEMIES = 71, - BLADE_AURA = 72, - ICY_RAIN = 73, - FLAME_AURA = 74, - SUMMON_AID = 75, - SUMMON_AID_MAJOR = 76, - FLASH_STEP = 77, - // Priest spells - BLESS_MINOR = 100, - HEAL_MINOR = 101, - POISON_WEAKEN = 102, - TURN_UNDEAD = 103, - LOCATION = 104, - SANCTUARY = 105, - SYMBIOSIS = 106, - MANNA_MINOR = 107, - RITUAL_SANCTIFY = 108, - STUMBLE = 109, - BLESS = 110, - POISON_CURE = 111, - CURSE = 112, - LIGHT_DIVINE = 113, - WOUND = 114, - SUMMON_SPIRIT = 115, - MOVE_MOUNTAINS = 116, - CHARM_FOE = 117, - DISEASE = 118, - AWAKEN = 119, - HEAL = 120, - HEAL_ALL_LIGHT = 121, - HOLY_SCOURGE = 122, - DETECT_LIFE = 123, - PARALYSIS_CURE = 124, - MANNA = 125, - FORCEFIELD = 126, - DISEASE_CURE = 127, - RESTORE_MIND = 128, - SMITE = 129, - POISON_CURE_ALL = 130, - CURSE_ALL = 131, - DISPEL_UNDEAD = 132, - CURSE_REMOVE = 133, - STICKS_TO_SNAKES = 134, - MARTYRS_SHIELD = 135, - CLEANSE = 136, - FIREWALK = 137, - BLESS_PARTY = 138, - HEAL_MAJOR = 139, - RAISE_DEAD = 140, - FLAMESTRIKE = 141, - SANCTUARY_MASS = 142, - SUMMON_HOST = 143, - SHATTER = 144, - DISPEL_SPHERE = 145, - HEAL_ALL = 146, - REVIVE = 147, - HYPERACTIVITY = 148, - DESTONE = 149, - SUMMON_GUARDIAN = 150, - CHARM_MASS = 151, - PROTECTIVE_CIRCLE = 152, - PESTILENCE = 153, - REVIVE_ALL = 154, - RAVAGE_SPIRIT = 155, - RESURRECT = 156, - DIVINE_THUD = 157, - AVATAR = 158, - WALL_BLADES = 159, - WORD_RECALL = 160, - CLEANSE_MAJOR = 161, - // Special spells - DISPEL_FIELD = 162, - MOVE_MOUNTAINS_MASS = 163, - WRACK = 164, - UNHOLY_RAVAGING = 165, - AUGMENTATION = 166, - NIRVANA = 167, -}; - -inline bool isMage(eSpell spell) { - int code = (int) spell; - return code >= 0 && code < 62; -} - -inline bool isPriest(eSpell spell) { - int code = (int) spell; - return code >= 100 && code < 162; -} - -enum class eAlchemy { - NONE = -1, - CURE_WEAK = 0, - HEAL_WEAK = 1, - POISON_WEAK = 2, - SPEED_WEAK = 3, - POISON_MED = 4, - HEAL_MED = 5, - CURE_STRONG = 6, - SPEED_MED = 7, - GRAYMOLD = 8, - POWER_WEAK = 9, - CLARITY = 10, - POISON_STRONG = 11, - HEAL_STRONG = 12, - POISON_KILL = 13, - RESURRECT = 14, - POWER_MED = 15, - KNOWLEDGE = 16, - STRENGTH = 17, - BLISS = 18, - POWER_STRONG = 19, -}; - -// MARK: eLighting -enum eLighting { - LIGHT_NORMAL = 0, - LIGHT_DARK = 1, - LIGHT_DRAINS = 2, - LIGHT_NONE = 3, -}; - -#endif diff --git a/src/classes/special.hpp b/src/classes/special.hpp deleted file mode 100644 index b3d0e2bc..00000000 --- a/src/classes/special.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * special.h - * BoE - * - * Created by Celtic Minstrel on 20/04/09. - * - */ - -#ifndef BOE_DATA_SPECIAL_H -#define BOE_DATA_SPECIAL_H - -#include -#include -#include -#include "simpletypes.hpp" -#include "location.hpp" - -namespace legacy { struct special_node_type; }; - -class cSpecial { -public: - eSpecType type; - short sd1; - short sd2; - short pic; - short pictype; - short m1; - short m2; - short m3; - short ex1a; - short ex1b; - short ex1c; - short ex2a; - short ex2b; - short ex2c; - short jumpto; - - cSpecial(); - void import_legacy(legacy::special_node_type& old); - void writeTo(std::ostream& file, int n) const; -}; - -class cTimer { -public: - long time = 0; - short node_type = 0; - short node = -1; -}; - -struct pending_special_type { - spec_num_t spec; - eSpecCtx mode; - unsigned short type; // 0 - scen, 1 - out, 2 - town - location where; - long long trigger_time; -}; - -struct node_properties_t { - eSpecType self; - std::string opcode() const; - std::string name() const, descr() const; - std::string sdf1_lbl() const, sdf2_lbl() const, sdf1_hlp() const, sdf2_hlp() const; - std::string msg1_lbl() const, msg2_lbl() const, msg3_lbl() const, msg1_hlp() const, msg2_hlp() const, msg3_hlp() const; - std::string pic_lbl() const, pt_lbl() const, pic_hlp() const, pt_hlp() const; - std::string ex1a_lbl() const, ex1b_lbl() const, ex1c_lbl() const, ex1a_hlp() const, ex1b_hlp() const, ex1c_hlp() const; - std::string ex2a_lbl() const, ex2b_lbl() const, ex2c_lbl() const, ex2a_hlp() const, ex2b_hlp() const, ex2c_hlp() const; - std::string jmp_lbl() const, jmp_hlp() const; - char sd1_btn, sd2_btn, m1_btn, m2_btn, m3_btn, p_btn, pt_btn; - char x1a_btn, x1b_btn, x1c_btn, x2a_btn, x2b_btn, x2c_btn; - node_properties_t() {} - node_properties_t(std::initializer_list>); -}; - -const node_properties_t& operator* (eSpecType t); - -#endif diff --git a/src/classes/spell.hpp b/src/classes/spell.hpp deleted file mode 100644 index b256a3db..00000000 --- a/src/classes/spell.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// spell.hpp -// BoE -// -// Created by Celtic Minstrel on 14-12-12. -// -// - -#ifndef BoE_DATA_SPELL_HPP -#define BoE_DATA_SPELL_HPP - -#include -#include "simpletypes.hpp" - -enum eSpellRefer {REFER_YES, REFER_IMMED, REFER_TARGET, REFER_FANCY}; -enum eSpellSelect {SELECT_NO, SELECT_ACTIVE, SELECT_ANY}; -// This one is meant for indexing a bit field -enum eSpellWhen {WHEN_COMBAT = 1, WHEN_TOWN = 2, WHEN_OUTDOORS = 4}; - -enum eSpellPat {PAT_SINGLE, PAT_SQ, PAT_SMSQ, PAT_OPENSQ, PAT_RAD2, PAT_RAD3, PAT_PLUS, PAT_WALL}; - -class cSpell { - static std::map dictionary; - friend const cSpell& operator*(eSpell spell_num); -public: - cSpell() {} // This is just here because the map doesn't work without it - cSpell(eSpell id); - cSpell& withRefer(eSpellRefer r); - cSpell& withCost(int c); - cSpell& withRange(int r); - cSpell& asLevel(int lvl); - cSpell& asType(eSkill type); - cSpell& asPeaceful(); - cSpell& needsSelect(eSpellSelect sel = SELECT_ACTIVE); - cSpell& when(eSpellWhen when); - const cSpell& finish(); - eSpell num; - eSpellRefer refer; - int cost, range, level; - eSpellSelect need_select; - eSkill type; - int when_cast; - bool peaceful = false; - std::string name() const; - bool is_priest() const; - static eSpell fromNum(eSkill type, int num); - static eSpell fromNum(int num); -}; - -// Need to declare this a second time in order for it to be in scope where it's needed -const cSpell& operator*(eSpell spell_num); - -#endif diff --git a/src/damage.hpp b/src/damage.hpp new file mode 100644 index 00000000..49618363 --- /dev/null +++ b/src/damage.hpp @@ -0,0 +1,122 @@ +// +// damage.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_DATA_DAMAGE_HPP +#define BoE_DATA_DAMAGE_HPP + +enum class eDamageType { + WEAPON = 0, + FIRE = 1, + POISON = 2, + MAGIC = 3, + UNBLOCKABLE = 4, + COLD = 5, + UNDEAD = 6, + DEMON = 7, + // Keep these two last + SPECIAL = 8, // Completely unblockable damage from assassination skill + MARKED = 10, +}; + +enum class eStatus { + MAIN = -1, // For saved games only + POISONED_WEAPON = 0, + BLESS_CURSE = 1, + POISON = 2, + HASTE_SLOW = 3, + INVULNERABLE = 4, + MAGIC_RESISTANCE = 5, + WEBS = 6, + DISEASE = 7, + INVISIBLE = 8, //sanctuary + DUMB = 9, + MARTYRS_SHIELD = 10, + ASLEEP = 11, + PARALYZED = 12, + ACID = 13, + FORCECAGE = 14, + // This one is new + // It's not quite a real status effect since it doesn't expire + CHARM = 15, +}; + +inline bool isStatusNegative(eStatus stat) { + switch(stat) { + case eStatus::MAIN: return false; + case eStatus::POISONED_WEAPON: return false; + case eStatus::BLESS_CURSE: return false; + case eStatus::POISON: return true; + case eStatus::HASTE_SLOW: return false; + case eStatus::INVULNERABLE: return false; + case eStatus::MAGIC_RESISTANCE: return false; + case eStatus::WEBS: return true; + case eStatus::DISEASE: return true; + case eStatus::INVISIBLE: return false; + case eStatus::DUMB: return true; + case eStatus::MARTYRS_SHIELD: return false; + case eStatus::ASLEEP: return true; + case eStatus::PARALYZED: return true; + case eStatus::ACID: return true; + case eStatus::FORCECAGE: return true; + case eStatus::CHARM: return true; + } + return false; +} + +enum class ePartyStatus { + STEALTH, + FLIGHT, + DETECT_LIFE, + FIREWALK, +}; + +enum class eMainStatus { + ABSENT = 0, // absent, empty slot + ALIVE = 1, + DEAD = 2, + DUST = 3, + STONE = 4, + FLED = 5, + SURFACE = 6, // fled to surface? + WON = 7, + SPLIT = 10, + SPLIT_ABSENT = SPLIT + ABSENT, + SPLIT_ALIVE = SPLIT + ALIVE, + SPLIT_DEAD = SPLIT + DEAD, + SPLIT_DUST = SPLIT + DUST, + SPLIT_STONE = SPLIT + STONE, + SPLIT_FLED = SPLIT + FLED, + SPLIT_SURFACE = SPLIT + SURFACE, + SPLIT_WON = SPLIT + WON, +}; + +inline eMainStatus exceptSplit(eMainStatus stat) { + if(int(stat) >= 10) + return (eMainStatus) (-10 + (int)stat); + return stat; +} + +inline bool isSplit(eMainStatus stat) { + return int(stat) >= 10; +} + +inline bool isAbsent(eMainStatus stat) { + return stat == eMainStatus::ABSENT || int(stat) > 4; +} + +inline bool isDead(eMainStatus stat) { + int code = (int) stat; + return code > 1 && code < 5; +} + +std::ostream& operator << (std::ostream& out, eStatus e); +std::istream& operator >> (std::istream& in, eStatus& e); +std::ostream& operator << (std::ostream& out, eDamageType e); +std::istream& operator >> (std::istream& in, eDamageType& e); + +#endif diff --git a/src/dialogxml/3choice.cpp b/src/dialogxml/dialogs/3choice.cpp similarity index 100% rename from src/dialogxml/3choice.cpp rename to src/dialogxml/dialogs/3choice.cpp diff --git a/src/dialogxml/3choice.hpp b/src/dialogxml/dialogs/3choice.hpp similarity index 100% rename from src/dialogxml/3choice.hpp rename to src/dialogxml/dialogs/3choice.hpp diff --git a/src/dialogxml/choicedlog.cpp b/src/dialogxml/dialogs/choicedlog.cpp similarity index 100% rename from src/dialogxml/choicedlog.cpp rename to src/dialogxml/dialogs/choicedlog.cpp diff --git a/src/dialogxml/choicedlog.hpp b/src/dialogxml/dialogs/choicedlog.hpp similarity index 100% rename from src/dialogxml/choicedlog.hpp rename to src/dialogxml/dialogs/choicedlog.hpp diff --git a/src/dialogxml/dialog.cpp b/src/dialogxml/dialogs/dialog.cpp similarity index 99% rename from src/dialogxml/dialog.cpp rename to src/dialogxml/dialogs/dialog.cpp index a5cad547..a15db75d 100644 --- a/src/dialogxml/dialog.cpp +++ b/src/dialogxml/dialogs/dialog.cpp @@ -10,9 +10,7 @@ #include #include "dialog.hpp" #include "graphtool.hpp" -#include "soundtool.hpp" -using namespace std; -using namespace ticpp; +#include "sounds.hpp" #include "pict.hpp" #include "button.hpp" #include "field.hpp" @@ -25,9 +23,11 @@ using namespace ticpp; #include "cursors.hpp" #include "prefs.hpp" +using namespace std; +using namespace ticpp; + // TODO: Would be nice if I could avoid depending on mainPtr extern sf::RenderWindow mainPtr; -extern cursor_type current_cursor; extern sf::Texture bg_gworld; const short cDialog::BG_DARK = 5, cDialog::BG_LIGHT = 16; @@ -386,7 +386,7 @@ void cDialog::run(std::function onopen){ cDialog* formerTop = topWindow; // TODO: The introduction of the static topWindow means I may be able to use this instead of parent->win; do I still need parent? sf::RenderWindow* parentWin = &(parent ? parent->win : mainPtr); - cursor_type former_curs = current_cursor; + cursor_type former_curs = Cursor::current; set_cursor(sword_curs); using kb = sf::Keyboard; kb::Key k; diff --git a/src/dialogxml/dialog.hpp b/src/dialogxml/dialogs/dialog.hpp similarity index 100% rename from src/dialogxml/dialog.hpp rename to src/dialogxml/dialogs/dialog.hpp diff --git a/src/dialogxml/dialog.keys.hpp b/src/dialogxml/dialogs/dialog.keys.hpp similarity index 100% rename from src/dialogxml/dialog.keys.hpp rename to src/dialogxml/dialogs/dialog.keys.hpp diff --git a/src/dialogxml/dlogevt.hpp b/src/dialogxml/dialogs/dlogevt.hpp similarity index 100% rename from src/dialogxml/dlogevt.hpp rename to src/dialogxml/dialogs/dlogevt.hpp diff --git a/src/dialogxml/pictchoice.cpp b/src/dialogxml/dialogs/pictchoice.cpp similarity index 100% rename from src/dialogxml/pictchoice.cpp rename to src/dialogxml/dialogs/pictchoice.cpp diff --git a/src/dialogxml/pictchoice.hpp b/src/dialogxml/dialogs/pictchoice.hpp similarity index 100% rename from src/dialogxml/pictchoice.hpp rename to src/dialogxml/dialogs/pictchoice.hpp diff --git a/src/dialogxml/strchoice.cpp b/src/dialogxml/dialogs/strchoice.cpp similarity index 100% rename from src/dialogxml/strchoice.cpp rename to src/dialogxml/dialogs/strchoice.cpp diff --git a/src/dialogxml/strchoice.hpp b/src/dialogxml/dialogs/strchoice.hpp similarity index 100% rename from src/dialogxml/strchoice.hpp rename to src/dialogxml/dialogs/strchoice.hpp diff --git a/src/dialogxml/strdlog.cpp b/src/dialogxml/dialogs/strdlog.cpp similarity index 100% rename from src/dialogxml/strdlog.cpp rename to src/dialogxml/dialogs/strdlog.cpp diff --git a/src/dialogxml/strdlog.hpp b/src/dialogxml/dialogs/strdlog.hpp similarity index 98% rename from src/dialogxml/strdlog.hpp rename to src/dialogxml/dialogs/strdlog.hpp index 5bffd8ce..60ae94d2 100644 --- a/src/dialogxml/strdlog.hpp +++ b/src/dialogxml/dialogs/strdlog.hpp @@ -12,7 +12,7 @@ #include #include #include "pictypes.hpp" -#include "soundtool.hpp" // for snd_num_t +#include "sounds.hpp" // for snd_num_t #include "dialog.hpp" /// The signature of a record handler for cStrDlog. diff --git a/src/dialogxml/basicbtns.cpp b/src/dialogxml/widgets/basicbtns.cpp similarity index 100% rename from src/dialogxml/basicbtns.cpp rename to src/dialogxml/widgets/basicbtns.cpp diff --git a/src/dialogxml/button.cpp b/src/dialogxml/widgets/button.cpp similarity index 99% rename from src/dialogxml/button.cpp rename to src/dialogxml/widgets/button.cpp index c1ea3013..80c06a72 100644 --- a/src/dialogxml/button.cpp +++ b/src/dialogxml/widgets/button.cpp @@ -19,7 +19,7 @@ #include #include -#include "restypes.hpp" +#include "res_image.hpp" extern sf::Texture bg_gworld; diff --git a/src/dialogxml/button.hpp b/src/dialogxml/widgets/button.hpp similarity index 100% rename from src/dialogxml/button.hpp rename to src/dialogxml/widgets/button.hpp diff --git a/src/dialogxml/control.cpp b/src/dialogxml/widgets/control.cpp similarity index 99% rename from src/dialogxml/control.cpp rename to src/dialogxml/widgets/control.cpp index 0cf29b3e..07a94afc 100644 --- a/src/dialogxml/control.cpp +++ b/src/dialogxml/widgets/control.cpp @@ -9,12 +9,13 @@ #include "control.hpp" #include #include "dialog.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "button.hpp" #include "graphtool.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "mathutil.hpp" #include "prefs.hpp" +#include "cursors.hpp" void cControl::setText(std::string l){ lbl = l; diff --git a/src/dialogxml/control.hpp b/src/dialogxml/widgets/control.hpp similarity index 100% rename from src/dialogxml/control.hpp rename to src/dialogxml/widgets/control.hpp diff --git a/src/dialogxml/field.cpp b/src/dialogxml/widgets/field.cpp similarity index 100% rename from src/dialogxml/field.cpp rename to src/dialogxml/widgets/field.cpp diff --git a/src/dialogxml/field.hpp b/src/dialogxml/widgets/field.hpp similarity index 100% rename from src/dialogxml/field.hpp rename to src/dialogxml/widgets/field.hpp diff --git a/src/dialogxml/message.cpp b/src/dialogxml/widgets/message.cpp similarity index 100% rename from src/dialogxml/message.cpp rename to src/dialogxml/widgets/message.cpp diff --git a/src/dialogxml/message.hpp b/src/dialogxml/widgets/message.hpp similarity index 100% rename from src/dialogxml/message.hpp rename to src/dialogxml/widgets/message.hpp diff --git a/src/dialogxml/pict.cpp b/src/dialogxml/widgets/pict.cpp similarity index 99% rename from src/dialogxml/pict.cpp rename to src/dialogxml/widgets/pict.cpp index d7394c18..12dfacf1 100644 --- a/src/dialogxml/pict.cpp +++ b/src/dialogxml/widgets/pict.cpp @@ -13,7 +13,7 @@ #include "graphtool.hpp" #include "dialog.hpp" -#include "restypes.hpp" +#include "res_image.hpp" extern sf::Texture bg_gworld; extern cCustomGraphics spec_scen_g; diff --git a/src/dialogxml/pict.hpp b/src/dialogxml/widgets/pict.hpp similarity index 100% rename from src/dialogxml/pict.hpp rename to src/dialogxml/widgets/pict.hpp diff --git a/src/dialogxml/pictypes.hpp b/src/dialogxml/widgets/pictypes.hpp similarity index 100% rename from src/dialogxml/pictypes.hpp rename to src/dialogxml/widgets/pictypes.hpp diff --git a/src/dialogxml/scrollbar.cpp b/src/dialogxml/widgets/scrollbar.cpp similarity index 99% rename from src/dialogxml/scrollbar.cpp rename to src/dialogxml/widgets/scrollbar.cpp index 0ad5d1a3..8551d380 100644 --- a/src/dialogxml/scrollbar.cpp +++ b/src/dialogxml/widgets/scrollbar.cpp @@ -7,9 +7,10 @@ // #include "scrollbar.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "graphtool.hpp" #include "mathutil.hpp" +#include "cursors.hpp" std::string cScrollbar::scroll_textures[NUM_STYLES] = { "dlogscrollwh", diff --git a/src/dialogxml/scrollbar.hpp b/src/dialogxml/widgets/scrollbar.hpp similarity index 100% rename from src/dialogxml/scrollbar.hpp rename to src/dialogxml/widgets/scrollbar.hpp diff --git a/src/dialogxml/scrollpane.cpp b/src/dialogxml/widgets/scrollpane.cpp similarity index 100% rename from src/dialogxml/scrollpane.cpp rename to src/dialogxml/widgets/scrollpane.cpp diff --git a/src/dialogxml/scrollpane.hpp b/src/dialogxml/widgets/scrollpane.hpp similarity index 100% rename from src/dialogxml/scrollpane.hpp rename to src/dialogxml/widgets/scrollpane.hpp diff --git a/src/dialogxml/stack.cpp b/src/dialogxml/widgets/stack.cpp similarity index 100% rename from src/dialogxml/stack.cpp rename to src/dialogxml/widgets/stack.cpp diff --git a/src/dialogxml/stack.hpp b/src/dialogxml/widgets/stack.hpp similarity index 100% rename from src/dialogxml/stack.hpp rename to src/dialogxml/widgets/stack.hpp diff --git a/src/fields.hpp b/src/fields.hpp new file mode 100644 index 00000000..f23267cf --- /dev/null +++ b/src/fields.hpp @@ -0,0 +1,103 @@ +// +// fields.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_FIELDS_HPP +#define BoE_FIELDS_HPP + +// This is a slight misnomer, as a couple of these are not true fields. +enum eFieldType { + SPECIAL_EXPLORED = 0, + WALL_FORCE = 1, + WALL_FIRE = 2, + FIELD_ANTIMAGIC = 3, + CLOUD_STINK = 4, + WALL_ICE = 5, + WALL_BLADES = 6, + CLOUD_SLEEP = 7, + // Begin fields saved in town setup + OBJECT_BLOCK = 8, + SPECIAL_SPOT = 9, // Space contains a white special spot + FIELD_WEB = 10, + OBJECT_CRATE = 11, + OBJECT_BARREL = 12, + BARRIER_FIRE = 13, + BARRIER_FORCE = 14, + FIELD_QUICKFIRE = 15, + // End fields saved in town setup + SFX_SMALL_BLOOD = 16, + SFX_MEDIUM_BLOOD = 17, + SFX_LARGE_BLOOD = 18, + SFX_SMALL_SLIME = 19, + SFX_LARGE_SLIME = 20, + SFX_ASH = 21, + SFX_BONES = 22, + SFX_RUBBLE = 23, + BARRIER_CAGE = 24, + SPECIAL_ROAD = 25, + // From here on are special values that don't index anything. + // Thus, they start at 32. + FIELD_DISPEL = 32, // Dispel field + FIELD_SMASH = 33, // Move Mountains + // Mustn't have anything >= 50 +}; + +// Field types are used to index bit fields. +// In this case, their values should be taken as a bit index that is set. +inline unsigned long operator&(unsigned long a, eFieldType b) { + return a & (1 << b); +} +inline unsigned long operator&(eFieldType a, unsigned long b) { + return (1 << a) & b; +} +inline unsigned long operator&(eFieldType a, eFieldType b) { + return (1 << a) & (1 << b); +} +inline unsigned long& operator &=(unsigned long& a, eFieldType b) { + a = a & b; + return a; +} +inline unsigned long operator|(unsigned long a, eFieldType b) { + return a | (1 << b); +} +inline unsigned long operator|(eFieldType a, unsigned long b) { + return (1 << a) | b; +} +inline unsigned long operator|(eFieldType a, eFieldType b) { + return (1 << a) | (1 << b); +} +inline unsigned long& operator |=(unsigned long& a, eFieldType b) { + a = a | b; + return a; +} +inline unsigned long operator^(unsigned long a, eFieldType b) { + return a ^ (1 << b); +} +inline unsigned long operator^(eFieldType a, unsigned long b) { + return (1 << a) ^ b; +} +inline unsigned long operator^(eFieldType a, eFieldType b) { + return (1 << a) ^ (1 << b); +} +inline unsigned long& operator ^=(unsigned long& a, eFieldType b) { + a = a ^ b; + return a; +} +inline unsigned long operator>>(eFieldType a, unsigned long b) { + return (1 << a) >> b; +} +inline unsigned long operator<<(eFieldType a, unsigned long b) { + return (1 << a) << b; +} +inline unsigned long operator~(eFieldType f) { + return ~(1 << f); +} + +std::ostream& operator << (std::ostream& out, eFieldType e); +std::istream& operator >> (std::istream& in, eFieldType& e); + +#endif diff --git a/src/classes/estreams.cpp b/src/fileio/estreams.cpp similarity index 96% rename from src/classes/estreams.cpp rename to src/fileio/estreams.cpp index 3af14e9c..f9225dc0 100644 --- a/src/classes/estreams.cpp +++ b/src/fileio/estreams.cpp @@ -6,6 +6,7 @@ // // +#include #include #include #include @@ -13,17 +14,37 @@ #include #include #include -#include "simpletypes.hpp" -#include "spell.hpp" -std::string oboeVersionString() { +#include "spell.hpp" +#include "item_abilities.hpp" +#include "item_variety.hpp" +#include "damage.hpp" +#include "race.hpp" +#include "location.hpp" +#include "fields.hpp" +#include "quest.hpp" +#include "shop.hpp" +#include "terrain_abilities.hpp" + +#include "monster.hpp" +#include "party.hpp" +#include "town.hpp" +#include "talking.hpp" +#include "scenario.hpp" + +const char* oboeVersionString() { + static std::shared_ptr version; + if(version) return version.get(); unsigned short M, m, f; M = OBOE_CURRENT_VERSION >> 16; m = (OBOE_CURRENT_VERSION & 0xff00) >> 8; f = OBOE_CURRENT_VERSION & 0xff; std::ostringstream sout; sout << M << '.' << m << '.' << f; - return sout.str(); + std::string vers = sout.str(); + version.reset(new char[vers.length()], std::default_delete()); + std::copy(vers.begin(), vers.end(), version.get()); + return version.get(); } // A simple lookup map based on the concept of a trie diff --git a/src/tools/fileio.cpp b/src/fileio/fileio.cpp similarity index 93% rename from src/tools/fileio.cpp rename to src/fileio/fileio.cpp index 2c0cd2a9..64954a0f 100644 --- a/src/tools/fileio.cpp +++ b/src/fileio/fileio.cpp @@ -9,23 +9,21 @@ #include "fileio.hpp" #include +#include #include -#include "restypes.hpp" -#include "cursors.hpp" +#include "res_image.hpp" +#include "res_cursor.hpp" +#include "res_font.hpp" +#include "res_strings.hpp" +#include "res_sound.hpp" bool mac_is_intel; fs::path progDir, tempDir, scenDir; -// Cursors included here so that they needn't be unnecessarily duplicated in platform-specific files -cursor_type current_cursor = sword_curs; -cursor_type arrow_curs[3][3] = { - {NW_curs, N_curs, NE_curs}, - {W_curs, wait_curs, E_curs}, - {SW_curs, S_curs, SE_curs}, -}; +// This is here to avoid unnecessarily duplicating it in platform-specific files. +cursor_type Cursor::current = sword_curs; -#include std::filebuf logfile; void init_directories(const char* exec_path) { diff --git a/src/tools/fileio.hpp b/src/fileio/fileio.hpp similarity index 97% rename from src/tools/fileio.hpp rename to src/fileio/fileio.hpp index 54d854ef..66c40e48 100644 --- a/src/tools/fileio.hpp +++ b/src/fileio/fileio.hpp @@ -18,8 +18,6 @@ class cScenario; class cUniverse; -namespace fs = boost::filesystem; // TODO: Centralize this alias! - fs::path locate_scenario(std::string scen_name); bool load_scenario(fs::path file_to_load, cScenario& scenario, bool only_header = false); diff --git a/src/tools/fileio_party.cpp b/src/fileio/fileio_party.cpp similarity index 100% rename from src/tools/fileio_party.cpp rename to src/fileio/fileio_party.cpp diff --git a/src/tools/fileio_scen.cpp b/src/fileio/fileio_scen.cpp similarity index 99% rename from src/tools/fileio_scen.cpp rename to src/fileio/fileio_scen.cpp index 5b7ea336..e1164b4d 100644 --- a/src/tools/fileio_scen.cpp +++ b/src/fileio/fileio_scen.cpp @@ -24,11 +24,12 @@ #include "tarball.hpp" #include "porting.hpp" -#include "restypes.hpp" +#include "res_image.hpp" +#include "res_sound.hpp" // Because the full template definition needs to be visible in this file // Also, for some reason, it's not found in the include paths, so use a relative path -#include "../classes/town_import.tpp" +#include "../scenario/town_import.tpp" bool cur_scen_is_mac = true; extern cCustomGraphics spec_scen_g; diff --git a/src/tools/gzstream/COPYING.LIB b/src/fileio/gzstream/COPYING.LIB similarity index 100% rename from src/tools/gzstream/COPYING.LIB rename to src/fileio/gzstream/COPYING.LIB diff --git a/src/tools/gzstream/Makefile b/src/fileio/gzstream/Makefile similarity index 100% rename from src/tools/gzstream/Makefile rename to src/fileio/gzstream/Makefile diff --git a/src/tools/gzstream/README b/src/fileio/gzstream/README similarity index 100% rename from src/tools/gzstream/README rename to src/fileio/gzstream/README diff --git a/src/tools/gzstream/gzstream.cpp b/src/fileio/gzstream/gzstream.cpp similarity index 100% rename from src/tools/gzstream/gzstream.cpp rename to src/fileio/gzstream/gzstream.cpp diff --git a/src/tools/gzstream/gzstream.h b/src/fileio/gzstream/gzstream.h similarity index 100% rename from src/tools/gzstream/gzstream.h rename to src/fileio/gzstream/gzstream.h diff --git a/src/tools/gzstream/index.html b/src/fileio/gzstream/index.html similarity index 100% rename from src/tools/gzstream/index.html rename to src/fileio/gzstream/index.html diff --git a/src/tools/gzstream/test_gunzip.cpp b/src/fileio/gzstream/test_gunzip.cpp similarity index 100% rename from src/tools/gzstream/test_gunzip.cpp rename to src/fileio/gzstream/test_gunzip.cpp diff --git a/src/tools/gzstream/test_gzip.cpp b/src/fileio/gzstream/test_gzip.cpp similarity index 100% rename from src/tools/gzstream/test_gzip.cpp rename to src/fileio/gzstream/test_gzip.cpp diff --git a/src/tools/gzstream/version b/src/fileio/gzstream/version similarity index 100% rename from src/tools/gzstream/version rename to src/fileio/gzstream/version diff --git a/src/tools/map_parse.cpp b/src/fileio/map_parse.cpp similarity index 100% rename from src/tools/map_parse.cpp rename to src/fileio/map_parse.cpp diff --git a/src/tools/map_parse.hpp b/src/fileio/map_parse.hpp similarity index 100% rename from src/tools/map_parse.hpp rename to src/fileio/map_parse.hpp diff --git a/src/tools/resmgr/restypes.hpp b/src/fileio/resmgr/res_cursor.hpp similarity index 53% rename from src/tools/resmgr/restypes.hpp rename to src/fileio/resmgr/res_cursor.hpp index cb742f35..045f95f1 100644 --- a/src/tools/resmgr/restypes.hpp +++ b/src/fileio/resmgr/res_cursor.hpp @@ -6,40 +6,21 @@ * */ -#ifndef BOE_RESTYPES_H -#define BOE_RESTYPES_H +#ifndef BOE_RES_CURSOR_HPP +#define BOE_RES_CURSOR_HPP -#include -#include - -#include "resmgr.hpp" -#include -#include #include -#include -#include #include +#include +#include "resmgr.hpp" #include "cursors.hpp" -#include "location.hpp" -using ImageRsrc = sf::Texture; using CursorRsrc = Cursor; -using FontRsrc = sf::Font; -using StringRsrc = std::vector; -using SoundRsrc = sf::SoundBuffer; // Redeclare this instead of including "fileio.h" extern std::ostream& std_fmterr(std::ostream& out); namespace ResMgr { - /// Load an image from a PNG file. - template<> inline ImageRsrc* resLoader::operator() (fs::path fpath) { - ImageRsrc* img = new ImageRsrc(); - if(img->loadFromFile(fpath.string())) return img; - delete img; - throw xResMgrErr("Failed to load PNG image: " + fpath.string()); - } - /// Load a cursor from a GIF file. /// The cursor's hotspot location is stored in a GIF comment, with the following syntax (case-sensitive): /// "Hotspot(x,y)" @@ -86,40 +67,6 @@ namespace ResMgr { CursorRsrc* cur = new Cursor(fpath.string(),x,y); return cur; } - - /// Load a font from a TTF file. - template<> inline FontRsrc* resLoader::operator() (fs::path fpath) { - FontRsrc* theFont = new FontRsrc; - if(theFont->loadFromFile(fpath.string())) return theFont; - delete theFont; - throw xResMgrErr("Failed to find font: " + fpath.string()); - } - - /// Load a list of strings from a TXT file. - /// Each line in the file becomes one string in the resulting list. - /// (Empty lines are included too.) - template<> inline StringRsrc* resLoader::operator() (fs::path fpath) { - std::ifstream fin(fpath.c_str()); - if(fin.fail()) { - std::cerr << std_fmterr << ": Error opening file"; - throw xResMgrErr("Failed to load string list: " + fpath.string()); - } - std::string next; - StringRsrc* strlist = new StringRsrc; - while(!fin.eof()) { - getline(fin,next); - strlist->push_back(next); - } - return strlist; - } - - /// Load a sound from a WAV file. - template<> inline SoundRsrc* resLoader::operator() (fs::path fpath) { - SoundRsrc* snd = new SoundRsrc; - if(snd->loadFromFile(fpath.string())) return snd; - delete snd; - throw xResMgrErr("Failed to load WAV sound: " + fpath.string()); - } } #endif diff --git a/src/fileio/resmgr/res_font.hpp b/src/fileio/resmgr/res_font.hpp new file mode 100644 index 00000000..36457f19 --- /dev/null +++ b/src/fileio/resmgr/res_font.hpp @@ -0,0 +1,31 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#ifndef BOE_RES_FONT_HPP +#define BOE_RES_FONT_HPP + +#include "resmgr.hpp" +#include +#include + +using FontRsrc = sf::Font; + +// Redeclare this instead of including "fileio.h" +extern std::ostream& std_fmterr(std::ostream& out); + +namespace ResMgr { + /// Load a font from a TTF file. + template<> inline FontRsrc* resLoader::operator() (fs::path fpath) { + FontRsrc* theFont = new FontRsrc; + if(theFont->loadFromFile(fpath.string())) return theFont; + delete theFont; + throw xResMgrErr("Failed to find font: " + fpath.string()); + } +} + +#endif diff --git a/src/fileio/resmgr/res_image.hpp b/src/fileio/resmgr/res_image.hpp new file mode 100644 index 00000000..cb9510a4 --- /dev/null +++ b/src/fileio/resmgr/res_image.hpp @@ -0,0 +1,31 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#ifndef BOE_RES_IMAGE_HPP +#define BOE_RES_IMAGE_HPP + +#include +#include +#include "resmgr.hpp" + +using ImageRsrc = sf::Texture; + +// Redeclare this instead of including "fileio.h" +extern std::ostream& std_fmterr(std::ostream& out); + +namespace ResMgr { + /// Load an image from a PNG file. + template<> inline ImageRsrc* resLoader::operator() (fs::path fpath) { + ImageRsrc* img = new ImageRsrc(); + if(img->loadFromFile(fpath.string())) return img; + delete img; + throw xResMgrErr("Failed to load PNG image: " + fpath.string()); + } +} + +#endif diff --git a/src/fileio/resmgr/res_sound.hpp b/src/fileio/resmgr/res_sound.hpp new file mode 100644 index 00000000..4d48bb3a --- /dev/null +++ b/src/fileio/resmgr/res_sound.hpp @@ -0,0 +1,31 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#ifndef BOE_RES_SOUND_HPP +#define BOE_RES_SOUND_HPP + +#include +#include +#include "resmgr.hpp" + +using SoundRsrc = sf::SoundBuffer; + +// Redeclare this instead of including "fileio.h" +extern std::ostream& std_fmterr(std::ostream& out); + +namespace ResMgr { + /// Load a sound from a WAV file. + template<> inline SoundRsrc* resLoader::operator() (fs::path fpath) { + SoundRsrc* snd = new SoundRsrc; + if(snd->loadFromFile(fpath.string())) return snd; + delete snd; + throw xResMgrErr("Failed to load WAV sound: " + fpath.string()); + } +} + +#endif diff --git a/src/fileio/resmgr/res_strings.hpp b/src/fileio/resmgr/res_strings.hpp new file mode 100644 index 00000000..4424c5a6 --- /dev/null +++ b/src/fileio/resmgr/res_strings.hpp @@ -0,0 +1,41 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#ifndef BOE_RES_STRINGS_HPP +#define BOE_RES_STRINGS_HPP + +#include +#include +#include "resmgr.hpp" + +using StringRsrc = std::vector; + +// Redeclare this instead of including "fileio.h" +extern std::ostream& std_fmterr(std::ostream& out); + +namespace ResMgr { + /// Load a list of strings from a TXT file. + /// Each line in the file becomes one string in the resulting list. + /// (Empty lines are included too.) + template<> inline StringRsrc* resLoader::operator() (fs::path fpath) { + std::ifstream fin(fpath.c_str()); + if(fin.fail()) { + std::cerr << std_fmterr << ": Error opening file"; + throw xResMgrErr("Failed to load string list: " + fpath.string()); + } + std::string next; + StringRsrc* strlist = new StringRsrc; + while(!fin.eof()) { + getline(fin,next); + strlist->push_back(next); + } + return strlist; + } +} + +#endif diff --git a/src/tools/resmgr/resmgr.hpp b/src/fileio/resmgr/resmgr.hpp similarity index 99% rename from src/tools/resmgr/resmgr.hpp rename to src/fileio/resmgr/resmgr.hpp index 7f479ad3..82a0c515 100644 --- a/src/tools/resmgr/resmgr.hpp +++ b/src/fileio/resmgr/resmgr.hpp @@ -36,7 +36,6 @@ namespace std { /// for the desired resource type. The operator() receives the /// full file path with the extension already applied. namespace ResMgr { - namespace fs = boost::filesystem; /// The signature of an ID map function. using idMapFn = std::function; diff --git a/src/tools/resmgr/restypes.cpp b/src/fileio/resmgr/restypes.cpp similarity index 78% rename from src/tools/resmgr/restypes.cpp rename to src/fileio/resmgr/restypes.cpp index f984a35e..230b54b6 100644 --- a/src/tools/resmgr/restypes.cpp +++ b/src/fileio/resmgr/restypes.cpp @@ -6,7 +6,11 @@ // // -#include "restypes.hpp" +#include "res_image.hpp" +#include "res_cursor.hpp" +#include "res_font.hpp" +#include "res_strings.hpp" +#include "res_sound.hpp" namespace ResMgr { template<> const std::string resLoader::file_ext = "png"; diff --git a/src/tools/specials_parse.cpp b/src/fileio/special_parse.cpp similarity index 100% rename from src/tools/specials_parse.cpp rename to src/fileio/special_parse.cpp diff --git a/src/tools/special_parse.hpp b/src/fileio/special_parse.hpp similarity index 100% rename from src/tools/special_parse.hpp rename to src/fileio/special_parse.hpp diff --git a/src/tools/tarball.cpp b/src/fileio/tarball.cpp similarity index 100% rename from src/tools/tarball.cpp rename to src/fileio/tarball.cpp diff --git a/src/tools/tarball.hpp b/src/fileio/tarball.hpp similarity index 100% rename from src/tools/tarball.hpp rename to src/fileio/tarball.hpp diff --git a/src/dialogxml/xml-parser/build_instructions.txt b/src/fileio/xml-parser/build_instructions.txt similarity index 100% rename from src/dialogxml/xml-parser/build_instructions.txt rename to src/fileio/xml-parser/build_instructions.txt diff --git a/src/dialogxml/xml-parser/changes.txt b/src/fileio/xml-parser/changes.txt similarity index 100% rename from src/dialogxml/xml-parser/changes.txt rename to src/fileio/xml-parser/changes.txt diff --git a/src/dialogxml/xml-parser/dox b/src/fileio/xml-parser/dox similarity index 100% rename from src/dialogxml/xml-parser/dox rename to src/fileio/xml-parser/dox diff --git a/src/dialogxml/xml-parser/readme.txt b/src/fileio/xml-parser/readme.txt similarity index 100% rename from src/dialogxml/xml-parser/readme.txt rename to src/fileio/xml-parser/readme.txt diff --git a/src/dialogxml/xml-parser/ticpp.cpp b/src/fileio/xml-parser/ticpp.cpp similarity index 100% rename from src/dialogxml/xml-parser/ticpp.cpp rename to src/fileio/xml-parser/ticpp.cpp diff --git a/src/dialogxml/xml-parser/ticpp.h b/src/fileio/xml-parser/ticpp.h similarity index 100% rename from src/dialogxml/xml-parser/ticpp.h rename to src/fileio/xml-parser/ticpp.h diff --git a/src/dialogxml/xml-parser/ticpp.lua b/src/fileio/xml-parser/ticpp.lua similarity index 100% rename from src/dialogxml/xml-parser/ticpp.lua rename to src/fileio/xml-parser/ticpp.lua diff --git a/src/dialogxml/xml-parser/ticppapi.h b/src/fileio/xml-parser/ticppapi.h similarity index 100% rename from src/dialogxml/xml-parser/ticppapi.h rename to src/fileio/xml-parser/ticppapi.h diff --git a/src/dialogxml/xml-parser/ticpprc.h b/src/fileio/xml-parser/ticpprc.h similarity index 100% rename from src/dialogxml/xml-parser/ticpprc.h rename to src/fileio/xml-parser/ticpprc.h diff --git a/src/dialogxml/xml-parser/tinyprint.cpp b/src/fileio/xml-parser/tinyprint.cpp similarity index 100% rename from src/dialogxml/xml-parser/tinyprint.cpp rename to src/fileio/xml-parser/tinyprint.cpp diff --git a/src/dialogxml/xml-parser/tinyprint.h b/src/fileio/xml-parser/tinyprint.h similarity index 100% rename from src/dialogxml/xml-parser/tinyprint.h rename to src/fileio/xml-parser/tinyprint.h diff --git a/src/dialogxml/xml-parser/tinystr.cpp b/src/fileio/xml-parser/tinystr.cpp similarity index 100% rename from src/dialogxml/xml-parser/tinystr.cpp rename to src/fileio/xml-parser/tinystr.cpp diff --git a/src/dialogxml/xml-parser/tinystr.h b/src/fileio/xml-parser/tinystr.h similarity index 100% rename from src/dialogxml/xml-parser/tinystr.h rename to src/fileio/xml-parser/tinystr.h diff --git a/src/dialogxml/xml-parser/tinyxml.cpp b/src/fileio/xml-parser/tinyxml.cpp similarity index 100% rename from src/dialogxml/xml-parser/tinyxml.cpp rename to src/fileio/xml-parser/tinyxml.cpp diff --git a/src/dialogxml/xml-parser/tinyxml.h b/src/fileio/xml-parser/tinyxml.h similarity index 100% rename from src/dialogxml/xml-parser/tinyxml.h rename to src/fileio/xml-parser/tinyxml.h diff --git a/src/dialogxml/xml-parser/tinyxmlerror.cpp b/src/fileio/xml-parser/tinyxmlerror.cpp similarity index 100% rename from src/dialogxml/xml-parser/tinyxmlerror.cpp rename to src/fileio/xml-parser/tinyxmlerror.cpp diff --git a/src/dialogxml/xml-parser/tinyxmlparser.cpp b/src/fileio/xml-parser/tinyxmlparser.cpp similarity index 100% rename from src/dialogxml/xml-parser/tinyxmlparser.cpp rename to src/fileio/xml-parser/tinyxmlparser.cpp diff --git a/src/dialogxml/xml-parser/tutorial_gettingStarted.txt b/src/fileio/xml-parser/tutorial_gettingStarted.txt similarity index 100% rename from src/dialogxml/xml-parser/tutorial_gettingStarted.txt rename to src/fileio/xml-parser/tutorial_gettingStarted.txt diff --git a/src/dialogxml/xml-parser/tutorial_ticpp.txt b/src/fileio/xml-parser/tutorial_ticpp.txt similarity index 100% rename from src/dialogxml/xml-parser/tutorial_ticpp.txt rename to src/fileio/xml-parser/tutorial_ticpp.txt diff --git a/src/boe.actions.cpp b/src/game/boe.actions.cpp similarity index 99% rename from src/boe.actions.cpp rename to src/game/boe.actions.cpp index 473b2e6a..dacb8c93 100644 --- a/src/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -20,7 +20,7 @@ #include "boe.newgraph.hpp" #include "boe.combat.hpp" #include "boe.items.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.infodlg.hpp" #include "boe.main.hpp" #include "mathutil.hpp" @@ -1072,7 +1072,7 @@ bool handle_action(sf::Event event) { if(overall_mode == MODE_OUTDOORS) { give_help(62,0); display_map(); - make_cursor_sword(); + set_cursor(sword_curs); } else if(overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) handle_get_items(did_something, need_redraw, need_reprint); break; @@ -1106,7 +1106,7 @@ bool handle_action(sf::Event event) { else if(overall_mode == MODE_TOWN) { give_help(62,0); display_map(); - make_cursor_sword(); + set_cursor(sword_curs); } else handle_missile(need_redraw, need_reprint); break; diff --git a/src/boe.actions.hpp b/src/game/boe.actions.hpp similarity index 97% rename from src/boe.actions.hpp rename to src/game/boe.actions.hpp index 6e3ad468..144a1e89 100644 --- a/src/boe.actions.hpp +++ b/src/game/boe.actions.hpp @@ -4,7 +4,6 @@ #include #include "location.hpp" -#include "simpletypes.hpp" void init_screen_locs(); bool prime_time(); diff --git a/src/boe.appleevents.mm b/src/game/boe.appleevents.mm similarity index 100% rename from src/boe.appleevents.mm rename to src/game/boe.appleevents.mm diff --git a/src/boe.combat.cpp b/src/game/boe.combat.cpp similarity index 99% rename from src/boe.combat.cpp rename to src/game/boe.combat.cpp index b3462d55..4a28dc7f 100644 --- a/src/boe.combat.cpp +++ b/src/game/boe.combat.cpp @@ -13,7 +13,7 @@ #include "boe.items.hpp" #include "boe.party.hpp" #include "boe.combat.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.town.hpp" #include "boe.specials.hpp" #include "boe.graphutil.hpp" diff --git a/src/boe.combat.hpp b/src/game/boe.combat.hpp similarity index 100% rename from src/boe.combat.hpp rename to src/game/boe.combat.hpp diff --git a/src/boe.consts.hpp b/src/game/boe.consts.hpp similarity index 100% rename from src/boe.consts.hpp rename to src/game/boe.consts.hpp diff --git a/src/boe.dlgutil.cpp b/src/game/boe.dlgutil.cpp similarity index 99% rename from src/boe.dlgutil.cpp rename to src/game/boe.dlgutil.cpp index 3e2b77d3..05bcd715 100644 --- a/src/boe.dlgutil.cpp +++ b/src/game/boe.dlgutil.cpp @@ -16,7 +16,7 @@ #include "boe.townspec.hpp" #include "boe.main.hpp" #include "boe.items.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include #include "boe.newgraph.hpp" #include "boe.infodlg.hpp" @@ -26,14 +26,14 @@ #include "choicedlog.hpp" #include "winutil.hpp" #include "fileio.hpp" -#include "restypes.hpp" +#include "res_strings.hpp" #include "scrollbar.hpp" #include "button.hpp" #include "pict.hpp" #include #include "prefs.hpp" #include "shop.hpp" -#include "restypes.hpp" +#include "cursors.hpp" extern short stat_window; extern eGameMode overall_mode; @@ -1065,7 +1065,7 @@ void handle_talk_event(location p) { void do_sign(short town_num, short which_sign, short sign_type) { std::string sign_text; - make_cursor_sword(); + set_cursor(sword_curs); cChoiceDlog sign("view-sign"); cPict& pict = dynamic_cast(sign->getControl("ter")); @@ -1153,7 +1153,7 @@ static bool prefs_event_filter (cDialog& me, std::string id, eKeyMod) { } void pick_preferences() { - make_cursor_sword(); + set_cursor(sword_curs); cDialog prefsDlog("preferences"); prefsDlog.attachClickHandlers(&prefs_event_filter, {"okay", "cancel"}); @@ -1288,7 +1288,7 @@ static bool edit_party_event_filter(cDialog& me, std::string item_hit, eKeyMod) } void edit_party() { - make_cursor_sword(); + set_cursor(sword_curs); cDialog pcDialog("edit-party"); std::vector buttons = {"done", "help"}; @@ -1334,7 +1334,7 @@ void tip_of_day() { short page = get_ran(1,0,ResMgr::get("tips")->size() - 51); - make_cursor_sword(); + set_cursor(sword_curs); cDialog tips("tip-of-day"); tips.attachClickHandlers(std::bind(tip_of_day_event_filter, _1, _2, std::ref(page)),{"done","next"}); @@ -1416,7 +1416,7 @@ short pick_a_scen() { err.show(); return -1; } - make_cursor_sword(); + set_cursor(sword_curs); cDialog pickScen("pick-scenario"); short page = 0; @@ -1435,7 +1435,7 @@ short pick_a_scen() { short pick_prefab_scen() { - make_cursor_sword(); + set_cursor(sword_curs); cChoiceDlog pickScenario("pick-prefab-scen", {"cancel", "scen1", "scen2", "scen3"}); diff --git a/src/boe.dlgutil.hpp b/src/game/boe.dlgutil.hpp similarity index 97% rename from src/boe.dlgutil.hpp rename to src/game/boe.dlgutil.hpp index cec7a409..7eedb392 100644 --- a/src/boe.dlgutil.hpp +++ b/src/game/boe.dlgutil.hpp @@ -3,7 +3,6 @@ #include #include "dialog.hpp" -#include "simpletypes.hpp" #include "shop.hpp" void start_shop_mode(short which,short cost_adj,std::string store_name); diff --git a/src/boe.fileio.cpp b/src/game/boe.fileio.cpp similarity index 98% rename from src/boe.fileio.cpp rename to src/game/boe.fileio.cpp index 641316c5..20f53347 100644 --- a/src/boe.fileio.cpp +++ b/src/game/boe.fileio.cpp @@ -15,12 +15,12 @@ #include "boe.infodlg.hpp" #include "boe.graphutil.hpp" #include "graphtool.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "fileio.hpp" +#include "cursors.hpp" #include -#include "restypes.hpp" #define DONE_BUTTON_ITEM 1 @@ -129,7 +129,7 @@ void finish_load_party(){ } void shift_universe_left() { - make_cursor_watch(); + set_cursor(watch_curs); save_outdoor_maps(); univ.party.outdoor_corner.x--; @@ -157,7 +157,7 @@ void shift_universe_left() { } void shift_universe_right() { - make_cursor_watch(); + set_cursor(watch_curs); save_outdoor_maps(); univ.party.outdoor_corner.x++; univ.party.i_w_c.x--; @@ -182,7 +182,7 @@ void shift_universe_right() { } void shift_universe_up() { - make_cursor_watch(); + set_cursor(watch_curs); save_outdoor_maps(); univ.party.outdoor_corner.y--; univ.party.i_w_c.y++; @@ -208,7 +208,7 @@ void shift_universe_up() { } void shift_universe_down() { - make_cursor_watch(); + set_cursor(watch_curs); save_outdoor_maps(); univ.party.outdoor_corner.y++; @@ -348,7 +348,7 @@ void build_scen_headers() { std::cout << progDir << '\n' << scenDir << std::endl; scen_headers.clear(); fs::recursive_directory_iterator iter(scenDir); - make_cursor_watch(); + set_cursor(watch_curs); while(iter != fs::recursive_directory_iterator()) { fs::file_status stat = iter->status(); diff --git a/src/boe.fileio.hpp b/src/game/boe.fileio.hpp similarity index 87% rename from src/boe.fileio.hpp rename to src/game/boe.fileio.hpp index b3845153..9955d533 100644 --- a/src/boe.fileio.hpp +++ b/src/game/boe.fileio.hpp @@ -4,9 +4,6 @@ #include #include "location.hpp" -#include "simpletypes.hpp" - -namespace fs = boost::filesystem; // TODO: Centralize this alias! void finish_load_party(); void change_rect_terrain(rectangle r,ter_num_t terrain_type,short probability,bool hollow); @@ -30,6 +27,6 @@ void build_scen_headers(); bool load_scenario_header(fs::path filename/*,short header_entry*/); fs::path locate_scenario(std::string scen_name); - void alter_rect(rectangle *r); +void alter_rect(rectangle *r); #endif diff --git a/src/boe.global.hpp b/src/game/boe.global.hpp similarity index 100% rename from src/boe.global.hpp rename to src/game/boe.global.hpp diff --git a/src/boe.graphics.cpp b/src/game/boe.graphics.cpp similarity index 99% rename from src/boe.graphics.cpp rename to src/game/boe.graphics.cpp index 88425d28..34bd1ffb 100644 --- a/src/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -13,7 +13,7 @@ #include "boe.locutils.hpp" #include "boe.text.hpp" #include "graphtool.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "button.hpp" @@ -25,7 +25,7 @@ #include "scrollbar.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "boe.menus.hpp" #include "winutil.hpp" #include "prefs.hpp" diff --git a/src/boe.graphics.hpp b/src/game/boe.graphics.hpp similarity index 98% rename from src/boe.graphics.hpp rename to src/game/boe.graphics.hpp index 3118047e..bcbe278f 100644 --- a/src/boe.graphics.hpp +++ b/src/game/boe.graphics.hpp @@ -4,7 +4,6 @@ #include #include "location.hpp" -#include "simpletypes.hpp" enum { REFRESH_NONE = 0, diff --git a/src/boe.graphutil.cpp b/src/game/boe.graphutil.cpp similarity index 99% rename from src/boe.graphutil.cpp rename to src/game/boe.graphutil.cpp index 795d9bdc..ffaaf92c 100644 --- a/src/boe.graphutil.cpp +++ b/src/game/boe.graphutil.cpp @@ -14,11 +14,11 @@ #include "boe.infodlg.hpp" #include "boe.monster.hpp" #include "boe.specials.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "graphtool.hpp" #include "mathutil.hpp" #include "strdlog.hpp" -#include "restypes.hpp" +#include "res_image.hpp" extern sf::RenderWindow mainPtr; extern rectangle windRect; diff --git a/src/boe.graphutil.hpp b/src/game/boe.graphutil.hpp similarity index 97% rename from src/boe.graphutil.hpp rename to src/game/boe.graphutil.hpp index 09c27b8e..21708fd6 100644 --- a/src/boe.graphutil.hpp +++ b/src/game/boe.graphutil.hpp @@ -4,7 +4,6 @@ #include "pict.hpp" #include "location.hpp" -#include "simpletypes.hpp" #include "graphtool.hpp" void draw_one_terrain_spot (short i,short j,short terrain_to_draw); diff --git a/src/boe.infodlg.cpp b/src/game/boe.infodlg.cpp similarity index 98% rename from src/boe.infodlg.cpp rename to src/game/boe.infodlg.cpp index 2fadf3d1..140b16e1 100644 --- a/src/boe.infodlg.cpp +++ b/src/game/boe.infodlg.cpp @@ -14,7 +14,7 @@ #include "boe.party.hpp" #include "boe.locutils.hpp" #include "boe.text.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.infodlg.hpp" #include "boe.fileio.hpp" #include "boe.main.hpp" @@ -22,11 +22,11 @@ #include "strdlog.hpp" #include "button.hpp" #include "fileio.hpp" -#include "restypes.hpp" #include #include "prefs.hpp" #include "spell.hpp" #include "view_dialogs.hpp" +#include "cursors.hpp" short mage_spell_pos = 0,priest_spell_pos = 0,skill_pos = 0; @@ -116,7 +116,7 @@ void display_spells(eSkill mode,short force_spell,cDialog* parent) { else priest_spell_pos = force_spell; } - make_cursor_sword(); + set_cursor(sword_curs); cDialog spellInfo("spell-info", parent); spellInfo.attachClickHandlers(std::bind(display_spells_event_filter,_1,_2,mode), {"done","left","right"}); @@ -172,7 +172,7 @@ void display_skills(eSkill force_skill,cDialog* parent) { if(skill_pos > 18) skill_pos = 18; - make_cursor_sword(); + set_cursor(sword_curs); cDialog skillDlog("skill-info", parent); skillDlog.attachClickHandlers(display_skills_event_filter,{"done", "left", "right"}); @@ -208,7 +208,7 @@ void display_pc_item(short pc_num,short item,cItem si,cDialog* parent) { if(pc_num == 6) store_i = si; else store_i = univ.party[pc_num].items[item]; - make_cursor_sword(); + set_cursor(sword_curs); cDialog itemInfo("item-info",parent); // By attaching the click handler to "id" and "magic", we suppress normal LED behaviour @@ -264,7 +264,7 @@ void display_monst(short array_pos,cCreature *which_m,short mode) { if(mode == 1) full_roster = true; else store_m = *which_m; - make_cursor_sword(); + set_cursor(sword_curs); cDialog monstInfo("monster-info"); auto event_filter = std::bind(display_monst_event_filter, _1, _2,std::ref(store_m)); @@ -307,7 +307,7 @@ void display_alchemy() { cur_entry = 3; - make_cursor_sword(); + set_cursor(sword_curs); cDialog alchemy("many-str"); alchemy.attachClickHandlers(display_alchemy_event_filter, {"done", "left", "right"}); @@ -441,7 +441,7 @@ void give_pc_info(short pc_num) { using namespace std::placeholders; std::string str; - make_cursor_sword(); + set_cursor(sword_curs); cDialog pcInfo("pc-info"); pcInfo.attachClickHandlers(std::bind(give_pc_info_event_filter, _1, _2, std::ref(pc_num)), {"done", "left", "right"}); @@ -507,7 +507,7 @@ void adventure_notes() { return; } - make_cursor_sword(); + set_cursor(sword_curs); cDialog encNotes("adventure-notes"); encNotes.attachClickHandlers(adventure_notes_event_filter, {"done", "left", "right", "del1", "del2", "del3"}); @@ -567,7 +567,7 @@ void talk_notes() { return; } - make_cursor_sword(); + set_cursor(sword_curs); cDialog talkNotes("talk-notes"); talkNotes.attachClickHandlers(talk_notes_event_filter, {"done", "left", "right", "del"}); @@ -620,7 +620,7 @@ void journal() { store_num_i = univ.party.journal.size(); store_page_on = 0; - make_cursor_sword(); + set_cursor(sword_curs); cDialog journal("event-journal"); journal.attachClickHandlers(journal_event_filter, {"done", "left", "right"}); diff --git a/src/boe.infodlg.hpp b/src/game/boe.infodlg.hpp similarity index 98% rename from src/boe.infodlg.hpp rename to src/game/boe.infodlg.hpp index f8cab0a2..509c82de 100644 --- a/src/boe.infodlg.hpp +++ b/src/game/boe.infodlg.hpp @@ -2,7 +2,6 @@ #ifndef BOE_GAME_INFODLG_H #define BOE_GAME_INFODLG_H -#include "simpletypes.hpp" #include "item.hpp" #include "monster.hpp" #include "pc.hpp" diff --git a/src/boe.items.cpp b/src/game/boe.items.cpp similarity index 99% rename from src/boe.items.cpp rename to src/game/boe.items.cpp index 71f7b091..39a31834 100644 --- a/src/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -14,18 +14,18 @@ #include "boe.locutils.hpp" #include "boe.newgraph.hpp" #include "boe.infodlg.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.monster.hpp" #include "boe.main.hpp" #include "graphtool.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "3choice.hpp" -#include "restypes.hpp" #include "message.hpp" #include #include #include "winutil.hpp" +#include "cursors.hpp" extern short stat_window,which_combat_type; extern eGameMode overall_mode; @@ -528,7 +528,7 @@ bool display_item(location from_loc,short /*pc_num*/,short mode, bool check_cont // short item_array[130]; std::vector item_array; - make_cursor_sword(); + set_cursor(sword_curs); short current_getting_pc = univ.cur_pc; @@ -589,7 +589,7 @@ bool show_get_items(std::string titleText, std::vector& itemRefs, short } short custom_choice_dialog(std::array& strs,short pic_num,ePicType pic_type,std::array& buttons) { - make_cursor_sword(); + set_cursor(sword_curs); std::vector vec(strs.begin(), strs.end()); // Strip off trailing empty strings @@ -664,7 +664,7 @@ static bool get_num_of_items_event_filter(cDialog& me, std::string, eKeyMod) { //town_num; // Will be 0 - 200 for town, 200 - 290 for outdoors //short sign_type; // terrain type short get_num_of_items(short max_num) { - make_cursor_sword(); + set_cursor(sword_curs); cDialog numPanel("get-num"); numPanel.attachClickHandlers(get_num_of_items_event_filter, {"okay"}); @@ -692,10 +692,6 @@ void init_mini_map() { } } -void make_cursor_watch() { - set_cursor(watch_curs); -} - void place_glands(location where,mon_num_t m_type) { cItem store_i; cMonster monst; @@ -848,7 +844,7 @@ static bool get_text_response_event_filter(cDialog& me, std::string, eKeyMod) { } std::string get_text_response(std::string prompt, pic_num_t pic) { - make_cursor_sword(); + set_cursor(sword_curs); cDialog strPanel("get-response"); strPanel.attachClickHandlers(get_text_response_event_filter, {"okay"}); @@ -868,7 +864,7 @@ short get_num_response(short min, short max, std::string prompt) { std::ostringstream sout; sout << prompt; - make_cursor_sword(); + set_cursor(sword_curs); cDialog numPanel("get-num"); numPanel.attachClickHandlers(get_num_of_items_event_filter, {"okay"}); @@ -905,7 +901,7 @@ static bool select_pc_event_filter (cDialog& me, std::string item_hit, eKeyMod) short char_select_pc(short mode,const char *title) { short item_hit; - make_cursor_sword(); + set_cursor(sword_curs); cDialog selectPc("select-pc"); selectPc.attachClickHandlers(select_pc_event_filter, {"cancel", "pick1", "pick2", "pick3", "pick4", "pick5", "pick6"}); diff --git a/src/boe.items.hpp b/src/game/boe.items.hpp similarity index 98% rename from src/boe.items.hpp rename to src/game/boe.items.hpp index bfcff871..969e4ee4 100644 --- a/src/boe.items.hpp +++ b/src/game/boe.items.hpp @@ -27,7 +27,6 @@ short get_num_of_items(short max_num); void init_mini_map(); void draw_help_dialog_item_buttons(cDialog& dialog,short item); void draw_help_dialog_forcefields(cDialog& dialog,short item); -void make_cursor_watch() ; void place_glands(location where,mon_num_t m_type); void reset_item_max(); short item_val(cItem item); diff --git a/src/boe.locutils.cpp b/src/game/boe.locutils.cpp similarity index 100% rename from src/boe.locutils.cpp rename to src/game/boe.locutils.cpp diff --git a/src/boe.locutils.hpp b/src/game/boe.locutils.hpp similarity index 100% rename from src/boe.locutils.hpp rename to src/game/boe.locutils.hpp diff --git a/src/boe.main.cpp b/src/game/boe.main.cpp similarity index 98% rename from src/boe.main.cpp rename to src/game/boe.main.cpp index 7d7e6d08..336a5750 100644 --- a/src/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -18,7 +18,7 @@ #include "boe.infodlg.hpp" #include "boe.main.hpp" #include "winutil.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "graphtool.hpp" #include "mathutil.hpp" #include "fileio.hpp" @@ -30,9 +30,6 @@ #include "prefs.hpp" #include "button.hpp" -extern cursor_type arrow_curs[3][3]; -extern cursor_type current_cursor; - bool All_Done = false; sf::Event event; sf::RenderWindow mainPtr; @@ -170,7 +167,7 @@ void init_boe(int argc, char* argv[]) { mainPtr.clear(sf::Color::Black); mainPtr.display(); - make_cursor_watch(); + set_cursor(watch_curs); boost::thread init_thread([]() { init_buf(); check_for_intel(); @@ -244,7 +241,7 @@ void Handle_One_Event() { case sf::Event::MouseLeft: // Make sure we don't have an arrow cursor when it's outside the window - make_cursor_sword(); + set_cursor(sword_curs); break; case sf::Event::GainedFocus: @@ -568,7 +565,7 @@ void handle_menu_choice(eMenu item_hit) { give_help(62,0); display_map(); } - make_cursor_sword(); + set_cursor(sword_curs); break; case eMenu::HELP_TOC: if(fs::is_directory(progDir/"doc")) @@ -640,7 +637,7 @@ void change_cursor(location where_curs) { cursor_needed = arrow_curs[cursor_direction.y + 1][cursor_direction.x + 1]; } - if(cursor_needed != current_cursor) + if(cursor_needed != Cursor::current) set_cursor(cursor_needed); } diff --git a/src/boe.main.hpp b/src/game/boe.main.hpp similarity index 100% rename from src/boe.main.hpp rename to src/game/boe.main.hpp diff --git a/src/boe.menus.hpp b/src/game/boe.menus.hpp similarity index 100% rename from src/boe.menus.hpp rename to src/game/boe.menus.hpp diff --git a/src/boe.menus.mac.mm b/src/game/boe.menus.mac.mm similarity index 100% rename from src/boe.menus.mac.mm rename to src/game/boe.menus.mac.mm diff --git a/src/boe.menus.win.cpp b/src/game/boe.menus.win.cpp similarity index 100% rename from src/boe.menus.win.cpp rename to src/game/boe.menus.win.cpp diff --git a/src/boe.monster.cpp b/src/game/boe.monster.cpp similarity index 99% rename from src/boe.monster.cpp rename to src/game/boe.monster.cpp index f1a636c0..3ee59ec6 100644 --- a/src/boe.monster.cpp +++ b/src/game/boe.monster.cpp @@ -10,7 +10,7 @@ #include "boe.text.hpp" #include "boe.specials.hpp" #include "boe.items.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.graphics.hpp" #include "boe.newgraph.hpp" #include "boe.main.hpp" diff --git a/src/boe.monster.hpp b/src/game/boe.monster.hpp similarity index 100% rename from src/boe.monster.hpp rename to src/game/boe.monster.hpp diff --git a/src/boe.newgraph.cpp b/src/game/boe.newgraph.cpp similarity index 99% rename from src/boe.newgraph.cpp rename to src/game/boe.newgraph.cpp index f942a2cc..9c16ae04 100644 --- a/src/boe.newgraph.cpp +++ b/src/game/boe.newgraph.cpp @@ -13,7 +13,7 @@ #include "boe.fileio.hpp" #include "boe.locutils.hpp" #include "boe.text.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "graphtool.hpp" #include "scrollbar.hpp" @@ -22,7 +22,7 @@ #include "shop.hpp" #include "spell.hpp" #include "button.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "prefs.hpp" short monsters_faces[190] = { diff --git a/src/boe.newgraph.hpp b/src/game/boe.newgraph.hpp similarity index 100% rename from src/boe.newgraph.hpp rename to src/game/boe.newgraph.hpp diff --git a/src/boe.party.cpp b/src/game/boe.party.cpp similarity index 99% rename from src/boe.party.cpp rename to src/game/boe.party.cpp index 9a976b95..4be0442d 100644 --- a/src/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -24,7 +24,7 @@ #include "boe.locutils.hpp" #include "boe.combat.hpp" #include "boe.text.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.main.hpp" #include "graphtool.hpp" #include "mathutil.hpp" @@ -34,10 +34,10 @@ #include "winutil.hpp" #include "fileio.hpp" #include "boe.menus.hpp" -#include "restypes.hpp" #include #include "button.hpp" #include "spell.hpp" +#include "cursors.hpp" extern short skill_bonus[21]; @@ -146,7 +146,7 @@ void put_party_in_scen(std::string scen_name) { showError("Could not find scenario!"); return; } - make_cursor_watch(); + set_cursor(watch_curs); if(!load_scenario(path, univ.scenario)) return; @@ -1969,8 +1969,7 @@ eSpell pick_spell(short pc_num,eSkill type) { // 70 - no spell OW spell num if(former_spell >= 38) on_which_spell_page = 1; else on_which_spell_page = 0; - - make_cursor_sword(); + set_cursor(sword_curs); cDialog castSpell("cast-spell"); @@ -2129,7 +2128,7 @@ eAlchemy alch_choice(short pc_num) { short difficulty[20] = {1,1,1,3,3, 4,5,5,7,9, 9,10,12,12,9, 14,19,10,16,20}; short store_alchemy_pc; - make_cursor_sword(); + set_cursor(sword_curs); store_alchemy_pc = pc_num; @@ -2158,7 +2157,7 @@ bool pick_pc_graphic(short pc_num,short mode,cDialog* parent) { store_graphic_pc_num = pc_num; store_graphic_mode = mode; - make_cursor_sword(); + set_cursor(sword_curs); cPictChoice pcPic(0,36,PIC_PC,parent); // Customize it for this special case of choosing a PC graphic @@ -2191,7 +2190,7 @@ static bool pc_name_event_filter(cDialog& me, short store_train_pc) { bool pick_pc_name(short pc_num,cDialog* parent) { using namespace std::placeholders; - make_cursor_sword(); + set_cursor(sword_curs); cDialog pcPickName("pick-pc-name", parent); pcPickName["name"].setText(univ.party[pc_num].name); @@ -2207,7 +2206,7 @@ mon_num_t pick_trapped_monst() { std::string sp; cMonster get_monst; - make_cursor_sword(); + set_cursor(sword_curs); cChoiceDlog soulCrystal("soul-crystal",{"cancel","pick1","pick2","pick3","pick4"}); diff --git a/src/boe.party.hpp b/src/game/boe.party.hpp similarity index 100% rename from src/boe.party.hpp rename to src/game/boe.party.hpp diff --git a/src/boe.specials.cpp b/src/game/boe.specials.cpp similarity index 99% rename from src/boe.specials.cpp rename to src/game/boe.specials.cpp index 628e77fb..cfbb373f 100644 --- a/src/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -16,7 +16,7 @@ #include "boe.monster.hpp" #include "boe.locutils.hpp" #include "boe.actions.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.townspec.hpp" #include "boe.graphics.hpp" #include "boe.fileio.hpp" diff --git a/src/boe.specials.hpp b/src/game/boe.specials.hpp similarity index 100% rename from src/boe.specials.hpp rename to src/game/boe.specials.hpp diff --git a/src/boe.startup.cpp b/src/game/boe.startup.cpp similarity index 97% rename from src/boe.startup.cpp rename to src/game/boe.startup.cpp index f1232121..ac3d36f2 100644 --- a/src/boe.startup.cpp +++ b/src/game/boe.startup.cpp @@ -12,14 +12,15 @@ #include "boe.items.hpp" #include "boe.party.hpp" #include "boe.main.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "fileio.hpp" #include "choicedlog.hpp" #include "winutil.hpp" #include "boe.menus.hpp" #include "mathutil.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "prefs.hpp" +#include "cursors.hpp" #include using std::vector; @@ -57,7 +58,7 @@ bool handle_startup_press(location the_point) { case STARTBTN_NEW: draw_startup(0); start_new_game(); - make_cursor_sword(); + set_cursor(sword_curs); draw_startup(0); break; @@ -129,7 +130,7 @@ void handle_splash_events() { extern sf::Event event; if(!mainPtr.pollEvent(event)) return; if(event.type == sf::Event::GainedFocus || event.type == sf::Event::MouseMoved) - make_cursor_watch(); + set_cursor(sword_curs); } void show_logo() { diff --git a/src/boe.text.cpp b/src/game/boe.text.cpp similarity index 99% rename from src/boe.text.cpp rename to src/game/boe.text.cpp index 936eb860..661056ca 100644 --- a/src/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -13,7 +13,8 @@ const int TEXT_BUF_LEN = 70; #include "mathutil.hpp" #include "graphtool.hpp" #include "scrollbar.hpp" -#include "restypes.hpp" +#include "res_image.hpp" +#include "res_font.hpp" #include "spell.hpp" typedef struct { @@ -1200,11 +1201,6 @@ rectangle coord_to_rect(short i,short j) { return to_return; } - -void make_cursor_sword() { - set_cursor(sword_curs); -} - // which_day is day event should happen // which_event is the univ.party.key_times value to cross reference with. // if the key_time is reached before which_day, event won't happen diff --git a/src/boe.text.hpp b/src/game/boe.text.hpp similarity index 98% rename from src/boe.text.hpp rename to src/game/boe.text.hpp index 0db1bc5f..0aeed8ce 100644 --- a/src/boe.text.hpp +++ b/src/game/boe.text.hpp @@ -34,7 +34,6 @@ void restart_printing(); void restore_mode(); void through_sending(); rectangle coord_to_rect(short i,short j); -void make_cursor_sword() ; bool day_reached(unsigned short which_day, unsigned short which_event); void Draw_Some_Item (sf::Texture& src_gworld, rectangle src_rect, sf::RenderTarget& targ_gworld, location target, char masked, short main_win); rectangle get_stat_effect_rect(int which_effect); diff --git a/src/boe.town.cpp b/src/game/boe.town.cpp similarity index 99% rename from src/boe.town.cpp rename to src/game/boe.town.cpp index c7523ae9..72515acf 100644 --- a/src/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -16,7 +16,7 @@ #include "boe.combat.hpp" #include "boe.party.hpp" #include "boe.text.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "boe.locutils.hpp" #include "boe.specials.hpp" #include "boe.infodlg.hpp" @@ -26,7 +26,7 @@ #include "strdlog.hpp" #include "fileio.hpp" #include "winutil.hpp" -#include "restypes.hpp" +#include "res_image.hpp" extern short stat_window,store_spell_target,which_combat_type,combat_active_pc; extern eGameMode overall_mode; diff --git a/src/boe.town.hpp b/src/game/boe.town.hpp similarity index 100% rename from src/boe.town.hpp rename to src/game/boe.town.hpp diff --git a/src/boe.townspec.cpp b/src/game/boe.townspec.cpp similarity index 99% rename from src/boe.townspec.cpp rename to src/game/boe.townspec.cpp index e9da4d59..65bc7960 100644 --- a/src/boe.townspec.cpp +++ b/src/game/boe.townspec.cpp @@ -11,7 +11,7 @@ #include "boe.locutils.hpp" #include "boe.text.hpp" #include "boe.townspec.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "choicedlog.hpp" diff --git a/src/boe.townspec.hpp b/src/game/boe.townspec.hpp similarity index 100% rename from src/boe.townspec.hpp rename to src/game/boe.townspec.hpp diff --git a/src/tools/graphtool.cpp b/src/gfx/graphtool.cpp similarity index 99% rename from src/tools/graphtool.cpp rename to src/gfx/graphtool.cpp index ec6c8bd5..4a66260b 100644 --- a/src/tools/graphtool.cpp +++ b/src/gfx/graphtool.cpp @@ -19,12 +19,15 @@ #endif #include +#include #include #include #include #include -#include "restypes.hpp" +#include "res_image.hpp" +#include "res_font.hpp" +#include "res_strings.hpp" #include "mathutil.hpp" #include "fileio.hpp" diff --git a/src/tools/graphtool.hpp b/src/gfx/graphtool.hpp similarity index 99% rename from src/tools/graphtool.hpp rename to src/gfx/graphtool.hpp index d8495b00..ec21f717 100644 --- a/src/tools/graphtool.hpp +++ b/src/gfx/graphtool.hpp @@ -18,8 +18,6 @@ #include "location.hpp" #include "pictypes.hpp" -namespace fs = boost::filesystem; - struct m_pic_index_t { unsigned char i, x, y; }; diff --git a/src/tools/mask.frag b/src/gfx/mask.frag similarity index 100% rename from src/tools/mask.frag rename to src/gfx/mask.frag diff --git a/src/tools/mask.vert b/src/gfx/mask.vert similarity index 100% rename from src/tools/mask.vert rename to src/gfx/mask.vert diff --git a/src/tools/qdpict.mac.cpp b/src/gfx/qdpict.mac.cpp similarity index 99% rename from src/tools/qdpict.mac.cpp rename to src/gfx/qdpict.mac.cpp index f474da6d..35b793f6 100644 --- a/src/tools/qdpict.mac.cpp +++ b/src/gfx/qdpict.mac.cpp @@ -21,8 +21,6 @@ #include "porting.hpp" #include "location.hpp" -namespace fs = boost::filesystem; - static int16_t extract_word(char* ptr) { int16_t s = *(int16_t*) ptr; flip_short(&s); diff --git a/src/global.hpp b/src/global.hpp new file mode 100644 index 00000000..c53f9a61 --- /dev/null +++ b/src/global.hpp @@ -0,0 +1,27 @@ +/* + * global.hpp + * BoE + * + * Created by Celtic Minstrel on 17-04-13. + * + */ + +#ifndef BOE_PCH +#define BOE_PCH + +typedef unsigned short mon_num_t; +typedef signed short miss_num_t; +typedef unsigned short ter_num_t; +typedef signed short spec_num_t; +typedef signed short item_num_t; +typedef unsigned short str_num_t; + +// OBoE Current Version +const unsigned long long OBOE_CURRENT_VERSION = 0x020000; // MMmmff; M - major, m - minor, f - bugfix +const char* oboeVersionString(); + +// A convenient alias +namespace boost { namespace filesystem {}} +namespace fs = boost::filesystem; + +#endif diff --git a/src/classes/location.cpp b/src/location.cpp similarity index 97% rename from src/classes/location.cpp rename to src/location.cpp index 6e2aebfc..ef1dd8b0 100644 --- a/src/classes/location.cpp +++ b/src/location.cpp @@ -10,6 +10,11 @@ #include "mathutil.hpp" #include +eDirection& operator++ (eDirection& me, int) { + if(me == DIR_HERE) return me = DIR_N; + else return me = (eDirection)(1 + (int)me); +} + bool operator == (location p1,location p2){ if((p1.x == p2.x) & (p1.y == p2.y)) return true; diff --git a/src/classes/location.hpp b/src/location.hpp similarity index 94% rename from src/classes/location.hpp rename to src/location.hpp index ef0ba3e1..97d94990 100644 --- a/src/classes/location.hpp +++ b/src/location.hpp @@ -13,6 +13,18 @@ #include #include +enum eDirection { + DIR_N = 0, + DIR_NE = 1, + DIR_E = 2, + DIR_SE = 3, + DIR_S = 4, + DIR_SW = 5, + DIR_W = 6, + DIR_NW = 7, + DIR_HERE = 8, +}; + struct rectangle; struct location { @@ -128,6 +140,8 @@ struct spec_loc_t : public location { spec_loc_t& operator=(const spec_loc_t& other) = default; }; +eDirection& operator++ (eDirection& me, int); + bool operator == (location p1,location p2); bool operator != (location p1,location p2); bool operator == (rectangle r1, rectangle r2); @@ -144,6 +158,8 @@ rectangle rect(); rectangle rect(location tl, location br); rectangle rect(int top, int left, int bottom, int right); +std::ostream& operator << (std::ostream& out, eDirection e); +std::istream& operator >> (std::istream& in, eDirection& e); std::ostream& operator<< (std::ostream& out, location l); std::ostream& operator<< (std::ostream& out, spec_loc_t l); std::ostream& operator<< (std::ostream& out, sign_loc_t l); diff --git a/src/tools/mathutil.cpp b/src/mathutil.cpp similarity index 100% rename from src/tools/mathutil.cpp rename to src/mathutil.cpp diff --git a/src/tools/mathutil.hpp b/src/mathutil.hpp similarity index 95% rename from src/tools/mathutil.hpp rename to src/mathutil.hpp index bc2a81b4..a3af00e3 100644 --- a/src/tools/mathutil.hpp +++ b/src/mathutil.hpp @@ -10,7 +10,7 @@ #include using std::abs; -short get_ran (short times,short min,short max); +short get_ran(short times, short min, short max); short max(short a,short b); short min(short a,short b); short minmax(short min,short max,short k); diff --git a/src/pcedit/pc.action.cpp b/src/pcedit/pc.action.cpp index 8e31dea2..219495d8 100644 --- a/src/pcedit/pc.action.cpp +++ b/src/pcedit/pc.action.cpp @@ -7,10 +7,11 @@ #include "pc.fileio.hpp" #include "pc.action.hpp" #include "graphtool.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "dialog.hpp" #include "control.hpp" +#include "cursors.hpp" #include extern cUniverse univ; @@ -105,7 +106,7 @@ void edit_gold_or_food(short which_to_edit) { store_which_to_edit = which_to_edit; - make_cursor_sword(); + set_cursor(sword_curs); cDialog dlog("get-num"); dlog["okay"].attachClickHandler(get_num_event_filter); if(which_to_edit == 0) @@ -126,7 +127,7 @@ void edit_day() { location view_loc; - make_cursor_sword(); + set_cursor(sword_curs); cDialog dlog("edit-day"); dlog["okay"].attachClickHandler(get_num_event_filter); @@ -154,7 +155,7 @@ bool take_gold(short amount,bool /*print_result*/) { void edit_xp(cPlayer *pc) { location view_loc; - make_cursor_sword(); + set_cursor(sword_curs); cDialog dlog("edit-xp"); dlog["okay"].attachClickHandler(get_num_event_filter); diff --git a/src/pcedit/pc.editors.cpp b/src/pcedit/pc.editors.cpp index a9cde3d3..4c9ce07e 100644 --- a/src/pcedit/pc.editors.cpp +++ b/src/pcedit/pc.editors.cpp @@ -10,6 +10,7 @@ #include "strdlog.hpp" #include "choicedlog.hpp" #include "winutil.hpp" +#include "cursors.hpp" #include /* @@ -98,7 +99,7 @@ void display_pc(short pc_num,short mode, cDialog* parent) { } which_pc_displayed = pc_num; - make_cursor_sword(); + set_cursor(sword_curs); cDialog pcInfo("pc-spell-info", parent); pcInfo.attachClickHandlers(std::bind(display_pc_event_filter, _1, _2, mode),{"done","left","right"}); @@ -194,7 +195,7 @@ void pick_race_abil(cPlayer *pc,short mode,cDialog* parent) { static const char*const start_str2 = "Click on advantage button to add/remove."; store_pc = pc; - make_cursor_sword(); + set_cursor(sword_curs); cDialog pickAbil("pick-race-abil",parent); pickAbil["done"].attachClickHandler(std::bind(&cDialog::toast, &pickAbil, true)); @@ -231,7 +232,7 @@ extern const eItemAbil alch_ingred2[20] = { }; void display_alchemy(bool allowEdit,cDialog* parent) { - make_cursor_sword(); + set_cursor(sword_curs); cChoiceDlog showAlch("pc-alchemy-info", {"done"}, parent); @@ -539,7 +540,7 @@ static bool spend_xp_event_filter(cDialog& me, std::string item_hit, eKeyMod mod bool spend_xp(short pc_num, short mode, cDialog* parent) { using namespace std::placeholders; - make_cursor_sword(); + set_cursor(sword_curs); xp_dlog_state save; save.who = pc_num; diff --git a/src/pcedit/pc.fileio.cpp b/src/pcedit/pc.fileio.cpp index e4441817..816c5dbe 100644 --- a/src/pcedit/pc.fileio.cpp +++ b/src/pcedit/pc.fileio.cpp @@ -6,10 +6,9 @@ #include "pc.fileio.hpp" #include "pc.graphics.hpp" #include "graphtool.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "pc.editors.hpp" #include "mathutil.hpp" -#include "restypes.hpp" #include "fileio.hpp" extern cUniverse univ; diff --git a/src/pcedit/pc.graphics.cpp b/src/pcedit/pc.graphics.cpp index f5e1671a..7b71ff66 100644 --- a/src/pcedit/pc.graphics.cpp +++ b/src/pcedit/pc.graphics.cpp @@ -4,9 +4,9 @@ #include "pc.graphics.hpp" #include "pc.editors.hpp" #include "pc.action.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "graphtool.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "message.hpp" #include "mathutil.hpp" #include "gitrev.hpp" @@ -788,8 +788,3 @@ void display_party() { win_draw_string(mainPtr,dest_rect,to_draw.str(),eTextMode::WRAP,style); } } - -void make_cursor_sword() { - set_cursor(sword_curs); -} - diff --git a/src/pcedit/pc.graphics.hpp b/src/pcedit/pc.graphics.hpp index 748281d0..1e0ce1fa 100644 --- a/src/pcedit/pc.graphics.hpp +++ b/src/pcedit/pc.graphics.hpp @@ -3,4 +3,3 @@ void init_main_buttons(); void Set_up_win (); void redraw_screen(); void do_button_action(short which_pc,short which_button); -void make_cursor_sword(); \ No newline at end of file diff --git a/src/pcedit/pc.main.cpp b/src/pcedit/pc.main.cpp index f951460f..540cbd05 100644 --- a/src/pcedit/pc.main.cpp +++ b/src/pcedit/pc.main.cpp @@ -7,7 +7,7 @@ #include "pc.editors.hpp" #include "pc.action.hpp" #include "pc.fileio.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "graphtool.hpp" #include "boe.consts.hpp" #include "dialog.hpp" @@ -18,7 +18,7 @@ #include "pc.menus.hpp" #include "winutil.hpp" #include "cursors.hpp" -#include "restypes.hpp" +#include "res_image.hpp" cUniverse univ; diff --git a/src/tools/porting.cpp b/src/porting.cpp similarity index 100% rename from src/tools/porting.cpp rename to src/porting.cpp diff --git a/src/tools/porting.hpp b/src/porting.hpp similarity index 100% rename from src/tools/porting.hpp rename to src/porting.hpp diff --git a/src/race.hpp b/src/race.hpp new file mode 100644 index 00000000..f3747623 --- /dev/null +++ b/src/race.hpp @@ -0,0 +1,53 @@ +// +// race.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_RACE_HPP +#define BoE_RACE_HPP + +enum class eRace { + UNKNOWN = -1, // for parameters to some functions; not valid in the class + HUMAN = 0, + NEPHIL = 1, + SLITH = 2, + VAHNATAI = 3, // Former value from eMonsterType + REPTILE = 4, // 1 + BEAST = 5, // 2 + IMPORTANT = 6, // 3 + MAGE = 7, // 4 + PRIEST = 8, // 5 + HUMANOID = 9, // 6 + DEMON = 10, // 7 + UNDEAD = 11, // 8 + GIANT = 12, // 9 + SLIME = 13, // 10 + STONE = 14, // 11 + BUG = 15, // 12 + DRAGON = 16, // 13 + MAGICAL = 17, // 14 + PLANT = 18, + BIRD = 19, + SKELETAL = 20, + GOBLIN = 21, +}; + +// Types IMPORTANT, MAGE, and PRIEST are implicitly human +inline bool isHuman(eRace race) { + int code = (int) race; + return code == 0 || (code >= 6 && code <= 8); +} + +// Types NEPHIL, SLITH, and VAHNATAI are implicitly humanoid +inline bool isHumanoid(eRace race) { + int code = (int) race; + return (code >= 0 && code <= 3) || (code >= 6 && code <= 9) || code == 21; +} + +std::ostream& operator << (std::ostream& out, eRace e); +std::istream& operator >> (std::istream& in, eRace& e); + +#endif diff --git a/src/classes/area.hpp b/src/scenario/area.hpp similarity index 100% rename from src/classes/area.hpp rename to src/scenario/area.hpp diff --git a/src/classes/item.cpp b/src/scenario/item.cpp similarity index 99% rename from src/classes/item.cpp rename to src/scenario/item.cpp index a3a9aa4a..bae9c169 100644 --- a/src/classes/item.cpp +++ b/src/scenario/item.cpp @@ -17,10 +17,13 @@ #include "boe.consts.hpp" // TODO: If this is needed here, maybe it shouldn't be in the "boe" namespace #include "oldstructs.hpp" -#include "spell.hpp" #include "graphtool.hpp" // for get_str() #include "fileio.hpp" +#include "damage.hpp" +#include "spell.hpp" +#include "race.hpp" + extern const std::multiset equippable = { eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::BOW, eItemType::ARROW, eItemType::THROWN_MISSILE, eItemType::TOOL, eItemType::SHIELD, eItemType::ARMOR, eItemType::HELM, eItemType::GLOVES, diff --git a/src/classes/item.hpp b/src/scenario/item.hpp similarity index 94% rename from src/classes/item.hpp rename to src/scenario/item.hpp index 82c21737..2121d5cd 100644 --- a/src/classes/item.hpp +++ b/src/scenario/item.hpp @@ -13,7 +13,10 @@ #include #include "location.hpp" -#include "simpletypes.hpp" +#include "item_abilities.hpp" +#include "item_variety.hpp" +#include "skills_traits.hpp" +#include "alchemy.hpp" namespace legacy { struct item_record_type; }; diff --git a/src/scenario/item_abilities.hpp b/src/scenario/item_abilities.hpp new file mode 100644 index 00000000..791f2ad4 --- /dev/null +++ b/src/scenario/item_abilities.hpp @@ -0,0 +1,114 @@ +// +// item_abilities.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_ITEM_ABILITIES_HPP +#define BoE_ITEM_ABILITIES_HPP + +enum class eItemAbil { + // Weapon abilities + NONE = 0, + DAMAGING_WEAPON = 1, + SLAYER_WEAPON = 2, + HEALING_WEAPON = 3, + EXPLODING_WEAPON = 4, + RETURNING_MISSILE = 5, + DISTANCE_MISSILE = 6, + SEEKING_MISSILE = 7, + ANTIMAGIC_WEAPON = 8, + STATUS_WEAPON = 9, + SOULSUCKER = 10, + UNUSED = 11, + WEAK_WEAPON = 12, + CAUSES_FEAR = 13, + WEAPON_CALL_SPECIAL = 14, + HP_DAMAGE = 15, + HP_DAMAGE_REVERSE = 16, + SP_DAMAGE = 17, + SP_DAMAGE_REVERSE = 18, + // General abilities + DAMAGE_PROTECTION = 30, + FULL_PROTECTION = 31, + MAGERY = 32, + EVASION = 33, + MARTYRS_SHIELD = 34, + ENCUMBERING = 35, + STATUS_PROTECTION = 36, + SKILL = 37, + BOOST_STAT = 38, + BOOST_WAR = 39, + BOOST_MAGIC = 40, + ACCURACY = 41, + THIEVING = 42, + GIANT_STRENGTH = 43, + LIGHTER_OBJECT = 44, + HEAVIER_OBJECT = 45, + OCCASIONAL_STATUS = 46, + HIT_CALL_SPECIAL = 47, + LIFE_SAVING = 48, + PROTECT_FROM_PETRIFY = 49, + REGENERATE = 50, + POISON_AUGMENT = 51, + RADIANT = 52, + WILL = 53, + FREE_ACTION = 54, + SPEED = 55, + SLOW_WEARER = 56, + PROTECT_FROM_SPECIES = 57, + LOCKPICKS = 58, + DRAIN_MISSILES = 59, + DROP_CALL_SPECIAL = 60, + // Usable + POISON_WEAPON = 70, + AFFECT_STATUS = 71, + CAST_SPELL = 72, + BLISS_DOOM = 73, + AFFECT_EXPERIENCE = 74, + AFFECT_SKILL_POINTS = 75, + AFFECT_HEALTH = 76, + AFFECT_SPELL_POINTS = 77, + LIGHT = 78, + AFFECT_PARTY_STATUS = 79, + HEALTH_POISON = 80, + CALL_SPECIAL = 81, + SUMMONING = 82, + MASS_SUMMONING = 83, + QUICKFIRE = 84, + MESSAGE = 85, + // Reagents + HOLLY = 150, // Holly/Toadstool + COMFREY = 151, // Comfrey Root + NETTLE = 152, // Glowing Nettle + WORMGRASS = 153, // Crypt Shroom/Wormgrass + ASPTONGUE = 154, // Asptongue Mold + EMBERF = 155, // Ember Flower + GRAYMOLD = 156, + MANDRAKE = 157, + SAPPHIRE = 158, + SMOKY_CRYSTAL = 159, + RESURRECTION_BALM = 160, +}; + +enum class eItemAbilCat { + INVALID = -1, + WEAPON, GENERAL, USABLE, REAGENT +}; + +inline eItemAbilCat getItemAbilCategory(eItemAbil abil) { + int code = (int) abil; + if(code >= 0 && code <= 13) + return eItemAbilCat::WEAPON; + if(code >= 30 && code <= 57) + return eItemAbilCat::GENERAL; + if(code >= 70 && code <= 129) + return eItemAbilCat::USABLE; + if(code >= 150 && code <= 161) + return eItemAbilCat::REAGENT; + return eItemAbilCat::INVALID; +} + +#endif diff --git a/src/scenario/item_variety.hpp b/src/scenario/item_variety.hpp new file mode 100644 index 00000000..e253dea5 --- /dev/null +++ b/src/scenario/item_variety.hpp @@ -0,0 +1,65 @@ +// +// item_variety.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_ITEM_VARIETY_HPP +#define BoE_ITEM_VARIETY_HPP + +enum class eItemType { + NO_ITEM = 0, + ONE_HANDED = 1, + TWO_HANDED = 2, + GOLD = 3, + BOW = 4, + ARROW = 5, + THROWN_MISSILE = 6, + POTION = 7, // potion/magic item + SCROLL = 8, // scroll/magic item + WAND = 9, + TOOL = 10, + FOOD = 11, + SHIELD = 12, + ARMOR = 13, + HELM = 14, + GLOVES = 15, + SHIELD_2 = 16, + // don't know why a second type of shield is used ; it is actually checked + // in the armor code -- see below + // and you can't equip another (12) shield while wearing it ... I didn't + // find a single item with this property in the bladbase.exs ... + BOOTS = 17, + RING = 18, + NECKLACE = 19, + WEAPON_POISON = 20, + NON_USE_OBJECT = 21, + PANTS = 22, + CROSSBOW = 23, + BOLTS = 24, + MISSILE_NO_AMMO = 25, //e.g slings + SPECIAL = 26, + QUEST = 27, +}; + +inline bool isArmourType(eItemType type) { + int code = (int) type; + return code >= 12 && code <= 17; +} + +inline bool isWeaponType(eItemType type) { + int code = (int) type; + return (code >= 1 && code <= 6 && code != 3) || (code >= 23 && code <= 25); +} + +inline bool isMissileType(eItemType type) { + return type == eItemType::ARROW || type == eItemType::BOLTS || type == eItemType::THROWN_MISSILE || type == eItemType::MISSILE_NO_AMMO; +} + +enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL}; + +enum class eEnchant {PLUS_ONE, PLUS_TWO, PLUS_THREE, SHOOT_FLAME, FLAMING, PLUS_FIVE, BLESSED}; + +#endif diff --git a/src/classes/monster.cpp b/src/scenario/monster.cpp similarity index 100% rename from src/classes/monster.cpp rename to src/scenario/monster.cpp diff --git a/src/scenario/monster.hpp b/src/scenario/monster.hpp new file mode 100644 index 00000000..9cba0340 --- /dev/null +++ b/src/scenario/monster.hpp @@ -0,0 +1,108 @@ +/* + * monster.h + * BoE + * + * Created by Celtic Minstrel on 20/04/09. + * + */ + +#ifndef BOE_DATA_MONSTER_H +#define BOE_DATA_MONSTER_H + +#include +#include +#include +#include + +#include "sounds.hpp" +#include "graphtool.hpp" +#include "living.hpp" +#include "monster_abilities.hpp" +#include "race.hpp" + +namespace legacy { + struct monster_record_type; + struct creature_data_type; + struct creature_start_type; +}; + +class cScenario; +class cUniverse; + +enum class eAttitude { + DOCILE, HOSTILE_A, FRIENDLY, HOSTILE_B +}; + +enum class eMonstTime { + ALWAYS, + APPEAR_ON_DAY, DISAPPEAR_ON_DAY, + SOMETIMES_C, SOMETIMES_A, SOMETIMES_B, + APPEAR_WHEN_EVENT, DISAPPEAR_WHEN_EVENT, + APPEAR_AFTER_CHOP, +}; + +class cMonster { +public: + struct cAttack{ + unsigned short dice = 0, sides = 0; + eMonstMelee type = eMonstMelee::SWING; + }; + unsigned int level; + std::string m_name; + short m_health; + unsigned int armor; + unsigned int skill; + std::array a; + eRace m_type; + unsigned int speed; + unsigned int mu; + unsigned int cl; + unsigned int treasure; + // HACK: This is only really marked mutable so that I can use operator[] from const methods + mutable std::map abil; + item_num_t corpse_item; + short corpse_item_chance; + std::map resist; + bool mindless, invuln, invisible, guard, amorphous; + unsigned int x_width,y_width; + eAttitude default_attitude; + unsigned int summon_type; + pic_num_t default_facial_pic; + pic_num_t picture_num; + snd_num_t ambient_sound; // has a chance of being played every move + spec_num_t see_spec; + + std::map::iterator addAbil(eMonstAbilTemplate what, int param = 0); + int addAttack(unsigned short dice, unsigned short sides, eMonstMelee type = eMonstMelee::SWING); + + void import_legacy(legacy::monster_record_type& old); + cMonster(); + void writeTo(std::ostream& file) const; + void readFrom(std::istream& file); +}; + +class cTownperson { +public: + mon_num_t number; + eAttitude start_attitude; + location start_loc; + unsigned short mobility; + eMonstTime time_flag; + short spec1, spec2; + short spec_enc_code, time_code; + short monster_time, personality; + short special_on_kill, special_on_talk; + pic_num_t facial_pic; + + void import_legacy(legacy::creature_start_type old); + cTownperson(); + cTownperson(location loc, mon_num_t num, const cMonster& monst); +}; + +std::ostream& operator << (std::ostream& out, eMonstTime e); +std::istream& operator >> (std::istream& in, eMonstTime& e); +std::ostream& operator<< (std::ostream& out, eAttitude node); +std::istream& operator>> (std::istream& in, eAttitude& node); +std::ostream& operator<<(std::ostream& out, const cMonster::cAttack& att); + +#endif diff --git a/src/scenario/monster_abilities.hpp b/src/scenario/monster_abilities.hpp new file mode 100644 index 00000000..bd2fbf9d --- /dev/null +++ b/src/scenario/monster_abilities.hpp @@ -0,0 +1,129 @@ +// +// monster_abilities.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_DATA_MONSTER_ABILITIES_HPP +#define BoE_DATA_MONSTER_ABILITIES_HPP + +#include "damage.hpp" +#include "fields.hpp" +#include "spell.hpp" + +enum class eMonstAbil { + NO_ABIL, + MISSILE, + + DAMAGE, STATUS, FIELD, PETRIFY, DRAIN_SP, + DRAIN_XP, KILL, STEAL_FOOD, STEAL_GOLD, STUN, + DAMAGE2, STATUS2, + + SPLITS, MARTYRS_SHIELD, ABSORB_SPELLS, MISSILE_WEB, + RAY_HEAT, SPECIAL, HIT_TRIGGER, DEATH_TRIGGER, + + RADIATE, SUMMON, +}; + +enum class eMonstMelee {SWING, CLAW, BITE, SLIME, PUNCH, STING, CLUB, BURN, HARM, STAB}; + +enum class eMonstMissile {DART, ARROW, SPEAR, ROCK, RAZORDISK, SPINE, KNIFE, BOLT, BOULDER, RAPID_ARROW}; + +enum class eMonstGen {RAY, TOUCH, GAZE, BREATH, SPIT}; + +enum class eMonstSummon {TYPE, LEVEL, SPECIES}; + +enum class eMonstAbilCat { + INVALID, MISSILE, GENERAL, SUMMON, RADIATE, SPECIAL +}; + +inline eMonstAbilCat getMonstAbilCategory(eMonstAbil what) { + if(what == eMonstAbil::NO_ABIL) + return eMonstAbilCat::SPECIAL; + if(what == eMonstAbil::MISSILE) + return eMonstAbilCat::MISSILE; + if(what >= eMonstAbil::DAMAGE && what <= eMonstAbil::STATUS2) + return eMonstAbilCat::GENERAL; + if(what >= eMonstAbil::SPLITS && what <= eMonstAbil::DEATH_TRIGGER) + return eMonstAbilCat::SPECIAL; + if(what == eMonstAbil::RADIATE) + return eMonstAbilCat::RADIATE; + if(what == eMonstAbil::SUMMON) + return eMonstAbilCat::SUMMON; + return eMonstAbilCat::INVALID; +} + +enum class eMonstAbilTemplate { + // Non-magical missiles + THROWS_DARTS, SHOOTS_ARROWS, THROWS_SPEARS, THROWS_ROCKS1, THROWS_ROCKS2, THROWS_ROCKS3, + THROWS_RAZORDISKS, THROWS_KNIVES, GOOD_ARCHER, SHOOTS_SPINES, CROSSBOWMAN, SLINGER, + // Magical missiles + RAY_PETRIFY, RAY_SP_DRAIN, RAY_HEAT, RAY_PARALYSIS, + BREATH_FIRE, BREATH_FROST, BREATH_ELECTRICITY, BREATH_DARKNESS, BREATH_FOUL, BREATH_SLEEP, + SPIT_ACID, SHOOTS_WEB, + // Touch abilities + TOUCH_POISON, TOUCH_ACID, TOUCH_DISEASE, TOUCH_WEB, TOUCH_SLEEP, TOUCH_DUMB, TOUCH_PARALYSIS, + TOUCH_PETRIFY, TOUCH_DEATH, TOUCH_XP_DRAIN, TOUCH_ICY, TOUCH_ICY_DRAINING, TOUCH_STUN, TOUCH_STEAL_FOOD, TOUCH_STEAL_GOLD, + // Misc abilities + SPLITS, MARTYRS_SHIELD, ABSORB_SPELLS, SUMMON_5, SUMMON_20, SUMMON_50, SPECIAL, HIT_TRIGGERS, DEATH_TRIGGERS, + // Radiate abilities + RADIATE_FIRE, RADIATE_ICE, RADIATE_SHOCK, RADIATE_ANTIMAGIC, RADIATE_SLEEP, RADIATE_STINK, RADIATE_BLADE, RADIATE_WEB, + // Advanced abilities + CUSTOM_MISSILE, CUSTOM_DAMAGE, CUSTOM_STATUS, CUSTOM_FIELD, CUSTOM_PETRIFY, CUSTOM_SP_DRAIN, CUSTOM_XP_DRAIN, + CUSTOM_KILL, CUSTOM_STEAL_FOOD, CUSTOM_STEAL_GOLD, CUSTOM_STUN, CUSTOM_STATUS2, CUSTOM_RADIATE, CUSTOM_SUMMON, + CUSTOM_DAMAGE2, +}; + +union uAbility { + bool active; + struct { + bool active; + eMonstMissile type; + miss_num_t pic; + int dice, sides, skill, range, odds; + } missile; + struct { + bool active; + eMonstGen type; + miss_num_t pic; + int strength, range, odds; + union { + eDamageType dmg; + eStatus stat; + eFieldType fld; + }; + } gen; + struct { + bool active; + eMonstSummon type; + mon_num_t what; + int min, max, len, chance; + } summon; + struct { + bool active; + eFieldType type; + int chance; + eSpellPat pat; + } radiate; + struct { + bool active; + int extra1, extra2, extra3; + } special; + std::string to_string(eMonstAbil myKey) const; + int get_ap_cost(eMonstAbil key) const; +}; + +std::ostream& operator << (std::ostream& out, eMonstAbil e); +std::istream& operator >> (std::istream& in, eMonstAbil& e); +std::ostream& operator << (std::ostream& out, eMonstMissile e); +std::istream& operator >> (std::istream& in, eMonstMissile& e); +std::ostream& operator << (std::ostream& out, eMonstSummon e); +std::istream& operator >> (std::istream& in, eMonstSummon& e); +std::ostream& operator << (std::ostream& out, eMonstMelee e); +std::istream& operator >> (std::istream& in, eMonstMelee& e); +std::ostream& operator << (std::ostream& out, eMonstGen e); +std::istream& operator >> (std::istream& in, eMonstGen& e); + +#endif diff --git a/src/classes/outdoors.cpp b/src/scenario/outdoors.cpp similarity index 100% rename from src/classes/outdoors.cpp rename to src/scenario/outdoors.cpp diff --git a/src/classes/outdoors.hpp b/src/scenario/outdoors.hpp similarity index 98% rename from src/classes/outdoors.hpp rename to src/scenario/outdoors.hpp index a545bf85..cbc060ac 100644 --- a/src/classes/outdoors.hpp +++ b/src/scenario/outdoors.hpp @@ -15,7 +15,6 @@ #include "location.hpp" #include "special.hpp" -#include "simpletypes.hpp" #include "monster.hpp" #include "area.hpp" diff --git a/src/scenario/quest.hpp b/src/scenario/quest.hpp new file mode 100644 index 00000000..3bab2b26 --- /dev/null +++ b/src/scenario/quest.hpp @@ -0,0 +1,25 @@ +// +// quest.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_QUEST_HPP +#define BoE_QUEST_HPP + +enum class eQuestStatus {AVAILABLE, STARTED, COMPLETED, FAILED}; + +class cQuest { +public: + short flags = 0; // 0 - absolute deadline, 1 - relative to when quest started, +10 - start quest when scenario starts + short deadline = -1; + short event = -1; // if this event occurs before the deadline, then the deadline is waived + short xp = 0, gold = 0; // automatically award this much XP and gold to the party when the quest is marked complete + short bank1 = -1, bank2 = -1; // which job bank(s) this quest is in; -1 for none + std::string name; + std::string descr; +}; + +#endif diff --git a/src/classes/scenario.cpp b/src/scenario/scenario.cpp similarity index 100% rename from src/classes/scenario.cpp rename to src/scenario/scenario.cpp diff --git a/src/classes/scenario.hpp b/src/scenario/scenario.hpp similarity index 86% rename from src/classes/scenario.hpp rename to src/scenario/scenario.hpp index 88bab8bf..c0d6e38d 100644 --- a/src/classes/scenario.hpp +++ b/src/scenario/scenario.hpp @@ -21,8 +21,7 @@ #include "town.hpp" #include "vector2d.hpp" #include "shop.hpp" - -namespace fs = boost::filesystem; // TODO: Centralize this namespace alias? +#include "quest.hpp" namespace legacy{ struct scenario_data_type; @@ -35,16 +34,7 @@ struct scenario_header_flags { unsigned char ver[3],min_run_ver,prog_make_ver[3],num_towns; }; -class cQuest { -public: - short flags = 0; // 0 - absolute deadline, 1 - relative to when quest started, +10 - start quest when scenario starts - short deadline = -1; - short event = -1; // if this event occurs before the deadline, then the deadline is waived - short xp = 0, gold = 0; // automatically award this much XP and gold to the party when the quest is marked complete - short bank1 = -1, bank2 = -1; // which job bank(s) this quest is in; -1 for none - std::string name; - std::string descr; -}; +enum eContentRating {G, PG, R, NC17}; class cScenario { public: diff --git a/src/classes/shop.cpp b/src/scenario/shop.cpp similarity index 100% rename from src/classes/shop.cpp rename to src/scenario/shop.cpp diff --git a/src/classes/shop.hpp b/src/scenario/shop.hpp similarity index 76% rename from src/classes/shop.hpp rename to src/scenario/shop.hpp index eb0a718f..17be1cd7 100644 --- a/src/classes/shop.hpp +++ b/src/scenario/shop.hpp @@ -20,6 +20,35 @@ #undef INFINITE #endif +enum class eShopType {NORMAL, ALLOW_DEAD, RANDOM}; + +enum class eShopPrompt {SHOPPING, HEALING, MAGE, PRIEST, SPELLS, ALCHEMY, TRAINING}; + +enum class eShopItemType { + EMPTY, + // These ones must have these numbers in order for old scenarios to be ported correctly + ITEM = 1, + MAGE_SPELL = 2, + PRIEST_SPELL = 3, + ALCHEMY = 4, + SKILL, + TREASURE, + CLASS, + OPT_ITEM, + CALL_SPECIAL, + // All non-healing types must be above here and all healing types below, with HEAL_WOUNDS kept first + HEAL_WOUNDS, + CURE_POISON, + CURE_DISEASE, + CURE_ACID, + CURE_PARALYSIS, + REMOVE_CURSE, + DESTONE, + RAISE_DEAD, + RESURRECT, + CURE_DUMBFOUNDING, +}; + struct cShopItem { eShopItemType type = eShopItemType::EMPTY; size_t quantity, index; diff --git a/src/classes/special.cpp b/src/scenario/special.cpp similarity index 97% rename from src/classes/special.cpp rename to src/scenario/special.cpp index d72a68d3..1c0d328c 100644 --- a/src/classes/special.cpp +++ b/src/scenario/special.cpp @@ -17,6 +17,11 @@ #include "oldstructs.hpp" #include "graphtool.hpp" +#include "spell.hpp" +#include "skills_traits.hpp" +#include "damage.hpp" +#include "fields.hpp" + cSpecial::cSpecial(){ type = eSpecType::NONE; sd1 = -1; @@ -651,6 +656,25 @@ static int offsets[] = { int(eSpecType::OUT_MAKE_WANDER), }; +eSpecCat getNodeCategory(eSpecType node) { + int code = (int) node; + if(code >= 0 && code <= 47) + return eSpecCat::GENERAL; + if(code >= 50 && code <= 63) + return eSpecCat::ONCE; + if(code >= 80 && code <= 107) + return eSpecCat::AFFECT; + if(code >= 130 && code <= 160) + return eSpecCat::IF_THEN; + if(code >= 170 && code <= 204) + return eSpecCat::TOWN; + if(code >= 210 && code <= 218) + return eSpecCat::RECT; + if(code >= 225 && code <= 228) + return eSpecCat::OUTDOOR; + return eSpecCat::INVALID; +} + static std::map loadProps() { std::map allNodeProps; // There's really no need to check all the way to the max of the underlying type. diff --git a/src/scenario/special.hpp b/src/scenario/special.hpp new file mode 100644 index 00000000..31510987 --- /dev/null +++ b/src/scenario/special.hpp @@ -0,0 +1,140 @@ +/* + * special.h + * BoE + * + * Created by Celtic Minstrel on 20/04/09. + * + */ + +#ifndef BOE_DATA_SPECIAL_H +#define BOE_DATA_SPECIAL_H + +#include +#include +#include +#include "location.hpp" + +namespace legacy { struct special_node_type; }; + +// TODO: Add win/lose option to END_SCENARIO +// TODO: Allow OUT_MOVE_PARTY to change the current sector +enum class eSpecType { + INVALID = -1, // A magic value used while processing nodes + NONE = 0, SET_SDF = 1, INC_SDF = 2, DISPLAY_MSG = 3, ENTER_SHOP = 4, + DISPLAY_SM_MSG = 5, FLIP_SDF = 6, SDF_RANDOM = 7, SDF_ADD = 8, SDF_DIFF = 9, + STORY_DIALOG = 10, CANT_ENTER = 11, CHANGE_TIME = 12, SCEN_TIMER_START = 13, PLAY_SOUND = 14, + CHANGE_HORSE_OWNER = 15, CHANGE_BOAT_OWNER = 16, SET_TOWN_VISIBILITY = 17, MAJOR_EVENT_OCCURRED = 18, FORCED_GIVE = 19, + BUY_ITEMS_OF_TYPE = 20, CALL_GLOBAL = 21, SET_SDF_ROW = 22, COPY_SDF = 23, DISPLAY_PICTURE = 24, + REST = 25, TITLED_MSG = 26, END_SCENARIO = 27, SET_POINTER = 28, SET_CAMP_FLAG = 29, + PRINT_NUMS = 30, SDF_TIMES = 31, SDF_DIVIDE = 32, SDF_POWER = 33, CHANGE_TER = 34, + SWAP_TER = 35, TRANS_TER = 36, CLEAR_BUF = 37, APPEND_STRING = 38, APPEND_NUM = 39, + APPEND_MONST = 40, APPEND_ITEM = 41, APPEND_TER = 42, PAUSE = 43, START_TALK = 44, + UPDATE_QUEST = 45, SWAP_STR_BUF = 46, STR_BUF_TO_SIGN = 47, + + ONCE_GIVE_ITEM = 50, ONCE_GIVE_SPEC_ITEM = 51, ONCE_NULL = 52, ONCE_SET_SDF = 53, ONCE_DISPLAY_MSG = 54, + ONCE_DIALOG = 55, UNUSED13 = 56, UNUSED14 = 57, ONCE_GIVE_ITEM_DIALOG = 58, UNUSED15 = 59, + UNUSED16 = 60, ONCE_OUT_ENCOUNTER = 61, ONCE_TOWN_ENCOUNTER = 62, ONCE_TRAP = 63, + + SELECT_TARGET = 80, DAMAGE = 81, AFFECT_HP = 82, AFFECT_SP = 83, AFFECT_XP = 84, + AFFECT_SKILL_PTS = 85, AFFECT_DEADNESS = 86, AFFECT_STATUS = 87, AFFECT_TRAITS = 88, AFFECT_AP = 89, + AFFECT_NAME = 90, AFFECT_LEVEL = 91, AFFECT_MORALE = 92, AFFECT_SOUL_CRYSTAL = 93, GIVE_ITEM = 94, + AFFECT_MONST_TARG = 95, AFFECT_MONST_ATT = 96, AFFECT_MONST_STAT = 97, AFFECT_STAT = 98, AFFECT_MAGE_SPELL = 99, + AFFECT_PRIEST_SPELL = 100, AFFECT_GOLD = 101, AFFECT_FOOD = 102, AFFECT_ALCHEMY = 103, AFFECT_PARTY_STATUS = 104, + CREATE_NEW_PC = 105, STORE_PC = 106, UNSTORE_PC = 107, + + IF_SDF = 130, IF_TOWN_NUM = 131, IF_RANDOM = 132, IF_HAVE_SPECIAL_ITEM = 133, IF_SDF_COMPARE = 134, + IF_TER_TYPE = 135, IF_ALIVE = 136, IF_HAS_GOLD = 137, IF_HAS_FOOD = 138, IF_ITEM_CLASS_ON_SPACE = 139, + IF_HAVE_ITEM_CLASS = 140, IF_EQUIP_ITEM_CLASS = 141, IF_MAGE_SPELL = 142, IF_PRIEST_SPELL = 143, IF_RECIPE = 144, + IF_STATUS = 145, IF_LOOKING = 146, IF_DAY_REACHED = 147, IF_FIELDS = 148, IF_PARTY_SIZE = 149, + IF_EVENT_OCCURRED = 150, IF_SPECIES = 151, IF_TRAIT = 152, IF_STATISTIC = 153, IF_TEXT_RESPONSE = 154, + IF_SDF_EQ = 155, IF_CONTEXT = 156, IF_NUM_RESPONSE = 157, IF_IN_BOAT = 158, IF_ON_HORSE = 159, + IF_QUEST = 160, + + MAKE_TOWN_HOSTILE = 170, TOWN_RUN_MISSILE = 171, TOWN_MONST_ATTACK = 172, TOWN_BOOM_SPACE = 173, TOWN_MOVE_PARTY = 174, + TOWN_HIT_SPACE = 175, TOWN_EXPLODE_SPACE = 176, TOWN_LOCK_SPACE = 177, TOWN_UNLOCK_SPACE = 178, TOWN_SFX_BURST = 179, + TOWN_CREATE_WANDERING = 180, TOWN_PLACE_MONST = 181, TOWN_DESTROY_MONST = 182, TOWN_NUKE_MONSTS = 183, TOWN_GENERIC_LEVER = 184, + TOWN_GENERIC_PORTAL = 185, TOWN_GENERIC_BUTTON = 186, TOWN_GENERIC_STAIR = 187, TOWN_LEVER = 188, TOWN_PORTAL = 189, + TOWN_STAIR = 190, TOWN_RELOCATE = 191, TOWN_PLACE_ITEM = 192, TOWN_SPLIT_PARTY = 193, TOWN_REUNITE_PARTY = 194, + TOWN_TIMER_START = 195, TOWN_CHANGE_LIGHTING = 196, TOWN_SET_ATTITUDE = 197, TOWN_SET_CENTER = 198, TOWN_LIFT_FOG = 199, + TOWN_START_TARGETING = 200, TOWN_SPELL_PAT_FIELD = 201, TOWN_SPELL_PAT_BOOM = 202, TOWN_RELOCATE_CREATURE = 203, TOWN_PLACE_LABEL = 204, + + RECT_PLACE_FIELD = 210, RECT_SET_EXPLORED = 211, RECT_MOVE_ITEMS = 212, RECT_DESTROY_ITEMS = 213, RECT_CHANGE_TER = 214, + RECT_SWAP_TER = 215, RECT_TRANS_TER = 216, RECT_LOCK = 217, RECT_UNLOCK = 218, + + OUT_MAKE_WANDER = 225, OUT_FORCE_TOWN = 226, OUT_PLACE_ENCOUNTER = 227, OUT_MOVE_PARTY = 228, +}; + +class cSpecial { +public: + eSpecType type; + short sd1; + short sd2; + short pic; + short pictype; + short m1; + short m2; + short m3; + short ex1a; + short ex1b; + short ex1c; + short ex2a; + short ex2b; + short ex2c; + short jumpto; + + cSpecial(); + void import_legacy(legacy::special_node_type& old); + void writeTo(std::ostream& file, int n) const; +}; + +class cTimer { +public: + long time = 0; + short node_type = 0; + short node = -1; +}; + +// HAIL means called when initiating conversation. +// TALK means called during conversation. +enum class eSpecCtx { + OUT_MOVE, TOWN_MOVE, COMBAT_MOVE, OUT_LOOK, TOWN_LOOK, + ENTER_TOWN, LEAVE_TOWN, TALK, USE_SPEC_ITEM, TOWN_TIMER, + SCEN_TIMER, PARTY_TIMER, KILL_MONST, OUTDOOR_ENC, FLEE_ENCOUNTER, + WIN_ENCOUNTER, TARGET, USE_SPACE, SEE_MONST, MONST_SPEC_ABIL, + TOWN_HOSTILE, ATTACKING_MELEE, ATTACKING_RANGE, ATTACKED_MELEE, ATTACKED_RANGE, + HAIL, SHOPPING, DROP_ITEM, STARTUP, +}; + +struct pending_special_type { + spec_num_t spec; + eSpecCtx mode; + unsigned short type; // 0 - scen, 1 - out, 2 - town + location where; + long long trigger_time; +}; + +enum class eSpecCat { + INVALID = -1, + GENERAL, ONCE, AFFECT, IF_THEN, TOWN, RECT, OUTDOOR +}; + +struct node_properties_t { + eSpecType self; + std::string opcode() const; + std::string name() const, descr() const; + std::string sdf1_lbl() const, sdf2_lbl() const, sdf1_hlp() const, sdf2_hlp() const; + std::string msg1_lbl() const, msg2_lbl() const, msg3_lbl() const, msg1_hlp() const, msg2_hlp() const, msg3_hlp() const; + std::string pic_lbl() const, pt_lbl() const, pic_hlp() const, pt_hlp() const; + std::string ex1a_lbl() const, ex1b_lbl() const, ex1c_lbl() const, ex1a_hlp() const, ex1b_hlp() const, ex1c_hlp() const; + std::string ex2a_lbl() const, ex2b_lbl() const, ex2c_lbl() const, ex2a_hlp() const, ex2b_hlp() const, ex2c_hlp() const; + std::string jmp_lbl() const, jmp_hlp() const; + char sd1_btn, sd2_btn, m1_btn, m2_btn, m3_btn, p_btn, pt_btn; + char x1a_btn, x1b_btn, x1c_btn, x2a_btn, x2b_btn, x2c_btn; + node_properties_t() {} + node_properties_t(std::initializer_list>); +}; + +const node_properties_t& operator* (eSpecType t); +eSpecCat getNodeCategory(eSpecType node); + +#endif diff --git a/src/classes/talking.cpp b/src/scenario/talking.cpp similarity index 100% rename from src/classes/talking.cpp rename to src/scenario/talking.cpp diff --git a/src/classes/talking.hpp b/src/scenario/talking.hpp similarity index 69% rename from src/classes/talking.hpp rename to src/scenario/talking.hpp index 6749981c..fc7f314b 100644 --- a/src/classes/talking.hpp +++ b/src/scenario/talking.hpp @@ -11,7 +11,6 @@ #include #include -#include "simpletypes.hpp" #include "shop.hpp" namespace legacy { @@ -32,6 +31,37 @@ struct shop_info_t { std::string name; }; +enum class eTalkNode { + REGULAR = 0, + DEP_ON_SDF = 1, + SET_SDF = 2, + INN = 3, + DEP_ON_TIME = 4, + DEP_ON_TIME_AND_EVENT = 5, + DEP_ON_TOWN = 6, + SHOP = 7, + TRAINING = 8, + JOB_BANK = 9, + SELL_WEAPONS = 13, + SELL_ARMOR = 14, + SELL_ITEMS = 15, + IDENTIFY = 16, + ENCHANT = 17, + BUY_INFO = 18, + BUY_SDF = 19, + BUY_SHIP = 20, + BUY_HORSE = 21, + BUY_SPEC_ITEM = 22, + RECEIVE_QUEST = 23, + BUY_TOWN_LOC = 24, + END_FORCE = 25, + END_FIGHT = 26, + END_ALARM = 27, // Town hostile + END_DIE = 28, + CALL_TOWN_SPEC = 29, + CALL_SCEN_SPEC = 30, +}; + class cSpeech { // formerly talking_record_type public: class cNode { // formerly talking_node_type diff --git a/src/classes/terrain.cpp b/src/scenario/terrain.cpp similarity index 99% rename from src/classes/terrain.cpp rename to src/scenario/terrain.cpp index c3f12115..c745d417 100644 --- a/src/classes/terrain.cpp +++ b/src/scenario/terrain.cpp @@ -16,6 +16,7 @@ #include "oldstructs.hpp" #include "graphtool.hpp" // for NO_PIC #include "boe.consts.hpp" // TODO: Put these constants in a global file +#include "damage.hpp" void cTerrain::import_legacy(legacy::terrain_type_type& old){ static const std::set archetypes = { diff --git a/src/classes/terrain.hpp b/src/scenario/terrain.hpp similarity index 96% rename from src/classes/terrain.hpp rename to src/scenario/terrain.hpp index 231ded22..ff3c3cf3 100644 --- a/src/classes/terrain.hpp +++ b/src/scenario/terrain.hpp @@ -12,10 +12,9 @@ #include #include -#include "simpletypes.hpp" #include "pictypes.hpp" #include "location.hpp" -#include "soundtool.hpp" // for snd_num_t +#include "terrain_abilities.hpp" namespace legacy { struct terrain_type_type; }; diff --git a/src/scenario/terrain_abilities.hpp b/src/scenario/terrain_abilities.hpp new file mode 100644 index 00000000..a6c4ae03 --- /dev/null +++ b/src/scenario/terrain_abilities.hpp @@ -0,0 +1,89 @@ +// +// terrain_abilities.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_TERRAIN_ABILITIES_HPP +#define BoE_TERRAIN_ABILITIES_HPP + +enum class eTerSpec { + NONE = 0, + CHANGE_WHEN_STEP_ON = 1, + DAMAGING = 2, // formerly "fire damage" + BRIDGE = 3, // new; formerly "cold damage" + BED = 4, // new; formerly "magic damage" + DANGEROUS = 5, // formerly "poison land" + UNUSED1 = 6, // formerly "disease land" + CRUMBLING = 7, + LOCKABLE = 8, + UNLOCKABLE = 9, + UNUSED2 = 10, // formerly "unlockable + bashable" + IS_A_SIGN = 11, + CALL_SPECIAL = 12, // formerly "call local special" + UNUSED3 = 13, // formerly "call scenario special" + IS_A_CONTAINER = 14, + WILDERNESS_CAVE = 15, + WILDERNESS_SURFACE = 16, // formerly "conveyor north" + WATERFALL_CAVE = 17, // formerly "conveyor east" + WATERFALL_SURFACE = 18, // formerly "conveyor south" + CONVEYOR = 19, // formerly "conveyor west" + BLOCKED_TO_MONSTERS = 20, + TOWN_ENTRANCE = 21, + CHANGE_WHEN_USED = 22, + CALL_SPECIAL_WHEN_USED = 23, + // 1. Change when step on (What to change to, number of sound, Unused) + // 2. Damaging terrain; can't rest here (Amount of damage done, multiplier, damage type) + // 3. Bridge - if the party boats over it, they get the option to land. (Unused, Unused, Unused) + // 4. Bed - change party graphic when they stand on this space + // 5. Dangerous land; can't rest here; percentage chance may be 0 (Strength, Percentage chance, status type) + // 6. Reserved + // 7. Crumbling terrain (Terrain to change to, strength?, destroyed by what - quickfire, shatter/move mountains, or both) + // 8. Lockable terrain (Terrain to change to when locked, Unused, Unused) + // 9. Unlockable terrain (Terrain to change to when locked, Difficulty, can be bashed) + // 10. Reserved + // 11. Sign (Unused, Unused, Unused) + // 12. Call special (Special to call, local or scenario?, Unused) + // 13. Reserved + // 14. Container (Unused, Unused, Unused) + // 15. Waterfall (Direction, Unused, Unused) + // 16. Conveyor Belt (Direction, Unused, Unused) + // 17. Reserved + // 18. Reserved + // 19. Reserved + // 20. Blocked to Monsters (Unused, Unused, Unused) + // 21. Town entrance (Terrain type if hidden, Unused, Unused) + // 22. Change when Used (Terrain to change to when used, Number of sound, Unused) + // 23. Call special when used (Special to call, local or scenario?, Unused) +}; + +enum class eTrimType { + NONE = 0, + WALL = 1, // not a trim, but trims will conform to it as if it's the same ground type (eg stone wall) + S, SE, E, NE, N, NW, W, SW, + NE_INNER, SE_INNER, SW_INNER, NW_INNER, + FRILLS = 14, // like on lava and underground water; no trim_ter required + WALKWAY = 16, // the game will draw walkway corners; trim_ter is base terrain to draw on + WATERFALL = 17, // special case for waterfalls + CITY = 18, // the game will join roads up to this space but not draw roads on the space +}; + +enum class eTerObstruct { + CLEAR = 0, + BLOCK_SIGHT = 1, + BLOCK_MONSTERS = 2, + BLOCK_MOVE = 3, + BLOCK_MOVE_AND_SHOOT = 4, + BLOCK_MOVE_AND_SIGHT = 5, +}; + +inline bool blocksMove(eTerObstruct block) { + int code = (int) block; + return code > 2; +} + +enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH}; + +#endif diff --git a/src/classes/town.cpp b/src/scenario/town.cpp similarity index 100% rename from src/classes/town.cpp rename to src/scenario/town.cpp diff --git a/src/classes/town.hpp b/src/scenario/town.hpp similarity index 96% rename from src/classes/town.hpp rename to src/scenario/town.hpp index fafbf254..640f2ad9 100644 --- a/src/classes/town.hpp +++ b/src/scenario/town.hpp @@ -13,7 +13,6 @@ #include #include #include -#include "simpletypes.hpp" #include "location.hpp" #include "special.hpp" #include "monster.hpp" @@ -32,6 +31,13 @@ namespace legacy { struct preset_field_type; }; +enum eLighting { + LIGHT_NORMAL = 0, + LIGHT_DARK = 1, + LIGHT_DRAINS = 2, + LIGHT_NONE = 3, +}; + class cScenario; class cTown : public cArea { // formerly town_record_type diff --git a/src/classes/town_import.tpp b/src/scenario/town_import.tpp similarity index 100% rename from src/classes/town_import.tpp rename to src/scenario/town_import.tpp diff --git a/src/classes/vehicle.cpp b/src/scenario/vehicle.cpp similarity index 100% rename from src/classes/vehicle.cpp rename to src/scenario/vehicle.cpp diff --git a/src/classes/vehicle.hpp b/src/scenario/vehicle.hpp similarity index 100% rename from src/classes/vehicle.hpp rename to src/scenario/vehicle.hpp diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index 386c36b9..aa43ae38 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -10,7 +10,7 @@ #include "graphtool.hpp" #include "scen.graphics.hpp" #include "scen.actions.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "scen.core.hpp" #include "scen.fileio.hpp" #include "scen.keydlgs.hpp" diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 6c0dca2e..8ba2685b 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -25,7 +25,10 @@ #include "strchoice.hpp" #include "fileio.hpp" #include "field.hpp" -#include "restypes.hpp" +#include "res_strings.hpp" +#include "res_image.hpp" +#include "res_sound.hpp" +#include "cursors.hpp" #include "stack.hpp" #include "spell.hpp" #include "mathutil.hpp" diff --git a/src/scenedit/scen.fileio.cpp b/src/scenedit/scen.fileio.cpp index 43240d9a..1d3b0452 100644 --- a/src/scenedit/scen.fileio.cpp +++ b/src/scenedit/scen.fileio.cpp @@ -10,7 +10,7 @@ #include "scen.keydlgs.hpp" #include "graphtool.hpp" #include "scen.core.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "oldstructs.hpp" #include "fileio.hpp" diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index fe943840..38127d34 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -8,16 +8,17 @@ #include "scen.graphics.hpp" #include #include "scen.keydlgs.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "mathutil.hpp" #include "boe.consts.hpp" // TODO: Put these constants in a global file +#include "cursors.hpp" #include "dialog.hpp" #include "scen.core.hpp" #include "scen.townout.hpp" #include "scrollbar.hpp" -#include "restypes.hpp" +#include "res_image.hpp" #include "scen.btnmg.hpp" diff --git a/src/scenedit/scen.graphics.hpp b/src/scenedit/scen.graphics.hpp index 52c6b480..5cf74beb 100644 --- a/src/scenedit/scen.graphics.hpp +++ b/src/scenedit/scen.graphics.hpp @@ -1,5 +1,5 @@ -#include "simpletypes.hpp" +#include "fields.hpp" void Set_up_win (); void run_startup_g(); diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 871777c4..ad6b0dd6 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -17,7 +17,7 @@ #include "3choice.hpp" #include "strchoice.hpp" #include "pictchoice.hpp" -#include "restypes.hpp" +#include "res_strings.hpp" #include "spell.hpp" extern short cen_x, cen_y; @@ -1209,7 +1209,3 @@ void edit_scen_intro() { edit.run(); } - -void make_cursor_sword() { - set_cursor(wand_curs); -} diff --git a/src/scenedit/scen.keydlgs.hpp b/src/scenedit/scen.keydlgs.hpp index 319c1743..e83ce739 100644 --- a/src/scenedit/scen.keydlgs.hpp +++ b/src/scenedit/scen.keydlgs.hpp @@ -32,7 +32,6 @@ void edit_dialog_text(eStrMode mode,short *str1,cDialog* parent); short edit_special_num(short mode,short what_start); void edit_scen_intro(); bool edit_area_rect_str(info_rect_t& r); -void make_cursor_sword() ; size_t num_strs(eStrMode str_mode); pic_num_t choose_damage_type(short cur, cDialog* parent, bool allow_spec); diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index d2a23bc0..74d8e196 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -11,7 +11,7 @@ #include "scen.actions.hpp" #include "scen.fileio.hpp" #include "scen.btnmg.hpp" -#include "soundtool.hpp" +#include "sounds.hpp" #include "scen.townout.hpp" #include "scen.core.hpp" #include "scen.keydlgs.hpp" @@ -23,7 +23,7 @@ #include "strdlog.hpp" #include "choicedlog.hpp" #include "scen.menus.hpp" -#include "restypes.hpp" +#include "res_image.hpp" /* Globals */ bool All_Done = false; diff --git a/src/skills_traits.hpp b/src/skills_traits.hpp new file mode 100644 index 00000000..4c5108ea --- /dev/null +++ b/src/skills_traits.hpp @@ -0,0 +1,63 @@ +// +// skills_traits.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-13. +// +// + +#ifndef BoE_SKILLS_TRAITS_HPP +#define BoE_SKILLS_TRAITS_HPP + +enum class eSkill { + INVALID = -1, + STRENGTH = 0, + DEXTERITY = 1, + INTELLIGENCE = 2, + EDGED_WEAPONS = 3, + BASHING_WEAPONS = 4, + POLE_WEAPONS = 5, + THROWN_MISSILES = 6, + ARCHERY = 7, + DEFENSE = 8, + MAGE_SPELLS = 9, + PRIEST_SPELLS = 10, + MAGE_LORE = 11, + ALCHEMY = 12, + ITEM_LORE = 13, + DISARM_TRAPS = 14, + LOCKPICKING = 15, + ASSASSINATION = 16, + POISON = 17, + LUCK = 18, + MAX_HP = 19, + MAX_SP = 20, + // Magic values; only for check_party_stat() + CUR_HP = 100, + CUR_SP = 101, + CUR_XP = 102, + CUR_SKILL = 103, + CUR_LEVEL = 104, +}; + +enum class eTrait { + TOUGHNESS = 0, + MAGICALLY_APT = 1, + AMBIDEXTROUS = 2, + NIMBLE = 3, + CAVE_LORE = 4, + WOODSMAN = 5, + GOOD_CONST = 6, + HIGHLY_ALERT = 7, + STRENGTH = 8, + RECUPERATION = 9, + SLUGGISH = 10, + MAGICALLY_INEPT = 11, + FRAIL = 12, + CHRONIC_DISEASE = 13, + BAD_BACK = 14, + PACIFIST = 15, + ANAMA = 16, +}; + +#endif diff --git a/src/tools/soundtool.cpp b/src/sounds.cpp similarity index 97% rename from src/tools/soundtool.cpp rename to src/sounds.cpp index 6f150b95..a199c7b3 100644 --- a/src/tools/soundtool.cpp +++ b/src/sounds.cpp @@ -5,7 +5,7 @@ * Created by Celtic Minstrel on 16/04/09. * */ -#include "soundtool.hpp" +#include "sounds.hpp" #include #include @@ -14,7 +14,7 @@ #include #include -#include "restypes.hpp" +#include "res_sound.hpp" #include "mathutil.hpp" #include "prefs.hpp" diff --git a/src/tools/soundtool.hpp b/src/sounds.hpp similarity index 100% rename from src/tools/soundtool.hpp rename to src/sounds.hpp diff --git a/src/classes/spell.cpp b/src/spell.cpp similarity index 100% rename from src/classes/spell.cpp rename to src/spell.cpp diff --git a/src/spell.hpp b/src/spell.hpp new file mode 100644 index 00000000..1af64896 --- /dev/null +++ b/src/spell.hpp @@ -0,0 +1,102 @@ +// +// spell.hpp +// BoE +// +// Created by Celtic Minstrel on 14-12-12. +// +// + +#ifndef BoE_DATA_SPELL_HPP +#define BoE_DATA_SPELL_HPP + +#include +#include "skills_traits.hpp" + +enum eSpellRefer {REFER_YES, REFER_IMMED, REFER_TARGET, REFER_FANCY}; +enum eSpellSelect {SELECT_NO, SELECT_ACTIVE, SELECT_ANY}; +// This one is meant for indexing a bit field +enum eSpellWhen {WHEN_COMBAT = 1, WHEN_TOWN = 2, WHEN_OUTDOORS = 4}; + +enum eSpellPat {PAT_SINGLE, PAT_SQ, PAT_SMSQ, PAT_OPENSQ, PAT_RAD2, PAT_RAD3, PAT_PLUS, PAT_WALL}; + +enum class eSpell { + NONE = -1, + // Mage spells + LIGHT = 0, SPARK = 1, HASTE_MINOR = 2, STRENGTH = 3, SCARE = 4, + CLOUD_FLAME = 5, IDENTIFY = 6, SCRY_MONSTER = 7, GOO = 8, TRUE_SIGHT = 9, + POISON_MINOR = 10, FLAME = 11, SLOW = 12, DUMBFOUND = 13, ENVENOM = 14, + CLOUD_STINK = 15, SUMMON_BEAST = 16, CONFLAGRATION = 17, DISPEL_SQUARE = 18, CLOUD_SLEEP = 19, + UNLOCK = 20, HASTE = 21, FIREBALL = 22, LIGHT_LONG = 23, FEAR = 24, + WALL_FORCE = 25, SUMMON_WEAK = 26, ARROWS_FLAME = 27, WEB = 28, RESIST_MAGIC = 29, + POISON = 30, ICE_BOLT = 31, SLOW_GROUP = 32, MAGIC_MAP = 33, CAPTURE_SOUL = 34, + SIMULACRUM = 35, ARROWS_VENOM = 36, WALL_ICE = 37, STEALTH = 38, HASTE_MAJOR = 39, + FIRESTORM = 40, DISPEL_BARRIER = 41, BARRIER_FIRE = 42, SUMMON = 43, SHOCKSTORM = 44, + SPRAY_FIELDS = 45, POISON_MAJOR = 46, FEAR_GROUP = 47, KILL = 48, PARALYZE = 49, + DEMON = 50, ANTIMAGIC = 51, MINDDUEL = 52, FLIGHT = 53, SHOCKWAVE = 54, + BLESS_MAJOR = 55, PARALYSIS_MASS = 56, PROTECTION = 57, SUMMON_MAJOR = 58, BARRIER_FORCE = 59, + QUICKFIRE = 60, ARROWS_DEATH = 61, /* Special spells */ STRENGTHEN_TARGET = 62, SUMMON_RAT = 63, WALL_ICE_BALL = 64, + GOO_BOMB = 65, FOUL_VAPOR = 66, CLOUD_SLEEP_LARGE = 67, ACID_SPRAY = 68, PARALYZE_BEAM = 69, + SLEEP_MASS = 70, RAVAGE_ENEMIES = 71, BLADE_AURA = 72, ICY_RAIN = 73, FLAME_AURA = 74, + SUMMON_AID = 75, SUMMON_AID_MAJOR = 76, FLASH_STEP = 77, + // Priest spells + BLESS_MINOR = 100, HEAL_MINOR = 101, POISON_WEAKEN = 102, TURN_UNDEAD = 103, LOCATION = 104, + SANCTUARY = 105, SYMBIOSIS = 106, MANNA_MINOR = 107, RITUAL_SANCTIFY = 108, STUMBLE = 109, + BLESS = 110, POISON_CURE = 111, CURSE = 112, LIGHT_DIVINE = 113, WOUND = 114, + SUMMON_SPIRIT = 115, MOVE_MOUNTAINS = 116, CHARM_FOE = 117, DISEASE = 118, AWAKEN = 119, + HEAL = 120, HEAL_ALL_LIGHT = 121, HOLY_SCOURGE = 122, DETECT_LIFE = 123, PARALYSIS_CURE = 124, + MANNA = 125, FORCEFIELD = 126, DISEASE_CURE = 127, RESTORE_MIND = 128, SMITE = 129, + POISON_CURE_ALL = 130, CURSE_ALL = 131, DISPEL_UNDEAD = 132, CURSE_REMOVE = 133, STICKS_TO_SNAKES = 134, + MARTYRS_SHIELD = 135, CLEANSE = 136, FIREWALK = 137, BLESS_PARTY = 138, HEAL_MAJOR = 139, + RAISE_DEAD = 140, FLAMESTRIKE = 141, SANCTUARY_MASS = 142, SUMMON_HOST = 143, SHATTER = 144, + DISPEL_SPHERE = 145, HEAL_ALL = 146, REVIVE = 147, HYPERACTIVITY = 148, DESTONE = 149, + SUMMON_GUARDIAN = 150, CHARM_MASS = 151, PROTECTIVE_CIRCLE = 152, PESTILENCE = 153, REVIVE_ALL = 154, + RAVAGE_SPIRIT = 155, RESURRECT = 156, DIVINE_THUD = 157, AVATAR = 158, WALL_BLADES = 159, + WORD_RECALL = 160, CLEANSE_MAJOR = 161, /* Special spells */ DISPEL_FIELD = 162, MOVE_MOUNTAINS_MASS = 163, WRACK = 164, + UNHOLY_RAVAGING = 165, AUGMENTATION = 166, NIRVANA = 167, +}; + +inline bool isMage(eSpell spell) { + int code = (int) spell; + return code >= 0 && code < 62; +} + +inline bool isPriest(eSpell spell) { + int code = (int) spell; + return code >= 100 && code < 162; +} + +class cSpell { + static std::map dictionary; + friend const cSpell& operator*(eSpell spell_num); +public: + cSpell() {} // This is just here because the map doesn't work without it + cSpell(eSpell id); + cSpell& withRefer(eSpellRefer r); + cSpell& withCost(int c); + cSpell& withRange(int r); + cSpell& asLevel(int lvl); + cSpell& asType(eSkill type); + cSpell& asPeaceful(); + cSpell& needsSelect(eSpellSelect sel = SELECT_ACTIVE); + cSpell& when(eSpellWhen when); + const cSpell& finish(); + eSpell num; + eSpellRefer refer; + int cost, range, level; + eSpellSelect need_select; + eSkill type; + int when_cast; + bool peaceful = false; + std::string name() const; + bool is_priest() const; + static eSpell fromNum(eSkill type, int num); + static eSpell fromNum(int num); +}; + +// Need to declare this a second time in order for it to be in scope where it's needed +const cSpell& operator*(eSpell spell_num); + +std::ostream& operator<< (std::ostream& out, eSpellPat pat); +std::istream& operator>> (std::istream& in, eSpellPat& pat); + +#endif diff --git a/src/tools/cursors.hpp b/src/tools/cursors.hpp index 6599b8bb..27077958 100644 --- a/src/tools/cursors.hpp +++ b/src/tools/cursors.hpp @@ -12,8 +12,6 @@ #include #include -namespace fs = boost::filesystem; - enum cursor_type { wand_curs = 0, eyedropper_curs = 1, @@ -47,6 +45,7 @@ enum cursor_type { class Cursor { void* ptr; public: + static cursor_type current; Cursor(fs::path imgPath, float hotSpotX, float hotSpotY); ~Cursor(); void apply(); @@ -69,4 +68,10 @@ static const char*const cursors[26] = { "talk", "key", "look", "bucket", "watch", }; +static const cursor_type arrow_curs[3][3] = { + {NW_curs, N_curs, NE_curs}, + {W_curs, wait_curs, E_curs}, + {SW_curs, S_curs, SE_curs}, +}; + #endif diff --git a/src/tools/cursors.mac.mm b/src/tools/cursors.mac.mm index c03936c0..dd6318f2 100644 --- a/src/tools/cursors.mac.mm +++ b/src/tools/cursors.mac.mm @@ -9,9 +9,7 @@ #include "cursors.hpp" #include #include -#include "restypes.hpp" - -extern cursor_type current_cursor; +#include "res_cursor.hpp" static NSImage* imageFromURL(CFURLRef url){ CGImageSourceRef imageSource = CGImageSourceCreateWithURL(url, nullptr); @@ -68,7 +66,7 @@ void obscureCursor() { void set_cursor(cursor_type which_c) { if(which_c != watch_curs) - current_cursor = which_c; + Cursor::current = which_c; if(which_c == text_curs) { [[NSCursor IBeamCursor] set]; } else { @@ -78,5 +76,5 @@ void set_cursor(cursor_type which_c) { } void restore_cursor(){ - set_cursor(current_cursor); + set_cursor(Cursor::current); } diff --git a/src/tools/prefs.win.cpp b/src/tools/prefs.win.cpp index 8e4a45b3..c39897f0 100644 --- a/src/tools/prefs.win.cpp +++ b/src/tools/prefs.win.cpp @@ -9,7 +9,6 @@ #include #include -namespace fs = boost::filesystem; std::map prefs; using iarray = std::vector; static bool prefsLoaded = false, prefsDirty = false; diff --git a/src/tools/winutil.hpp b/src/tools/winutil.hpp index 9682d2aa..9c6b7d56 100644 --- a/src/tools/winutil.hpp +++ b/src/tools/winutil.hpp @@ -13,8 +13,6 @@ #include #include -namespace fs = boost::filesystem; // TODO: Centralize this alias - char keyToChar(sf::Keyboard::Key key, bool isShift); void makeFrontWindow(sf::Window& win); diff --git a/src/classes/creature.cpp b/src/universe/creature.cpp similarity index 100% rename from src/classes/creature.cpp rename to src/universe/creature.cpp diff --git a/src/classes/creature.hpp b/src/universe/creature.hpp similarity index 98% rename from src/classes/creature.hpp rename to src/universe/creature.hpp index a361e1df..6bba86a0 100644 --- a/src/classes/creature.hpp +++ b/src/universe/creature.hpp @@ -13,7 +13,6 @@ #include "location.hpp" #include "monster.hpp" #include "living.hpp" -#include "simpletypes.hpp" class cCreature : public cMonster, public cTownperson, public iLiving { public: diff --git a/src/classes/living.cpp b/src/universe/living.cpp similarity index 100% rename from src/classes/living.cpp rename to src/universe/living.cpp diff --git a/src/classes/living.hpp b/src/universe/living.hpp similarity index 98% rename from src/classes/living.hpp rename to src/universe/living.hpp index 4994b4c6..8cfc80da 100644 --- a/src/classes/living.hpp +++ b/src/universe/living.hpp @@ -13,7 +13,7 @@ #include #include "location.hpp" -#include "simpletypes.hpp" +#include "damage.hpp" class iLiving { public: diff --git a/src/classes/party.cpp b/src/universe/party.cpp similarity index 100% rename from src/classes/party.cpp rename to src/universe/party.cpp diff --git a/src/classes/party.hpp b/src/universe/party.hpp similarity index 98% rename from src/classes/party.hpp rename to src/universe/party.hpp index 9ec058d2..9cef9cab 100644 --- a/src/classes/party.hpp +++ b/src/universe/party.hpp @@ -18,12 +18,13 @@ #include #include "vehicle.hpp" -#include "creatlist.hpp" +#include "population.hpp" #include "item.hpp" #include "pc.hpp" #include "outdoors.hpp" #include "monster.hpp" #include "living.hpp" +#include "quest.hpp" namespace legacy { struct party_record_type; @@ -45,6 +46,12 @@ struct job_bank_t { bool inited = false; }; +enum eEncNoteType { + NOTE_SCEN, + NOTE_OUT, + NOTE_TOWN, +}; + class cUniverse; class cItem; diff --git a/src/classes/pc.cpp b/src/universe/pc.cpp similarity index 100% rename from src/classes/pc.cpp rename to src/universe/pc.cpp diff --git a/src/classes/pc.hpp b/src/universe/pc.hpp similarity index 98% rename from src/classes/pc.hpp rename to src/universe/pc.hpp index 281ec351..c417fc0c 100644 --- a/src/classes/pc.hpp +++ b/src/universe/pc.hpp @@ -15,10 +15,12 @@ #include #include -#include "simpletypes.hpp" #include "item.hpp" #include "pictypes.hpp" #include "living.hpp" +#include "skills_traits.hpp" +#include "race.hpp" +#include "spell.hpp" namespace legacy { struct pc_record_type; }; diff --git a/src/classes/creatlist.cpp b/src/universe/population.cpp similarity index 98% rename from src/classes/creatlist.cpp rename to src/universe/population.cpp index 585ccc85..7017c6d8 100644 --- a/src/classes/creatlist.cpp +++ b/src/universe/population.cpp @@ -6,7 +6,7 @@ * */ -#include "creatlist.hpp" +#include "population.hpp" #include #include diff --git a/src/classes/creatlist.hpp b/src/universe/population.hpp similarity index 100% rename from src/classes/creatlist.hpp rename to src/universe/population.hpp diff --git a/src/classes/universe.cpp b/src/universe/universe.cpp similarity index 100% rename from src/classes/universe.cpp rename to src/universe/universe.cpp diff --git a/src/classes/universe.hpp b/src/universe/universe.hpp similarity index 98% rename from src/classes/universe.hpp rename to src/universe/universe.hpp index b3729ea8..96c16dac 100644 --- a/src/classes/universe.hpp +++ b/src/universe/universe.hpp @@ -15,16 +15,13 @@ #include #include #include "party.hpp" -#include "creatlist.hpp" +#include "population.hpp" #include "item.hpp" #include "town.hpp" #include "talking.hpp" -#include "simpletypes.hpp" #include "scenario.hpp" #include "pictypes.hpp" -namespace fs = boost::filesystem; // TODO: Centralize this namespace alias? - namespace legacy { struct out_info_type; struct current_town_type; diff --git a/src/tools/view_dialogs.cpp b/src/view_dialogs.cpp similarity index 100% rename from src/tools/view_dialogs.cpp rename to src/view_dialogs.cpp diff --git a/src/tools/view_dialogs.hpp b/src/view_dialogs.hpp similarity index 100% rename from src/tools/view_dialogs.hpp rename to src/view_dialogs.hpp diff --git a/test/init.cpp b/test/init.cpp index c6c09685..a76ca88d 100644 --- a/test/init.cpp +++ b/test/init.cpp @@ -9,7 +9,7 @@ #include "catch.hpp" #include "scenario.hpp" #include "creature.hpp" -#include "creatlist.hpp" +#include "population.hpp" #include "pc.hpp" #include "party.hpp" diff --git a/test/item_legacy.cpp b/test/item_legacy.cpp index fad8ba29..0611de28 100644 --- a/test/item_legacy.cpp +++ b/test/item_legacy.cpp @@ -10,6 +10,8 @@ #include "item.hpp" #include "oldstructs.hpp" #include "spell.hpp" +#include "damage.hpp" +#include "race.hpp" static void set_item_name(legacy::item_record_type& item, const std::string& full, const std::string& name) { std::copy_n(full.begin(), std::min(25, 1 + full.size()), item.full_name); diff --git a/test/scen_read.cpp b/test/scen_read.cpp index 6fd04198..8bbabf2a 100644 --- a/test/scen_read.cpp +++ b/test/scen_read.cpp @@ -5,7 +5,7 @@ #include "dialog.hpp" #include "catch.hpp" #include "scenario.hpp" -#include "restypes.hpp" +#include "res_strings.hpp" using namespace std; using namespace ticpp; diff --git a/test/scen_write.cpp b/test/scen_write.cpp index 9cb7d115..efa05673 100644 --- a/test/scen_write.cpp +++ b/test/scen_write.cpp @@ -6,7 +6,7 @@ #include "catch.hpp" #include "scenario.hpp" #include "town.hpp" -#include "restypes.hpp" +#include "res_strings.hpp" using namespace std; using namespace ticpp; diff --git a/test/spec_legacy.cpp b/test/spec_legacy.cpp index 0553a38d..d53981f5 100644 --- a/test/spec_legacy.cpp +++ b/test/spec_legacy.cpp @@ -9,8 +9,15 @@ #include "catch.hpp" #include "oldstructs.hpp" #include "special.hpp" -#include "restypes.hpp" +#include "res_strings.hpp" #include "pictypes.hpp" +#include "spell.hpp" +#include "damage.hpp" +#include "skills_traits.hpp" +#include "fields.hpp" +#include "race.hpp" +#include "monster.hpp" // for eAttitude +#include "town.hpp" // for lighting constants using namespace std; diff --git a/test/ter_legacy.cpp b/test/ter_legacy.cpp index 28b952c7..838a59ae 100644 --- a/test/ter_legacy.cpp +++ b/test/ter_legacy.cpp @@ -9,6 +9,7 @@ #include "catch.hpp" #include "terrain.hpp" #include "oldstructs.hpp" +#include "damage.hpp" TEST_CASE("Converting terrain types from legacy scenarios") { cTerrain new_ter; From d5a02fa4cb1dcce54e5d46394da35866e05d8a6b Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 00:27:20 -0400 Subject: [PATCH 02/11] Ignore any unpacked scenarios in the rsrc subtree --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0b3c6f94..74e47a8f 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,4 @@ test/junk/*.map # Misc oldstructs.txt src/tools/gitrev.hpp +rsrc/**/scenario From 791c2a27d4a494126654fbac9ec71490ae451b05 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 00:28:12 -0400 Subject: [PATCH 03/11] Update style guide on header order --- StyleGuide.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/StyleGuide.md b/StyleGuide.md index a48da71b..3eafef72 100644 --- a/StyleGuide.md +++ b/StyleGuide.md @@ -74,7 +74,7 @@ Order of Includes ----------------- Include files at the top of any file (header or source) should appear in -the following order, with a blank line between groups: +the following order: * the source file's counterpart header (only applicable for source files) @@ -88,7 +88,10 @@ for C headers) * Component-specific Blades of Exile headers All except the last three and the first one should use the angle -brackets include style. +brackets include style. Normally, there should be a blank line +between groups; however, if there are only one or two headers in +a group, it can be merged with an adjacent group. The counterpart +header should always be followed by a blank line, however. Try to make all includes explicit in the header files, rather than relying on indirect includes by including one file that includes others. From e98f9381feb6d6049c37c9ceaeca76737a0a1b2f Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 00:40:05 -0400 Subject: [PATCH 04/11] Move special node category into the node properties struct --- src/fileio/special_parse.cpp | 2 +- src/game/boe.specials.cpp | 2 +- src/scenario/special.cpp | 7 +++++-- src/scenario/special.hpp | 4 ++-- src/scenedit/scen.keydlgs.cpp | 7 +++---- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/fileio/special_parse.cpp b/src/fileio/special_parse.cpp index b431b10c..3a4c448b 100644 --- a/src/fileio/special_parse.cpp +++ b/src/fileio/special_parse.cpp @@ -121,7 +121,7 @@ static void init_specials_parse() { using underlying = unsigned short; for(underlying i = 1; i < std::numeric_limits::max(); i++) { eSpecType check = (eSpecType) i; - eSpecCat category = getNodeCategory(check); + eSpecCat category = (*check).cat; if(category == eSpecCat::INVALID) continue; if((*check).opcode().empty()) warn_missing_opcode(i); diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index cfbb373f..e1688505 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -2059,7 +2059,7 @@ void run_special(eSpecCtx which_mode,short which_type,short start_spec,location special_in_progress = false; return; } - switch(getNodeCategory(cur_node.type)) { + switch((*cur_node.type).cat) { case eSpecCat::GENERAL: if(cur_node.type == eSpecType::NONE && univ.debug_mode) { std::string type("???"); diff --git a/src/scenario/special.cpp b/src/scenario/special.cpp index 1c0d328c..13de6719 100644 --- a/src/scenario/special.cpp +++ b/src/scenario/special.cpp @@ -656,7 +656,7 @@ static int offsets[] = { int(eSpecType::OUT_MAKE_WANDER), }; -eSpecCat getNodeCategory(eSpecType node) { +static eSpecCat getNodeCategory(eSpecType node) { int code = (int) node; if(code >= 0 && code <= 47) return eSpecCat::GENERAL; @@ -688,6 +688,7 @@ static std::map loadProps() { if(category == eSpecCat::INVALID) continue; node_properties_t props; props.self = check; + props.cat = category; int j = int(category), k = i - offsets[j]; props.m1_btn = button_dict[j][0][k]; props.m2_btn = button_dict[j][1][k]; @@ -716,8 +717,10 @@ static std::map loadProps() { } const node_properties_t& operator* (eSpecType t) { + static node_properties_t invalid; static std::map allNodeProps = loadProps(); - return allNodeProps.at(t); + auto iter = allNodeProps.find(t); + return iter == allNodeProps.end() ? invalid : iter->second; } std::string node_properties_t::opcode() const { diff --git a/src/scenario/special.hpp b/src/scenario/special.hpp index 31510987..d936c6d1 100644 --- a/src/scenario/special.hpp +++ b/src/scenario/special.hpp @@ -120,6 +120,7 @@ enum class eSpecCat { struct node_properties_t { eSpecType self; + eSpecCat cat; std::string opcode() const; std::string name() const, descr() const; std::string sdf1_lbl() const, sdf2_lbl() const, sdf1_hlp() const, sdf2_hlp() const; @@ -130,11 +131,10 @@ struct node_properties_t { std::string jmp_lbl() const, jmp_hlp() const; char sd1_btn, sd2_btn, m1_btn, m2_btn, m3_btn, p_btn, pt_btn; char x1a_btn, x1b_btn, x1c_btn, x2a_btn, x2b_btn, x2c_btn; - node_properties_t() {} + node_properties_t() : self(eSpecType::INVALID), cat(eSpecCat::INVALID) {} node_properties_t(std::initializer_list>); }; const node_properties_t& operator* (eSpecType t); -eSpecCat getNodeCategory(eSpecType node); #endif diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index ad6b0dd6..9b56bd9d 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -657,12 +657,11 @@ static bool edit_spec_enc_type(cDialog& me, std::string item_hit, node_stack_t& else if(item_hit == "rect") category = eSpecCat::RECT; int start = -1, finish = -1, current = int(edit_stack.top().node.type); for(int i = 0; i < std::numeric_limits::max(); i++) { - eSpecType check = eSpecType(i); - eSpecCat checkCat = getNodeCategory(check); - if(start >= 0 && checkCat == eSpecCat::INVALID) { + eSpecCat check = (*eSpecType(i)).cat; + if(start >= 0 && check == eSpecCat::INVALID) { finish = i - 1; break; - } else if(checkCat == category && start < 0) + } else if(check == category && start < 0) start = i; } if(start < 0 || finish < 0) return true; From 4baac518e9f0345f16634dd4d3b3df14a4c965ec Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 01:07:21 -0400 Subject: [PATCH 05/11] Move stream operator declarations into the same file as their types --- src/damage.hpp | 7 +++++++ src/scenario/item.hpp | 9 --------- src/scenario/item_abilities.hpp | 3 +++ src/scenario/item_variety.hpp | 5 +++++ src/scenario/quest.hpp | 3 +++ src/scenario/terrain.hpp | 9 --------- src/scenario/terrain_abilities.hpp | 9 +++++++++ src/skills_traits.hpp | 5 +++++ src/universe/party.hpp | 4 ---- src/universe/pc.hpp | 7 ------- 10 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/damage.hpp b/src/damage.hpp index 49618363..efaf94a5 100644 --- a/src/damage.hpp +++ b/src/damage.hpp @@ -116,7 +116,14 @@ inline bool isDead(eMainStatus stat) { std::ostream& operator << (std::ostream& out, eStatus e); std::istream& operator >> (std::istream& in, eStatus& e); +std::istream& operator >> (std::istream& in, ePartyStatus& type); +std::ostream& operator << (std::ostream& out, ePartyStatus type); +std::ostream& operator << (std::ostream& out, eMainStatus e); +std::istream& operator >> (std::istream& in, eMainStatus& e); std::ostream& operator << (std::ostream& out, eDamageType e); std::istream& operator >> (std::istream& in, eDamageType& e); +void operator += (eMainStatus& stat, eMainStatus othr); +void operator -= (eMainStatus& stat, eMainStatus othr); + #endif diff --git a/src/scenario/item.hpp b/src/scenario/item.hpp index 2121d5cd..a465fb53 100644 --- a/src/scenario/item.hpp +++ b/src/scenario/item.hpp @@ -61,15 +61,6 @@ public: void readFrom(std::istream& sin); }; -std::ostream& operator << (std::ostream& out, eItemType e); -std::ostream& operator << (std::ostream& out, eItemAbil e); -std::istream& operator >> (std::istream& in, eItemType& e); -std::istream& operator >> (std::istream& in, eItemAbil& e); -std::ostream& operator << (std::ostream& out, eSkill e); -std::istream& operator >> (std::istream& in, eSkill& e); -std::ostream& operator << (std::ostream& out, eItemUse e); -std::istream& operator >> (std::istream& in, eItemUse& e); - class cSpecItem { public: short flags = 0; diff --git a/src/scenario/item_abilities.hpp b/src/scenario/item_abilities.hpp index 791f2ad4..b6842810 100644 --- a/src/scenario/item_abilities.hpp +++ b/src/scenario/item_abilities.hpp @@ -111,4 +111,7 @@ inline eItemAbilCat getItemAbilCategory(eItemAbil abil) { return eItemAbilCat::INVALID; } +std::ostream& operator << (std::ostream& out, eItemAbil e); +std::istream& operator >> (std::istream& in, eItemAbil& e); + #endif diff --git a/src/scenario/item_variety.hpp b/src/scenario/item_variety.hpp index e253dea5..1b95a878 100644 --- a/src/scenario/item_variety.hpp +++ b/src/scenario/item_variety.hpp @@ -62,4 +62,9 @@ enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL}; enum class eEnchant {PLUS_ONE, PLUS_TWO, PLUS_THREE, SHOOT_FLAME, FLAMING, PLUS_FIVE, BLESSED}; +std::ostream& operator << (std::ostream& out, eItemUse e); +std::istream& operator >> (std::istream& in, eItemUse& e); +std::ostream& operator << (std::ostream& out, eItemType e); +std::istream& operator >> (std::istream& in, eItemType& e); + #endif diff --git a/src/scenario/quest.hpp b/src/scenario/quest.hpp index 3bab2b26..1b2ccc4c 100644 --- a/src/scenario/quest.hpp +++ b/src/scenario/quest.hpp @@ -22,4 +22,7 @@ public: std::string descr; }; +std::istream& operator>>(std::istream& in, eQuestStatus& type); +std::ostream& operator<<(std::ostream& out, eQuestStatus type); + #endif diff --git a/src/scenario/terrain.hpp b/src/scenario/terrain.hpp index ff3c3cf3..49d60601 100644 --- a/src/scenario/terrain.hpp +++ b/src/scenario/terrain.hpp @@ -49,13 +49,4 @@ public: void writeTo(std::ostream& file) const; }; -std::ostream& operator << (std::ostream& out, eTerSpec e); -std::istream& operator >> (std::istream& in, eTerSpec& e); -std::ostream& operator << (std::ostream& out, eTrimType e); -std::istream& operator >> (std::istream& in, eTrimType& e); -std::ostream& operator << (std::ostream& out, eTerObstruct e); -std::istream& operator >> (std::istream& in, eTerObstruct& e); -std::ostream& operator << (std::ostream& out, eStepSnd e); -std::istream& operator >> (std::istream& in, eStepSnd& e); - #endif diff --git a/src/scenario/terrain_abilities.hpp b/src/scenario/terrain_abilities.hpp index a6c4ae03..6bd467d2 100644 --- a/src/scenario/terrain_abilities.hpp +++ b/src/scenario/terrain_abilities.hpp @@ -86,4 +86,13 @@ inline bool blocksMove(eTerObstruct block) { enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH}; +std::ostream& operator << (std::ostream& out, eTerSpec e); +std::istream& operator >> (std::istream& in, eTerSpec& e); +std::ostream& operator << (std::ostream& out, eTrimType e); +std::istream& operator >> (std::istream& in, eTrimType& e); +std::ostream& operator << (std::ostream& out, eTerObstruct e); +std::istream& operator >> (std::istream& in, eTerObstruct& e); +std::ostream& operator << (std::ostream& out, eStepSnd e); +std::istream& operator >> (std::istream& in, eStepSnd& e); + #endif diff --git a/src/skills_traits.hpp b/src/skills_traits.hpp index 4c5108ea..2f2009c3 100644 --- a/src/skills_traits.hpp +++ b/src/skills_traits.hpp @@ -60,4 +60,9 @@ enum class eTrait { ANAMA = 16, }; +std::ostream& operator << (std::ostream& out, eSkill e); +std::istream& operator >> (std::istream& in, eSkill& e); +std::ostream& operator << (std::ostream& out, eTrait e); +std::istream& operator >> (std::istream& in, eTrait& e); + #endif diff --git a/src/universe/party.hpp b/src/universe/party.hpp index 9cef9cab..6587b2c0 100644 --- a/src/universe/party.hpp +++ b/src/universe/party.hpp @@ -236,9 +236,5 @@ bool operator==(const cParty::cEncNote& one, const cParty::cEncNote& two); std::istream& operator>>(std::istream& in, eEncNoteType& type); std::ostream& operator<<(std::ostream& out, eEncNoteType type); -std::istream& operator>>(std::istream& in, ePartyStatus& type); -std::ostream& operator<<(std::ostream& out, ePartyStatus type); -std::istream& operator>>(std::istream& in, eQuestStatus& type); -std::ostream& operator<<(std::ostream& out, eQuestStatus type); #endif diff --git a/src/universe/pc.hpp b/src/universe/pc.hpp index c417fc0c..c2665678 100644 --- a/src/universe/pc.hpp +++ b/src/universe/pc.hpp @@ -176,11 +176,4 @@ public: cPlayer& operator=(cPlayer other) = delete; }; -void operator += (eMainStatus& stat, eMainStatus othr); -void operator -= (eMainStatus& stat, eMainStatus othr); -std::ostream& operator << (std::ostream& out, eMainStatus e); -std::istream& operator >> (std::istream& in, eMainStatus& e); -std::ostream& operator << (std::ostream& out, eTrait e); -std::istream& operator >> (std::istream& in, eTrait& e); - #endif From 936a848166c8f086d080c19455e3fe5af73bc783 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 01:12:56 -0400 Subject: [PATCH 06/11] Move terrain blockage check into cTerrain class --- src/game/boe.actions.cpp | 2 +- src/game/boe.graphics.cpp | 2 +- src/game/boe.locutils.cpp | 4 ++-- src/game/boe.specials.cpp | 4 ++-- src/scenario/terrain.cpp | 5 +++++ src/scenario/terrain.hpp | 1 + src/scenario/terrain_abilities.hpp | 5 ----- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index dacb8c93..7bcdef26 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -2346,7 +2346,7 @@ void increase_age() { if(univ.party.status[ePartyStatus::FLIGHT] == 2) add_string_to_buf("You are starting to descend."); if(univ.party.status[ePartyStatus::FLIGHT] == 1) { - if(blocksMove(univ.scenario.ter_types[univ.out[univ.party.out_loc.x][univ.party.out_loc.y]].blockage)) { + if(univ.scenario.ter_types[univ.out[univ.party.out_loc.x][univ.party.out_loc.y]].blocksMove()) { add_string_to_buf(" You plummet to your deaths."); slay_party(eMainStatus::DEAD); print_buf(); diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 34bd1ffb..44da0252 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -947,7 +947,7 @@ void draw_terrain(short mode) { static ter_num_t get_ground_for_shore(ter_num_t ter){ if(univ.scenario.ter_types[ter].block_horse) return current_ground; - else if(blocksMove(univ.scenario.ter_types[ter].blockage)) return current_ground; + else if(univ.scenario.ter_types[ter].blocksMove()) return current_ground; else return ter; } diff --git a/src/game/boe.locutils.cpp b/src/game/boe.locutils.cpp index f3a6d2df..1774636c 100644 --- a/src/game/boe.locutils.cpp +++ b/src/game/boe.locutils.cpp @@ -208,7 +208,7 @@ short sight_obscurity(short x,short y) { } short combat_obscurity(short x, short y) { - if(blocksMove(univ.scenario.ter_types[coord_to_ter(x,y)].blockage)) return 5; + if(univ.scenario.ter_types[coord_to_ter(x,y)].blocksMove()) return 5; if(is_lava(x,y)) return 5; return sight_obscurity(x,y); } @@ -440,7 +440,7 @@ bool outd_is_special(location to_check) { } bool impassable(ter_num_t terrain_to_check) { - if(blocksMove(univ.scenario.ter_types[terrain_to_check].blockage)) + if(univ.scenario.ter_types[terrain_to_check].blocksMove()) return true; else return false; } diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index e1688505..28e6ae22 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -297,7 +297,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc, play_sound(-1 * ter_flag2); } give_help(47,65); - if(blocksMove(univ.scenario.ter_types[ter].blockage)) + if(univ.scenario.ter_types[ter].blocksMove()) can_enter = false; break; case eTerSpec::DAMAGING: @@ -1018,7 +1018,7 @@ void use_item(short pc,short item) { case ePartyStatus::DETECT_LIFE: ASB(" Your vision of life becomes blurry."); break; case ePartyStatus::FLIGHT: if(i <= str) { - if(blocksMove(univ.scenario.ter_types[univ.out[univ.party.out_loc.x][univ.party.out_loc.y]].blockage)) { + if(univ.scenario.ter_types[univ.out[univ.party.out_loc.x][univ.party.out_loc.y]].blocksMove()) { add_string_to_buf(" You plummet to your deaths."); slay_party(eMainStatus::DEAD); print_buf(); diff --git a/src/scenario/terrain.cpp b/src/scenario/terrain.cpp index c745d417..8b9222e9 100644 --- a/src/scenario/terrain.cpp +++ b/src/scenario/terrain.cpp @@ -408,3 +408,8 @@ void cTerrain::import_legacy(legacy::terrain_type_type& old){ else if(i == 37) frill_for = 36, frill_chance = 25; } + +bool cTerrain::blocksMove() const { + int code = (int) blockage; + return code > 2; +} diff --git a/src/scenario/terrain.hpp b/src/scenario/terrain.hpp index 49d60601..0a8c8473 100644 --- a/src/scenario/terrain.hpp +++ b/src/scenario/terrain.hpp @@ -45,6 +45,7 @@ public: pic_num_t map_pic = -1; unsigned short i; // for temporary use in porting + bool blocksMove() const; void import_legacy(legacy::terrain_type_type& old); void writeTo(std::ostream& file) const; }; diff --git a/src/scenario/terrain_abilities.hpp b/src/scenario/terrain_abilities.hpp index 6bd467d2..93e501c6 100644 --- a/src/scenario/terrain_abilities.hpp +++ b/src/scenario/terrain_abilities.hpp @@ -79,11 +79,6 @@ enum class eTerObstruct { BLOCK_MOVE_AND_SIGHT = 5, }; -inline bool blocksMove(eTerObstruct block) { - int code = (int) block; - return code > 2; -} - enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH}; std::ostream& operator << (std::ostream& out, eTerSpec e); From 5b5b2af46f51a5312a5483394dd8280339fb6c5b Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 01:16:57 -0400 Subject: [PATCH 07/11] Remove custom erase_if function in favor of std::remove_if It was originally added before I understood the correct way to use remove_if As a side-effect, remove bad status now also removes forcecage and charm. --- src/game/boe.town.cpp | 17 +++++------------ src/mathutil.hpp | 10 ---------- src/universe/living.cpp | 34 +++++++++++++++++++--------------- src/universe/living.hpp | 1 + 4 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 72515acf..670c9488 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -578,9 +578,10 @@ location end_town_mode(short switching_level,location destination) { // returns to_return = univ.party.out_loc; - erase_if(univ.party.party_event_timers, [](const cTimer& t) { + auto& timers = univ.party.party_event_timers; + timers.erase(std::remove_if(timers.begin(), timers.end(), [](const cTimer& t) { return t.node_type == 2; - }); + }), timers.end()); } @@ -629,16 +630,8 @@ location end_town_mode(short switching_level,location destination) { // returns univ.party.status[ePartyStatus::STEALTH] = 0; univ.party.status[ePartyStatus::DETECT_LIFE] = 0; // TODO: Yes? No? Maybe? - for(short i = 0; i < 6; i++) - erase_if(univ.party[i].status, [](std::pair kv) -> bool { - if(kv.first == eStatus::POISON) return false; - if(kv.first == eStatus::DISEASE) return false; - if(kv.first == eStatus::DUMB) return false; - if(kv.first == eStatus::ACID && kv.second > 2) - return false; - return true; - }); - + for(cPlayer& who : univ.party) + who.clear_brief_status(); update_explored(to_return); redraw_screen(REFRESH_TERRAIN | REFRESH_TEXT); diff --git a/src/mathutil.hpp b/src/mathutil.hpp index a3af00e3..e00572d1 100644 --- a/src/mathutil.hpp +++ b/src/mathutil.hpp @@ -25,16 +25,6 @@ inline void move_to_zero(T& val){ val--; } -// Not quite mathutil... perhaps I need a more general util file. -// This is from . -template -void erase_if(ContainerT& items, const PredicateT& predicate) { - for(auto it = items.begin(); it != items.end();) { - if(predicate(*it)) it = items.erase(it); - else ++it; - } -}; - // Case-insensitive string comparison seems to be semi-standard, but with different names. #if defined(__APPLE__) #define strnicmp strncasecmp diff --git a/src/universe/living.cpp b/src/universe/living.cpp index 7a5d1aa3..2f3f13a9 100644 --- a/src/universe/living.cpp +++ b/src/universe/living.cpp @@ -9,6 +9,7 @@ #include "living.hpp" #include +#include #include "mathutil.hpp" void iLiving::apply_status(eStatus which, int how_much) { @@ -46,21 +47,24 @@ void iLiving::apply_status(eStatus which, int how_much) { } void iLiving::clear_bad_status() { - status[eStatus::POISON] = 0; - if(status[eStatus::BLESS_CURSE] < 0) - status[eStatus::BLESS_CURSE] = 0; - if(status[eStatus::HASTE_SLOW] < 0) - status[eStatus::HASTE_SLOW] = 0; - status[eStatus::WEBS] = 0; - status[eStatus::DISEASE] = 0; - if(status[eStatus::DUMB] > 0) - status[eStatus::DUMB] = 0; - if(status[eStatus::ASLEEP] > 0) - status[eStatus::ASLEEP] = 0; - status[eStatus::PARALYZED] = 0; - status[eStatus::ACID] = 0; - if(status[eStatus::MAGIC_RESISTANCE] < 0) - status[eStatus::MAGIC_RESISTANCE] = 0; + std::map old; + status.swap(old); + std::remove_copy_if(old.begin(), old.end(), std::inserter(status, status.begin()), [](std::pair kv) { + return isStatusNegative(kv.first) ? kv.second > 0 : kv.second < 0; + }); +} + +void iLiving::clear_brief_status() { + std::map old; + status.swap(old); + std::remove_copy_if(old.begin(), old.end(), std::inserter(status, status.begin()), [](std::pair kv) -> bool { + if(kv.first == eStatus::POISON) return false; + if(kv.first == eStatus::DISEASE) return false; + if(kv.first == eStatus::DUMB) return false; + if(kv.first == eStatus::ACID && kv.second > 2) + return false; + return true; + }); } void iLiving::void_sanctuary() { diff --git a/src/universe/living.hpp b/src/universe/living.hpp index 8cfc80da..50b68644 100644 --- a/src/universe/living.hpp +++ b/src/universe/living.hpp @@ -30,6 +30,7 @@ public: virtual int get_shared_dmg(int base_dmg) const = 0; // And this goes with the above. virtual void apply_status(eStatus which, int how_much); + virtual void clear_brief_status(); virtual void clear_bad_status(); virtual void void_sanctuary(); From e57441f6a02d98bff50bba785cbe54990638e7e0 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 11:38:06 -0400 Subject: [PATCH 08/11] Consolidate active quest data into a single map --- src/game/boe.dlgutil.cpp | 10 +++------ src/game/boe.infodlg.cpp | 2 +- src/game/boe.items.cpp | 6 ++--- src/game/boe.specials.cpp | 47 +++++++++++++++++++++------------------ src/game/boe.text.cpp | 6 ++--- src/game/boe.town.cpp | 2 +- src/scenario/quest.hpp | 9 ++++++++ src/universe/party.cpp | 14 +++++------- src/universe/party.hpp | 5 +---- src/universe/pc.cpp | 6 ++--- src/universe/universe.cpp | 6 ++--- 11 files changed, 55 insertions(+), 58 deletions(-) diff --git a/src/game/boe.dlgutil.cpp b/src/game/boe.dlgutil.cpp index 05bcd715..72714e73 100644 --- a/src/game/boe.dlgutil.cpp +++ b/src/game/boe.dlgutil.cpp @@ -638,9 +638,7 @@ static void show_job_bank(int which_bank, std::string title) { int which = hit[4] - '1'; me["prompt"].setText("Job accepted."); job_bank_t& bank = univ.party.job_banks[which_bank]; - univ.party.quest_status[bank.jobs[which]] = eQuestStatus::STARTED; - univ.party.quest_source[bank.jobs[which]] = store_personality; - univ.party.quest_start[bank.jobs[which]] = univ.party.calc_day(); + univ.party.active_quests[bank.jobs[which]] = cJob(univ.party.calc_day(), store_personality); // Now, if there are spare jobs available, fill in. Otherwise, clear space. if(bank.jobs[4] >= 0) std::swap(bank.jobs[which], bank.jobs[4]); @@ -977,11 +975,9 @@ void handle_talk_event(location p) { showError("Tried to give a nonexistent quest!"); return; } - switch(univ.party.quest_status[a]) { + switch(univ.party.active_quests[a].status) { case eQuestStatus::AVAILABLE: - univ.party.quest_status[a] = eQuestStatus::STARTED; - univ.party.quest_source[a] = -1; - univ.party.quest_start[a] = univ.party.calc_day(); + univ.party.active_quests[a] = cJob(univ.party.calc_day()); break; case eQuestStatus::STARTED: break; diff --git a/src/game/boe.infodlg.cpp b/src/game/boe.infodlg.cpp index 140b16e1..f74ef603 100644 --- a/src/game/boe.infodlg.cpp +++ b/src/game/boe.infodlg.cpp @@ -675,7 +675,7 @@ void put_quest_info(short which_i) { cDialog quest_dlg("quest-info"); quest_dlg["name"].setText(quest.name); quest_dlg["descr"].setText(quest.descr); - int start = univ.party.quest_start[which_i]; + int start = univ.party.active_quests[which_i].start; quest_dlg["start"].setText("Day " + std::to_string(start)); if(quest.deadline > 0) quest_dlg["chop"].setText("Day " + std::to_string(quest.deadline + (quest.flags % 10) * start)); diff --git a/src/game/boe.items.cpp b/src/game/boe.items.cpp index 39a31834..b0de1e14 100644 --- a/src/game/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -495,9 +495,9 @@ static bool display_item_event_filter(cDialog& me, std::string id, size_t& first univ.party.spec_items.insert(item.item_level); set_item_flag(&item); } else if(item.variety == eItemType::QUEST) { - univ.party.quest_status[item.item_level] = eQuestStatus::STARTED; - univ.party.quest_start[item.item_level] = univ.party.calc_day(); - univ.party.quest_source[item.item_level] = -1; + univ.party.active_quests[item.item_level].status = eQuestStatus::STARTED; + univ.party.active_quests[item.item_level].start = univ.party.calc_day(); + univ.party.active_quests[item.item_level].source = -1; set_item_flag(&item); } else { if(!allow_overload && item.item_weight() > univ.party[current_getting_pc].free_weight()) { diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index 28e6ae22..fe5ff2ed 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -1806,18 +1806,18 @@ void special_increase_age(long length, bool queue) { trigger_loc = univ.party.out_loc; } - for(auto& p : univ.party.quest_status) { - if(p.second != eQuestStatus::STARTED) + for(auto& p : univ.party.active_quests) { + if(p.second.status != eQuestStatus::STARTED) continue; cQuest& quest = univ.scenario.quests[p.first]; if(quest.deadline <= 0) continue; bool is_relative = quest.flags % 10; - int deadline = quest.deadline + is_relative * univ.party.quest_start[p.first]; + int deadline = quest.deadline + is_relative * p.second.start; if(day_reached(deadline + 1, quest.event)) { - p.second = eQuestStatus::FAILED; - if(univ.party.quest_source[p.first] >= 0) { - int bank = univ.party.quest_source[p.first]; + p.second.status = eQuestStatus::FAILED; + if(p.second.source >= 0) { + int bank = p.second.source; // Safety valve in case it was given by a special node if(bank >= univ.party.job_banks.size()) univ.party.job_banks.resize(bank + 1); @@ -1829,7 +1829,7 @@ void special_increase_age(long length, bool queue) { add_anger++; if(quest.deadline < 5) add_anger++; - } else if(quest.deadline - univ.party.quest_start[p.first] > 20) + } else if(quest.deadline - p.second.start > 20) add_anger++; univ.party.job_banks[bank].anger += add_anger; } @@ -2460,7 +2460,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, *next_spec = -1; break; } - case eSpecType::UPDATE_QUEST: + case eSpecType::UPDATE_QUEST: { check_mess = true; if(spec.ex1a < 0 || spec.ex1a >= univ.scenario.quests.size()) { showError("The scenario tried to update a non-existent quest."); @@ -2470,33 +2470,36 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, showError("Invalid quest status (range 0 .. 3)."); break; } - if(spec.ex1b == int(eQuestStatus::STARTED) && univ.party.quest_status[spec.ex1a] != eQuestStatus::STARTED) { - univ.party.quest_start[spec.ex1a] = univ.party.calc_day(); - univ.party.quest_source[spec.ex1a] = max(-1,spec.ex2a); - if(univ.party.quest_source[spec.ex1a] >= univ.party.job_banks.size()) - univ.party.job_banks.resize(univ.party.quest_source[spec.ex1a] + 1); + auto& job = univ.party.active_quests[spec.ex1a]; + auto& quest = univ.scenario.quests[spec.ex1a]; + if(spec.ex1b == int(eQuestStatus::STARTED) && job.status != eQuestStatus::STARTED) { + job.start = univ.party.calc_day(); + job.source = max(-1,spec.ex2a); + if(job.source >= univ.party.job_banks.size()) + univ.party.job_banks.resize(job.source + 1); } - univ.party.quest_status[spec.ex1a] = eQuestStatus(spec.ex1b); - switch(univ.party.quest_status[spec.ex1a]) { + job.status = eQuestStatus(spec.ex1b); + switch(job.status) { case eQuestStatus::STARTED: add_string_to_buf("You have received a quest."); break; case eQuestStatus::AVAILABLE: break; // TODO: Should this award XP/gold if the quest was previously started? case eQuestStatus::FAILED: add_string_to_buf("You have failed to complete a quest."); - if(univ.party.quest_source[spec.ex1a] >= 0 && univ.party.quest_source[spec.ex1a] < univ.party.job_banks.size()) - univ.party.job_banks[univ.party.quest_source[spec.ex1a]].anger += spec.ex2a < 0 ? 1 : spec.ex2a; + if(job.source >= 0 && job.source < univ.party.job_banks.size()) + univ.party.job_banks[job.source].anger += spec.ex2a < 0 ? 1 : spec.ex2a; break; case eQuestStatus::COMPLETED: add_string_to_buf("You have completed a quest!"); - if(univ.scenario.quests[spec.ex1a].gold > 0) { - int gold = univ.scenario.quests[spec.ex1a].gold; + if(quest.gold > 0) { + int gold = quest.gold; add_string_to_buf(" Received " + std::to_string(gold) + " as a reward."); give_gold(gold, true); } - if(univ.scenario.quests[spec.ex1a].xp > 0) - award_party_xp(univ.scenario.quests[spec.ex1a].xp); + if(quest.xp > 0) + award_party_xp(quest.xp); break; } break; + } default: showError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!"); break; @@ -3738,7 +3741,7 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, showError("Invalid quest status (range 0 .. 3)."); break; } - if(univ.party.quest_status[spec.ex1a] == eQuestStatus(spec.ex1b)) + if(univ.party.active_quests[spec.ex1a].status == eQuestStatus(spec.ex1b)) *next_spec = spec.ex1c; break; case eSpecType::IF_CONTEXT: diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index 661056ca..711a8a25 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -573,13 +573,13 @@ void set_stat_window(short new_stat) { case ITEM_WIN_QUESTS: std::fill(spec_item_array.begin(), spec_item_array.end(), -1); for(short i = 0; i < univ.scenario.quests.size(); i++) - if(univ.party.quest_status[i] == eQuestStatus::STARTED) { + if(univ.party.active_quests[i].status == eQuestStatus::STARTED) { spec_item_array.push_back(i); array_pos++; - } else if(univ.party.quest_status[i] == eQuestStatus::COMPLETED) { + } else if(univ.party.active_quests[i].status == eQuestStatus::COMPLETED) { spec_item_array.push_back(i + 10000); array_pos++; - } else if(univ.party.quest_status[i] == eQuestStatus::FAILED) { + } else if(univ.party.active_quests[i].status == eQuestStatus::FAILED) { spec_item_array.push_back(i + 20000); array_pos++; } diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 670c9488..48b7f3b4 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -377,7 +377,7 @@ void start_town_mode(short which_town, short entry_dir) { continue; } // Don't place quest items if party already started - if(item.variety == eItemType::QUEST && univ.party.quest_status[item.item_level] != eQuestStatus::AVAILABLE) { + if(item.variety == eItemType::QUEST && univ.party.active_quests[item.item_level].status != eQuestStatus::AVAILABLE) { univ.town.items.pop_back(); continue; } diff --git a/src/scenario/quest.hpp b/src/scenario/quest.hpp index 1b2ccc4c..3a0c06f6 100644 --- a/src/scenario/quest.hpp +++ b/src/scenario/quest.hpp @@ -22,6 +22,15 @@ public: std::string descr; }; +class cJob { +public: + cJob() : status(eQuestStatus::AVAILABLE), start(0), source(-1) {} + explicit cJob(int start, int source = -1) : status(eQuestStatus::STARTED), start(start), source(source) {} + eQuestStatus status; + int start; // the day the quest was started; used for quests with relative deadlines + int source; // if gotten from a job board, this is the number of the job board; otherwise -1 +}; + std::istream& operator>>(std::istream& in, eQuestStatus& type); std::ostream& operator<<(std::ostream& out, eQuestStatus type); diff --git a/src/universe/party.cpp b/src/universe/party.cpp index 8559ba11..133e8c4d 100644 --- a/src/universe/party.cpp +++ b/src/universe/party.cpp @@ -86,9 +86,7 @@ cParty::cParty(const cParty& other) , special_notes(other.special_notes) , talk_save(other.talk_save) , status(other.status) - , quest_status(other.quest_status) - , quest_start(other.quest_start) - , quest_source(other.quest_source) + , active_quests(other.active_quests) , left_at(other.left_at) , left_in(other.left_in) , direction(other.direction) @@ -158,9 +156,7 @@ void cParty::swap(cParty& other) { std::swap(special_notes, other.special_notes); std::swap(talk_save, other.talk_save); std::swap(status, other.status); - std::swap(quest_status, other.quest_status); - std::swap(quest_start, other.quest_start); - std::swap(quest_source, other.quest_source); + std::swap(active_quests, other.active_quests); std::swap(left_at, other.left_at); std::swap(left_in, other.left_in); std::swap(direction, other.direction); @@ -741,8 +737,8 @@ void cParty::writeTo(std::ostream& file, const cScenario& scen) const { file << "SCENARIO " << scen_name << '\n'; file << "WON " << scen_won << '\n'; file << "PLAYED " << scen_played << '\n'; - for(auto p : quest_status) - file << "QUEST " << p.first << ' ' << p.second << ' ' << quest_start.at(p.first) << ' ' << quest_source.at(p.first) << '\n'; + for(auto p : active_quests) + file << "QUEST " << p.first << ' ' << p.second.status << ' ' << p.second.start << ' ' << p.second.source << '\n'; for(auto p : store_limited_stock) { for(auto p2 : p.second) { file << "SHOPSTOCK " << p.first << p2.first << p2.second; @@ -990,7 +986,7 @@ void cParty::readFrom(std::istream& file, cScenario& scen){ } else if(cur == "QUEST") { int i; sin >> i; - sin >> quest_status[i] >> quest_start[i] >> quest_source[i]; + sin >> active_quests[i].status >> active_quests[i].start >> active_quests[i].source; } else if(cur == "SHOPSTOCK") { int i, j; sin >> i >> j >> store_limited_stock[i][j]; diff --git a/src/universe/party.hpp b/src/universe/party.hpp index 6587b2c0..8a29b14a 100644 --- a/src/universe/party.hpp +++ b/src/universe/party.hpp @@ -111,10 +111,7 @@ public: std::vector special_notes; std::vector talk_save; std::map status; - // Quest stuff - std::map quest_status; - std::map quest_start; // the day the quest was started; used for quests with relative deadlines - std::map quest_source; // if gotten from a job board, this is the number of the job board; otherwise -1 + std::map active_quests; location left_at; size_t left_in; eDirection direction; diff --git a/src/universe/pc.cpp b/src/universe/pc.cpp index 9d3ca522..e9961fed 100644 --- a/src/universe/pc.cpp +++ b/src/universe/pc.cpp @@ -465,9 +465,7 @@ bool cPlayer::give_item(cItem item, int flags) { } if(item.variety == eItemType::QUEST) { if(!party) return false; - party->quest_status[item.item_level] = eQuestStatus::STARTED; - party->quest_start[item.item_level] = party->calc_day(); - party->quest_source[item.item_level] = -1; + party->active_quests[item.item_level] = cJob(party->calc_day()); if(do_print && print_result) print_result("You get a quest."); return true; @@ -832,7 +830,7 @@ eBuyStatus cPlayer::ok_to_buy(short cost,cItem item) const { if(party->spec_items.count(item.item_level)) return eBuyStatus::HAVE_LOTS; } else if(item.variety == eItemType::QUEST) { - if(party->quest_status[item.item_level] != eQuestStatus::AVAILABLE) + if(party->active_quests[item.item_level].status != eQuestStatus::AVAILABLE) return eBuyStatus::HAVE_LOTS; } else if(item.variety != eItemType::GOLD && item.variety != eItemType::FOOD) { for(int i = 0; i < items.size(); i++) diff --git a/src/universe/universe.cpp b/src/universe/universe.cpp index 85580099..c3f75656 100644 --- a/src/universe/universe.cpp +++ b/src/universe/universe.cpp @@ -1369,9 +1369,7 @@ void cUniverse::enter_scenario(const std::string& name) { } for(short i = 0; i < scenario.quests.size(); i++) { if(scenario.quests[i].flags >= 10) { - party.quest_status[i] = eQuestStatus::STARTED; - party.quest_start[i] = 1; - party.quest_source[i] = -1; + party.active_quests[i] = cJob(1); } } @@ -1397,7 +1395,7 @@ void cUniverse::generate_job_bank(int which, job_bank_t& bank) { for(size_t i = 0; iSlot < 4 && i < scenario.quests.size(); i++) { if(scenario.quests[i].bank1 != which && scenario.quests[i].bank2 != which) continue; - if(party.quest_status[i] != eQuestStatus::AVAILABLE) + if(party.active_quests[i].status != eQuestStatus::AVAILABLE) continue; if(get_ran(1,1,100) <= 50 - bank.anger) bank.jobs[iSlot++] = i; From c2ce2a2cd14c862890674e368dd7e3aead1fe777 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 14 Apr 2017 15:43:07 -0400 Subject: [PATCH 09/11] Split up the graphtool files --- src/BoE.xcodeproj/project.pbxproj | 42 +- src/dialogxml/dialogs/dialog.cpp | 2 +- src/dialogxml/widgets/button.cpp | 2 +- src/dialogxml/widgets/button.hpp | 2 +- src/dialogxml/widgets/control.cpp | 2 +- src/dialogxml/widgets/field.cpp | 2 +- src/dialogxml/widgets/field.hpp | 2 +- src/dialogxml/widgets/message.cpp | 1 - src/dialogxml/widgets/message.hpp | 2 +- src/dialogxml/widgets/pict.cpp | 7 +- src/dialogxml/widgets/pictypes.hpp | 2 - src/dialogxml/widgets/scrollbar.cpp | 3 +- src/dialogxml/widgets/scrollbar.hpp | 1 - src/dialogxml/widgets/scrollpane.cpp | 1 + src/fileio/fileio_party.cpp | 2 +- src/fileio/fileio_scen.cpp | 2 +- src/game/boe.actions.cpp | 1 + src/game/boe.combat.cpp | 1 + src/game/boe.dlgutil.cpp | 2 +- src/game/boe.fileio.cpp | 1 - src/game/boe.graphics.cpp | 4 +- src/game/boe.graphutil.cpp | 3 +- src/game/boe.graphutil.hpp | 2 +- src/game/boe.infodlg.cpp | 1 + src/game/boe.items.cpp | 1 - src/game/boe.locutils.cpp | 1 + src/game/boe.main.cpp | 6 +- src/game/boe.monster.cpp | 2 +- src/game/boe.newgraph.cpp | 5 +- src/game/boe.newgraph.hpp | 1 + src/game/boe.party.cpp | 2 +- src/game/boe.startup.cpp | 1 + src/game/boe.text.cpp | 6 +- src/game/boe.town.cpp | 5 +- src/game/boe.townspec.cpp | 1 + src/gfx/gfxsheets.cpp | 197 +++++ src/gfx/gfxsheets.hpp | 51 ++ src/gfx/graphtool.cpp | 1074 -------------------------- src/gfx/graphtool.hpp | 140 ---- src/gfx/render_image.cpp | 122 +++ src/gfx/render_image.hpp | 30 + src/gfx/render_shapes.cpp | 241 ++++++ src/gfx/render_shapes.hpp | 46 ++ src/gfx/render_text.cpp | 232 ++++++ src/gfx/render_text.hpp | 58 ++ src/gfx/tiling.cpp | 111 +++ src/gfx/tiling.hpp | 29 + src/global.hpp | 1 + src/mathutil.hpp | 9 - src/pcedit/pc.action.cpp | 1 - src/pcedit/pc.editors.cpp | 2 +- src/pcedit/pc.fileio.cpp | 1 - src/pcedit/pc.graphics.cpp | 6 +- src/pcedit/pc.main.cpp | 7 +- src/scenario/item.cpp | 2 +- src/scenario/monster.cpp | 1 + src/scenario/monster.hpp | 1 - src/scenario/shop.cpp | 2 +- src/scenario/special.cpp | 2 +- src/scenario/terrain.cpp | 2 +- src/scenario/town.cpp | 1 + src/scenedit/scen.actions.cpp | 2 +- src/scenedit/scen.btnmg.cpp | 1 - src/scenedit/scen.core.cpp | 3 +- src/scenedit/scen.fileio.cpp | 2 +- src/scenedit/scen.graphics.cpp | 6 +- src/scenedit/scen.graphics.hpp | 1 + src/scenedit/scen.keydlgs.cpp | 3 +- src/scenedit/scen.main.cpp | 6 +- src/scenedit/scen.townout.cpp | 2 +- src/spell.cpp | 3 +- src/universe/universe.cpp | 1 + src/utility.cpp | 62 ++ src/utility.hpp | 28 + src/view_dialogs.cpp | 1 + test/catch.cpp | 2 +- 76 files changed, 1334 insertions(+), 1279 deletions(-) create mode 100644 src/gfx/gfxsheets.cpp create mode 100644 src/gfx/gfxsheets.hpp delete mode 100644 src/gfx/graphtool.cpp delete mode 100644 src/gfx/graphtool.hpp create mode 100644 src/gfx/render_image.cpp create mode 100644 src/gfx/render_image.hpp create mode 100644 src/gfx/render_shapes.cpp create mode 100644 src/gfx/render_shapes.hpp create mode 100644 src/gfx/render_text.cpp create mode 100644 src/gfx/render_text.hpp create mode 100644 src/gfx/tiling.cpp create mode 100644 src/gfx/tiling.hpp create mode 100644 src/utility.cpp create mode 100644 src/utility.hpp diff --git a/src/BoE.xcodeproj/project.pbxproj b/src/BoE.xcodeproj/project.pbxproj index 3314034a..6b3b8912 100755 --- a/src/BoE.xcodeproj/project.pbxproj +++ b/src/BoE.xcodeproj/project.pbxproj @@ -176,7 +176,7 @@ 919CC2721B3773F800273FDA /* fileio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2D1A7481C20057C54A /* fileio.cpp */; }; 919CC2731B3773FD00273FDA /* fileio_party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2A1A74819B0057C54A /* fileio_party.cpp */; }; 919CC2741B37740200273FDA /* fileio_scen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E5C7A60F9F615400C21460 /* fileio_scen.cpp */; }; - 919CC2751B37740A00273FDA /* graphtool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */; }; + 919CC2751B37740A00273FDA /* render_image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F10A0F9779C300BF5B67 /* render_image.cpp */; }; 919CC2761B37741000273FDA /* mathutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F11E0F97801F00BF5B67 /* mathutil.cpp */; }; 919CC2771B37741500273FDA /* map_parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 915E09081A316D89008BDF00 /* map_parse.cpp */; }; 919CC2781B37741A00273FDA /* porting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D005A0F9FEEC200184C18 /* porting.cpp */; }; @@ -257,6 +257,11 @@ 91CC173C1B421CA0003D9A69 /* catch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CC17391B421CA0003D9A69 /* catch.cpp */; }; 91CC173E1B421CA0003D9A69 /* scen_write.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CC173B1B421CA0003D9A69 /* scen_write.cpp */; }; 91CC17491B422D5C003D9A69 /* scen_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CC173A1B421CA0003D9A69 /* scen_read.cpp */; }; + 91CE248A1EA12866005BDCE4 /* utility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CE24891EA1284B005BDCE4 /* utility.cpp */; }; + 91CE248C1EA12A96005BDCE4 /* render_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CE248B1EA12A91005BDCE4 /* render_text.cpp */; }; + 91CE248E1EA12AA3005BDCE4 /* render_shapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CE248D1EA12AA0005BDCE4 /* render_shapes.cpp */; }; + 91CE24921EA12ABD005BDCE4 /* gfxsheets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CE24911EA12ABB005BDCE4 /* gfxsheets.cpp */; }; + 91CE24931EA12AC9005BDCE4 /* tiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91CE248F1EA12AAD005BDCE4 /* tiling.cpp */; }; 91D634560F8FD77800674AB3 /* BoE.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2B8F435C0C0973680012E4A8 /* BoE.icns */; }; 91E128E41BC1624700C8BE1D /* ter_legacy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E128E31BC1624700C8BE1D /* ter_legacy.cpp */; }; 91E128E61BC19DA400C8BE1D /* init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E128E51BC19DA400C8BE1D /* init.cpp */; }; @@ -714,8 +719,8 @@ 91B3EF0A0F969BD300BF5B67 /* pc.graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pc.graphics.cpp; sourceTree = ""; }; 91B3EF110F969BD300BF5B67 /* BoECharEd.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = BoECharEd.icns; path = icons/mac/BoECharEd.icns; sourceTree = ""; }; 91B3EF130F969BD300BF5B67 /* BoECharEd-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "BoECharEd-Info.plist"; path = "pcedit/BoECharEd-Info.plist"; sourceTree = SOURCE_ROOT; }; - 91B3F1090F9779C300BF5B67 /* graphtool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = graphtool.hpp; sourceTree = ""; }; - 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphtool.cpp; sourceTree = ""; }; + 91B3F1090F9779C300BF5B67 /* render_image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = render_image.hpp; sourceTree = ""; }; + 91B3F10A0F9779C300BF5B67 /* render_image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_image.cpp; sourceTree = ""; }; 91B3F10E0F9779D000BF5B67 /* sounds.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = sounds.hpp; sourceTree = ""; }; 91B3F10F0F9779D000BF5B67 /* sounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sounds.cpp; sourceTree = ""; }; 91B3F11D0F97801F00BF5B67 /* mathutil.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = mathutil.hpp; sourceTree = ""; }; @@ -744,6 +749,16 @@ 91CC173A1B421CA0003D9A69 /* scen_read.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scen_read.cpp; sourceTree = ""; }; 91CC173B1B421CA0003D9A69 /* scen_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scen_write.cpp; sourceTree = ""; }; 91CC173F1B421CAA003D9A69 /* catch.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch.hpp; sourceTree = ""; }; + 91CE24841EA124E4005BDCE4 /* gfxsheets.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = gfxsheets.hpp; sourceTree = ""; }; + 91CE24851EA12534005BDCE4 /* render_text.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = render_text.hpp; sourceTree = ""; }; + 91CE24861EA12595005BDCE4 /* tiling.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = tiling.hpp; sourceTree = ""; }; + 91CE24871EA12620005BDCE4 /* render_shapes.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = render_shapes.hpp; sourceTree = ""; }; + 91CE24881EA127EC005BDCE4 /* utility.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = utility.hpp; sourceTree = ""; }; + 91CE24891EA1284B005BDCE4 /* utility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utility.cpp; sourceTree = ""; }; + 91CE248B1EA12A91005BDCE4 /* render_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_text.cpp; sourceTree = ""; }; + 91CE248D1EA12AA0005BDCE4 /* render_shapes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_shapes.cpp; sourceTree = ""; }; + 91CE248F1EA12AAD005BDCE4 /* tiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tiling.cpp; sourceTree = ""; }; + 91CE24911EA12ABB005BDCE4 /* gfxsheets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfxsheets.cpp; sourceTree = ""; }; 91E128E31BC1624700C8BE1D /* ter_legacy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ter_legacy.cpp; sourceTree = ""; }; 91E128E51BC19DA400C8BE1D /* init.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = init.cpp; sourceTree = ""; }; 91E128E81BC2076B00C8BE1D /* 3choice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 3choice.cpp; sourceTree = ""; }; @@ -1137,9 +1152,17 @@ 9185BDA21EA042BE0027C346 /* gfx */ = { isa = PBXGroup; children = ( - 91B3F10A0F9779C300BF5B67 /* graphtool.cpp */, + 91CE24911EA12ABB005BDCE4 /* gfxsheets.cpp */, 91F6F8F518F8DE6300E3EA15 /* qdpict.mac.cpp */, - 91B3F1090F9779C300BF5B67 /* graphtool.hpp */, + 91B3F10A0F9779C300BF5B67 /* render_image.cpp */, + 91CE248D1EA12AA0005BDCE4 /* render_shapes.cpp */, + 91CE248B1EA12A91005BDCE4 /* render_text.cpp */, + 91CE248F1EA12AAD005BDCE4 /* tiling.cpp */, + 91CE24841EA124E4005BDCE4 /* gfxsheets.hpp */, + 91B3F1090F9779C300BF5B67 /* render_image.hpp */, + 91CE24871EA12620005BDCE4 /* render_shapes.hpp */, + 91CE24851EA12534005BDCE4 /* render_text.hpp */, + 91CE24861EA12595005BDCE4 /* tiling.hpp */, 91A0B15A1900F73E00EF438F /* mask.frag */, 91BFA3D61901B024001686E4 /* mask.vert */, ); @@ -1176,6 +1199,7 @@ 913D005A0F9FEEC200184C18 /* porting.cpp */, 91B3F10F0F9779D000BF5B67 /* sounds.cpp */, 91597A6E1A3BEDC700BE7BF9 /* spell.cpp */, + 91CE24891EA1284B005BDCE4 /* utility.cpp */, 91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */, 9185BD9B1EA02B8F0027C346 /* alchemy.hpp */, 9185BD961EA0234A0027C346 /* damage.hpp */, @@ -1189,6 +1213,7 @@ 9185BD9A1EA02B840027C346 /* skills_traits.hpp */, 91B3F10E0F9779D000BF5B67 /* sounds.hpp */, 91597A6C1A3BED2D00BE7BF9 /* spell.hpp */, + 91CE24881EA127EC005BDCE4 /* utility.hpp */, 91B0D5D31E3446CF002BE4DA /* view_dialogs.hpp */, ); name = misc; @@ -1856,7 +1881,7 @@ 919CC2711B3773F300273FDA /* cursors.mac.mm in Sources */, 919CC2721B3773F800273FDA /* fileio.cpp in Sources */, 919CC2741B37740200273FDA /* fileio_scen.cpp in Sources */, - 919CC2751B37740A00273FDA /* graphtool.cpp in Sources */, + 919CC2751B37740A00273FDA /* render_image.cpp in Sources */, 919CC2761B37741000273FDA /* mathutil.cpp in Sources */, 919CC2771B37741500273FDA /* map_parse.cpp in Sources */, 919CC2781B37741A00273FDA /* porting.cpp in Sources */, @@ -1875,6 +1900,11 @@ 91E128EF1BC2076B00C8BE1D /* pictchoice.cpp in Sources */, 91E128F01BC2076B00C8BE1D /* strchoice.cpp in Sources */, 91E128F11BC2076B00C8BE1D /* strdlog.cpp in Sources */, + 91CE248A1EA12866005BDCE4 /* utility.cpp in Sources */, + 91CE248C1EA12A96005BDCE4 /* render_text.cpp in Sources */, + 91CE248E1EA12AA3005BDCE4 /* render_shapes.cpp in Sources */, + 91CE24921EA12ABD005BDCE4 /* gfxsheets.cpp in Sources */, + 91CE24931EA12AC9005BDCE4 /* tiling.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/dialogxml/dialogs/dialog.cpp b/src/dialogxml/dialogs/dialog.cpp index a15db75d..78502d33 100644 --- a/src/dialogxml/dialogs/dialog.cpp +++ b/src/dialogxml/dialogs/dialog.cpp @@ -9,7 +9,7 @@ #include #include #include "dialog.hpp" -#include "graphtool.hpp" +#include "tiling.hpp" // for bg #include "sounds.hpp" #include "pict.hpp" #include "button.hpp" diff --git a/src/dialogxml/widgets/button.cpp b/src/dialogxml/widgets/button.cpp index 80c06a72..8fd532d2 100644 --- a/src/dialogxml/widgets/button.cpp +++ b/src/dialogxml/widgets/button.cpp @@ -14,7 +14,7 @@ #include #include "dialog.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" #include #include diff --git a/src/dialogxml/widgets/button.hpp b/src/dialogxml/widgets/button.hpp index 638085b3..252ab7a3 100644 --- a/src/dialogxml/widgets/button.hpp +++ b/src/dialogxml/widgets/button.hpp @@ -18,7 +18,7 @@ #include #include #include "control.hpp" -#include "graphtool.hpp" // for eFont +#include "render_text.hpp" /// A button type. enum eBtnType { // w x h diff --git a/src/dialogxml/widgets/control.cpp b/src/dialogxml/widgets/control.cpp index 07a94afc..4cf15c35 100644 --- a/src/dialogxml/widgets/control.cpp +++ b/src/dialogxml/widgets/control.cpp @@ -11,7 +11,7 @@ #include "dialog.hpp" #include "sounds.hpp" #include "button.hpp" -#include "graphtool.hpp" +#include "render_shapes.hpp" #include "res_image.hpp" #include "mathutil.hpp" #include "prefs.hpp" diff --git a/src/dialogxml/widgets/field.cpp b/src/dialogxml/widgets/field.cpp index 71f66a6f..74c8a153 100644 --- a/src/dialogxml/widgets/field.cpp +++ b/src/dialogxml/widgets/field.cpp @@ -13,7 +13,7 @@ #include #include "dialog.hpp" #include "strdlog.hpp" -#include "graphtool.hpp" +#include "render_shapes.hpp" #include "winutil.hpp" #include "cursors.hpp" diff --git a/src/dialogxml/widgets/field.hpp b/src/dialogxml/widgets/field.hpp index 14560926..26b31797 100644 --- a/src/dialogxml/widgets/field.hpp +++ b/src/dialogxml/widgets/field.hpp @@ -14,7 +14,7 @@ #include #include "control.hpp" -#include "graphtool.hpp" +#include "render_text.hpp" #include "undo.hpp" /// The field's expected input type. diff --git a/src/dialogxml/widgets/message.cpp b/src/dialogxml/widgets/message.cpp index ec5070ee..2005c35d 100644 --- a/src/dialogxml/widgets/message.cpp +++ b/src/dialogxml/widgets/message.cpp @@ -7,7 +7,6 @@ */ #include "message.hpp" -#include "graphtool.hpp" #include "mathutil.hpp" #include "dialog.hpp" diff --git a/src/dialogxml/widgets/message.hpp b/src/dialogxml/widgets/message.hpp index 957fda09..0d142b16 100644 --- a/src/dialogxml/widgets/message.hpp +++ b/src/dialogxml/widgets/message.hpp @@ -16,7 +16,7 @@ #include #include "control.hpp" -#include "graphtool.hpp" // for eFont +#include "render_text.hpp" /// A simple static text message. /// This class can also create a frame for grouping controls or a clickable area. diff --git a/src/dialogxml/widgets/pict.cpp b/src/dialogxml/widgets/pict.cpp index 12dfacf1..c225ed5f 100644 --- a/src/dialogxml/widgets/pict.cpp +++ b/src/dialogxml/widgets/pict.cpp @@ -11,7 +11,12 @@ #include #include -#include "graphtool.hpp" +#include "gfxsheets.hpp" +#include "render_shapes.hpp" +#include "render_image.hpp" +#include "render_text.hpp" +#include "tiling.hpp" +#include "location.hpp" #include "dialog.hpp" #include "res_image.hpp" diff --git a/src/dialogxml/widgets/pictypes.hpp b/src/dialogxml/widgets/pictypes.hpp index eacc70df..c55a9e7c 100644 --- a/src/dialogxml/widgets/pictypes.hpp +++ b/src/dialogxml/widgets/pictypes.hpp @@ -12,8 +12,6 @@ /// @file /// Constants to specify the type of an icon -typedef signed short pic_num_t; ///< An icon's unique number - /// Specifies an icon type. enum ePicType { PIC_TER = 1, ///< 28x36 terrain graphic from the preset sheets diff --git a/src/dialogxml/widgets/scrollbar.cpp b/src/dialogxml/widgets/scrollbar.cpp index 8551d380..efe76b03 100644 --- a/src/dialogxml/widgets/scrollbar.cpp +++ b/src/dialogxml/widgets/scrollbar.cpp @@ -8,7 +8,8 @@ #include "scrollbar.hpp" #include "res_image.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" #include "mathutil.hpp" #include "cursors.hpp" diff --git a/src/dialogxml/widgets/scrollbar.hpp b/src/dialogxml/widgets/scrollbar.hpp index d8927ac0..9232e120 100644 --- a/src/dialogxml/widgets/scrollbar.hpp +++ b/src/dialogxml/widgets/scrollbar.hpp @@ -13,7 +13,6 @@ /// Scrollbar-related classes and types. #include "control.hpp" -#include "graphtool.hpp" /// Specifies the style of a scrollbar. enum eScrollStyle { diff --git a/src/dialogxml/widgets/scrollpane.cpp b/src/dialogxml/widgets/scrollpane.cpp index 825552b8..d8f2effc 100644 --- a/src/dialogxml/widgets/scrollpane.cpp +++ b/src/dialogxml/widgets/scrollpane.cpp @@ -12,6 +12,7 @@ #include "button.hpp" #include "pict.hpp" #include "stack.hpp" +#include "render_shapes.hpp" cScrollPane::cScrollPane(cDialog& parent) : cContainer(CTRL_PANE, parent), scroll(parent) { recalcRect(); diff --git a/src/fileio/fileio_party.cpp b/src/fileio/fileio_party.cpp index f84008a3..d648cfc8 100644 --- a/src/fileio/fileio_party.cpp +++ b/src/fileio/fileio_party.cpp @@ -15,7 +15,7 @@ #include "gzstream.h" #include "universe.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" #include "porting.hpp" #include "tarball.hpp" diff --git a/src/fileio/fileio_scen.cpp b/src/fileio/fileio_scen.cpp index e1164b4d..a5a7ad5a 100644 --- a/src/fileio/fileio_scen.cpp +++ b/src/fileio/fileio_scen.cpp @@ -18,7 +18,7 @@ #include "town.hpp" #include "map_parse.hpp" #include "special_parse.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" #include "mathutil.hpp" #include "gzstream.h" #include "tarball.hpp" diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index 7bcdef26..2cbf94d2 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -34,6 +34,7 @@ #include "spell.hpp" #include "shop.hpp" #include "prefs.hpp" +#include "render_shapes.hpp" rectangle bottom_buttons[14]; rectangle world_screen = {23, 23, 346, 274}; diff --git a/src/game/boe.combat.cpp b/src/game/boe.combat.cpp index 4a28dc7f..ef33d273 100644 --- a/src/game/boe.combat.cpp +++ b/src/game/boe.combat.cpp @@ -23,6 +23,7 @@ #include "boe.menus.hpp" #include "spell.hpp" #include "prefs.hpp" +#include "utility.hpp" extern eGameMode overall_mode; extern short which_combat_type; diff --git a/src/game/boe.dlgutil.cpp b/src/game/boe.dlgutil.cpp index 72714e73..7f8902d9 100644 --- a/src/game/boe.dlgutil.cpp +++ b/src/game/boe.dlgutil.cpp @@ -20,7 +20,7 @@ #include #include "boe.newgraph.hpp" #include "boe.infodlg.hpp" -#include "graphtool.hpp" +#include "utility.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "choicedlog.hpp" diff --git a/src/game/boe.fileio.cpp b/src/game/boe.fileio.cpp index 20f53347..c5fae18e 100644 --- a/src/game/boe.fileio.cpp +++ b/src/game/boe.fileio.cpp @@ -14,7 +14,6 @@ #include "boe.dlgutil.hpp" #include "boe.infodlg.hpp" #include "boe.graphutil.hpp" -#include "graphtool.hpp" #include "sounds.hpp" #include "mathutil.hpp" #include "strdlog.hpp" diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 44da0252..3c1313be 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -12,7 +12,9 @@ #include "boe.monster.hpp" #include "boe.locutils.hpp" #include "boe.text.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" +#include "tiling.hpp" #include "sounds.hpp" #include "mathutil.hpp" #include "button.hpp" diff --git a/src/game/boe.graphutil.cpp b/src/game/boe.graphutil.cpp index ffaaf92c..c3fab6b7 100644 --- a/src/game/boe.graphutil.cpp +++ b/src/game/boe.graphutil.cpp @@ -15,7 +15,8 @@ #include "boe.monster.hpp" #include "boe.specials.hpp" #include "sounds.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "res_image.hpp" diff --git a/src/game/boe.graphutil.hpp b/src/game/boe.graphutil.hpp index 21708fd6..7a79f3dc 100644 --- a/src/game/boe.graphutil.hpp +++ b/src/game/boe.graphutil.hpp @@ -4,7 +4,7 @@ #include "pict.hpp" #include "location.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" void draw_one_terrain_spot (short i,short j,short terrain_to_draw); void draw_monsters(); diff --git a/src/game/boe.infodlg.cpp b/src/game/boe.infodlg.cpp index f74ef603..0e2c949a 100644 --- a/src/game/boe.infodlg.cpp +++ b/src/game/boe.infodlg.cpp @@ -27,6 +27,7 @@ #include "spell.hpp" #include "view_dialogs.hpp" #include "cursors.hpp" +#include "utility.hpp" short mage_spell_pos = 0,priest_spell_pos = 0,skill_pos = 0; diff --git a/src/game/boe.items.cpp b/src/game/boe.items.cpp index b0de1e14..4fade38e 100644 --- a/src/game/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -17,7 +17,6 @@ #include "sounds.hpp" #include "boe.monster.hpp" #include "boe.main.hpp" -#include "graphtool.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "3choice.hpp" diff --git a/src/game/boe.locutils.cpp b/src/game/boe.locutils.cpp index 1774636c..c48ad04e 100644 --- a/src/game/boe.locutils.cpp +++ b/src/game/boe.locutils.cpp @@ -6,6 +6,7 @@ #include "boe.locutils.hpp" #include "boe.text.hpp" #include "boe.monster.hpp" +#include "utility.hpp" bool combat_pt_in_light(); location obs_sec; diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp index 336a5750..bc714adb 100644 --- a/src/game/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -19,7 +19,8 @@ #include "boe.main.hpp" #include "winutil.hpp" #include "sounds.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "tiling.hpp" #include "mathutil.hpp" #include "fileio.hpp" #include "strdlog.hpp" @@ -152,7 +153,8 @@ void init_boe(int argc, char* argv[]) { init_directories(argv[0]); init_menubar(); // Do this first of all because otherwise a default File and Window menu will be seen sync_prefs(); - init_graph_tool(); + init_shaders(); + init_tiling(); init_snd_tool(); cDialog::init(); diff --git a/src/game/boe.monster.cpp b/src/game/boe.monster.cpp index 3ee59ec6..4e6184c4 100644 --- a/src/game/boe.monster.cpp +++ b/src/game/boe.monster.cpp @@ -15,7 +15,7 @@ #include "boe.newgraph.hpp" #include "boe.main.hpp" #include "mathutil.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" extern eGameMode overall_mode; extern short which_combat_type; diff --git a/src/game/boe.newgraph.cpp b/src/game/boe.newgraph.cpp index 9c16ae04..0e420663 100644 --- a/src/game/boe.newgraph.cpp +++ b/src/game/boe.newgraph.cpp @@ -15,7 +15,10 @@ #include "boe.text.hpp" #include "sounds.hpp" #include "mathutil.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" +#include "tiling.hpp" +#include "utility.hpp" #include "scrollbar.hpp" #include #include "location.hpp" diff --git a/src/game/boe.newgraph.hpp b/src/game/boe.newgraph.hpp index d7177ced..970ac17d 100644 --- a/src/game/boe.newgraph.hpp +++ b/src/game/boe.newgraph.hpp @@ -3,6 +3,7 @@ #include #include "location.hpp" #include "item.hpp" +#include "gfxsheets.hpp" struct word_rect_t { std::string word; diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index 4be0442d..11aadc02 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -26,7 +26,7 @@ #include "boe.text.hpp" #include "sounds.hpp" #include "boe.main.hpp" -#include "graphtool.hpp" +#include "utility.hpp" #include "mathutil.hpp" #include "strdlog.hpp" #include "choicedlog.hpp" diff --git a/src/game/boe.startup.cpp b/src/game/boe.startup.cpp index ac3d36f2..ded1a0e6 100644 --- a/src/game/boe.startup.cpp +++ b/src/game/boe.startup.cpp @@ -21,6 +21,7 @@ #include "res_image.hpp" #include "prefs.hpp" #include "cursors.hpp" +#include "render_image.hpp" #include using std::vector; diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index 711a8a25..becaab6f 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -11,7 +11,11 @@ const int TEXT_BUF_LEN = 70; #include "boe.text.hpp" #include "boe.locutils.hpp" #include "mathutil.hpp" -#include "graphtool.hpp" +#include "render_text.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" +#include "tiling.hpp" +#include "utility.hpp" #include "scrollbar.hpp" #include "res_image.hpp" #include "res_font.hpp" diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 48b7f3b4..6c591644 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -22,7 +22,10 @@ #include "boe.infodlg.hpp" #include "mathutil.hpp" #include "boe.main.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" +#include "render_text.hpp" +#include "tiling.hpp" #include "strdlog.hpp" #include "fileio.hpp" #include "winutil.hpp" diff --git a/src/game/boe.townspec.cpp b/src/game/boe.townspec.cpp index 65bc7960..cd19f7ad 100644 --- a/src/game/boe.townspec.cpp +++ b/src/game/boe.townspec.cpp @@ -17,6 +17,7 @@ #include "choicedlog.hpp" #include "winutil.hpp" #include "boe.menus.hpp" +#include "utility.hpp" extern eGameMode overall_mode; extern short stat_window; diff --git a/src/gfx/gfxsheets.cpp b/src/gfx/gfxsheets.cpp new file mode 100644 index 00000000..f01d062b --- /dev/null +++ b/src/gfx/gfxsheets.cpp @@ -0,0 +1,197 @@ +// +// gfxsheets.cpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#include "gfxsheets.hpp" + +#include "location.hpp" +#include "res_image.hpp" +#include "render_image.hpp" + +bool use_win_graphics = false; + +rectangle calc_rect(short i, short j){ + rectangle base_rect = {0,0,36,28}; + + base_rect.offset(i * 28, j * 36); + return base_rect; +} + +graf_pos cCustomGraphics::find_graphic(pic_num_t which_rect, bool party) { + bool valid = true; + if(party && !party_sheet) valid = false; + else if(!party && !is_old && (which_rect / 100) >= numSheets) + valid = false; + else if(numSheets == 0) valid = false; + if(!valid) { + INVALID: + sf::Texture* blank = ResMgr::get("blank").get(); + return {blank, {0,0,36,28}}; + } + short sheet = which_rect / 100; + if(is_old || party) sheet = 0; + else which_rect %= 100; + rectangle store_rect = {0,0,36,28}; + + store_rect.offset(28 * (which_rect % 10),36 * (which_rect / 10)); + sf::Texture* the_sheet = party ? party_sheet.get() : &sheets[sheet]; + rectangle test(*the_sheet); + if((store_rect & test) != store_rect) goto INVALID; // FIXME: HACK + return std::make_pair(the_sheet,store_rect); +} + +size_t cCustomGraphics::count(bool party) { + if(!party && sheets == nullptr) return 0; + else if(party && party_sheet == nullptr) return 0; + else if(is_old || party) { + rectangle bounds(party ? *party_sheet : sheets[0]); + if(bounds.width() < 280) return bounds.width() / 28; + return 10 * bounds.height() / 36; + } else { + size_t count = 100 * (numSheets - 1); + rectangle bounds(sheets[numSheets - 1]); + if(bounds.width() < 280) count += bounds.width() / 28; + else count += 10 * bounds.height() / 36; + return count; + } +} + +void cCustomGraphics::copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlots) { + if(numSlots < 1) return; + if(!party_sheet) { + sf::Image empty; + empty.create(280, 180, sf::Color::Transparent); + party_sheet.reset(new sf::Texture); + party_sheet->create(280, 180); + party_sheet->update(empty); + numSheets = 1; + } + size_t havePics = count(); + if(havePics < dest + numSlots) { + int addRows = 1; + while(havePics + 10 * addRows < dest + numSlots) + addRows++; + sf::RenderTexture temp; + temp.create(280, party_sheet->getSize().y + 36 * addRows); + temp.clear(sf::Color::Transparent); + rect_draw_some_item(*party_sheet, rectangle(*party_sheet), temp, rectangle(*party_sheet)); + *party_sheet = temp.getTexture(); + } + sf::Texture* from_sheet; + sf::Texture* to_sheet; + sf::Texture* last_src = nullptr; + sf::RenderTexture temp; + rectangle from_rect, to_rect; + for(size_t i = 0; i < numSlots; i++) { + graf_pos_ref(from_sheet, from_rect) = find_graphic(src + i); + graf_pos_ref(to_sheet, to_rect) = find_graphic(dest + i, true); + if(to_sheet != last_src) { + if(last_src) *last_src = temp.getTexture(); + last_src = to_sheet; + temp.create(to_sheet->getSize().x, to_sheet->getSize().y); + rect_draw_some_item(*to_sheet, rectangle(*to_sheet), temp, rectangle(*to_sheet)); + } + rect_draw_some_item(*from_sheet, from_rect, temp, to_rect); + } + *last_src = temp.getTexture(); +} + +extern std::string scenario_temp_dir_name; +void cCustomGraphics::convert_sheets() { + if(!is_old) return; + int num_graphics = count(); + is_old = false; + sf::Image old_graph = sheets[0].copyToImage(); + delete[] sheets; + numSheets = num_graphics / 100; + if(num_graphics % 100) numSheets++; + sheets = new sf::Texture[numSheets]; + extern fs::path tempDir; + fs::path pic_dir = tempDir/scenario_temp_dir_name/"graphics"; + for(size_t i = 0; i < numSheets; i++) { + sf::IntRect subrect; + subrect.top = i * 280; + subrect.width = 280; + subrect.height = 360; + + sf::Image sheet; + sheet.create(280, 360); + sheet.copy(old_graph, 0, 0, subrect); + + sheets[i].create(280, 360); + sheets[i].update(sheet); + + fs::path sheetPath = pic_dir/("sheet" + std::to_string(i) + ".png"); + sheets[i].copyToImage().saveToFile(sheetPath.string().c_str()); + } + ResMgr::pushPath(pic_dir); +} + +void cCustomGraphics::replace_sheet(size_t num, sf::Image& newSheet) { + if(num >= numSheets) return; // TODO: Fail silently? Is that a good idea? + sheets[num].loadFromImage(newSheet); + // Then we need to do some extra stuff to ensure the dialog engine also sees the change + extern fs::path tempDir; + std::string sheetname = "sheet" + std::to_string(num); + fs::path tmpPath = tempDir/scenario_temp_dir_name/"graphics"/(sheetname + ".png"); + newSheet.saveToFile(tmpPath.string().c_str()); + ResMgr::free(sheetname); +} + +void cCustomGraphics::init_sheet(size_t num) { + sheets[num].create(280,360); + sf::Image fill1, fill2; + fill1.create(28,36,{0xff,0xff,0xc0}); + fill2.create(28,36,{0xc0,0xff,0xc0}); + for(int y = 0; y < 10; y++) { + for(int x = 0; x < 10; x++) { + if(x % 2 == y % 2) { + sheets[num].update(fill1.getPixelsPtr(), 28, 36, x * 28, y * 36); + } else { + sheets[num].update(fill2.getPixelsPtr(), 28, 36, x * 28, y * 36); + } + } + } +} + +extern const std::vector m_pic_index = { + {1, 1, 1}, {2, 1, 1}, {3, 1, 1}, {4, 1, 1}, {5, 1, 1}, + {6, 1, 1}, {7, 1, 1}, {8, 1, 1}, {9, 1, 1}, {10, 1, 1}, + {11, 1, 1}, {12, 1, 1}, {13, 1, 1}, {14, 1, 1}, {15, 1, 1}, + {16, 1, 1}, {17, 1, 1}, {18, 1, 1}, {19, 1, 1}, {20, 1, 1}, + {21, 1, 1}, {22, 1, 1}, {23, 1, 1}, {24, 1, 1}, {25, 1, 1}, + {26, 1, 1}, {27, 1, 1}, {28, 1, 1}, {29, 1, 1}, {30, 1, 1}, + {31, 1, 1}, {32, 1, 1}, {33, 1, 1}, {34, 1, 1}, {35, 1, 1}, + {36, 1, 1}, {37, 1, 1}, {38, 1, 1}, {39, 1, 1}, {40, 1, 1}, + {41, 1, 1}, {42, 1, 1}, {43, 1, 1}, {44, 1, 1}, {46, 1, 1}, + {47, 1, 1}, {48, 1, 1}, {49, 1, 1}, {50, 1, 1}, {51, 1, 2}, + {53, 1, 2}, {55, 1, 2}, {57, 1, 2}, {59, 1, 1}, {60, 1, 1}, + {61, 1, 1}, {62, 1, 1}, {63, 1, 1}, {64, 1, 1}, {65, 1, 1}, + {66, 1, 1}, {67, 1, 1}, {68, 1, 1}, {69, 1, 1}, {70, 1, 1}, + {71, 1, 1}, {72, 1, 1}, {73, 1, 1}, {74, 1, 1}, {75, 1, 1}, + {76, 1, 1}, {77, 1, 1}, {78, 1, 1}, {79, 2, 1}, {81, 1, 1}, + {82, 1, 1}, {83, 1, 2}, {85, 1, 1}, {86, 1, 1}, {87, 1, 1}, + {88, 1, 1}, {89, 1, 1}, {90, 1, 1}, {91, 1, 1}, {92, 1, 1}, + {93, 1, 1}, {94, 1, 1}, {95, 1, 1}, {96, 1, 1}, {97, 1, 1}, + {98, 1, 1}, {99, 1, 1}, {100, 1, 1}, {101, 1, 1}, {102, 1, 1}, + {103, 1, 1}, {104, 1, 1}, {105, 1, 1}, {106, 1, 1}, {107, 1, 1}, + {108, 1, 1}, {109, 2, 1}, {111, 1, 1}, {112, 1, 1}, {113, 1, 1}, + {114, 2, 1}, {116, 1, 1}, {117, 1, 1}, {118, 1, 1}, {119, 1, 1}, + {120, 2, 1}, {122, 1, 1}, {123, 1, 2}, {125, 1, 2}, {127, 1, 1}, + {128, 1, 1}, {129, 1, 1}, {130, 1, 1}, {131, 2, 2}, {135, 1, 1}, + {136, 1, 1}, {137, 2, 1}, {139, 1, 1}, {140, 1, 1}, {141, 1, 1}, + {142, 1, 1}, {143, 1, 1}, {144, 1, 1}, {145, 1, 1}, {146, 1, 1}, + {147, 1, 1}, {148, 1, 1}, {149, 1, 1}, {150, 1, 1}, {151, 1, 1}, + {152, 1, 1}, {153, 1, 1}, {154, 1, 1}, {155, 2, 2}, {159, 1, 1}, + {160, 2, 2}, {164, 2, 1}, {166, 2, 1}, {168, 1, 2}, {170, 1, 1}, + {171, 1, 1}, {172, 1, 1}, {173, 1, 1}, {174, 1, 1}, {175, 1, 1}, + {176, 1, 1}, {177, 1, 1}, {178, 1, 1}, {179, 1, 1}, {180, 1, 1}, + {181, 1, 1}, {182, 1, 1}, {183, 1, 1}, {184, 1, 1}, {185, 1, 1}, + {186, 1, 1}, {187, 1, 1}, {188, 1, 1}, {189, 1, 1}, {190, 1, 1}, + {191, 1, 1}, {192, 1, 1}, {193, 1, 1}, {194, 1, 1}, {195, 1, 1}, + {196, 1, 1}, {197, 1, 1}, {198, 1, 1}, +}; diff --git a/src/gfx/gfxsheets.hpp b/src/gfx/gfxsheets.hpp new file mode 100644 index 00000000..5f675230 --- /dev/null +++ b/src/gfx/gfxsheets.hpp @@ -0,0 +1,51 @@ +// +// gfxsheets.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#ifndef BoE_CUSTOM_SHEETS_HPP +#define BoE_CUSTOM_SHEETS_HPP + +#include +#include +#include +#include "location.hpp" + +static const pic_num_t NO_PIC = -1; +using graf_pos = std::pair; +using graf_pos_ref = std::pair; + +struct m_pic_index_t { + unsigned char i, x, y; +}; + +struct cCustomGraphics { + size_t numSheets; + sf::Texture* sheets = nullptr; + std::shared_ptr party_sheet; + bool is_old = false; + void clear() { + if(sheets != nullptr) delete[] sheets; + sheets = nullptr; + } + ~cCustomGraphics() { + clear(); + } + explicit operator bool() { + return sheets; + } + void convert_sheets(); + void copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlots); + graf_pos find_graphic(pic_num_t pic, bool party = false); + size_t count(bool party = false); + void replace_sheet(size_t num, sf::Image& newSheet); + void init_sheet(size_t num); +}; + +rectangle calc_rect(short i, short j); +extern const std::vector m_pic_index; + +#endif diff --git a/src/gfx/graphtool.cpp b/src/gfx/graphtool.cpp deleted file mode 100644 index 4a66260b..00000000 --- a/src/gfx/graphtool.cpp +++ /dev/null @@ -1,1074 +0,0 @@ -/* - * graphtool.cpp - * BoE - * - * Created by Celtic Minstrel on 16/04/09. - * - */ - -#define GRAPHTOOL_CPP -#include "graphtool.hpp" - -#ifdef __APPLE__ -#include -#else -#ifdef _WIN32 -#include -#endif -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "res_image.hpp" -#include "res_font.hpp" -#include "res_strings.hpp" -#include "mathutil.hpp" -#include "fileio.hpp" - -using boost::math::constants::pi; - -rectangle bg_rects[21]; -tessel_ref_t bg[21]; -tessel_ref_t bw_pats[6]; -bool use_win_graphics = false; -sf::Shader maskShader; -extern fs::path progDir; -// TODO: Shouldn't need this -extern sf::RenderWindow mainPtr; - -static void register_main_patterns(); - -void init_graph_tool(){ - fs::path shaderPath = progDir/"data"/"shaders"; - fs::path fragPath = shaderPath/"mask.frag", vertPath = shaderPath/"mask.vert"; - - do { - std::ifstream fin; - fin.open(fragPath.string().c_str()); - if(!fin.good()) { - std::cerr << std_fmterr << ": Error loading fragment shader" << std::endl; - break; - } - fin.seekg(0, std::ios::end); - int size = fin.tellg(); - fin.seekg(0); - char* fbuf = new char[size + 1]; - fbuf[size] = 0; - fin.read(fbuf, size); - fbuf[fin.gcount()] = 0; - fin.close(); - - fin.open(vertPath.string().c_str()); - if(!fin.good()) { - std::cerr << std_fmterr << ": Error loading vertex shader" << std::endl; - delete[] fbuf; - break; - } - fin.seekg(0, std::ios::end); - size = fin.tellg(); - fin.seekg(0); - char* vbuf = new char[size + 1]; - vbuf[size] = 0; - fin.read(vbuf, size); - vbuf[fin.gcount()] = 0; - - if(!maskShader.loadFromMemory(vbuf, fbuf)) { - std::cerr << "Error: Failed to load shaders from " << shaderPath << "\nVertex:\n" << vbuf << "\nFragment:\n" << fbuf << std::endl; - } - delete[] fbuf; - delete[] vbuf; - } while(false); - static const location pat_offs[17] = { - {0,3}, {1,1}, {2,1}, {2,0}, - {3,0}, {3,1}, {1,3}, {0,0}, - {0,2}, {1,2}, {0,1}, {2,2}, - {2,3}, {3,2}, {1,0}, {4,0}, {3,3} - }; - static const int pat_i[17] = { - 2, 3, 4, 5, 6, 8, 9, 10, - 11,12,13,14,15,16,17,19,20 - }; - for(short i = 0; i < 17; i++){ - bg_rects[pat_i[i]] = {0,0,64,64}; - bg_rects[pat_i[i]].offset(64 * pat_offs[i].x,64 * pat_offs[i].y); - } - rectangle tmp_rect = bg_rects[19]; - tmp_rect.offset(0, 64); - bg_rects[0] = bg_rects[1] = bg_rects[18] = bg_rects[7] = tmp_rect; - bg_rects[0].right -= 32; - bg_rects[0].bottom -= 32; - bg_rects[1].left += 32; - bg_rects[1].bottom -= 32; - bg_rects[18].right -= 32; - bg_rects[18].top += 32; - bg_rects[7].left += 32; - bg_rects[7].top += 32; - register_main_patterns(); -} - -void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect) { - rectangle from_rect = rectangle(splash); - targ.clear(sf::Color::Black); - rect_draw_some_item(splash, from_rect, targ, dest_rect); - targ.display(); -} - -static void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::RenderStates mode); - -void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect) { - fill_rect(targ_gworld, targ_rect, sf::Color::Black); -} - -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode){ - rect_draw_some_item(src_gworld, src_rect, targ_gworld, targ_rect, sf::RenderStates(mode)); -} - -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::RenderStates mode) { - setActiveRenderTarget(targ_gworld); - sf::Sprite tile(src_gworld, src_rect); - tile.setPosition(targ_rect.left, targ_rect.top); - double xScale = targ_rect.width(), yScale = targ_rect.height(); - xScale /= src_rect.width(); - yScale /= src_rect.height(); - tile.setScale(xScale, yScale); - targ_gworld.draw(tile, mode); -} - -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,rectangle targ_rect,location offset, sf::BlendMode mode) { - targ_rect.offset(offset); - rect_draw_some_item(src_gworld,src_rect,mainPtr,targ_rect,mode); -} - -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect) { - static sf::RenderTexture src; - static bool inited = false; - if(!inited || src_rect.width() != src.getSize().x || src_rect.height() != src.getSize().y) { - src.create(src_rect.width(), src_rect.height()); - inited = true; - } - rectangle dest_rect = src_rect; - dest_rect.offset(-dest_rect.left,-dest_rect.top); - rect_draw_some_item(src_gworld, src_rect, src, dest_rect); - src.display(); - - maskShader.setParameter("texture", sf::Shader::CurrentTexture); - maskShader.setParameter("mask", mask_gworld); - rect_draw_some_item(src.getTexture(), dest_rect, targ_gworld, targ_rect, &maskShader); -} - -void TextStyle::applyTo(sf::Text& text) { - switch(font) { - case FONT_PLAIN: - text.setFont(*ResMgr::get("plain")); - break; - case FONT_BOLD: - text.setFont(*ResMgr::get("bold")); - break; - case FONT_DUNGEON: - text.setFont(*ResMgr::get("dungeon")); - break; - case FONT_MAIDWORD: - text.setFont(*ResMgr::get("maidenword")); - break; - } - text.setCharacterSize(pointSize); - int style = sf::Text::Regular; - if(italic) style |= sf::Text::Italic; - if(underline) style |= sf::Text::Underlined; - text.setStyle(style); - text.setColor(colour); -} - -struct text_params_t { - TextStyle style; - eTextMode mode; - bool showBreaks = false; - location offset = {0,0}; - // Hilite ranges are, like the STL, of the form [first, last). - std::vector hilite_ranges; - sf::Color hilite_fg, hilite_bg = sf::Color::Transparent; - enum {RECTS, SNIPPETS} returnType; - std::vector returnRects; - std::vector snippets; -}; - -void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,text_params_t& options); - -void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, location offset) { - text_params_t params; - params.mode = mode; - params.style = style; - params.offset = offset; - win_draw_string(dest_window, dest_rect, str, params); -} - -std::vector draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr) { - text_params_t params; - params.mode = eTextMode::WRAP; - params.hilite_ranges = hilites; - params.style = style; - params.hilite_fg = hiliteClr; - params.returnType = text_params_t::RECTS; - win_draw_string(dest_window, dest_rect, str, params); - return params.returnRects; -} - -std::vector draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr) { - text_params_t params; - params.mode = eTextMode::WRAP; - params.showBreaks = true; - params.hilite_ranges = hilites; - params.style = style; - params.hilite_fg = style.colour; - params.hilite_bg = hiliteClr; - params.returnType = text_params_t::RECTS; - win_draw_string(dest_window, dest_rect, str, params); - return params.snippets; -} - -static void push_snippets(size_t start, size_t end, text_params_t& options, size_t& iHilite, const std::string& str, location loc) { - std::vector& hilites = options.hilite_ranges; - std::vector& snippets = options.snippets; - // Check if we have any hilites on this line. - // We assume the list of hilites is sorted, so we just need to - // check the current entry. - size_t upper_bound = end; - do { - bool hilited = false; - // Skip any hilite rules that have start = end - while(iHilite < hilites.size() && hilites[iHilite].first == hilites[iHilite].second) - iHilite++; - if(iHilite < hilites.size()) { - // Possibilities: (vertical bars indicate line boundaries, parentheses for hilite boundaries, dots are data) - // 1. |...|...(...) --> no hilite on this line - // 2a. |...(...|...) --> hilite starts on this line and continues past it - // 2b. |...(...)...| --> hilite starts and ends on this line - // 3a. (...|...)...| --> hilite starts (or continues) at the start of the line and ends on this line - // 3b. (...|......)| --> entire line hilited - // Case 1 needs no special handling; check case 3, then case 2. - if(hilites[iHilite].first <= start) { - hilited = true; - if(hilites[iHilite].second < end) // 3a - end = hilites[iHilite].second; - } else if(hilites[iHilite].first < end) - end = hilites[iHilite].first; - // 2b will reduce to 3a after shifting start over - } - size_t amount = end - start; - snippets.push_back({str.substr(start,amount), loc, hilited}); - loc.x += string_length(snippets[snippets.size()-1].text, options.style); - start = end; - end = upper_bound; - if(iHilite < hilites.size() && start >= hilites[iHilite].second) - iHilite++; - } while(start < upper_bound); -} - -void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,text_params_t& options) { - if(str.empty()) return; // Nothing to do! - short line_height = options.style.lineHeight; - sf::Text str_to_draw; - options.style.applyTo(str_to_draw); - short str_len; - unsigned short last_line_break = 0,last_word_break = 0; - short total_width = 0; - short adjust_x = 0,adjust_y = 0; - - adjust_x = options.offset.x; - adjust_y = options.offset.y; - str_to_draw.setString("fj"); // Something that has both an ascender and a descender - adjust_y -= str_to_draw.getLocalBounds().height; - - str_to_draw.setString(str); - str_len = str.length(); - if(str_len == 0) { - return; - } - - eTextMode mode = options.mode; - total_width = str_to_draw.getLocalBounds().width; - if(mode == eTextMode::WRAP && total_width < dest_rect.width()) - mode = eTextMode::LEFT_TOP; - if(mode == eTextMode::LEFT_TOP && str.find('|') != std::string::npos) - mode = eTextMode::WRAP; - - auto text_len = [&str_to_draw](size_t i) -> int { - return str_to_draw.findCharacterPos(i).x; - }; - - // Special stuff - size_t iHilite = 0; - - location moveTo; - line_height -= 2; // TODO: ...why are we arbitrarily reducing the line height from the requested value? - - if(mode == eTextMode::WRAP) { - moveTo = location(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + adjust_y + 9); - short i; - for(i = 0; text_len(i) != text_len(i + 1) && i < str_len; i++) { - if(((text_len(i) - text_len(last_line_break) > (dest_rect.width() - 6)) - && (last_word_break >= last_line_break)) || (str[i] == '|')) { - if(str[i] == '|') { - if(!options.showBreaks) str[i] = ' '; - last_word_break = i + 1; - } else if(last_line_break == last_word_break) - last_word_break = i; - push_snippets(last_line_break, last_word_break, options, iHilite, str, moveTo); - moveTo.y += line_height; - last_line_break = last_word_break; - } - if(str[i] == ' ') - last_word_break = i + 1; - } - - if(i - last_line_break > 0) { - std::string snippet = str.substr(last_line_break); - if(!snippet.empty()) - push_snippets(last_line_break, str.length() + 1, options, iHilite, str, moveTo); - } - } else { - switch(mode) { - case eTextMode::CENTRE: - moveTo = location((dest_rect.right + dest_rect.left) / 2 - (4 * total_width) / 9 + adjust_x, - (dest_rect.bottom + dest_rect.top - line_height) / 2 + 9 + adjust_y); - break; - case eTextMode::LEFT_TOP: - moveTo = location(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + adjust_y + 9); - break; - case eTextMode::LEFT_BOTTOM: - moveTo = location(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + adjust_y + 9 + dest_rect.height() / 6); - break; - case eTextMode::WRAP: - break; // Never happens, but put this here to silence warning - } - push_snippets(0, str.length() + 1, options, iHilite, str, moveTo); - } - - for(auto& snippet : options.snippets) { - str_to_draw.setString(snippet.text); - str_to_draw.setPosition(snippet.at); - if(snippet.hilited) { - rectangle bounds = str_to_draw.getGlobalBounds(); - // Adjust so that drawing the same text to - // the same rect is positioned exactly right - bounds.left = snippet.at.x - 1; - bounds.top = snippet.at.y + 5; - if(options.returnType == text_params_t::RECTS) - options.returnRects.push_back(bounds); - str_to_draw.setColor(options.hilite_fg); - bounds.inset(0,-4); - fill_rect(dest_window, bounds, options.hilite_bg); - } else str_to_draw.setColor(options.style.colour); - dest_window.draw(str_to_draw); - if(options.style.font == FONT_BOLD) { - str_to_draw.move(1, 0); - dest_window.draw(str_to_draw); - } - } -} - -size_t string_length(std::string str, TextStyle style, short* height){ - size_t total_width = 0; - - sf::Text text; - style.applyTo(text); - text.setString(str); - total_width = text.getLocalBounds().width; - if(height) *height = text.getLocalBounds().height; - return total_width; -} - -rectangle calc_rect(short i, short j){ - rectangle base_rect = {0,0,36,28}; - - base_rect.offset(i * 28, j * 36); - return base_rect; -} - -graf_pos cCustomGraphics::find_graphic(pic_num_t which_rect, bool party) { - bool valid = true; - if(party && !party_sheet) valid = false; - else if(!party && !is_old && (which_rect / 100) >= numSheets) - valid = false; - else if(numSheets == 0) valid = false; - if(!valid) { - INVALID: - sf::Texture* blank = ResMgr::get("blank").get(); - return {blank, {0,0,36,28}}; - } - short sheet = which_rect / 100; - if(is_old || party) sheet = 0; - else which_rect %= 100; - rectangle store_rect = {0,0,36,28}; - - store_rect.offset(28 * (which_rect % 10),36 * (which_rect / 10)); - sf::Texture* the_sheet = party ? party_sheet.get() : &sheets[sheet]; - rectangle test(*the_sheet); - if((store_rect & test) != store_rect) goto INVALID; // FIXME: HACK - return std::make_pair(the_sheet,store_rect); -} - -size_t cCustomGraphics::count(bool party) { - if(!party && sheets == nullptr) return 0; - else if(party && party_sheet == nullptr) return 0; - else if(is_old || party) { - rectangle bounds(party ? *party_sheet : sheets[0]); - if(bounds.width() < 280) return bounds.width() / 28; - return 10 * bounds.height() / 36; - } else { - size_t count = 100 * (numSheets - 1); - rectangle bounds(sheets[numSheets - 1]); - if(bounds.width() < 280) count += bounds.width() / 28; - else count += 10 * bounds.height() / 36; - return count; - } -} - -void cCustomGraphics::copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlots) { - if(numSlots < 1) return; - if(!party_sheet) { - sf::Image empty; - empty.create(280, 180, sf::Color::Transparent); - party_sheet.reset(new sf::Texture); - party_sheet->create(280, 180); - party_sheet->update(empty); - numSheets = 1; - } - size_t havePics = count(); - if(havePics < dest + numSlots) { - int addRows = 1; - while(havePics + 10 * addRows < dest + numSlots) - addRows++; - sf::RenderTexture temp; - temp.create(280, party_sheet->getSize().y + 36 * addRows); - temp.clear(sf::Color::Transparent); - rect_draw_some_item(*party_sheet, rectangle(*party_sheet), temp, rectangle(*party_sheet)); - *party_sheet = temp.getTexture(); - } - sf::Texture* from_sheet; - sf::Texture* to_sheet; - sf::Texture* last_src = nullptr; - sf::RenderTexture temp; - rectangle from_rect, to_rect; - for(size_t i = 0; i < numSlots; i++) { - graf_pos_ref(from_sheet, from_rect) = find_graphic(src + i); - graf_pos_ref(to_sheet, to_rect) = find_graphic(dest + i, true); - if(to_sheet != last_src) { - if(last_src) *last_src = temp.getTexture(); - last_src = to_sheet; - temp.create(to_sheet->getSize().x, to_sheet->getSize().y); - rect_draw_some_item(*to_sheet, rectangle(*to_sheet), temp, rectangle(*to_sheet)); - } - rect_draw_some_item(*from_sheet, from_rect, temp, to_rect); - } - *last_src = temp.getTexture(); -} - -extern std::string scenario_temp_dir_name; -void cCustomGraphics::convert_sheets() { - if(!is_old) return; - int num_graphics = count(); - is_old = false; - sf::Image old_graph = sheets[0].copyToImage(); - delete[] sheets; - numSheets = num_graphics / 100; - if(num_graphics % 100) numSheets++; - sheets = new sf::Texture[numSheets]; - extern fs::path tempDir; - fs::path pic_dir = tempDir/scenario_temp_dir_name/"graphics"; - for(size_t i = 0; i < numSheets; i++) { - sf::IntRect subrect; - subrect.top = i * 280; - subrect.width = 280; - subrect.height = 360; - - sf::Image sheet; - sheet.create(280, 360); - sheet.copy(old_graph, 0, 0, subrect); - - sheets[i].create(280, 360); - sheets[i].update(sheet); - - fs::path sheetPath = pic_dir/("sheet" + std::to_string(i) + ".png"); - sheets[i].copyToImage().saveToFile(sheetPath.string().c_str()); - } - ResMgr::pushPath(pic_dir); -} - -void cCustomGraphics::replace_sheet(size_t num, sf::Image& newSheet) { - if(num >= numSheets) return; // TODO: Fail silently? Is that a good idea? - sheets[num].loadFromImage(newSheet); - // Then we need to do some extra stuff to ensure the dialog engine also sees the change - extern fs::path tempDir; - std::string sheetname = "sheet" + std::to_string(num); - fs::path tmpPath = tempDir/scenario_temp_dir_name/"graphics"/(sheetname + ".png"); - newSheet.saveToFile(tmpPath.string().c_str()); - ResMgr::free(sheetname); -} - -void cCustomGraphics::init_sheet(size_t num) { - sheets[num].create(280,360); - sf::Image fill1, fill2; - fill1.create(28,36,{0xff,0xff,0xc0}); - fill2.create(28,36,{0xc0,0xff,0xc0}); - for(int y = 0; y < 10; y++) { - for(int x = 0; x < 10; x++) { - if(x % 2 == y % 2) { - sheets[num].update(fill1.getPixelsPtr(), 28, 36, x * 28, y * 36); - } else { - sheets[num].update(fill2.getPixelsPtr(), 28, 36, x * 28, y * 36); - } - } - } -} - -// TODO: This doesn't belong in this file -std::string get_str(std::string list, short j){ - if(j == 0) return list; - StringRsrc& strings = *ResMgr::get(list); - return strings[j - 1]; -} - -extern const std::vector m_pic_index = { - {1, 1, 1}, - {2, 1, 1}, - {3, 1, 1}, - {4, 1, 1}, - {5, 1, 1}, - {6, 1, 1}, - {7, 1, 1}, - {8, 1, 1}, - {9, 1, 1}, - {10, 1, 1}, - //10 - {11, 1, 1}, - {12, 1, 1}, - {13, 1, 1}, - {14, 1, 1}, - {15, 1, 1}, - {16, 1, 1}, - {17, 1, 1}, - {18, 1, 1}, - {19, 1, 1}, - {20, 1, 1}, - //20 - {21, 1, 1}, - {22, 1, 1}, - {23, 1, 1}, - {24, 1, 1}, - {25, 1, 1}, - {26, 1, 1}, - {27, 1, 1}, - {28, 1, 1}, - {29, 1, 1}, - {30, 1, 1}, - //30 - {31, 1, 1}, - {32, 1, 1}, - {33, 1, 1}, - {34, 1, 1}, - {35, 1, 1}, - {36, 1, 1}, - {37, 1, 1}, - {38, 1, 1}, - {39, 1, 1}, - {40, 1, 1}, - //40 - {41, 1, 1}, - {42, 1, 1}, - {43, 1, 1}, - {44, 1, 1}, - {46, 1, 1}, - {47, 1, 1}, - {48, 1, 1}, - {49, 1, 1}, - {50, 1, 1}, - {51, 1, 2}, - //50 - {53, 1, 2}, - {55, 1, 2}, - {57, 1, 2}, - {59, 1, 1}, - {60, 1, 1}, - {61, 1, 1}, - {62, 1, 1}, - {63, 1, 1}, - {64, 1, 1}, - {65, 1, 1}, - //60 - {66, 1, 1}, - {67, 1, 1}, - {68, 1, 1}, - {69, 1, 1}, - {70, 1, 1}, - {71, 1, 1}, - {72, 1, 1}, - {73, 1, 1}, - {74, 1, 1}, - {75, 1, 1}, - //70 - {76, 1, 1}, - {77, 1, 1}, - {78, 1, 1}, - {79, 2, 1}, - {81, 1, 1}, - {82, 1, 1}, - {83, 1, 2}, - {85, 1, 1}, - {86, 1, 1}, - {87, 1, 1}, - //80 - {88, 1, 1}, - {89, 1, 1}, - {90, 1, 1}, - {91, 1, 1}, - {92, 1, 1}, - {93, 1, 1}, - {94, 1, 1}, - {95, 1, 1}, - {96, 1, 1}, - {97, 1, 1}, - //90 - {98, 1, 1}, - {99, 1, 1}, - {100, 1, 1}, - {101, 1, 1}, - {102, 1, 1}, - {103, 1, 1}, - {104, 1, 1}, - {105, 1, 1}, - {106, 1, 1}, - {107, 1, 1}, - //100 - {108, 1, 1}, - {109, 2, 1}, - {111, 1, 1}, - {112, 1, 1}, - {113, 1, 1}, - {114, 2, 1}, - {116, 1, 1}, - {117, 1, 1}, - {118, 1, 1}, - {119, 1, 1}, - //110 - {120, 2, 1}, - {122, 1, 1}, - {123, 1, 2}, - {125, 1, 2}, - {127, 1, 1}, - {128, 1, 1}, - {129, 1, 1}, - {130, 1, 1}, - {131, 2, 2}, - {135, 1, 1}, - //120 - {136, 1, 1}, - {137, 2, 1}, - {139, 1, 1}, - {140, 1, 1}, - {141, 1, 1}, - {142, 1, 1}, - {143, 1, 1}, - {144, 1, 1}, - {145, 1, 1}, - {146, 1, 1}, - //130 - {147, 1, 1}, - {148, 1, 1}, - {149, 1, 1}, - {150, 1, 1}, - {151, 1, 1}, - {152, 1, 1}, - {153, 1, 1}, - {154, 1, 1}, - {155, 2, 2}, - {159, 1, 1}, - //140 - {160, 2, 2}, - {164, 2, 1}, - {166, 2, 1}, - {168, 1, 2}, - {170, 1, 1}, - {171, 1, 1}, - {172, 1, 1}, - {173, 1, 1}, - {174, 1, 1}, - {175, 1, 1}, - //150 - {176, 1, 1}, - {177, 1, 1}, - {178, 1, 1}, - {179, 1, 1}, - {180, 1, 1}, - {181, 1, 1}, - {182, 1, 1}, - {183, 1, 1}, - {184, 1, 1}, - {185, 1, 1}, - //160 - {186, 1, 1}, - {187, 1, 1}, - {188, 1, 1}, - {189, 1, 1}, - {190, 1, 1}, - {191, 1, 1}, - {192, 1, 1}, - {193, 1, 1}, - {194, 1, 1}, - {195, 1, 1}, - //170 - {196, 1, 1}, - {197, 1, 1}, - {198, 1, 1}, -}; - -// TODO: Put these classes in a header? -class EllipseShape : public sf::Shape { - float divSz; - int points; - float a, b; -public: - explicit EllipseShape(sf::Vector2f size, std::size_t points = 30) : points(points) { - a = size.x / 2.0f; - b = size.y / 2.0f; - divSz = 2 * pi() / points; - update(); - } - - std::size_t getPointCount() const override { - return points; - } - - sf::Vector2f getPoint(std::size_t i) const override { - float t = i * divSz; - return sf::Vector2f(a + a*sin(t), b + b*cos(t)); - } - - // TODO: Additional functions? -}; - -class RoundRectShape : public sf::Shape { - float divSz; - int points; - float w,h,r; -public: - RoundRectShape(sf::Vector2f size, float cornerRadius, std::size_t points = 32) : points(points / 4) { - w = size.x; - h = size.y; - r = cornerRadius; - divSz = 2 * pi() / points; - update(); - } - - std::size_t getPointCount() const override { - return points * 4; - } - - sf::Vector2f getPoint(std::size_t i) const override { - const float pi = ::pi(); - const float half_pi = 0.5 * pi; - float t = i * divSz; - switch(i / points) { - case 0: // top left corner - return {r + r*sinf(t + pi), r + r*cosf(t + pi)}; - case 1: // bottom left corner - return {r + r*cosf(t + half_pi), h - r + r*sinf(t - half_pi)}; - case 2: // bottom right corner - return {w - r + r*cosf(t + half_pi), h - r - r*sinf(t + half_pi)}; - case 3: // top right corner - return {w - r - r*cosf(t - half_pi), r + r*sinf(t - half_pi)}; - } - // Unreachable - std::cerr << "Whoops, rounded rectangle had bad point!" << std::endl; - return {0,0}; - } - - // TODO: Additional functions? -}; - -void draw_line(sf::RenderTarget& target, location from, location to, int thickness, sf::Color colour, sf::BlendMode mode) { - sf::VertexArray line(sf::LinesStrip, 2); - line[0].position = from; - line[0].color = colour; - line[1].position = to; - line[1].color = colour; - setActiveRenderTarget(target); - float saveThickness; - glGetFloatv(GL_LINE_WIDTH, &saveThickness); - glLineWidth(thickness); - target.draw(line, mode); - glLineWidth(saveThickness); -} - -static void fill_shape(sf::RenderTarget& target, sf::Shape& shape, int x, int y, sf::Color colour) { - shape.setPosition(x, y); - shape.setFillColor(colour); - setActiveRenderTarget(target); - target.draw(shape); - -} - -static void frame_shape(sf::RenderTarget& target, sf::Shape& shape, int x, int y, sf::Color colour) { - shape.setPosition(x, y); - shape.setOutlineColor(colour); - shape.setFillColor(sf::Color::Transparent); - // TODO: Determine the correct outline value; should be one pixel, not sure if it should be negative - shape.setOutlineThickness(-1.0); - target.draw(shape); -} - -void fill_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour) { - sf::RectangleShape fill(sf::Vector2f(rect.width(), rect.height())); - fill_shape(target, fill, rect.left, rect.top, colour); -} - -void frame_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour) { - sf::RectangleShape frame(sf::Vector2f(rect.width(), rect.height())); - frame_shape(target, frame, rect.left, rect.top, colour); -} - -void fill_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour) { - RoundRectShape fill(sf::Vector2f(rect.width(), rect.height()), rad); - fill_shape(target, fill, rect.left, rect.top, colour); -} - -void frame_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour) { - RoundRectShape frame(sf::Vector2f(rect.width(), rect.height()), rad); - frame_shape(target, frame, rect.left, rect.top, colour); -} - -void fill_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour) { - EllipseShape fill(sf::Vector2f(rect.width(), rect.height())); - fill_shape(target, fill, rect.left, rect.top, colour); -} - -void frame_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour) { - EllipseShape frame(sf::Vector2f(rect.width(), rect.height())); - frame_shape(target, frame, rect.left, rect.top, colour); -} - -void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour) { - clip_region(target, region); - fill_rect(target, rectangle(target), colour); - undo_clip(target); -} - -void Region::addEllipse(rectangle frame) { - EllipseShape* ellipse = new EllipseShape(sf::Vector2f(frame.width(), frame.height())); - ellipse->setFillColor(sf::Color::Black); - shapes.push_back(std::shared_ptr(ellipse)); -} - -void Region::addRect(rectangle rect){ - sf::RectangleShape* frame = new sf::RectangleShape(sf::Vector2f(rect.width(), rect.height())); - frame->setPosition(rect.left, rect.top); - frame->setFillColor(sf::Color::Black); - shapes.push_back(std::shared_ptr(frame)); -} - -void Region::clear() { - shapes.clear(); -} - -void Region::offset(int x, int y) { - for(auto shape : shapes) { - shape->move(x,y); - } -} - -void Region::offset(location off) { - offset(off.x, off.y); -} - -rectangle Region::getEnclosingRect() { - if(shapes.empty()) return rectangle(); - rectangle bounds = shapes[0]->getGlobalBounds(); - for(size_t i = 0; i < shapes.size(); i++) { - rectangle shapeRect = shapes[i]->getGlobalBounds(); - if(shapeRect.top < bounds.top) bounds.top = shapeRect.top; - if(shapeRect.left < bounds.left) bounds.top = shapeRect.top; - if(shapeRect.bottom > bounds.bottom) bounds.top = shapeRect.top; - if(shapeRect.right > bounds.right) bounds.top = shapeRect.top; - } - return bounds; -} - -// We can only use stencil buffer in the main window -// Could request it in dialogs, but currently don't -// SFML does not appear to allow requesting it for render textures -void Region::setStencil(sf::RenderWindow& where) { - where.setActive(); - glClearStencil(0); - glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 1, 1); - for(auto shape : shapes) { - // Save the colour in case we need to reuse this region - sf::Color colour = shape->getFillColor(); - if(colour == sf::Color::Black) - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - else glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); - // Make transparent so we don't overwrite important stuff - shape->setFillColor(sf::Color::Transparent); - where.draw(*shape); - shape->setFillColor(colour); - } - glStencilFunc(GL_EQUAL, 1, 1); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); -} - -void clip_rect(sf::RenderTarget& where, rectangle rect) { - rect &= rectangle(where); // Make sure we don't draw out of bounds - // TODO: Make sure this works for the scissor test... - setActiveRenderTarget(where); - glEnable(GL_SCISSOR_TEST); - glScissor(rect.left, rectangle(where).height() - rect.bottom, rect.width(), rect.height()); -} - -void clip_region(sf::RenderWindow& where, Region& region) { - region.setStencil(where); -} - -void undo_clip(sf::RenderTarget& where) { - setActiveRenderTarget(where); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_STENCIL_TEST); -} - -void setActiveRenderTarget(sf::RenderTarget& where) { - const std::type_info& type = typeid(where); - if(type == typeid(sf::RenderWindow&)) - dynamic_cast(where).setActive(); - else if(type == typeid(sf::RenderTexture&)) - dynamic_cast(where).setActive(); - else throw std::bad_cast(); -} - -Region& Region::operator-=(Region& other) { - for(auto shape : other.shapes) { - // TODO: Shouldn't this be done to a copy of the shape instead? - if(shape->getFillColor() == sf::Color::Black) - shape->setFillColor(sf::Color::White); - else shape->setFillColor(sf::Color::Black); - shapes.push_back(shape); - } - return *this; -} - -struct tessel_t { - sf::RenderTexture* tessel; - sf::Texture* img; - rectangle srcRect; -}; - -bool operator==(const tessel_ref_t& a, const tessel_ref_t& b) { - return a.key == b.key; -} - -template<> struct std::hash { - size_t operator()(tessel_ref_t key) const { - return key.key; - } -}; - -std::unordered_map tiling_reservoir; -static int tessel_index = 0; - -tessel_ref_t prepareForTiling(sf::Texture& srcImg, rectangle srcRect) { - tessel_ref_t ref = {tessel_index++}; - tiling_reservoir[ref].img = &srcImg; - tiling_reservoir[ref].srcRect = srcRect; - tiling_reservoir[ref].tessel = new sf::RenderTexture; - tiling_reservoir[ref].tessel->create(srcRect.width(), srcRect.height()); - rectangle tesselRect(*tiling_reservoir[ref].tessel); - rect_draw_some_item(srcImg, srcRect, *tiling_reservoir[ref].tessel, tesselRect); - tiling_reservoir[ref].tessel->display(); - tiling_reservoir[ref].tessel->setRepeated(true); - return ref; -} - - -static void register_main_patterns() { - rectangle bw_rect = {0,0,8,8}; - sf::Texture& bg_gworld = *ResMgr::get("pixpats"); - sf::Texture& bw_gworld = *ResMgr::get("bwpats"); - for(int i = 0; i < 21; i++) { - if(i < 6) { - bw_pats[i] = prepareForTiling(bw_gworld, bw_rect); - bw_rect.offset(8,0); - } - bg[i] = prepareForTiling(bg_gworld, bg_rects[i]); - } -} - -void tileImage(sf::RenderTarget& target, rectangle area, tessel_ref_t tessel, sf::BlendMode mode) { - // First, set up a dictionary of all textures ever tiled. - // The key type is a pair. - // The value type is a Texture. - tessel_t& tesselInfo = tiling_reservoir[tessel]; - rectangle clipArea = area; - area.left -= area.left % tesselInfo.srcRect.width(); - area.top -= area.top % tesselInfo.srcRect.height(); - area &= rectangle(target); // Make sure we don't draw out of bounds - - sf::RectangleShape tesselShape(sf::Vector2f(area.width(),area.height())); - tesselShape.setTexture(&tesselInfo.tessel->getTexture()); - tesselShape.setTextureRect(area); - tesselShape.setPosition(area.left, area.top); - sf::RenderStates renderMode(mode); - setActiveRenderTarget(target); - clip_rect(target, clipArea); - target.draw(tesselShape, renderMode); - undo_clip(target); -} - -short can_see(location p1,location p2,std::function get_obscurity) { - short storage = 0; - - if(p1.y == p2.y) { - if(p1.x > p2.x) { - for(short count = p2.x + 1; count < p1.x; count++) - storage += get_obscurity(count, p1.y); - } else { - for(short count = p1.x + 1; count < p2.x; count++) - storage += get_obscurity(count, p1.y); - } - } else if(p1.x == p2.x) { - if(p1.y > p2.y) { - for(short count = p1.y - 1; count > p2.y; count--) - storage += get_obscurity(p1.x, count); - } else { - for(short count = p1.y + 1; count < p2.y; count++) - storage += get_obscurity(p1.x, count); - } - } else { - short dx = p2.x - p1.x; - short dy = p2.y - p1.y; - - if(abs(dy) > abs(dx)) { - if(p2.y > p1.y) { - for(short count = 1; count < dy; count++) - storage += get_obscurity(p1.x + (count * dx) / dy, p1.y + count); - } else { - for(short count = -1; count > dy; count--) - storage += get_obscurity(p1.x + (count * dx) / dy, p1.y + count); - } - } - if(abs(dy) <= abs(dx)) { - if(p2.x > p1.x) { - for(short count = 1; count < dx; count++) - storage += get_obscurity(p1.x + count, p1.y + (count * dy) / dx); - } else { - for(short count = -1; count > dx; count--) - storage += get_obscurity(p1.x + count, p1.y + (count * dy) / dx); - } - } - } - return storage; -} diff --git a/src/gfx/graphtool.hpp b/src/gfx/graphtool.hpp deleted file mode 100644 index ec21f717..00000000 --- a/src/gfx/graphtool.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * graphtool.h - * BoE - * - * Created by Celtic Minstrel on 16/04/09. - * - */ - -#ifndef GRAPHTOOL_H -#define GRAPHTOOL_H - -#include -#include -#include -#include -#include -#include -#include "location.hpp" -#include "pictypes.hpp" - -struct m_pic_index_t { - unsigned char i, x, y; -}; - -enum eFont { - FONT_PLAIN, - FONT_BOLD, - FONT_DUNGEON, - FONT_MAIDWORD -}; - -struct TextStyle { - bool italic = false, underline = false; - eFont font = FONT_BOLD; - int pointSize = 10, lineHeight; - sf::Color colour; - TextStyle() : colour(sf::Color::Black) {} - void applyTo(sf::Text& text); -}; - -class Region { - std::vector> shapes; - void setStencil(sf::RenderWindow& where); - friend void clip_region(sf::RenderWindow& where, Region& region); -public: - void addEllipse(rectangle frame); - void addRect(rectangle rect); - void clear(); - void offset(int x, int y); - void offset(location off); - Region& operator-=(Region& other); - rectangle getEnclosingRect(); -}; - -static const pic_num_t NO_PIC = -1; -using graf_pos = std::pair; -using graf_pos_ref = std::pair; -using hilite_t = std::pair; - -struct cCustomGraphics { - size_t numSheets; - sf::Texture* sheets = nullptr; - std::shared_ptr party_sheet; - bool is_old = false; - void clear() { - if(sheets != nullptr) delete[] sheets; - sheets = nullptr; - } - ~cCustomGraphics() { - clear(); - } - explicit operator bool() { - return sheets; - } - void convert_sheets(); - void copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlots); - graf_pos find_graphic(pic_num_t pic, bool party = false); - size_t count(bool party = false); - void replace_sheet(size_t num, sf::Image& newSheet); - void init_sheet(size_t num); -}; - -struct snippet_t { - std::string text; - location at; - bool hilited; -}; - -struct tessel_ref_t { - int key; -}; - -bool operator==(const tessel_ref_t& a, const tessel_ref_t& b); - -enum class eTextMode { - WRAP, - CENTRE, - LEFT_TOP, - LEFT_BOTTOM, -}; - -void init_graph_tool(); -void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect); -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone); -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,rectangle targ_rect,location offset,sf::BlendMode mode = sf::BlendNone); -void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect); -void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect); - -std::vector draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr); -std::vector draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr); -void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, location offset = {0,0}); -size_t string_length(std::string str, TextStyle style, short* height = nullptr); -rectangle calc_rect(short i, short j); -void setActiveRenderTarget(sf::RenderTarget& where); -tessel_ref_t prepareForTiling(sf::Texture& srcImg, rectangle srcRect); -void tileImage(sf::RenderTarget& target, rectangle area, tessel_ref_t tessel, sf::BlendMode mode = sf::BlendNone); -void tileImage(sf::RenderWindow& target, Region& rgn, tessel_ref_t tessel, sf::BlendMode mode = sf::BlendNone); -void fill_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour); -void frame_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour); -void fill_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour); -void frame_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour); -void fill_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour); -void frame_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour); -void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour); -void draw_line(sf::RenderTarget& target, location from, location to, int thickness, sf::Color colour, sf::BlendMode mode = sf::BlendNone); - -void clip_rect(sf::RenderTarget& where, rectangle rect); -void clip_region(sf::RenderWindow& where, Region& region); -void undo_clip(sf::RenderTarget& where); - -// This probably doesn't quite fit here, but it fits worse pretty much everywhere else in the common sources -short can_see(location p1,location p2,std::function get_obscurity); -std::string get_str(std::string list, short j); - -#ifndef GRAPHTOOL_CPP -extern const std::vector m_pic_index; -extern tessel_ref_t bg[]; -#endif - -#endif diff --git a/src/gfx/render_image.cpp b/src/gfx/render_image.cpp new file mode 100644 index 00000000..d32ca6cc --- /dev/null +++ b/src/gfx/render_image.cpp @@ -0,0 +1,122 @@ +/* + * graphtool.cpp + * BoE + * + * Created by Celtic Minstrel on 16/04/09. + * + */ + +#include "render_image.hpp" + +#include +#include +#include + +#include "fileio.hpp" +#include "render_shapes.hpp" + +sf::Shader maskShader; +extern fs::path progDir; +// TODO: Shouldn't need this +extern sf::RenderWindow mainPtr; + +void init_shaders() { + fs::path shaderPath = progDir/"data"/"shaders"; + fs::path fragPath = shaderPath/"mask.frag", vertPath = shaderPath/"mask.vert"; + + do { + std::ifstream fin; + fin.open(fragPath.string().c_str()); + if(!fin.good()) { + std::cerr << std_fmterr << ": Error loading fragment shader" << std::endl; + break; + } + fin.seekg(0, std::ios::end); + int size = fin.tellg(); + fin.seekg(0); + char* fbuf = new char[size + 1]; + fbuf[size] = 0; + fin.read(fbuf, size); + fbuf[fin.gcount()] = 0; + fin.close(); + + fin.open(vertPath.string().c_str()); + if(!fin.good()) { + std::cerr << std_fmterr << ": Error loading vertex shader" << std::endl; + delete[] fbuf; + break; + } + fin.seekg(0, std::ios::end); + size = fin.tellg(); + fin.seekg(0); + char* vbuf = new char[size + 1]; + vbuf[size] = 0; + fin.read(vbuf, size); + vbuf[fin.gcount()] = 0; + + if(!maskShader.loadFromMemory(vbuf, fbuf)) { + std::cerr << "Error: Failed to load shaders from " << shaderPath << "\nVertex:\n" << vbuf << "\nFragment:\n" << fbuf << std::endl; + } + delete[] fbuf; + delete[] vbuf; + } while(false); +} + +void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect) { + rectangle from_rect = rectangle(splash); + targ.clear(sf::Color::Black); + rect_draw_some_item(splash, from_rect, targ, dest_rect); + targ.display(); +} + +static void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::RenderStates mode); + +void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect) { + fill_rect(targ_gworld, targ_rect, sf::Color::Black); +} + +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode){ + rect_draw_some_item(src_gworld, src_rect, targ_gworld, targ_rect, sf::RenderStates(mode)); +} + +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::RenderStates mode) { + setActiveRenderTarget(targ_gworld); + sf::Sprite tile(src_gworld, src_rect); + tile.setPosition(targ_rect.left, targ_rect.top); + double xScale = targ_rect.width(), yScale = targ_rect.height(); + xScale /= src_rect.width(); + yScale /= src_rect.height(); + tile.setScale(xScale, yScale); + targ_gworld.draw(tile, mode); +} + +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,rectangle targ_rect,location offset, sf::BlendMode mode) { + targ_rect.offset(offset); + rect_draw_some_item(src_gworld,src_rect,mainPtr,targ_rect,mode); +} + +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect) { + static sf::RenderTexture src; + static bool inited = false; + if(!inited || src_rect.width() != src.getSize().x || src_rect.height() != src.getSize().y) { + src.create(src_rect.width(), src_rect.height()); + inited = true; + } + rectangle dest_rect = src_rect; + dest_rect.offset(-dest_rect.left,-dest_rect.top); + rect_draw_some_item(src_gworld, src_rect, src, dest_rect); + src.display(); + + maskShader.setParameter("texture", sf::Shader::CurrentTexture); + maskShader.setParameter("mask", mask_gworld); + rect_draw_some_item(src.getTexture(), dest_rect, targ_gworld, targ_rect, &maskShader); +} + +void setActiveRenderTarget(sf::RenderTarget& where) { + const std::type_info& type = typeid(where); + if(type == typeid(sf::RenderWindow&)) + dynamic_cast(where).setActive(); + else if(type == typeid(sf::RenderTexture&)) + dynamic_cast(where).setActive(); + else throw std::bad_cast(); +} diff --git a/src/gfx/render_image.hpp b/src/gfx/render_image.hpp new file mode 100644 index 00000000..928b9553 --- /dev/null +++ b/src/gfx/render_image.hpp @@ -0,0 +1,30 @@ +/* + * graphtool.h + * BoE + * + * Created by Celtic Minstrel on 16/04/09. + * + */ + +#ifndef GRAPHTOOL_H +#define GRAPHTOOL_H + +#include +#include +#include +#include +#include +#include +#include "location.hpp" +#include "pictypes.hpp" + +void init_shaders(); +void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect); +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone); +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,rectangle targ_rect,location offset,sf::BlendMode mode = sf::BlendNone); +void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect); +void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect); + +void setActiveRenderTarget(sf::RenderTarget& where); + +#endif diff --git a/src/gfx/render_shapes.cpp b/src/gfx/render_shapes.cpp new file mode 100644 index 00000000..8dfc02b9 --- /dev/null +++ b/src/gfx/render_shapes.cpp @@ -0,0 +1,241 @@ +// +// render_shapes.cpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#include "render_shapes.hpp" + +#include +#include +#include +#include +#include "render_image.hpp" + +using boost::math::constants::pi; + +// TODO: Put these classes in a header? +class EllipseShape : public sf::Shape { + float divSz; + int points; + float a, b; +public: + explicit EllipseShape(sf::Vector2f size, std::size_t points = 30) : points(points) { + a = size.x / 2.0f; + b = size.y / 2.0f; + divSz = 2 * pi() / points; + update(); + } + + std::size_t getPointCount() const override { + return points; + } + + sf::Vector2f getPoint(std::size_t i) const override { + float t = i * divSz; + return sf::Vector2f(a + a*sin(t), b + b*cos(t)); + } + + // TODO: Additional functions? +}; + +class RoundRectShape : public sf::Shape { + float divSz; + int points; + float w,h,r; +public: + RoundRectShape(sf::Vector2f size, float cornerRadius, std::size_t points = 32) : points(points / 4) { + w = size.x; + h = size.y; + r = cornerRadius; + divSz = 2 * pi() / points; + update(); + } + + std::size_t getPointCount() const override { + return points * 4; + } + + sf::Vector2f getPoint(std::size_t i) const override { + const float pi = ::pi(); + const float half_pi = 0.5 * pi; + float t = i * divSz; + switch(i / points) { + case 0: // top left corner + return {r + r*sinf(t + pi), r + r*cosf(t + pi)}; + case 1: // bottom left corner + return {r + r*cosf(t + half_pi), h - r + r*sinf(t - half_pi)}; + case 2: // bottom right corner + return {w - r + r*cosf(t + half_pi), h - r - r*sinf(t + half_pi)}; + case 3: // top right corner + return {w - r - r*cosf(t - half_pi), r + r*sinf(t - half_pi)}; + } + // Unreachable + std::cerr << "Whoops, rounded rectangle had bad point!" << std::endl; + return {0,0}; + } + + // TODO: Additional functions? +}; + +void draw_line(sf::RenderTarget& target, location from, location to, int thickness, sf::Color colour, sf::BlendMode mode) { + sf::VertexArray line(sf::LinesStrip, 2); + line[0].position = from; + line[0].color = colour; + line[1].position = to; + line[1].color = colour; + setActiveRenderTarget(target); + float saveThickness; + glGetFloatv(GL_LINE_WIDTH, &saveThickness); + glLineWidth(thickness); + target.draw(line, mode); + glLineWidth(saveThickness); +} + +static void fill_shape(sf::RenderTarget& target, sf::Shape& shape, int x, int y, sf::Color colour) { + shape.setPosition(x, y); + shape.setFillColor(colour); + setActiveRenderTarget(target); + target.draw(shape); + +} + +static void frame_shape(sf::RenderTarget& target, sf::Shape& shape, int x, int y, sf::Color colour) { + shape.setPosition(x, y); + shape.setOutlineColor(colour); + shape.setFillColor(sf::Color::Transparent); + // TODO: Determine the correct outline value; should be one pixel, not sure if it should be negative + shape.setOutlineThickness(-1.0); + target.draw(shape); +} + +void fill_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour) { + sf::RectangleShape fill(sf::Vector2f(rect.width(), rect.height())); + fill_shape(target, fill, rect.left, rect.top, colour); +} + +void frame_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour) { + sf::RectangleShape frame(sf::Vector2f(rect.width(), rect.height())); + frame_shape(target, frame, rect.left, rect.top, colour); +} + +void fill_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour) { + RoundRectShape fill(sf::Vector2f(rect.width(), rect.height()), rad); + fill_shape(target, fill, rect.left, rect.top, colour); +} + +void frame_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour) { + RoundRectShape frame(sf::Vector2f(rect.width(), rect.height()), rad); + frame_shape(target, frame, rect.left, rect.top, colour); +} + +void fill_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour) { + EllipseShape fill(sf::Vector2f(rect.width(), rect.height())); + fill_shape(target, fill, rect.left, rect.top, colour); +} + +void frame_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour) { + EllipseShape frame(sf::Vector2f(rect.width(), rect.height())); + frame_shape(target, frame, rect.left, rect.top, colour); +} + +void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour) { + clip_region(target, region); + fill_rect(target, rectangle(target), colour); + undo_clip(target); +} + +void Region::addEllipse(rectangle frame) { + EllipseShape* ellipse = new EllipseShape(sf::Vector2f(frame.width(), frame.height())); + ellipse->setFillColor(sf::Color::Black); + shapes.push_back(std::shared_ptr(ellipse)); +} + +void Region::addRect(rectangle rect){ + sf::RectangleShape* frame = new sf::RectangleShape(sf::Vector2f(rect.width(), rect.height())); + frame->setPosition(rect.left, rect.top); + frame->setFillColor(sf::Color::Black); + shapes.push_back(std::shared_ptr(frame)); +} + +void Region::clear() { + shapes.clear(); +} + +void Region::offset(int x, int y) { + for(auto shape : shapes) { + shape->move(x,y); + } +} + +void Region::offset(location off) { + offset(off.x, off.y); +} + +rectangle Region::getEnclosingRect() { + if(shapes.empty()) return rectangle(); + rectangle bounds = shapes[0]->getGlobalBounds(); + for(size_t i = 0; i < shapes.size(); i++) { + rectangle shapeRect = shapes[i]->getGlobalBounds(); + if(shapeRect.top < bounds.top) bounds.top = shapeRect.top; + if(shapeRect.left < bounds.left) bounds.top = shapeRect.top; + if(shapeRect.bottom > bounds.bottom) bounds.top = shapeRect.top; + if(shapeRect.right > bounds.right) bounds.top = shapeRect.top; + } + return bounds; +} + +// We can only use stencil buffer in the main window +// Could request it in dialogs, but currently don't +// SFML does not appear to allow requesting it for render textures +void Region::setStencil(sf::RenderWindow& where) { + where.setActive(); + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 1); + for(auto shape : shapes) { + // Save the colour in case we need to reuse this region + sf::Color colour = shape->getFillColor(); + if(colour == sf::Color::Black) + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + else glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); + // Make transparent so we don't overwrite important stuff + shape->setFillColor(sf::Color::Transparent); + where.draw(*shape); + shape->setFillColor(colour); + } + glStencilFunc(GL_EQUAL, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +} + +void clip_rect(sf::RenderTarget& where, rectangle rect) { + rect &= rectangle(where); // Make sure we don't draw out of bounds + // TODO: Make sure this works for the scissor test... + setActiveRenderTarget(where); + glEnable(GL_SCISSOR_TEST); + glScissor(rect.left, rectangle(where).height() - rect.bottom, rect.width(), rect.height()); +} + +void clip_region(sf::RenderWindow& where, Region& region) { + region.setStencil(where); +} + +void undo_clip(sf::RenderTarget& where) { + setActiveRenderTarget(where); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_STENCIL_TEST); +} + +Region& Region::operator-=(Region& other) { + for(auto shape : other.shapes) { + // TODO: Shouldn't this be done to a copy of the shape instead? + if(shape->getFillColor() == sf::Color::Black) + shape->setFillColor(sf::Color::White); + else shape->setFillColor(sf::Color::Black); + shapes.push_back(shape); + } + return *this; +} diff --git a/src/gfx/render_shapes.hpp b/src/gfx/render_shapes.hpp new file mode 100644 index 00000000..71a52f08 --- /dev/null +++ b/src/gfx/render_shapes.hpp @@ -0,0 +1,46 @@ +// +// render_shapes.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#ifndef BoE_RENDER_SHAPES_HPP +#define BoE_RENDER_SHAPES_HPP + +#include +#include +#include +#include "location.hpp" + +class Region { + std::vector> shapes; + void setStencil(sf::RenderWindow& where); + friend void clip_region(sf::RenderWindow& where, Region& region); +public: + void addEllipse(rectangle frame); + void addRect(rectangle rect); + void clear(); + void offset(int x, int y); + void offset(location off); + Region& operator-=(Region& other); + rectangle getEnclosingRect(); +}; + +void fill_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour); +void fill_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour); +void fill_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour); +void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour); + +void frame_rect(sf::RenderTarget& target, rectangle rect, sf::Color colour); +void frame_circle(sf::RenderTarget& target, rectangle rect, sf::Color colour); +void frame_roundrect(sf::RenderTarget& target, rectangle rect, int rad, sf::Color colour); + +void draw_line(sf::RenderTarget& target, location from, location to, int thickness, sf::Color colour, sf::BlendMode mode = sf::BlendNone); + +void clip_rect(sf::RenderTarget& where, rectangle rect); +void clip_region(sf::RenderWindow& where, Region& region); +void undo_clip(sf::RenderTarget& where); + +#endif diff --git a/src/gfx/render_text.cpp b/src/gfx/render_text.cpp new file mode 100644 index 00000000..24c5748d --- /dev/null +++ b/src/gfx/render_text.cpp @@ -0,0 +1,232 @@ +// +// render_text.cpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#include "render_text.hpp" + +#include "res_font.hpp" +#include "render_shapes.hpp" + +void TextStyle::applyTo(sf::Text& text) { + switch(font) { + case FONT_PLAIN: + text.setFont(*ResMgr::get("plain")); + break; + case FONT_BOLD: + text.setFont(*ResMgr::get("bold")); + break; + case FONT_DUNGEON: + text.setFont(*ResMgr::get("dungeon")); + break; + case FONT_MAIDWORD: + text.setFont(*ResMgr::get("maidenword")); + break; + } + text.setCharacterSize(pointSize); + int style = sf::Text::Regular; + if(italic) style |= sf::Text::Italic; + if(underline) style |= sf::Text::Underlined; + text.setStyle(style); + text.setColor(colour); +} + +struct text_params_t { + TextStyle style; + eTextMode mode; + bool showBreaks = false; + location offset = {0,0}; + // Hilite ranges are, like the STL, of the form [first, last). + std::vector hilite_ranges; + sf::Color hilite_fg, hilite_bg = sf::Color::Transparent; + enum {RECTS, SNIPPETS} returnType; + std::vector returnRects; + std::vector snippets; +}; + +static void push_snippets(size_t start, size_t end, text_params_t& options, size_t& iHilite, const std::string& str, location loc) { + std::vector& hilites = options.hilite_ranges; + std::vector& snippets = options.snippets; + // Check if we have any hilites on this line. + // We assume the list of hilites is sorted, so we just need to + // check the current entry. + size_t upper_bound = end; + do { + bool hilited = false; + // Skip any hilite rules that have start = end + while(iHilite < hilites.size() && hilites[iHilite].first == hilites[iHilite].second) + iHilite++; + if(iHilite < hilites.size()) { + // Possibilities: (vertical bars indicate line boundaries, parentheses for hilite boundaries, dots are data) + // 1. |...|...(...) --> no hilite on this line + // 2a. |...(...|...) --> hilite starts on this line and continues past it + // 2b. |...(...)...| --> hilite starts and ends on this line + // 3a. (...|...)...| --> hilite starts (or continues) at the start of the line and ends on this line + // 3b. (...|......)| --> entire line hilited + // Case 1 needs no special handling; check case 3, then case 2. + if(hilites[iHilite].first <= start) { + hilited = true; + if(hilites[iHilite].second < end) // 3a + end = hilites[iHilite].second; + } else if(hilites[iHilite].first < end) + end = hilites[iHilite].first; + // 2b will reduce to 3a after shifting start over + } + size_t amount = end - start; + snippets.push_back({str.substr(start,amount), loc, hilited}); + loc.x += string_length(snippets[snippets.size()-1].text, options.style); + start = end; + end = upper_bound; + if(iHilite < hilites.size() && start >= hilites[iHilite].second) + iHilite++; + } while(start < upper_bound); +} + +static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,text_params_t& options) { + if(str.empty()) return; // Nothing to do! + short line_height = options.style.lineHeight; + sf::Text str_to_draw; + options.style.applyTo(str_to_draw); + short str_len; + unsigned short last_line_break = 0,last_word_break = 0; + short total_width = 0; + short adjust_x = 0,adjust_y = 0; + + adjust_x = options.offset.x; + adjust_y = options.offset.y; + str_to_draw.setString("fj"); // Something that has both an ascender and a descender + adjust_y -= str_to_draw.getLocalBounds().height; + + str_to_draw.setString(str); + str_len = str.length(); + if(str_len == 0) { + return; + } + + eTextMode mode = options.mode; + total_width = str_to_draw.getLocalBounds().width; + if(mode == eTextMode::WRAP && total_width < dest_rect.width()) + mode = eTextMode::LEFT_TOP; + if(mode == eTextMode::LEFT_TOP && str.find('|') != std::string::npos) + mode = eTextMode::WRAP; + + auto text_len = [&str_to_draw](size_t i) -> int { + return str_to_draw.findCharacterPos(i).x; + }; + + // Special stuff + size_t iHilite = 0; + + location moveTo; + line_height -= 2; // TODO: ...why are we arbitrarily reducing the line height from the requested value? + + if(mode == eTextMode::WRAP) { + moveTo = location(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + adjust_y + 9); + short i; + for(i = 0; text_len(i) != text_len(i + 1) && i < str_len; i++) { + if(((text_len(i) - text_len(last_line_break) > (dest_rect.width() - 6)) + && (last_word_break >= last_line_break)) || (str[i] == '|')) { + if(str[i] == '|') { + if(!options.showBreaks) str[i] = ' '; + last_word_break = i + 1; + } else if(last_line_break == last_word_break) + last_word_break = i; + push_snippets(last_line_break, last_word_break, options, iHilite, str, moveTo); + moveTo.y += line_height; + last_line_break = last_word_break; + } + if(str[i] == ' ') + last_word_break = i + 1; + } + + if(i - last_line_break > 0) { + std::string snippet = str.substr(last_line_break); + if(!snippet.empty()) + push_snippets(last_line_break, str.length() + 1, options, iHilite, str, moveTo); + } + } else { + switch(mode) { + case eTextMode::CENTRE: + moveTo = location((dest_rect.right + dest_rect.left) / 2 - (4 * total_width) / 9 + adjust_x, + (dest_rect.bottom + dest_rect.top - line_height) / 2 + 9 + adjust_y); + break; + case eTextMode::LEFT_TOP: + moveTo = location(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + adjust_y + 9); + break; + case eTextMode::LEFT_BOTTOM: + moveTo = location(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + adjust_y + 9 + dest_rect.height() / 6); + break; + case eTextMode::WRAP: + break; // Never happens, but put this here to silence warning + } + push_snippets(0, str.length() + 1, options, iHilite, str, moveTo); + } + + for(auto& snippet : options.snippets) { + str_to_draw.setString(snippet.text); + str_to_draw.setPosition(snippet.at); + if(snippet.hilited) { + rectangle bounds = str_to_draw.getGlobalBounds(); + // Adjust so that drawing the same text to + // the same rect is positioned exactly right + bounds.left = snippet.at.x - 1; + bounds.top = snippet.at.y + 5; + if(options.returnType == text_params_t::RECTS) + options.returnRects.push_back(bounds); + str_to_draw.setColor(options.hilite_fg); + bounds.inset(0,-4); + fill_rect(dest_window, bounds, options.hilite_bg); + } else str_to_draw.setColor(options.style.colour); + dest_window.draw(str_to_draw); + if(options.style.font == FONT_BOLD) { + str_to_draw.move(1, 0); + dest_window.draw(str_to_draw); + } + } +} + +void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, location offset) { + text_params_t params; + params.mode = mode; + params.style = style; + params.offset = offset; + win_draw_string(dest_window, dest_rect, str, params); +} + +std::vector draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr) { + text_params_t params; + params.mode = eTextMode::WRAP; + params.hilite_ranges = hilites; + params.style = style; + params.hilite_fg = hiliteClr; + params.returnType = text_params_t::RECTS; + win_draw_string(dest_window, dest_rect, str, params); + return params.returnRects; +} + +std::vector draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr) { + text_params_t params; + params.mode = eTextMode::WRAP; + params.showBreaks = true; + params.hilite_ranges = hilites; + params.style = style; + params.hilite_fg = style.colour; + params.hilite_bg = hiliteClr; + params.returnType = text_params_t::RECTS; + win_draw_string(dest_window, dest_rect, str, params); + return params.snippets; +} + +size_t string_length(std::string str, TextStyle style, short* height){ + size_t total_width = 0; + + sf::Text text; + style.applyTo(text); + text.setString(str); + total_width = text.getLocalBounds().width; + if(height) *height = text.getLocalBounds().height; + return total_width; +} diff --git a/src/gfx/render_text.hpp b/src/gfx/render_text.hpp new file mode 100644 index 00000000..fe2e9aec --- /dev/null +++ b/src/gfx/render_text.hpp @@ -0,0 +1,58 @@ +// +// render_text.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#ifndef BoE_RENDER_TEXT_HPP +#define BoE_RENDER_TEXT_HPP + +#include +#include +#include + +#include +#include +#include + +#include "location.hpp" + +using hilite_t = std::pair; + +enum eFont { + FONT_PLAIN, + FONT_BOLD, + FONT_DUNGEON, + FONT_MAIDWORD +}; + +struct TextStyle { + bool italic = false, underline = false; + eFont font = FONT_BOLD; + int pointSize = 10, lineHeight; + sf::Color colour; + TextStyle() : colour(sf::Color::Black) {} + void applyTo(sf::Text& text); +}; + +struct snippet_t { + std::string text; + location at; + bool hilited; +}; + +enum class eTextMode { + WRAP, + CENTRE, + LEFT_TOP, + LEFT_BOTTOM, +}; + +std::vector draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr); +std::vector draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr); +void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, location offset = {0,0}); +size_t string_length(std::string str, TextStyle style, short* height = nullptr); + +#endif diff --git a/src/gfx/tiling.cpp b/src/gfx/tiling.cpp new file mode 100644 index 00000000..073187eb --- /dev/null +++ b/src/gfx/tiling.cpp @@ -0,0 +1,111 @@ +// +// tiling.cpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#include "tiling.hpp" + +#include +#include +#include "res_image.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" + +rectangle bg_rects[21]; +tessel_ref_t bg[21]; +tessel_ref_t bw_pats[6]; + +struct tessel_t { + sf::RenderTexture* tessel; + sf::Texture* img; + rectangle srcRect; +}; + +bool operator==(const tessel_ref_t& a, const tessel_ref_t& b) { + return a.key == b.key; +} + +template<> struct std::hash { + size_t operator()(tessel_ref_t key) const { + return key.key; + } +}; + +std::unordered_map tiling_reservoir; +static int tessel_index = 0; + +tessel_ref_t prepareForTiling(sf::Texture& srcImg, rectangle srcRect) { + tessel_ref_t ref = {tessel_index++}; + tiling_reservoir[ref].img = &srcImg; + tiling_reservoir[ref].srcRect = srcRect; + tiling_reservoir[ref].tessel = new sf::RenderTexture; + tiling_reservoir[ref].tessel->create(srcRect.width(), srcRect.height()); + rectangle tesselRect(*tiling_reservoir[ref].tessel); + rect_draw_some_item(srcImg, srcRect, *tiling_reservoir[ref].tessel, tesselRect); + tiling_reservoir[ref].tessel->display(); + tiling_reservoir[ref].tessel->setRepeated(true); + return ref; +} + +void tileImage(sf::RenderTarget& target, rectangle area, tessel_ref_t tessel, sf::BlendMode mode) { + // First, set up a dictionary of all textures ever tiled. + // The key type is a pair. + // The value type is a Texture. + tessel_t& tesselInfo = tiling_reservoir[tessel]; + rectangle clipArea = area; + area.left -= area.left % tesselInfo.srcRect.width(); + area.top -= area.top % tesselInfo.srcRect.height(); + area &= rectangle(target); // Make sure we don't draw out of bounds + + sf::RectangleShape tesselShape(sf::Vector2f(area.width(),area.height())); + tesselShape.setTexture(&tesselInfo.tessel->getTexture()); + tesselShape.setTextureRect(area); + tesselShape.setPosition(area.left, area.top); + sf::RenderStates renderMode(mode); + setActiveRenderTarget(target); + clip_rect(target, clipArea); + target.draw(tesselShape, renderMode); + undo_clip(target); +} + +void init_tiling() { + static const location pat_offs[17] = { + {0,3}, {1,1}, {2,1}, {2,0}, + {3,0}, {3,1}, {1,3}, {0,0}, + {0,2}, {1,2}, {0,1}, {2,2}, + {2,3}, {3,2}, {1,0}, {4,0}, {3,3} + }; + static const int pat_i[17] = { + 2, 3, 4, 5, 6, 8, 9, 10, + 11,12,13,14,15,16,17,19,20 + }; + for(short i = 0; i < 17; i++){ + bg_rects[pat_i[i]] = {0,0,64,64}; + bg_rects[pat_i[i]].offset(64 * pat_offs[i].x,64 * pat_offs[i].y); + } + rectangle tmp_rect = bg_rects[19]; + tmp_rect.offset(0, 64); + bg_rects[0] = bg_rects[1] = bg_rects[18] = bg_rects[7] = tmp_rect; + bg_rects[0].right -= 32; + bg_rects[0].bottom -= 32; + bg_rects[1].left += 32; + bg_rects[1].bottom -= 32; + bg_rects[18].right -= 32; + bg_rects[18].top += 32; + bg_rects[7].left += 32; + bg_rects[7].top += 32; + + rectangle bw_rect = {0,0,8,8}; + sf::Texture& bg_gworld = *ResMgr::get("pixpats"); + sf::Texture& bw_gworld = *ResMgr::get("bwpats"); + for(int i = 0; i < 21; i++) { + if(i < 6) { + bw_pats[i] = prepareForTiling(bw_gworld, bw_rect); + bw_rect.offset(8,0); + } + bg[i] = prepareForTiling(bg_gworld, bg_rects[i]); + } +} diff --git a/src/gfx/tiling.hpp b/src/gfx/tiling.hpp new file mode 100644 index 00000000..e11c92b7 --- /dev/null +++ b/src/gfx/tiling.hpp @@ -0,0 +1,29 @@ +// +// tiling.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#ifndef BoE_TILING_HPP +#define BoE_TILING_HPP + +#include +#include +#include "location.hpp" + +struct tessel_ref_t { + int key; +}; + +bool operator==(const tessel_ref_t& a, const tessel_ref_t& b); + +void init_tiling(); +tessel_ref_t prepareForTiling(sf::Texture& srcImg, rectangle srcRect); +void tileImage(sf::RenderTarget& target, rectangle area, tessel_ref_t tessel, sf::BlendMode mode = sf::BlendNone); +void tileImage(sf::RenderWindow& target, class Region& rgn, tessel_ref_t tessel, sf::BlendMode mode = sf::BlendNone); + +extern tessel_ref_t bg[]; + +#endif diff --git a/src/global.hpp b/src/global.hpp index c53f9a61..a0d23ede 100644 --- a/src/global.hpp +++ b/src/global.hpp @@ -15,6 +15,7 @@ typedef unsigned short ter_num_t; typedef signed short spec_num_t; typedef signed short item_num_t; typedef unsigned short str_num_t; +typedef signed short pic_num_t; // OBoE Current Version const unsigned long long OBOE_CURRENT_VERSION = 0x020000; // MMmmff; M - major, m - minor, f - bugfix diff --git a/src/mathutil.hpp b/src/mathutil.hpp index e00572d1..55baa4d0 100644 --- a/src/mathutil.hpp +++ b/src/mathutil.hpp @@ -24,12 +24,3 @@ inline void move_to_zero(T& val){ if(val > 0) val--; } - -// Case-insensitive string comparison seems to be semi-standard, but with different names. -#if defined(__APPLE__) -#define strnicmp strncasecmp -#elif defined(_MSC_VER) -#define strnicmp _strnicmp -#else -#error Missing strnicmp / strncasecmp -#endif diff --git a/src/pcedit/pc.action.cpp b/src/pcedit/pc.action.cpp index 219495d8..b4fa02b6 100644 --- a/src/pcedit/pc.action.cpp +++ b/src/pcedit/pc.action.cpp @@ -6,7 +6,6 @@ #include "pc.editors.hpp" #include "pc.fileio.hpp" #include "pc.action.hpp" -#include "graphtool.hpp" #include "sounds.hpp" #include "mathutil.hpp" #include "dialog.hpp" diff --git a/src/pcedit/pc.editors.cpp b/src/pcedit/pc.editors.cpp index 4c9ce07e..1e43208f 100644 --- a/src/pcedit/pc.editors.cpp +++ b/src/pcedit/pc.editors.cpp @@ -2,7 +2,7 @@ #include "pc.graphics.hpp" #include "universe.hpp" #include "pc.editors.hpp" -#include "graphtool.hpp" +#include "utility.hpp" #include "dialog.hpp" #include "control.hpp" #include "button.hpp" diff --git a/src/pcedit/pc.fileio.cpp b/src/pcedit/pc.fileio.cpp index 816c5dbe..4f048a22 100644 --- a/src/pcedit/pc.fileio.cpp +++ b/src/pcedit/pc.fileio.cpp @@ -5,7 +5,6 @@ #include "universe.hpp" #include "pc.fileio.hpp" #include "pc.graphics.hpp" -#include "graphtool.hpp" #include "sounds.hpp" #include "pc.editors.hpp" #include "mathutil.hpp" diff --git a/src/pcedit/pc.graphics.cpp b/src/pcedit/pc.graphics.cpp index 7b71ff66..7762da00 100644 --- a/src/pcedit/pc.graphics.cpp +++ b/src/pcedit/pc.graphics.cpp @@ -5,11 +5,15 @@ #include "pc.editors.hpp" #include "pc.action.hpp" #include "sounds.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" +#include "render_shapes.hpp" +#include "render_image.hpp" #include "res_image.hpp" #include "message.hpp" #include "mathutil.hpp" #include "gitrev.hpp" +#include "tiling.hpp" // for bg +#include "utility.hpp" extern cUniverse univ; diff --git a/src/pcedit/pc.main.cpp b/src/pcedit/pc.main.cpp index 540cbd05..6279383a 100644 --- a/src/pcedit/pc.main.cpp +++ b/src/pcedit/pc.main.cpp @@ -8,7 +8,9 @@ #include "pc.action.hpp" #include "pc.fileio.hpp" #include "sounds.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "tiling.hpp" +#include "utility.hpp" #include "boe.consts.hpp" #include "dialog.hpp" #include "control.hpp" @@ -72,7 +74,8 @@ int main(int argc, char* argv[]) { init_fileio(); init_main_buttons(); Set_up_win(); - init_graph_tool(); + init_shaders(); + init_tiling(); init_snd_tool(); set_up_apple_events(argc, argv); diff --git a/src/scenario/item.cpp b/src/scenario/item.cpp index bae9c169..cd210396 100644 --- a/src/scenario/item.cpp +++ b/src/scenario/item.cpp @@ -17,7 +17,7 @@ #include "boe.consts.hpp" // TODO: If this is needed here, maybe it shouldn't be in the "boe" namespace #include "oldstructs.hpp" -#include "graphtool.hpp" // for get_str() +#include "utility.hpp" #include "fileio.hpp" #include "damage.hpp" diff --git a/src/scenario/monster.cpp b/src/scenario/monster.cpp index 1f820b90..7bad7d51 100644 --- a/src/scenario/monster.cpp +++ b/src/scenario/monster.cpp @@ -19,6 +19,7 @@ #include "oldstructs.hpp" #include "fileio.hpp" #include "spell.hpp" +#include "gfxsheets.hpp" // for NO_PIC void cMonster::import_legacy(legacy::monster_record_type& old){ level = old.level; diff --git a/src/scenario/monster.hpp b/src/scenario/monster.hpp index 9cba0340..84a64cc3 100644 --- a/src/scenario/monster.hpp +++ b/src/scenario/monster.hpp @@ -15,7 +15,6 @@ #include #include "sounds.hpp" -#include "graphtool.hpp" #include "living.hpp" #include "monster_abilities.hpp" #include "race.hpp" diff --git a/src/scenario/shop.cpp b/src/scenario/shop.cpp index 2a49338a..e895c26b 100644 --- a/src/scenario/shop.cpp +++ b/src/scenario/shop.cpp @@ -10,7 +10,7 @@ #include #include #include "mathutil.hpp" -#include "graphtool.hpp" // for get_str +#include "utility.hpp" std::map skill_cost = { {eSkill::STRENGTH,3}, {eSkill::DEXTERITY,3}, {eSkill::INTELLIGENCE,3}, diff --git a/src/scenario/special.cpp b/src/scenario/special.cpp index 13de6719..4809221e 100644 --- a/src/scenario/special.cpp +++ b/src/scenario/special.cpp @@ -15,7 +15,7 @@ #include "strdlog.hpp" #include "oldstructs.hpp" -#include "graphtool.hpp" +#include "utility.hpp" #include "spell.hpp" #include "skills_traits.hpp" diff --git a/src/scenario/terrain.cpp b/src/scenario/terrain.cpp index 8b9222e9..502b3342 100644 --- a/src/scenario/terrain.cpp +++ b/src/scenario/terrain.cpp @@ -14,7 +14,7 @@ #include #include "oldstructs.hpp" -#include "graphtool.hpp" // for NO_PIC +#include "gfxsheets.hpp" // for NO_PIC #include "boe.consts.hpp" // TODO: Put these constants in a global file #include "damage.hpp" diff --git a/src/scenario/town.cpp b/src/scenario/town.cpp index d73e0b6c..cb827fc4 100644 --- a/src/scenario/town.cpp +++ b/src/scenario/town.cpp @@ -17,6 +17,7 @@ #include "oldstructs.hpp" #include "mathutil.hpp" #include "fileio.hpp" +#include "utility.hpp" void cTown::import_legacy(legacy::town_record_type& old){ town_chop_time = old.town_chop_time; diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index aa43ae38..eea18d29 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -7,7 +7,7 @@ #include #include "scen.global.hpp" #include "scenario.hpp" -#include "graphtool.hpp" +#include "render_shapes.hpp" #include "scen.graphics.hpp" #include "scen.actions.hpp" #include "sounds.hpp" diff --git a/src/scenedit/scen.btnmg.cpp b/src/scenedit/scen.btnmg.cpp index c42fe117..5cbce1b8 100644 --- a/src/scenedit/scen.btnmg.cpp +++ b/src/scenedit/scen.btnmg.cpp @@ -5,7 +5,6 @@ #include "scen.global.hpp" #include #include -#include "graphtool.hpp" #include "scen.graphics.hpp" #include #include "scen.btnmg.hpp" diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 8ba2685b..37d203a3 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -9,7 +9,8 @@ #include "scen.global.hpp" #include "scenario.hpp" #include "town.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" +#include "utility.hpp" #include "scen.graphics.hpp" #include "scen.core.hpp" #include "scen.keydlgs.hpp" diff --git a/src/scenedit/scen.fileio.cpp b/src/scenedit/scen.fileio.cpp index 1d3b0452..3b10e2e2 100644 --- a/src/scenedit/scen.fileio.cpp +++ b/src/scenedit/scen.fileio.cpp @@ -8,7 +8,7 @@ #include #include "scen.fileio.hpp" #include "scen.keydlgs.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" #include "scen.core.hpp" #include "sounds.hpp" #include "mathutil.hpp" diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index 38127d34..f8c1fb24 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -4,7 +4,11 @@ #include #include "scen.global.hpp" #include "scenario.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" +#include "render_image.hpp" +#include "render_shapes.hpp" +#include "render_text.hpp" +#include "tiling.hpp" // for bg #include "scen.graphics.hpp" #include #include "scen.keydlgs.hpp" diff --git a/src/scenedit/scen.graphics.hpp b/src/scenedit/scen.graphics.hpp index 5cf74beb..b1666006 100644 --- a/src/scenedit/scen.graphics.hpp +++ b/src/scenedit/scen.graphics.hpp @@ -1,5 +1,6 @@ #include "fields.hpp" +#include "location.hpp" void Set_up_win (); void run_startup_g(); diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 9b56bd9d..ae95acb2 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -6,7 +6,8 @@ #include #include "scen.global.hpp" #include "scenario.hpp" -#include "graphtool.hpp" +#include "gfxsheets.hpp" +#include "utility.hpp" #include "scen.graphics.hpp" #include "scen.keydlgs.hpp" #include "scen.core.hpp" diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index 74d8e196..e6a34b12 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -6,7 +6,8 @@ #include "scen.global.hpp" #include "scenario.hpp" -#include "graphtool.hpp" +#include "render_image.hpp" +#include "tiling.hpp" #include "scen.graphics.hpp" #include "scen.actions.hpp" #include "scen.fileio.hpp" @@ -101,7 +102,8 @@ void init_scened(int argc, char* argv[]) { init_directories(argv[0]); init_menubar(); // TODO: Sync and load prefs - init_graph_tool(); + init_shaders(); + init_tiling(); init_snd_tool(); sf::VideoMode mode = sf::VideoMode::getDesktopMode(); diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index 97308c4c..860af8f5 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -6,7 +6,7 @@ #include "scen.global.hpp" #include "scenario.hpp" #include "town.hpp" -#include "graphtool.hpp" +#include "utility.hpp" #include "scen.actions.hpp" #include "scen.graphics.hpp" #include "scen.townout.hpp" diff --git a/src/spell.cpp b/src/spell.cpp index 7e0e9d60..55a6d93c 100644 --- a/src/spell.cpp +++ b/src/spell.cpp @@ -7,7 +7,8 @@ // #include "spell.hpp" -#include "graphtool.hpp" // for get_str + +#include "utility.hpp" std::map cSpell::dictionary; diff --git a/src/universe/universe.cpp b/src/universe/universe.cpp index c3f75656..f9f0427a 100644 --- a/src/universe/universe.cpp +++ b/src/universe/universe.cpp @@ -18,6 +18,7 @@ #include "oldstructs.hpp" #include "mathutil.hpp" #include "fileio.hpp" +#include "gfxsheets.hpp" void cCurOut::import_legacy(legacy::out_info_type& old){ for(int i = 0; i < 96; i++) diff --git a/src/utility.cpp b/src/utility.cpp new file mode 100644 index 00000000..05a535fc --- /dev/null +++ b/src/utility.cpp @@ -0,0 +1,62 @@ +// +// utility.cpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#include "utility.hpp" + +#include "res_strings.hpp" + +std::string get_str(std::string list, short j){ + if(j == 0) return list; + StringRsrc& strings = *ResMgr::get(list); + return strings[j - 1]; +} + +short can_see(location p1,location p2,std::function get_obscurity) { + short storage = 0; + + if(p1.y == p2.y) { + if(p1.x > p2.x) { + for(short count = p2.x + 1; count < p1.x; count++) + storage += get_obscurity(count, p1.y); + } else { + for(short count = p1.x + 1; count < p2.x; count++) + storage += get_obscurity(count, p1.y); + } + } else if(p1.x == p2.x) { + if(p1.y > p2.y) { + for(short count = p1.y - 1; count > p2.y; count--) + storage += get_obscurity(p1.x, count); + } else { + for(short count = p1.y + 1; count < p2.y; count++) + storage += get_obscurity(p1.x, count); + } + } else { + short dx = p2.x - p1.x; + short dy = p2.y - p1.y; + + if(abs(dy) > abs(dx)) { + if(p2.y > p1.y) { + for(short count = 1; count < dy; count++) + storage += get_obscurity(p1.x + (count * dx) / dy, p1.y + count); + } else { + for(short count = -1; count > dy; count--) + storage += get_obscurity(p1.x + (count * dx) / dy, p1.y + count); + } + } + if(abs(dy) <= abs(dx)) { + if(p2.x > p1.x) { + for(short count = 1; count < dx; count++) + storage += get_obscurity(p1.x + count, p1.y + (count * dy) / dx); + } else { + for(short count = -1; count > dx; count--) + storage += get_obscurity(p1.x + count, p1.y + (count * dy) / dx); + } + } + } + return storage; +} diff --git a/src/utility.hpp b/src/utility.hpp new file mode 100644 index 00000000..f0c68d3d --- /dev/null +++ b/src/utility.hpp @@ -0,0 +1,28 @@ +// +// utility.hpp +// BoE +// +// Created by Celtic Minstrel on 17-04-14. +// +// + +#ifndef BoE_UTILITY_HPP +#define BoE_UTILITY_HPP + +#include +#include +#include "location.hpp" + +short can_see(location p1,location p2,std::function get_obscurity); +std::string get_str(std::string list, short j); + +// Case-insensitive string comparison seems to be semi-standard, but with different names. +#if defined(__APPLE__) +#define strnicmp strncasecmp +#elif defined(_MSC_VER) +#define strnicmp _strnicmp +#else +#error Missing strnicmp / strncasecmp +#endif + +#endif diff --git a/src/view_dialogs.cpp b/src/view_dialogs.cpp index 07a1b822..3266e04b 100644 --- a/src/view_dialogs.cpp +++ b/src/view_dialogs.cpp @@ -15,6 +15,7 @@ #include "item.hpp" #include "creature.hpp" #include "scenario.hpp" +#include "utility.hpp" void put_item_info(cDialog& me, const cItem& s_i, const cScenario& scen) { std::string desc_str; diff --git a/test/catch.cpp b/test/catch.cpp index 1dbc5815..903ce969 100644 --- a/test/catch.cpp +++ b/test/catch.cpp @@ -3,7 +3,7 @@ #include "catch.hpp" // After this are some globals that are referenced from common code but not defined, and not used in the test cases -#include "graphtool.hpp" +#include "gfxsheets.hpp" #include "universe.hpp" sf::RenderWindow mainPtr; std::string scenario_temp_dir_name = "test_scenario"; From 1f9615d185527a05418eb58ce29adce3f24d5303 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 15 Apr 2017 02:03:42 -0400 Subject: [PATCH 10/11] Add an info structure for eItemType enum --- src/game/boe.party.cpp | 2 +- src/game/boe.text.cpp | 6 ++-- src/scenario/item.cpp | 61 ++++++++++++++++++++++++----------- src/scenario/item_variety.hpp | 21 ++++++------ src/scenedit/scen.core.cpp | 5 ++- src/scenedit/scen.fileio.cpp | 4 +-- src/universe/pc.cpp | 49 ++++++++++------------------ 7 files changed, 78 insertions(+), 70 deletions(-) diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index 11aadc02..f6a8e99e 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -2278,7 +2278,7 @@ bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace ty how_much -= minmax(-5,5,which_pc.status[eStatus::BLESS_CURSE]); for(short i = 0; i < which_pc.items.size(); i++) { if((which_pc.items[i].variety != eItemType::NO_ITEM) && (which_pc.equip[i])) { - if(isArmourType(which_pc.items[i].variety)) { + if((*which_pc.items[i].variety).is_armour) { r1 = get_ran(1,1,which_pc.items[i].item_level); how_much -= r1; diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index becaab6f..f73c46e3 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -314,7 +314,7 @@ void put_item_screen(short screen_num) { style.italic = true; if(univ.party[pc].items[i_num].variety == eItemType::ONE_HANDED || univ.party[pc].items[i_num].variety == eItemType::TWO_HANDED) style.colour = sf::Color::Magenta; - else if(isArmourType(univ.party[pc].items[i_num].variety)) + else if((*univ.party[pc].items[i_num].variety).is_armour) style.colour = sf::Color::Green; else style.colour = sf::Color::Blue; } else style.colour = sf::Color::Black; @@ -394,7 +394,7 @@ void place_buy_button(short position,short pc_num,short item_num) { } break; case MODE_SELL_WEAP: - if(isWeaponType(univ.party[pc_num].items[item_num].variety) && + if((*univ.party[pc_num].items[item_num].variety).is_weapon && (!univ.party[pc_num].equip[item_num]) && (univ.party[pc_num].items[item_num].ident) && (val_to_place > 0) && (!univ.party[pc_num].items[item_num].unsellable)) { @@ -403,7 +403,7 @@ void place_buy_button(short position,short pc_num,short item_num) { } break; case MODE_SELL_ARMOR: - if(isArmourType(univ.party[pc_num].items[item_num].variety) && + if((*univ.party[pc_num].items[item_num].variety).is_armour && (!univ.party[pc_num].equip[item_num]) && (univ.party[pc_num].items[item_num].ident) && (val_to_place > 0) && (!univ.party[pc_num].items[item_num].unsellable)) { diff --git a/src/scenario/item.cpp b/src/scenario/item.cpp index cd210396..5217a982 100644 --- a/src/scenario/item.cpp +++ b/src/scenario/item.cpp @@ -24,25 +24,50 @@ #include "spell.hpp" #include "race.hpp" -extern const std::multiset equippable = { - eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::BOW, eItemType::ARROW, eItemType::THROWN_MISSILE, - eItemType::TOOL, eItemType::SHIELD, eItemType::ARMOR, eItemType::HELM, eItemType::GLOVES, - eItemType::SHIELD_2, eItemType::BOOTS, eItemType::RING, eItemType::NECKLACE, eItemType::PANTS, - eItemType::CROSSBOW, eItemType::BOLTS, eItemType::MISSILE_NO_AMMO, - // And these are the ones that you can equip two of - eItemType::ONE_HANDED, eItemType::RING, -}; +static std::array load_item_type_info() { + std::multiset equippable = { + eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::BOW, eItemType::ARROW, eItemType::THROWN_MISSILE, + eItemType::TOOL, eItemType::SHIELD, eItemType::ARMOR, eItemType::HELM, eItemType::GLOVES, + eItemType::SHIELD_2, eItemType::BOOTS, eItemType::RING, eItemType::NECKLACE, eItemType::PANTS, + eItemType::CROSSBOW, eItemType::BOLTS, eItemType::MISSILE_NO_AMMO, + // And these are the ones that you can equip two of + eItemType::ONE_HANDED, eItemType::RING, + }; + + std::multiset num_hands_to_use = { + eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::TWO_HANDED, eItemType::SHIELD, eItemType::SHIELD_2, + }; + + // For following, if an item of type n is equipped, no other items of type n can be equipped, + std::map excluding_types = { + {eItemType::BOW, eItemCat::MISSILE_WEAPON}, + {eItemType::CROSSBOW, eItemCat::MISSILE_WEAPON}, + {eItemType::MISSILE_NO_AMMO, eItemCat::MISSILE_WEAPON}, + {eItemType::ARROW, eItemCat::MISSILE_AMMO}, + {eItemType::THROWN_MISSILE, eItemCat::MISSILE_AMMO}, + {eItemType::BOLTS, eItemCat::MISSILE_AMMO}, + }; + + std::array all_info; + int i = -1; + for(auto& info : all_info) { + eItemType type = eItemType(++i); + info.self = type; + // TODO: Maybe don't base these on i? + info.is_armour = i >= 12 && i <= 17; + info.is_weapon = (i >= 1 && i <= 6 && i != 3) || (i >= 23 && i <= 25); + info.is_missile = i == 5 || i == 6 || i == 24 || i == 25; + info.equip_count = equippable.count(type); + info.num_hands = num_hands_to_use.count(type); + info.exclusion = info.num_hands ? eItemCat::HANDS : excluding_types[type]; + } + return all_info; +} -extern const std::multiset num_hands_to_use = { - eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::TWO_HANDED, eItemType::SHIELD, eItemType::SHIELD_2, -}; - -// For following, if an item of type n is equipped, no other items of type n can be equipped, -// TODO: Should SHIELD and SHIELD_2 have an entry here? -std::map excluding_types = { - {eItemType::BOW, 2}, {eItemType::ARROW, 1}, {eItemType::THROWN_MISSILE, 1}, - {eItemType::CROSSBOW, 2}, {eItemType::BOLTS, 1}, {eItemType::MISSILE_NO_AMMO, 2} -}; +const item_variety_t& operator*(eItemType type) { + static std::array item_type_info = load_item_type_info(); + return item_type_info[int(type)]; +} unsigned char cItem::rec_treas_class() const { short tmp = value; diff --git a/src/scenario/item_variety.hpp b/src/scenario/item_variety.hpp index 1b95a878..14f76ed6 100644 --- a/src/scenario/item_variety.hpp +++ b/src/scenario/item_variety.hpp @@ -44,19 +44,18 @@ enum class eItemType { QUEST = 27, }; -inline bool isArmourType(eItemType type) { - int code = (int) type; - return code >= 12 && code <= 17; -} +enum class eItemCat { + MISC, MISSILE_WEAPON, MISSILE_AMMO, HANDS, +}; -inline bool isWeaponType(eItemType type) { - int code = (int) type; - return (code >= 1 && code <= 6 && code != 3) || (code >= 23 && code <= 25); -} +struct item_variety_t { + eItemType self; + bool is_armour, is_weapon, is_missile; + int equip_count, num_hands; + eItemCat exclusion; +}; -inline bool isMissileType(eItemType type) { - return type == eItemType::ARROW || type == eItemType::BOLTS || type == eItemType::THROWN_MISSILE || type == eItemType::MISSILE_NO_AMMO; -} +const item_variety_t& operator*(eItemType type); enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL}; diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 37d203a3..94e6de67 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -47,7 +47,6 @@ extern ter_num_t template_terrain[64][64]; extern cScenario scenario; extern cCustomGraphics spec_scen_g; extern location cur_out; -extern const std::multiset equippable; const std::set items_no_strength = { eItemAbil::NONE, eItemAbil::HEALING_WEAPON, eItemAbil::RETURNING_MISSILE, eItemAbil::SEEKING_MISSILE, eItemAbil::DRAIN_MISSILES, @@ -1918,7 +1917,7 @@ static bool edit_item_abil_event_filter(cDialog& me, std::string hit, cItem& ite put_item_abils_in_dlog(me, item, which); } else if(hit == "weapon") { save_item_abils(me, item); - if(!isWeaponType(item.variety)) { + if(!(*item.variety).is_weapon) { showError("You can only give an ability of this sort to a weapon.","",&me); return true; } @@ -1936,7 +1935,7 @@ static bool edit_item_abil_event_filter(cDialog& me, std::string hit, cItem& ite put_item_abils_in_dlog(me, item, which); } else if(hit == "general") { save_item_abils(me, item); - if(equippable.count(item.variety) == 0 || item.variety == eItemType::ARROW || item.variety == eItemType::THROWN_MISSILE || item.variety == eItemType::BOLTS){ + if((*item.variety).equip_count == 0 || item.variety == eItemType::ARROW || item.variety == eItemType::THROWN_MISSILE || item.variety == eItemType::BOLTS){ showError("You can only give an ability of this sort to an non-missile item which can be equipped (like armor, or a ring).",&me); return true; } diff --git a/src/scenedit/scen.fileio.cpp b/src/scenedit/scen.fileio.cpp index 3b10e2e2..0570382c 100644 --- a/src/scenedit/scen.fileio.cpp +++ b/src/scenedit/scen.fileio.cpp @@ -439,9 +439,9 @@ void writeItemsToXml(ticpp::Printer&& data, cScenario& scenario) { data.PushElement("protection", item.protection); if(item.charges > 0) data.PushElement("charges", item.charges); - if(isWeaponType(item.variety) && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS) + if((*item.variety).is_weapon && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS) data.PushElement("weapon-type", item.weap_type); - if(item.missile > 0 || isMissileType(item.variety)) + if(item.missile > 0 || (*item.variety).is_missile) data.PushElement("missile-type", item.missile); data.PushElement("pic", item.graphic_num); if(item.type_flag > 0) diff --git a/src/universe/pc.cpp b/src/universe/pc.cpp index e9961fed..e6bc3779 100644 --- a/src/universe/pc.cpp +++ b/src/universe/pc.cpp @@ -18,10 +18,6 @@ #include "mathutil.hpp" #include "fileio.hpp" -extern const std::multiset equippable; -extern const std::multiset num_hands_to_use; -extern std::map excluding_types; - extern short skill_bonus[21]; // A nice convenient bitset with just the low 30 bits set, for initializing spells const uint32_t cPlayer::basic_spells = std::numeric_limits::max() >> 2; @@ -496,24 +492,18 @@ bool cPlayer::give_item(cItem item, int flags) { print_result(announce.str()); } - if(equip_type != 0 && equippable.count(item.variety)) { + if(equip_type != 0 && (*item.variety).equip_count) { if(!equip_item(free_space.slot, false) && equip_type != GIVE_EQUIP_SOFT) { - int exclude = 0; - if(num_hands_to_use.count(item.variety)) - exclude = 100; - else exclude = excluding_types[item.variety]; + eItemCat exclude = (*item.variety).exclusion; int rem1 = items.size(), rem2 = items.size(); for(int i = 0; i < items.size(); i++) { if(i == free_space.slot) continue; if(!equip[i]) continue; - int check_exclude = 0; - if(num_hands_to_use.count(items[i].variety)) - check_exclude = 100; - else check_exclude = excluding_types[items[i].variety]; + eItemCat check_exclude = (*items[i].variety).exclusion; if(exclude != check_exclude) continue; - if(exclude == 0 && item.variety != items[i].variety) + if(exclude == eItemCat::MISC && item.variety != items[i].variety) continue; - if(exclude == 100) { + if(exclude == eItemCat::HANDS) { if(rem1 == items.size()) { if(item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED || rem2 < items.size()) rem1 = i; @@ -528,18 +518,13 @@ bool cPlayer::give_item(cItem item, int flags) { } bool can_rem1 = rem1 < items.size() && (!items[rem1].cursed || equip_type == GIVE_EQUIP_FORCE); bool can_rem2 = rem2 < items.size() && (!items[rem2].cursed || equip_type == GIVE_EQUIP_FORCE); - if(exclude == 100) { - if(item.variety == eItemType::TWO_HANDED) { - if(can_rem1) equip[rem1] = false; - if(can_rem2) equip[rem2] = false; - } else if(item.variety == eItemType::ONE_HANDED) { + if(exclude == eItemCat::HANDS) { + if((*item.variety).num_hands == 2 && can_rem1 && can_rem2) { + equip[rem1] = false; + equip[rem2] = false; + } else if((*item.variety).num_hands == 1) { if(can_rem1) equip[rem1] = false; else if(can_rem2) equip[rem2] = false; - } else { // It's a shield - if(can_rem2 && items[rem2].variety != item.variety) - equip[rem2] = false; - else if(can_rem1 && items[rem1].variety != item.variety) - equip[rem1] = false; } if((rem1 == weap_poisoned.slot && !equip[rem1]) || (rem2 == weap_poisoned.slot && !equip[rem2])) { status[eStatus::POISONED_WEAPON] = 0; @@ -559,7 +544,7 @@ bool cPlayer::give_item(cItem item, int flags) { } bool cPlayer::equip_item(int which_item, bool do_print) { - if(!equippable.count(items[which_item].variety)) { + if((*items[which_item].variety).equip_count == 0) { if(do_print && print_result) print_result("Equip: Can't equip this item."); return false; @@ -569,15 +554,15 @@ bool cPlayer::equip_item(int which_item, bool do_print) { if(equip[i]) { if(items[i].variety == items[which_item].variety) num_this_type++; - hands_occupied += num_hands_to_use.count(items[i].variety); + hands_occupied += (*items[i].variety).num_hands; } - short equip_item_type = excluding_types[items[which_item].variety]; + eItemCat equip_item_type = (*items[which_item].variety).exclusion; // Now if missile is already equipped, no more missiles - if(equip_item_type > 0) { + if(equip_item_type != eItemCat::MISC) { for(int i = 0; i < items.size(); i++) - if(equip[i] && excluding_types[items[i].variety] == equip_item_type) { + if(equip[i] && (*items[i].variety).exclusion == equip_item_type) { if(do_print && print_result) { print_result("Equip: You have something of this type"); print_result(" equipped."); @@ -587,11 +572,11 @@ bool cPlayer::equip_item(int which_item, bool do_print) { } size_t hands_free = 2 - hands_occupied; - if(hands_free < num_hands_to_use.count(items[which_item].variety)) { + if(hands_free < (*items[which_item].variety).num_hands) { if(do_print && print_result) print_result("Equip: Not enough free hands"); return false; - } else if(equippable.count(items[which_item].variety) <= num_this_type) { + } else if((*items[which_item].variety).equip_count <= num_this_type) { if(do_print && print_result) print_result("Equip: Can't equip another"); return false; From 7987680bf462340205ae7dcfe2f990e30c95483f Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 15 Apr 2017 02:04:11 -0400 Subject: [PATCH 11/11] Simplify some stuff with references --- src/game/boe.party.cpp | 25 +++++++++-------- src/game/boe.text.cpp | 62 ++++++++++++++++++------------------------ src/universe/pc.cpp | 12 ++++---- 3 files changed, 45 insertions(+), 54 deletions(-) diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index f6a8e99e..39fceb27 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -2277,30 +2277,31 @@ bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace ty if(damage_type == eDamageType::WEAPON || damage_type == eDamageType::UNDEAD || damage_type == eDamageType::DEMON) { how_much -= minmax(-5,5,which_pc.status[eStatus::BLESS_CURSE]); for(short i = 0; i < which_pc.items.size(); i++) { - if((which_pc.items[i].variety != eItemType::NO_ITEM) && (which_pc.equip[i])) { - if((*which_pc.items[i].variety).is_armour) { - r1 = get_ran(1,1,which_pc.items[i].item_level); + const cItem& item = which_pc.items[i]; + if(item.variety != eItemType::NO_ITEM && which_pc.equip[i]) { + if((*item.variety).is_armour) { + r1 = get_ran(1,1,item.item_level); how_much -= r1; // bonus for magical items - if(which_pc.items[i].bonus > 0) { - r1 = get_ran(1,1,which_pc.items[i].bonus); + if(item.bonus > 0) { + r1 = get_ran(1,1,item.bonus); how_much -= r1; - how_much -= which_pc.items[i].bonus / 2; + how_much -= item.bonus / 2; } - if(which_pc.items[i].bonus < 0) { - how_much = how_much - which_pc.items[i].bonus; + if(item.bonus < 0) { + how_much = how_much - item.bonus; } r1 = get_ran(1,1,100); if(r1 < hit_chance[which_pc.skill(eSkill::DEFENSE)] - 20) how_much -= 1; } - if(which_pc.items[i].protection > 0) { - r1 = get_ran(1,1,which_pc.items[i].protection); + if(item.protection > 0) { + r1 = get_ran(1,1,item.protection); how_much -= r1; } - if(which_pc.items[i].protection < 0) { - r1 = get_ran(1,1,-1 * which_pc.items[i].protection); + if(item.protection < 0) { + r1 = get_ran(1,1,-1 * item.protection); how_much += r1; } } diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index f73c46e3..b4690270 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -305,29 +305,27 @@ void put_item_screen(short screen_num) { dest_rect.left += 36; dest_rect.top -= 2; - if(univ.party[pc].items[i_num].variety == eItemType::NO_ITEM) { - - } - else { + const cPlayer& who = univ.party[pc]; + const cItem& item = who.items[i_num]; + + if(item.variety != eItemType::NO_ITEM) { style.font = FONT_PLAIN; - if(univ.party[pc].equip[i_num]) { + if(who.equip[i_num]) { style.italic = true; - if(univ.party[pc].items[i_num].variety == eItemType::ONE_HANDED || univ.party[pc].items[i_num].variety == eItemType::TWO_HANDED) + if(item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED) style.colour = sf::Color::Magenta; - else if((*univ.party[pc].items[i_num].variety).is_armour) + else if((*item.variety).is_armour) style.colour = sf::Color::Green; else style.colour = sf::Color::Blue; } else style.colour = sf::Color::Black; sout.str(""); - if(!univ.party[pc].items[i_num].ident) - sout << univ.party[pc].items[i_num].name << " "; + if(!item.ident) + sout << item.name << " "; else { /// Don't place # of charges when Sell button up and space tight - sout << univ.party[pc].items[i_num].full_name << ' '; - // TODO: Why are bashing weapons excluded from this? - if(univ.party[pc].items[i_num].charges > 0 && univ.party[pc].items[i_num].ability != eItemAbil::MESSAGE - && (stat_screen_mode == MODE_INVEN || stat_screen_mode == MODE_SHOP)) - sout << '(' << int(univ.party[pc].items[i_num].charges) << ')'; + sout << item.full_name << ' '; + if(item.charges > 0 && item.ability != eItemAbil::MESSAGE && (stat_screen_mode == MODE_INVEN || stat_screen_mode == MODE_SHOP)) + sout << '(' << int(item.charges) << ')'; } dest_rect.left -= 2; win_draw_string(item_stats_gworld,dest_rect,sout.str(),eTextMode::WRAP,style); @@ -350,7 +348,7 @@ void put_item_screen(short screen_num) { ((is_town()) || (is_out()) || ((is_combat()) && (pc == univ.cur_pc)))) { // place give and drop and use place_item_button(1,i,2,0); place_item_button(2,i,3,0); - if(abil_chart[univ.party[pc].items[i_num].ability]) // place use if can + if(abil_chart[item.ability]) // place use if can place_item_button(0,i,1,0); } } @@ -375,58 +373,50 @@ void place_buy_button(short position,short pc_num,short item_num) { // TODO: This is now duplicated here and in start_town_mode() short aug_cost[10] = {4,7,10,8, 15,15,10, 0,0,0}; - if(univ.party[pc_num].items[item_num].variety == eItemType::NO_ITEM) + const cPlayer& pc = univ.party[pc_num]; + const cItem& item = pc.items[item_num]; + + if(item.variety == eItemType::NO_ITEM) return; dest_rect = item_buttons[position][5]; - val_to_place = (univ.party[pc_num].items[item_num].charges > 0) ? - univ.party[pc_num].items[item_num].charges * univ.party[pc_num].items[item_num].value : - univ.party[pc_num].items[item_num].value; + val_to_place = (item.charges > 0) ? + item.charges * item.value : + item.value; val_to_place = val_to_place / 2; switch(stat_screen_mode) { case MODE_IDENTIFY: - if(!univ.party[pc_num].items[item_num].ident) { + if(!item.ident) { item_area_button_active[position][5] = true; source_rect = button_sources[0]; val_to_place = shop_identify_cost; } break; case MODE_SELL_WEAP: - if((*univ.party[pc_num].items[item_num].variety).is_weapon && - (!univ.party[pc_num].equip[item_num]) && - (univ.party[pc_num].items[item_num].ident) && (val_to_place > 0) && - (!univ.party[pc_num].items[item_num].unsellable)) { + if((*item.variety).is_weapon && !pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { item_area_button_active[position][5] = true; source_rect = button_sources[1]; } break; case MODE_SELL_ARMOR: - if((*univ.party[pc_num].items[item_num].variety).is_armour && - (!univ.party[pc_num].equip[item_num]) && - (univ.party[pc_num].items[item_num].ident) && (val_to_place > 0) && - (!univ.party[pc_num].items[item_num].unsellable)) { + if((*item.variety).is_armour && !pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { item_area_button_active[position][5] = true; source_rect = button_sources[1]; } break; case MODE_SELL_ANY: - if((val_to_place > 0) && (univ.party[pc_num].items[item_num].ident) && - (!univ.party[pc_num].equip[item_num]) && - (!univ.party[pc_num].items[item_num].unsellable)) { + if(!pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { item_area_button_active[position][5] = true; source_rect = button_sources[1]; } break; case MODE_ENCHANT: - if((univ.party[pc_num].items[item_num].variety == eItemType::ONE_HANDED || univ.party[pc_num].items[item_num].variety == eItemType::TWO_HANDED) && - (univ.party[pc_num].items[item_num].ident) && - univ.party[pc_num].items[item_num].ability == eItemAbil::NONE && - (!univ.party[pc_num].items[item_num].magic)) { + if((item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED) && item.ident && item.ability == eItemAbil::NONE && !item.magic) { item_area_button_active[position][5] = true; source_rect = button_sources[2]; - val_to_place = max(aug_cost[shop_identify_cost] * 100,univ.party[pc_num].items[item_num].value * (5 + aug_cost[shop_identify_cost])); + val_to_place = max(aug_cost[shop_identify_cost] * 100, item.value * (5 + aug_cost[shop_identify_cost])); } break; case MODE_INVEN: case MODE_SHOP: diff --git a/src/universe/pc.cpp b/src/universe/pc.cpp index e6bc3779..f3e9713d 100644 --- a/src/universe/pc.cpp +++ b/src/universe/pc.cpp @@ -544,7 +544,8 @@ bool cPlayer::give_item(cItem item, int flags) { } bool cPlayer::equip_item(int which_item, bool do_print) { - if((*items[which_item].variety).equip_count == 0) { + const cItem& item = items[which_item]; + if((*item.variety).equip_count == 0) { if(do_print && print_result) print_result("Equip: Can't equip this item."); return false; @@ -552,13 +553,12 @@ bool cPlayer::equip_item(int which_item, bool do_print) { unsigned short num_this_type = 0, hands_occupied = 0; for(int i = 0; i < items.size(); i++) if(equip[i]) { - if(items[i].variety == items[which_item].variety) + if(items[i].variety == item.variety) num_this_type++; hands_occupied += (*items[i].variety).num_hands; } - - eItemCat equip_item_type = (*items[which_item].variety).exclusion; + eItemCat equip_item_type = (*item.variety).exclusion; // Now if missile is already equipped, no more missiles if(equip_item_type != eItemCat::MISC) { for(int i = 0; i < items.size(); i++) @@ -572,11 +572,11 @@ bool cPlayer::equip_item(int which_item, bool do_print) { } size_t hands_free = 2 - hands_occupied; - if(hands_free < (*items[which_item].variety).num_hands) { + if(hands_free < (*item.variety).num_hands) { if(do_print && print_result) print_result("Equip: Not enough free hands"); return false; - } else if((*items[which_item].variety).equip_count <= num_this_type) { + } else if((*item.variety).equip_count <= num_this_type) { if(do_print && print_result) print_result("Equip: Can't equip another"); return false;